Sayfalar

23 Ekim 2015 Cuma

ETU ACM Java Kursu: 2. Hafta (Branching)

Evet, arkadaşlar. Doğruyu söylemek gerekirse bu haftaki ders pek içime sinmedi. Dersin başında yaşadığımız aksilikler, sınıf değiştirmemiz daha sonrasında projektörün de çalışmamasıyla planladığımın aksine dersi tahtada anlatmak zorunda kaldım. Göstermek istediğim bazı şeyleri gösteremedim, bundan dolayı. Bu yayınla ve gelecek haftaki derste bu durumu telafi etmeye çalışacağım.


Derse geçen haftanın tekrarı olması amacıyla, çift-tek kontrolü yapan bir programla başladık.

public class CiftTek {
 
 public static void main(String[] args) {
  
  int sayi = 7;
  
  if (sayi % 2 == 0) 
   System.out.println("Çift");
  else 
   System.out.println("Tek");
 }

}

Burada = in, matematikten alışık olduğumuzun aksine atama, == işaretinin ise eşittir anlamına geldiğini hatırlatmakta fayda var.

Vakti gelmişken bazılarının aklına takılan birşeye açıklık getirmektede fayda, zorunda olmadığımız halde uyduğumuz bazı kurallar var. Bunlara "convention" deniyor. Dikkatinizi çekmiş olabileceği üzere değişken isimlerine hep küçük harfle başlarken, sınıf isimlerine büyük harfle baslıyoruz. Bunun nedeni kod içerisinde bir isim gördüğünüzde onun bir değişkenmi yoksa bir sınıf mı olduğunu rahatça anlayabilmek için.

Daha sonra programımızın yukarıdaki gibi 2 değil de, 3 veya daha fazla sayıda dallanma yapmak istersek ne olacağını tartışktık. Bunu açıklamak için ağaçları kullanmıştım.

Yukarıdaki şekilde gördüğünüz gibi, örneğin else'den sonra bir tane daha if-else ifadesi koyarak programın 3 farklı yola çıkması sağlanabilir. Örnek olarak iki tane sayının büyük, küçük ya da eşit olma durumuna bakan bir kod parçası yazmıştık.


int sayi1 = 4;
int sayi2 = 5;
 
if (sayi1 > sayi2)
 System.out.println("Büyüktür.");
else 
 if (sayi1 < sayi2)
  System.out.println("Küçüktür.");
 else
  System.out.println("Eşittir");
Gördüğünüz gibi kodda tıpki bir ağaç gibi dallanıyor. Burada ki tablar aslında programın bir parçası değil, sadece hangi kısmın nereye ait olduğunu kodu okuyan kişinin daha rahat anlaması için yapılıyor (indentation) ama dallanma sayısı arrtıkça kod ileri doğru çok fazla kayacağından anlaşılırlık kaybolabiliyor.


Bu yüzden genelde else'in için başak bir if-else ifadesi olunca kod şu şekilde düzenlenir.

if (sayi1 > sayi2)
 System.out.println("Büyüktür.");
else if (sayi1 < sayi2)
 System.out.println("Küçüktür.");
else
 System.out.println("Eşittir");
Daha sonra liseden de hatırlıyor olabileceğiniz ve, veya mantıksal işlemlerini gördük. Geçen haftaki notlarda bunlardan bahsetmiştim. Egzersiz olarak ise birbirinden farklı girilen 3 sayıdan ortancasını bulan bir program yazdık.

Diyelim ki bu 3 sayı x, y ve z olsun. Bu 3 sayı 3! = 6 dan, 6 farklı şekilde sıralı olabilir. Bunlar:

y > x > z 
z > x > y

x > y > z
z > y > x

x > z > y
y > z > x

Bu 6 durumdan ilk ikisi olması durumunda ortanca x, diğer ikisi olması durumunda y, diğer ikisi olması durumunda ise ortanca z olur.

Şimdi bu mantığı kullanarak programalmaya kalkıştığımızda bir sorun ortaya çıkıyor. Örneğin y > x > z yazdığımızda beklemedik şekilde bir hata alıyoruz. Aslında düşünürseniz bunun nedeni basit. Program ilk önce x > z yi hesaplıyor, sonuç doğru ya da yanlış çıkıyor. Diyelim ki doğru olsun. Daha sonra y > true'yu hesaplamaya kalkıyor ama bu anlamsız olduğundan dolayı hata veriyor. Bu sorunu aşmak için y > x > z yerine y > x && x > z yazmamız gerekiyor. Böylece iki tarafada bakıyor, ve(&&) işlemi sayesinde iki tarafta doğru ise doğru dönüyor bu da matematikten bildiğimiz y > x > z 'ye karşılık gelmekte. Programın tam hali ise bu şekilde:


public class Ortanca {

 public static void main(String[] args) {
  
  int x, y, z;
  
  x = 3;
  y = 4;
  z = 5;
  
  if (y > x && x > z || z > x && x > y) 
   System.out.println(x);
  else if (x > y && y > z || z > y && y > x) 
   System.out.println(y);
  else 
   System.out.println(z);
  
 }
}

Ancak bu koda baktığınızda if ifadelerinin içinin ne kadar da gereksiz yere uzadığı dikkatiniz çekmiş olabilir. Aslında bunu daha sade bir halde yapmak mümkün.

örneğin ilk ifadede y > x && x > z || z > x && x > y yazan kısımda veya işlemenin iki tarafındaki eşitsizlikler birbirlerini tersleri, p = y > x ve q = x > z olsun. O zaman bu ifade de p && q || !p && !q (! işareti değil demek). Bu ifadeyi boolean cebri, lisede de gördüğünüz mantık problemlerindeki gibi sadeleştirmek mümkün. Ancak söylede düşünübeliriz: Diyelim ki p ile q doğru, o zaman bu ifade de doğru olur, peki diyelim p ile q yanlış, o zaman !p ile !q doğru olacağından yine doğru olur. Yani bu ifade hem p hem q doğru olduğunda, ya da hem p hem q yanlış olduğunda doğru oluyor. Demek ki p ve q nün değerleri aynı olunca doğru: p == q yani y > x == x > z. Diğer ifadeyi de aynı şekilde sadeleştirebilir, böyle şu programı elde ederiz:


public class SadeOrtanca {
  
 public static void main(String[] args) {

  int x, y, z;
  
  x = 3;
  y = 4;
  z = 5;
  
  if (y > x == x > z) 
   System.out.println(x);
  else if (x > y == y > z)  
   System.out.println(y);
  else
   System.out.println(z);
  
 }

}

Dersin geri kalan kısmında charlardan, type castingden, stringlerden, nesnelerden ve methodlardan bahsetmiştik. Nesne ve methodlardan daha çok bahsedeceğiz. Ama saat biraz geç oldu. Bu akşam sınavım olduğu için notları hazırlamak biraz gecikti. Tamamlayınca buraya ekleyeceğim.

Hiç yorum yok: