D.ershane D Programlama Dili Dersleri

atama: [assign], değişkene yeni bir değer vermek
dizgi: [string], "merhaba" gibi bir karakter dizisi
ifade: [expression], programın değer oluşturan veya yan etki üreten bir bölümü
işleç: [operator], bir veya daha fazla değişkenle iş yapan özel işaret (||, &&, +, -, =, vs.)
işlev: [function], programdaki bir kaç adımı bir araya getiren program parçası
öncelik: [precedence], işleçlerin hangi sırada işletilecekleri
yan etki: [side effect], bir ifadenin, ürettiği değer dışındaki etkisi
... bütün sözlük

Bölümler
İngilizce Kaynaklar
Diğer



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:

  1. "Şu anda hava " ifadesi
  2. hava_sıcaklığı() ifadesi
  3. " derece" ifadesi
  4. 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 İfadeler

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. Örneğin Türkçe "başkent İstanbul'dur" ifadesinin değeri false, "başkent Ankara'dır" ifadesinin değeri true'dur.

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:

İ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 de || işlecinden daha yüksek olduğu için, yukarıdaki mantıksal ifadeyi gruplamadan şöyle yazarsak

writeln("Keyfim yerinde: ",
        kahve_var || çay_var && baklava_var || kadayıf_var);

işlem öncelikleri nedeniyle şunun eşdeğeri olarak işletilir

writeln("Keyfim yerinde: ",
        kahve_var || (çay_var && baklava_var) || kadayıf_var);

ve tamamen farklı anlamda bir ifadeye dönüşür: "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.

Girişten bool Okumak

Yukarıdaki örneklerdeki bütün bool ifadeler çıkışa "false" veya "true" dizgileri olarak yazdırılırlar. Bunun karşıtı doğru değildir: girişten okunan "false" ve "true" dizgileri otomatik olarak false ve true değerlerine dönüştürülmezler. O yüzden, girişten gelen kelimeyi önce bir dizgi olarak okumamız, ve sonra ona bakarak bir bool değere dönüştürmemiz gerekir.

Aşağıdaki programı denerken girişten "false" ve "true" girebilmenizi istiyorum. Böylece bu derste anlatılanları aynen deneyebileceksiniz. Bunun olabilmesi için, derslerin başında planladığım yoldan sapacak ve istemeyerek henüz anlatmadığım kodlar göstereceğim. Girişten gelen "false" dizgisini false değerine, "true" dizgisini de true değerine dönüştüren bir işlev kullanacağım. Bu işlev, std.conv modülünde tanımlanmış olan to'dan yararlanacak. ("false" veya "true"dan başka bir dizgi girdiğinizde ConvException hatası atılır.)

Aşağıdaki programlardaki main'ler içinde anlaşılmaz bir taraf olmadığını umuyorum. Ama girişten_bool_oku() işlevinde henüz görmediğiniz olanaklar kullanılıyor; içine açıklamalar koydum ama isterseniz o işlevi şimdilik tamamen gözardı da edebilirsiniz.

Problemler
  1. Sayıların büyüklüğü ve küçüklüğü ile ilgili olan <, > vs. işleçleri bu derste 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:
  2. 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));
    

    Yine derlenemediğini görün.

  3. Aynı arkadaşınız hatayı gidermek için bir şeyler denerken derleme hatasının gruplama ile giderildiğini farketsin:
  4. writeln("Arasında: ", (10 < sayı) < 20);
    

    Bu sefer programın beklendiği gibi çalıştığını ve "true" yazdığını gözlemleyin. Ne yazık ki 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ın yine de "true" yazdırdığını görün.

    İpucu: Mantıksal ifadelerin değerlerinin bool türünde olduklarını hatırlayın. Bildiğiniz bool değerlerin 20 gibi bir sayıdan küçük olması gibi bir kavram tanımadık.

  5. 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.
  6. 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;
    import std.conv;
    import std.string;
    
    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);
    
        bool araba_var = girişten_bool_oku("Araba var mı? ");
        bool ehliyet_var = girişten_bool_oku("Ehliyet var mı? ");
    
        /*
          Buradaki true'yu silin ve yerine sorudaki koşullardan
          birisi gerçekleştiğinde true üreten bir mantıksal ifade
          yazın:
         */
        writeln("Plaja gidiyoruz: ", true);
    }
    
    /*
      Bu işlevde henüz göstermediğim olanaklar kullanılıyor. Bu
      yüzden, aslında gerekmeyen açıklamalar da ekledim.
     */
    bool girişten_bool_oku(string mesaj)
    {
        // Mesajı yazdır
        writef(mesaj ~ "(false veya true) ");
    
        // Girilen satırı bir dizgiye oku
        string giriş;
        while (giriş.length == 0) {
            giriş = chomp(readln());
        }
    
        // O dizgiden bir bool değer üret
        bool dönüştürülen_değer = to!bool(giriş);
    
        // Üretilen değeri işlevi çağırana döndür
        return dönüştürülen_değer;
    }
    

    Çeşitli değerler girin, ve yazdığınız ifadenin her durumda doğru çalıştığını denetleyin: koşullara uyduğunda "true", uymadığında "false" yazsın.

... çözümler