C Programlama

Ek Bilgiler

C'de Switch Kalıbı

Daha önce if deyimini kullanarak iki veya daha fazla seçenekli bir sistemin nasıl oluşturulduğunu görmüştük. Ancak, seçeneğin fazla olduğu durumlarda, programın her durumda bütün if satırlarını tek tek kontrol etme zorunluluğundan dolayı, bu sistemin programı gereksiz yere meşgul ettiğinden bahsetmiştik. Bu sakıncayı ortadan kaldırmak için kullanılan if-else-if yapısını ise yine birlikte incelemiştik.

Şimdi, C dilinde çok seçenekli bir sistem sağlayan switch kalıbını inceleyelim. switch kalıbı bir ifadenin sonucuna bağlı olarak içinde yer alan herhangi bir seçenekteki işlem satırlarını çalıştıran bir kalıptır. Bu kalıbın genel yapısını birlikte inceleyelim:

switch(ifade) {
   case sabit1:
      işlem-satırı
      break;
   case sabit2:
      işlem-satırı;
      break;
      .
      .
      .
      default:
         işlem-satırı;
}

switch satırında yer alan ifade ile elde ettiğimiz değer mutlaka case terimlerinin bulunduğu satırlarda yer alan sabit değerlerle karşılaştırılabilecek bir değer olmalıdır. Buradaki ifade genellikle bir değişken değeri olmaktadır.

Program, switch deyiminin bulunduğu satırda yer alan ifadenin sonucu ile switch kalıbının case satırlarında yer alan sabit değerleri karşılaştırır. Burada bahsi geçen sabit değerler ya bir char ya da bir int sabitidir. İfade sonucu ile aynı değeri taşıyan sabit değerin yer aldığı case bölümüne bağlı işlem satırını veya satırlarını çalıştırır. break deyimini görür görmez, switch kalıbının dışına çıkar ve bir sonraki işlem satırından çalışmasına devam eder.

break deyimini, case yapıları içinde tanımlamak şart değildir. Değişken değeri ile aynı değeri taşıyan sabit değerin yer aldığı case bölümüne bağlı işlem satırı veya satırları çalıştığında, case yapısında bir break deyimi yer almaz ise, program hemen switch kalıbı dışına çıkmaz. Aksine, eğer aşağıda devam eden case yapıları varsa, herhangi bir koşul kontrolü yapmadan, bir sonraki case yapısındaki işlem satırlarını çalıştırır. Ancak, bütün case yapıları içinde break deyimini kullanırsanız, switch kalıbı içinde yer alan sadece tek bir case yapısına bağlı işlem satırı ya da satırları çalışır.

Koşul sağlanarak bir case yapısı içine girildiğinde çıkış ancak break deyimi ile ya da switch kalıbının sonuna gelmekle sağlanır.

case yapısı içinde break tanımı yapılmamışsa, herhangi bir koşul kontrolü yapmadan, bir sonraki case yapısındaki işlem satırları çalıştırılır.

Eğer, switch satırındaki değişken değeri case satırlarında yer alan sabit değerlerin herhangi biri ile aynı değeri taşımıyorsa, program default satırında yer alan işlem satırı veya satırlarını çalıştırır. default satırının tanımlanması tamamen isteğe bağlıdır. Yani, bu satır tanımlanmasa bile switch kalıbı normal olarak çalışır.

Program, switch kalıbı için tanımlanan değişken değeri ile aynı değeri taşıyan bir sabitin yer aldığı case satırı ile karşılaştığında, bir break ifadesi ile karşılaşana kadar o case satırında yer alan işlem satırlarının gereğini yerine getirir. Eğer son case satırı veya default satırı ile ilgili işlem satırlarının gereğini yerine getiriyorsa switch kalıbının sonuna geldiğinden işlemler otomatik olarak sona ermiş olur. Eğer, case satırlarında yer alan sabit değerlerinden hiçbiri değişken değeri ile aynı değilse ve switch kalıbı içinde default satırı tanımlanmamışsa, program switch kalıbında herhangi bir işlem yapmadan bir sonraki program işlem satırından çalışmasına devam eder.

Yukarıda anlattıklarımızı bir örnek üzerinde incelemeye çalışalım:

#include <stdio.h>
#include <conio.h>

main()
{
  char cd1;

  printf("Şu harflerden birini giriniz : [A]  [B]  [C]");
  cd1 = toupper(getch());
  printf("\n");

  switch (cd1) {
     case 'A' :
       printf("A harfini girdiniz!");
       break;
     case 'B' :
       printf("B harfini girdiniz!");
       break;
     case 'C' :
       printf("C harfini girdiniz!");
       break;
     default :
       printf("İstenen harflerden birini girmediniz!");

  }
}

