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 gelentruedeğerini, eşit olmadıklarında da "doğru olmama" anlamına gelenfalsedeğ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ğeritrueise hiç sağ taraftaki ifadeyi işletmedentruedeğerini üretir. Sol taraffalseise sağ taraftakinin değerini üretir. Bu işlem Türkçe veya ifadesine benzer: birincisi, ikincisi, veya ikisi birdentrueolduğ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 birtruedeğer olduğu içintruedeğerini üretir. -
&&"Ve" anlamındadır. Sol tarafındaki ifadenin değerifalseise hiç sağ taraftaki ifadeyi işletmedenfalsedeğerini üretir. Sol taraftrueise sağ taraftakinin değerini üretir. Bu işlem Türkçe ve ifadesine benzer: birincisi ve ikincisitrueolduğ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ütrueolduğunda (ama ikisi birden değil)truedeğ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ğilsefalsedeğ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ğilsefalsedeğ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:trueisefalse,falseisetrue.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
booltüründe olduklarını hatırlayın. Bildiğinizbooldeğ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.
Kitaplar
Forum
Tanıtım
İletişim
Hakları