15 Nisan 2011 Cuma

boolean Türü ve İlkel Türler Arasında Tür Uyumluluğu

İlkel türleri tanıtmaya devam ettiğimiz bu yazıda, çalışmakta olan programda bir koşulun oluşup oluşmadığını denetlemek amacıyla kullanılan boolean türüne baktıktan sonra ilkel türden değerlerin birbirleri yerine kullanılabilme özelliklerine göz atacağız.

boolean Türü

Koşullu ve yinelemeli komut işlemenin temeli olan doğruluk denetimi, boolean türlü sabitler olan true veya false değerlerinden birini üreten ilişkisel işleçlerin1 kullanılmasıyla yapılır. Denetlenmesi istenen koşulun karmaşıklaşması durumunda ilişkisel işleçli ifadeler mantıksal işleçler2 kullanılarak birleştirilebilir.3 Bir örnekle görelim.

Faktöryel.java
import java.util.Scanner;

public class Faktöryel {
  public static void main(String[] ksa) {
    Scanner grdKnl = new Scanner(System.in);
    System.out.print("Faktöryeli bulunacak sayı: ");
    int n = grdKnl.nextInt();
    System.out.println(n + "!: " + fakt(n));
  } // void main(String[]) sonu

  public static long fakt(int n) {
    if (n == 1 || n == 0)
      return 1;
      else return n * fakt(n-1);
  } // long fakt(int) sonu
} // Faktöryel sınıfının sonu

Programımız, standart girdi dosyasından—değiştirilmediği müddetçe klavye—girilen karakterleri tarayarak istenen türden veriler haline dönüştüren Scanner türündeki grdKnl kullanılarak alınan tamsayı değerin faktöryelini hesaplıyor. Bu amaçla yazılmış olan özyinelemeli fakt metodunun sonsuz döngüye girmesini engellemekte kullanılan koşul deyimi, eşitlik denetleme işleci (==) ile oluşturulan iki altdeyimin veya bağlacı (||) ile birleştirilmesiyle oluşturuluyor. Buna göre, metottan parametre değerinin 0 veya 1'e eşit olması durumunda 1, aksi takdirde parametrenin 1 küçük değerin faktöryeli ile çarpımı döndürülüyor.

Mantıksal türün sonradan eklendiği C'nin yerleştirdiği alışkanlıklar sonucu, C/C++'da bir koşulun oluşmama durumu sıfır-benzeri bir değerle (NULL, 0,0, 0, vd.) temsil edilebilirken, oluşma durumu sıfır-benzeri olmayan herhangi bir değerle temsil edilebilir. Tür güvenliğine önem veren Java'da bu alışkanlığın unutulması gerekecektir. Dolayısıyla, aşağıdaki kod parçası Java derleyicisi tarafından kabul edilmez.

if (n % 2)
  System.out.println(n + " çift değil");
  else System.out.println(n + " çift");

İlkel Türler Arasında Tür Uyumluluğu

C/C++ dünyasından aşina son satırların Java derleyicisi tarafından kabul görmemesi, tamsayıların boolean değerler ile tür uyumlu olmadığı şeklinde ifade edilir. C/C++ dilinin "Programcı hata yapmaz, hata gibi gözüken şey muhtemelen yaratıcı bir kestirmedir" anlayışına karşılık, "Programcı da bir insandır ve hata yapabilir" felsefesinden hareket eden Java, belirtiyi ciddiye alır ve olası hatanın başkalaşmasına izin vermeden programcıya en erken aşamada (derleme) durumu bildirmeyi tercih eder.

Tamsayıların mantıksal değerlerin yerine kullanılamamasına benzer bir şekilde, byte türlü bir tanımlayıcıya int türlü bir değer sağlanması da hata olarak görülecektir. Bunun sebebi, int türünün temsil aralığının byte türünün temsil aralığında bulunmayan değerler içermesidir. Mesela, yukarıda verilen Faktöryel.fakt metodunun parametre türü byte olacak biçimde değiştirilmesi hataya neden olacaktır. Çünkü, söz konusu metodun çağrıldığı satırda geçirilen argüman int türlüdür ve -231 ile 231-1 arasındaki herhangi bir değere sahip olabilir; buna karşılık, argümanın değeriyle ilklenecek parametre byte türlüdür ve -128 ile 127 arasındaki değerleri temsil edebilir. İşte bu yüzdendir ki, parametre türünün byte olarak değiştirilmesi durumunda geçirilen argüman değerinin aşağıdaki kod parçasında olduğu gibi biçimlendirilmesi gerekir.

import java.util.Scanner;

public class Faktöryel {
  public static void main(String[] ksa) {
    ...
    System.out.println(n + "!: " + fakt((byte) n));
  } // void main(String[]) sonu

  public static long fakt(byte n) { ... } // long fakt(int) sonu
} // Faktöryel sınıfının sonu

Pek çok—kesin olmak gerekirse, sekiz—ilkel türün varlığı, tür uyumluluğu konusunda karar verme işini zorlaştırabilir. Bu noktada, türlerin kayan noktalı ve tamsayı türler şeklinde dizilmesi imdadınıza yetişecektir.

doublefloatlongintshortbyte
intchar
doubleboolean = ∅

Yukarıdaki geçişken üstküme-altküme ilişkisi ile resmedilen dizilim, en baştaki türün en kapsayıcı en sondakinin ise en az kapsayıcı olduğu şeklinde yorumlanmalıdır.4 Buna göre, double değerin beklendiği yerlerde diğer tüm sayısal türlerden değerler kullanılabilir. Buna karşılık, short değerin beklendiği yerlerde sadece byte türlü değerler kulanılabilirken, diğer tüm sayısal değerler ancak biçimlendirme yapılmak suretiyle kullanılabilecektir.

Dizilimde char türü için ayrı bir kapsama ilişkisinin tanımlanması, bu türün tamsayı türü olarak ele alınması durumunda eksi sayıları temsil edemeyecek olmasından kaynaklanır. Aynı büyüklükte bir alan kaplayan short -32768 ile 32767 aralığındaki değerleri temsil edebilirken, char 0 ile 65536 arasındaki değerleri temsil edebilir. Bir diğer deyişle, short'un char, char'ın short yerine konulması kimi zaman değer kaybına sebep olacaktır.


  1. Yararlanılabilecek ilişkisel işleçler ve varlığı denetlenen ilişki çeşidi şunlardır: == (eşitlik), != (eşitsizlik), > (büyüklük), < (küçüklük), >= (büyük veya eşitlik), < (küçük veya eşitlik).
  2. Mantıksal değerleri birleştirmede kullanılabilecek bağlaçlar ve anlamları şunlardır: ! (değilleme), && (ve), || (veya).
  3. Gerekli görüldüğü takdirde, denetleme işinin tümü veya bir bölümü, yüklem olarak da adlandırılan boolean dönüş türlü bir metodun çağrılması ile yapılabilir.
  4. Aslına bakacak olursanız, tür uyumluluğu için üstküme-altküme ilişkisinin kullanılması yanıltıcı bir uygulama. Çünkü, long ile temsil edilen kimi değerler ne double ne de float ile temsil edilebilirken, int ile temsil edilen kimi değerler float ile temsil edilemez. Ancak, anılan türler arasında dizilimin önerdiği cinsten bir tür uyumluluğundan bahsetmek her zaman doğrudur.