Yukarıdaki örnekte, program A, B veya C harflerinden birisini girmenizi ister. Sonra, girdiğiniz harfi switch kalıbı için tanımlanmış olan d1 değişkenine atayarak case satırlarında yer alan harflerle karşılaştırır. Girdiğiniz harf case satırlarından birinde tanımlanmışsa ilgili satırda yer alan karakter dizisini, aksi takdirde default satırında yer alan karakter dizisini ekrana yazar.

switch kalıbı ile ilgili göz önünde bulundurulması gereken bazı önemli noktalar vardır:

* Daha önce gördüğümüz gibi, if deyiminde koşul ifadesi herhangi bir veri türünden olabilir. Ancak, switch kalıbı sadece int ve char veri türleri ile çalışır.

* Ayrıca, switch kalıbında sadece eşitlik için kontrol yapılır.

* Diğer önemli bir nokta ise, switch kalıbı ile ilgili case satırlarında yer alan işlem satırlarının { } işaretleri arasında yer almamış olmasıdır. Dolayısıyla, case satırlarında yer alan işlem satırları kod bloğu olarak değerlendirilemez.

Aynı switch kalıbındaki farklı case satırlarında yer alan değişken değerleri birbirinin aynı olamaz. Bu şekilde hazırlanmış olan bir program derlenirken hata verir.

ANSI standartlarına göre, bir derleyicide switch kalıbı içinde en az 257 adet case satırı tanımlanabilmelidir. Bu arada, program içinde switch kalıpları ile mümkün olduğu kadar az case satırı tanımlamanın programı daha kullanışlı bir hale getireceği unutulmamalıdır.

switch kalıplarını birbiri içinde kullanabilirsiniz. Yani, bir switch kalıbına ait bir case satırı ile ilgili işlem satırları yerine başka bir switch kalıbı tanımlayabilirsiniz. ANSI standartlarına göre, bir derleyici birbiri içinde en az 15 adet switch kalıbı tanımlama imkanı sağlamalıdır. Aşağıda birbiri içinde tanımlanmış 2 switch kalıbı gösterilmektedir. Koyu renkle yazılmış olan ifadeler dışta kalan switch kalıbına aittir:

switch(değişken1) {
     case sabit1:
         switch(değişken2) {
             case sabit1:
                 işlem satırı;
                 break;
             case sabit2:
                 işlem satırı;
                 break;
             case sabit3:
                 işlem satırı;
                 break;
         }
     case sabit2:
         işlem satırı;
         break;
     .
     .
     .
     default:
         işlem satırı;
}

Şimdi, bu özelliği bir örnek üzerinde incelemeye çalışalım:

#include <stdio.h>
#include <conio.h>

main()
{
  int id1;
  char cd1;

  printf("Şu sayılardan birini giriniz: [1] [2] [3]");
  scanf("%d", &id1);

  switch (id1) {
        case 1 :
          printf("Şu harflerden birini giriniz: [A] [B]\n");
          cd1 = toupper (getch());
          switch (cd1) {
             case 'A':
               fonk1();
               break;
             case 'B':
               fonk2();
               break;
             default :
               printf("Belirtilen harflerden birini girmediniz!\n");
          }
          break;
        case 2 :
          printf("2 numaralı seçeneği seçtiniz!\n");
          break;
        case 3 :
          printf("3 numaralı seçeneği seçtiniz!\n");
          break;
        default :
          printf("Verilen seçeneklerden birini girmediniz!\n");
  }
}

fonk1()
{
  printf("1 numaralı seçenek içinde A harfini girdiniz!\n");
}

fonk2()
{
  printf("1 numaralı seçenek içinde B harfini girdiniz!\n");
}

Yukarıdaki örnekte, program 1, 2 veya 3 sayılarından birini girmenizi ister. Sonra girdiğiniz değeri id1 değişkenine atar. İlk switch kalıbını id1 değişken değeri ile çalıştırır. Eğer girilen değer, 1, 2 veya 3 sayılarından biri değilse, case satırlarında yer alan sabit değerlerin hiçbiri girdiğiniz değer ile aynı olmadığından, sadece switch kalıbı içinde yer alan default satırındaki aşağıdaki cümleyi ekrana yazar:

Verilen seçeneklerden birini girmediniz!

