Mantıksal İfadeler
Programda asıl işleri ifadeler yaparlar. Programda değer veya yan etki üreten her şeye ifade denir. Aslında oldukça geniş bir kavramdır, çünkü 42
gibi bir tamsayı sabiti bile 42 değerini ürettiği için bir ifadedir. "merhaba"
gibi bir dizgi de bir ifadedir, çünkü "merhaba"
sabit dizgisini üretir. (Not: Buradaki üretme kavramını değişken tanımlama ile karıştırmayın. Burada yalnızca değer üretmekten söz ediliyor; değişken üretmekten değil. Her değerin bir değişkene ait olması gerekmez.)
writeln
gibi kullanımlar da ifadedirler, çünkü yan etkileri vardır: çıkış akımına karakter yerleştirdikleri için çıkış akımını etkilemiş olurlar. Şimdiye kadar gördükleriniz arasından atama işlecini de bir ifade örneği olarak verebiliriz.
İfadelerin değer üretiyor olmaları, onların başka ifadelerde değer olarak kullanılmalarını sağlar. Böylece basit ifadeler kullanılarak daha karmaşık ifadeler elde edilebilir. Örneğin hava sıcaklığını veren bir hava_sıcaklığı()
işlevi olduğunu düşünürsek, onu kullanarak şöyle bir çıktı oluşturabiliriz:
writeln("Şu anda hava ", hava_sıcaklığı(), " derece");
O satır toplam dört ifadeden oluşur:
"Şu anda hava "
ifadesihava_sıcaklığı()
ifadesi" derece"
ifadesi- ve o üç ifadeyi kullanan
writeln
'li ifade
Bu bölümde mantıksal ifadeleri göreceğiz ama daha ileri gitmeden önce en temel işlemlerden olan atama işlecini hatırlayalım.
= (atama işleci): Sağ tarafındaki ifadenin değerini sol tarafındaki ifadeye (örneğin bir değişkene) atar.
hava_sıcaklığı = 23 // hava_sıcaklığı'nın değeri 23 olur
Mantıksal ifadeler
Mantıksal ifadeler Bool aritmetiğinde geçen ifadelerdir. Karar verme düzeneğinin parçası oldukları için bilgisayarları akıllı gösteren davranışların da temelidirler. Örneğin bir programın "eğer girilen yanıt Evet ise dosyayı kaydedeceğim" gibi bir kararında bir mantıksal ifade kullanılır.
Mantıksal ifadelerde yalnızca iki değer vardır: "doğru olmama" anlamını taşıyan false
ve "doğruluk" anlamını taşıyan true
.
Aşağıdaki örneklerde bir soru ile kullanılan writeln
ifadelerini şöyle anlamanız gerekiyor: Eğer sorunun karşısına "true" yazılmışsa evet, "false" yazılmışsa hayır... Örneğin programın çıktısı
Tatlı var: true
olduğunda "evet, tatlı var" demektir. Aynı şekilde
Tatlı var: false
olduğunda "hayır, tatlı yok" demektir. Yani çıktıda "var" göründüğü için "var olduğunu" düşünmeyin; çıktıdaki "... var: false", "yok" anlamına geliyor. Aşağıdaki program parçalarını hep öyle okumanız gerekiyor.
Mantıksal ifadeleri daha ileride göreceğimiz koşullarda, döngülerde, parametrelerde, vs. çok kullanacağız. Programlarda bu kadar çok kullanıldıkları için mantıksal ifadeleri çok iyi anlamak gerekir. Tanımları son derece kısa olduğu için çok da kolaydırlar.
Mantıksal ifadelerde kullanılan mantıksal işleçler şunlardır:
-
==
"Eşit midir" sorusunu yanıtlar. İki tarafındaki ifadelerin değerlerini karşılaştırır ve eşit olduklarında "doğruluk" anlamına gelentrue
değerini, eşit olmadıklarında da "doğru olmama" anlamına gelenfalse
değerini üretir. Ürettiği değerin türü de doğal olarakbool
'dur. İki değişkenimiz olsun:int haftadaki_gün_sayısı = 7; int yıldaki_ay_sayısı = 12;
Onları kullanan iki eşitlik işleci ifadesi ve sonuçları şöyle gösterilebilir:
haftadaki_gün_sayısı == 7 // true yıldaki_ay_sayısı == 11 // false
-
!=
"Eşit değil midir" sorusunu yanıtlar. İki tarafındaki ifadeleri karşılaştırır ve==
işlecinin tersi sonuç üretir.haftadaki_gün_sayısı != 7 // false yıldaki_ay_sayısı != 11 // true
-
||
"Veya" anlamındadır. Sol tarafındaki ifadenin değeritrue
ise hiç sağ taraftaki ifadeyi işletmedentrue
değerini üretir. Sol taraffalse
ise sağ taraftakinin değerini üretir. Bu işlem Türkçe veya ifadesine benzer: birincisi, ikincisi, veya ikisi birdentrue
olduğundatrue
üretir.
Bu işlece verilen iki ifadenin alabileceği olası değerler ve sonuçları şöyledir:
Sol ifade İşleç Sağ ifade Sonuç false || false false false || true true true || false (bakılmaz) true true || true (bakılmaz) true import std.stdio; void main() { /* false "yok" anlamına gelsin, * true "var" anlamına gelsin */ bool baklava_var = false; bool kadayıf_var = true; writeln("Tatlı var: ", baklava_var || kadayıf_var); }
Yukarıdaki programdaki
||
işlecini kullanan ifade, en az birtrue
değer olduğu içintrue
değerini üretir. -
&&
"Ve" anlamındadır. Sol tarafındaki ifadenin değerifalse
ise hiç sağ taraftaki ifadeyi işletmedenfalse
değerini üretir. Sol taraftrue
ise sağ taraftakinin değerini üretir. Bu işlem Türkçe ve ifadesine benzer: birincisi ve ikincisitrue
olduğundatrue
üretir.Sol ifade İşleç Sağ ifade Sonuç false && false (bakılmaz) false false && true (bakılmaz) false true && false false true && true true writeln("Baklava yiyeceğim: ", baklava_yemek_istiyorum && baklava_var);
Not:
||
ve&&
işleçlerinin bu "sağ tarafı ancak gerektiğinde" işletme davranışları işleçler arasında çok nadirdir, ve bir de şimdilik sonraya bırakacağımız?:
işlecinde vardır. Diğer işleçler bütün ifadelerinin değerlerini her zaman için hesaplarlar ve kullanırlar. -
^
"Yalnızca birisi mi" sorusunu yanıtlar. İki ifadeden ya biri ya öbürütrue
olduğunda (ama ikisi birden değil)true
değerini üretir.Sol ifade İşleç Sağ ifade Sonuç false ^ false false false ^ true true true ^ false true true ^ true false Örneğin ancak ve ancak bir arkadaşımın geldiğinde tavla oynayacağımı, aksi taktirde onlarla başka bir şey yapacağımı düşünürsek; onların gelip gelmeme durumlarına göre tavla oynayıp oynamayacağımı şöyle hesaplayabiliriz:
writeln("Tavla oynayacağım: ", ahmet_burada ^ barış_burada);
-
<
"Küçük müdür" sorusunu yanıtlar. Sol taraf sağ taraftan küçükse (veya sıralamada önceyse)true
, değilsefalse
değerini üretir.writeln("Yendik: ", yediğimiz_gol < attığımız_gol);
-
>
"Büyük müdür" sorusunu yanıtlar. Sol taraf sağ taraftan büyükse (veya sıralamada sonraysa)true
, değilsefalse
değerini üretir.writeln("Yenildik: ", yediğimiz_gol > attığımız_gol);
-
<=
"Küçük veya eşit midir" sorusunu yanıtlar. Sol taraf sağ taraftan küçük (veya sıralamada daha önce) veya ona eşit olduğundatrue
üretir.>
işlecinin tersidir.writeln("Yenilmedik: ", yediğimiz_gol <= attığımız_gol);
-
>=
"Büyük veya eşit midir" sorusunu yanıtlar. Sol taraf sağ taraftan büyük (veya sıralamada daha sonra) veya ona eşit olduğundatrue
üretir.<
işlecinin tersidir.writeln("Yenmedik: ", yediğimiz_gol >= attığımız_gol);
-
!
"Tersi" anlamındadır. Diğer mantıksal işleçlerden farklı olarak tek bir ifade ile çalışır ve sağ tarafındaki ifadenin değerinin tersini üretir:true
isefalse
,false
isetrue
.writeln("Bakkala gideceğim: ", !ekmek_var);
İfadeleri gruplamak
İfadelerin hangi sırada işletilecekleri gerektiğinde parantezlerle belirtilir. Karmaşık ifadelerde önce parantez içindeki ifadeler işletilir ve onların değeri dıştaki işleçle kullanılır. Örneğin "kahve veya çay varsa ve yanında da baklava veya kadayıf varsa keyfim yerinde" gibi bir ifadeyi şöyle hesaplayabiliriz:
writeln("Keyfim yerinde: ",
(kahve_var || çay_var) && (baklava_var || kadayıf_var));
Kendimiz parantezlerle gruplamazsak, ifadeler D dilinin kuralları ile belirlenmiş olan önceliklere uygun olarak işletilirler. &&
işlecinin önceliği ||
işlecininkinden daha yüksektir. Yukarıdaki mantıksal ifadeyi parantezlerle gruplamadan şöyle yazdığımızı düşünelim:
writeln("Keyfim yerinde: ",
kahve_var || çay_var && baklava_var || kadayıf_var);
O ifade, işlem öncelikleri nedeniyle aşağıdakinin eşdeğeri olarak işletilir:
writeln("Keyfim yerinde: ",
kahve_var || (çay_var && baklava_var) || kadayıf_var);
Bu da tamamen farklı anlamda bir ifadeye dönüşmüş olur: "kahve varsa, veya çay ve baklava varsa, veya kadayıf varsa; keyfim yerinde".
Bütün işleçlerin işlem önceliklerini hemen hemen hiçbir programcı ezbere bilmez. O yüzden, gerekmese bile parantezler kullanarak hangi ifadeyi kurmak istediğinizi açıkça belirtmek kodun anlaşılırlığı açısından çok yararlıdır.
İşleç öncelikleri tablosunu ilerideki bir bölümde göreceğiz.
Girişten bool
okumak
Yukarıdaki örneklerdeki bütün bool
ifadeler çıkışa "false"
veya "true"
dizgileri olarak yazdırılırlar. Bunun tersi de doğrudur: readf()
girişten gelen "false"
ve "true"
dizgilerini false
ve true
değerlerine dönüştürür. Bu dizgilerdeki harfler büyük veya küçük olabilir; örneğin, "False"
ve "FALSE"
dizgileri false
'a, "True"
ve "TRUE"
dizgileri de true
'ya dönüştürülür.
Bu dönüşümler yalnızca bool
değişkenlere okunurken geçerlidir. Girişteki karakterler string
değişkenlere okunurken oldukları gibi okunurlar. (Daha sonra dizgiler bölümünde göreceğimiz gibi, string
okurken readln()
işlevini kullanmak gerekir.)
Problemler
- Sayıların büyüklüğü ve küçüklüğü ile ilgili olan
<
,>
vs. işleçleri bu bölümde tanıdık. Bu işleçler içinde "arasında mıdır" sorusunu yanıtlayan işleç bulunmaz. Yani verilen bir sayının iki değer arasında olup olmadığını hesaplayan işleç yoktur. Bir arkadaşınız bunun üstesinden gelmek için şöyle bir program yazmış olsun. Bu programı derlemeye çalışın ve derlenemediğini görün:import std.stdio; void main() { int sayı = 15; writeln("Arasında: ", 10 < sayı < 20); // ← derleme HATASI }
Derleme hatasını gidermek için bütün ifadenin etrafında parantez kullanmayı deneyin:
writeln("Arasında: ", (10 < sayı < 20)); // ← derleme HATASI
Yine derlenemediğini görün.
- Aynı arkadaşınız hatayı gidermek için bir şeyler denerken derleme hatasının gruplama ile giderildiğini farketsin:
writeln("Arasında: ", (10 < sayı) < 20);
Bu sefer programın beklendiği gibi çalıştığını ve "true" yazdığını gözlemleyin. O çıktı yanıltıcıdır çünkü programda gizli bir hata bulunuyor. Hatanın etkisini görmek için 15 yerine bu sefer 20'den büyük bir değer kullanın:
int sayı = 21;
O değer 20'den küçük olmadığı halde program yine "true" yazdıracaktır.
İpucu: Mantıksal ifadelerin değerlerinin
bool
türünde olduklarını hatırlayın. Bildiğinizbool
değerlerin 20 gibi bir sayıdan küçük olması gibi bir kavram tanımadık. - D'de "arasında mıdır" sorusunu yanıtlayan mantıksal ifadeyi şu şekilde kodlamamız gerekir: alt sınırdan büyüktür ve üst sınırdan küçüktür. Programdaki ifadeyi o şekilde değiştirin ve artık çıktının beklendiği gibi "true" olduğunu görün. Ayrıca, yazdığınız ifadenin
sayı
'nın başka değerleri için de doğru çalıştığını denetleyin. Örneğin,sayı
50 veya 1 olduğunda sonuç "false" çıksın; 12 olduğunda "true" çıksın. - Plaja ancak iki koşuldan birisi gerçekleştiğinde gidiyor olalım:
- Mesafe 10'dan az (kilometre varsayalım) ve yeterince bisiklet var
- Kişi sayısı 5 veya daha az, arabamız var, ve ehliyetli birisi var
Aşağıdaki programdaki mantıksal ifadeyi bu koşullar sağlandığında "true" yazdıracak şekilde kurun. Programı denerken "... var mı?" sorularına "false" veya "true" diye yanıt verin:
import std.stdio; void main() { write("Kaç kişiyiz? "); int kişi_sayısı; readf(" %s", &kişi_sayısı); write("Kaç bisiklet var? "); int bisiklet_sayısı; readf(" %s", &bisiklet_sayısı); write("Mesafe? "); int mesafe; readf(" %s", &mesafe); write("Araba var mı? "); bool araba_var; readf(" %s", &araba_var); write("Ehliyet var mı? "); bool ehliyet_var; readf(" %s", &ehliyet_var); /* Aşağıdaki true'yu silin ve yerine sorudaki koşullardan * birisi gerçekleştiğinde true üretecek olan bir * mantıksal ifade yazın: */ writeln("Plaja gidiyoruz: ", true); }
Programın doğru çalıştığını farklı değerler girerek denetleyin.