Üçlü İşleç ?:
?: işleci, temelde bir if-else deyimi gibi çalışır:
if (/* koşul */) { /* doğruluk işlemleri */ } else { /* doğru olmama işlemleri */ }
if deyimi, koşul doğru olduğunda doğruluk işlemlerini, aksi durumda diğer işlemleri işletir. Hatırlarsanız, if bir deyimdir ve bu yüzden kendi değeri yoktur; tek etkisi, programın işleyişini etkilemesidir.
?: işleci ise bir ifadedir ve if-else ile aynı işi, ama bir değer üretecek şekilde gerçekleştirir. Yukarıdaki kodu ?: kullanarak şöyle yazabiliriz (bölüm açıklamalarını kısaltarak gösteriyorum):
/* koşul */ ? /* doğruluk işlemi */ : /* doğru olmama işlemi */
?: işleci üç bölümündeki üç ifade yüzünden üçlü işleç olarak adlandırılır.
Bu işlecin değeri; koşula bağlı olarak ya doğruluk işleminin, ya da doğru olmama işleminin değeridir. İfade olduğu için, ifadelerin kullanılabildiği her yerde kullanılabilir.
Aşağıdaki örneklerde aynı işi hem ?: işleci ile, hem de if deyimi ile gerçekleştireceğim. ?: işlecinin bu örneklerdeki gibi durumlarda çok daha kısa olduğunu göreceksiniz.
- İlkleme
Artık yıl olduğunda 366, olmadığında 365 değeri ile ilklemek için:
int günAdedi = artıkYıl ? 366 : 365;
Aynı işi if ile yapmak istesek; bir yol, baştan hiç ilklememek ve değeri sonra vermektir:
int günAdedi; if (artıkYıl) { günAdedi = 366; } else { günAdedi = 365; }
if ile başka bir yol; baştan artık yıl değilmiş gibi ilklemek ve adedi sonra bir arttırmak olabilir:
int günAdedi = 365; if (artıkYıl) { ++günAdedi; }
Yazdırılan bir mesajın bir parçasını ?: ile duruma göre farklı yazdırmak:
writeln("Bardağın yarısı ", iyimser ? "dolu" : "boş");
Aynı işi yapmak için mesajın baş tarafını önce yazdırabilir ve gerisini sonra if ile seçebiliriz:
write("Bardağın yarısı "); if (iyimser) { writeln("dolu"); } else { writeln("boş"); }
if ile başka bir yol, bütün mesajı farklı olarak yazdırmaktır:
if (iyimser) { writeln("Bardağın yarısı dolu"); } else { writeln("Bardağın yarısı boş"); }
Tavla puanını mars olup olmama durumuna göre ?: ile 2 veya 1 arttırmak:
tavlaPuanı += marsOldu ? 2 : 1;
if ile puanı duruma göre 2 veya 1 arttırmak:
if (marsOldu) { tavlaPuanı += 2; } else { tavlaPuanı += 1; }
if ile başka bir yol; baştan bir arttırmak ve mars ise bir kere daha arttırmak olabilir:
++tavlaPuanı;
if (marsOldu) {
++tavlaPuanı;
}
Bu örneklerden görüldüğü gibi kod ?: işleci ile çok daha kısa olmaktadır.
Seçilecek ifadelerin türleri uyumlu olmalıdır
?: işlecinin ifade değeri, denetlenen koşula bağlı olarak ya doğru ifadesinin değeridir, ya da doğru olmama ifadesinin. İşlecin kullanımının D kurallarına göre geçerli olarak kabul edilebilmesi için bu iki ifadenin türlerinin uyumlu olmaları gerekir.
Örneğin yukarıdaki günAdedi değişkeni ilklenirken seçilen değer, artıkYıl koşuluna bağlı olarak ya 366'dır ya da 365. Bu değerlerin ikisinin de türü int olduğu için ifade geçerlidir.
Geçerli olmayan bir örnek olarak Ddili Forum'un mesajlarından birisine bakalım. Bağlı olan kullanıcı sayısı 1 olduğunda mesaj "tek" kelimesi ile yazılır: "Şu an tek kullanıcı bağlı".
Kullanıcı sayısı 1'den fazla olduğunda ise rakamla gösterilir. Örneğin, "Şu an 3 kullanıcı bağlı".
O mesajı kodlarken "tek" ve 3 arasındaki seçimi ?: işleciyle kolayca gerçekleştirebileceğimizi düşünebiliriz:
writeln("Şu an ", (adet == 1) ? "tek" : adet, // ← derleme HATASI " kullanıcı bağlı");
Ne yazık ki o kod yasal değildir, çünkü koşul sonucunda seçilecek iki ifadenin türleri farklıdır: "tek" bir string olduğu halde, adet bir int'tir.
Çözüm olarak adet'i de string'e dönüştürebiliriz. std.conv modülünde bulunan to!string işlevi, kendisine verilen ifadenin string karşılığını üretir:
import std.conv; // ... writeln("Şu an ", (adet == 1) ? "tek" : to!string(adet), " kullanıcı bağlı");
Artık ?: işlecinin her iki ifadesi de aynı türden (string) olduğu için kod hatasız olarak derlenir ve çalışır.
Problem
- Program kullanıcıdan bir tamsayı değer alsın; bu değerin sıfırdan küçük olması zararda olmak, sıfırdan büyük olması da kazançlı olmak anlamına gelsin.
Program verilen değere göre sonu "zarardasınız" veya "kazançlısınız" ile biten bir mesaj yazdırsın. Örneğin "100 lira zarardasınız" veya "70 lira kazançlısınız". Daha uygun görseniz bile bu dersle ilgili olabilmesi için if koşulunu kullanmayın.
D.ershane
Forum
Wiki
Projeler
Tanıtım
İletişim
Hakları