Eğer 1 sayısını girerseniz, ilk case satırında koşul sağlandığı için program 'A' veya 'B' harflerinden birisini girmenizi ister. Eğer 'A' harfini girerseniz, program fonk1() fonksiyonunu, 'B' harfini girerseniz fonk2() fonksiyonunu çalıştırarak ilgili fonksiyonlarda yer alan karakter dizilerini ekrana yazar. Eğer, başlangıçta 2 sayısını girerseniz, program ikinci case satır koşulu sağlandığı için "2 numaralı seçeneği seçtiniz!" ifadesini, 3 sayısını girerseniz, üçüncü case satır koşulu sağlandığı için "3 numaralı seçeneği seçtiniz!" ifadesini ekrana yazar. Eğer girdiğiniz değer 'A' veya 'B' harflerinden farklı ise sadece switch kalıbı içinde yer alan default satırındaki aşağıdaki cümleyi ekrana yazar:

Belirtilen harflerden birini girmediniz!

Şimdi, başka bir örnek üzerinde switch kalıbının farklı bir kullanımını incelemeye çalışalım:

#include <stdio.h>
#include <conio.h>

main()
{
  char cd1;
  int id1;

  printf("Ekrana yazdırmak istediğiniz harfi girin!: [A] [B] [C]\n");
  cd1 = toupper(getch());

  printf("Ekrana kaç kez yazdırmak istersiniz: [1] [3] [5]");
  scanf("%d", &id1);

  switch(id1) {
     case 1:
        printf("%c", cd1);
        break;
     case 3:
        printf("%c %c %c", cd1, cd1, cd1);
        break;
     case 5:
        printf("%c %c %c %c %c", cd1, cd1, cd1, cd1, cd1);
        break;
  }
}

Yukarıdaki örnekte, program A, B veya C harflerinden birisini girmenizi ister. Program girdiğiniz harfi cd1 değişkenine atar. Sonra, harfi kaç kez ekran yazdırmak istediğinizi belirlemek için 1, 3 veya 5 sayılarından birini girmenizi ister ve girdiğiniz değeri id1 değişkenine atar. switch kalıbında id1 değişken değeri kadar girdiğiniz harfi ekrana yazar.

Daha önce break ifadesinin tanımlanmasının isteğinize bağlı olduğunu görmüştük. Bir switch kalıbının sona ermesi için ya program bir break ifadesi ile karşılaşmalıdır ya da kalıbın sonu gelmiş olmalıdır. Şimdiye kadar gördüğümüz örneklerde switch kalıbında en sonda yer alan hariç bütün case satırları için break ifadesi tanımladık. Bu durumda, sadece switch kalıbının tek bir case satırıyla ilgili işlem satır veya satırları çalışır.

Eğer bir switch kalıbında son case satırı dışındaki case satırlarından birinde break ifadesi tanımlanmazsa ve bu case satırında yer alan sabit değer switch kalıbının kontrol değişkeni ile aynı değeri taşıyorsa, bu case satırı ile ilgili işlemler tamamlandıktan sonra, break ifadesi olmadığından eğer varsa bir sonraki case satırı ile ilgili işlemler yapılır. Bu işlem program bir break ifadesi ile karşılaşana veya switch kalıbının sonu gelene kadar devam eder. Yani bu durumda, switch kalıbının birden fazla seçeneği içinde yer alan işlemler yerine getirilmiş olur. Şimdi, bu özelliği bir örnek üzerinde incelemeye çalışalım:

#include <stdio.h>

main()
{
  int id1;

  printf("Bir sayı giriniz [1-5]");
  scanf("%d", &id1);
  printf("\n");
  switch (id1) {
    case 1 :
      printf("Bir ");
    case 2 :
      printf("İki ");
    case 3 :
      printf("Üç ");
    case 4 :
      printf("Dört ");
    case 5 :
      printf("Beş ");
  }
}

Yukarıdaki örnekte, program 1 ile 5 arasında bir sayı girmenizi ister. Girdiğiniz değeri id1 değişkenine atar. id1 değişkeni ile switch kalıbını kontrol eder ve değişken değeri ile aynı değeri taşıyan sabit değerin bulunduğu case satırından itibaren switch kalıbının sonuna kadar olan bütün case satırlarındaki işlem satırlarının gereğini yerine getirir. Yani, 1 ile 5 arasında girdiğiniz sayıdan 5'e kadar olan sayıları yazı ile ekrana yazar. Eğer 2 değerini girerseniz aşağıdaki satırı ekrana yazar:

İki Üç Dört Beş