switch deyimi

switch deyimi bir tamsayı ifadesinin farklı değerleri için, programın akışının farklı noktalara yönlendirilmesini, böylece farklı işlerin yapılmasını sağlar. switch deyimi, else if merdivenine (else if ladder) okunabilirlik yönünden bir seçenek oluşturur. Deyimin genel biçimi aşağıdaki gibidir:

switch, case, default C dilinin anahtar sözcükleridir.

switch deyiminin yürütülmesi

switch parantezi içindeki ifadenin sayısal değeri hesaplanır. Bu değerde bir case ifadesi olup olmadığı yukarıdan aşağı doğru sınanır. Eğer böyle bir case ifadesi bulunursa programın akışı o case ifadesini izleyen deyime yönlendirilir. Artık program buradan akarak ilerler. Daha aşağıdaki case etiketlerini izleyen deyimler de yapılır (fall through)switch parantezi içindeki ifadenin sayısal değerine eşit bir case ifadesi yok ise, programın akışı (varsa) default anahtar sözcüğünü izleyen deyime yönlendirilir.

Yukarıdaki örnekte scanf işlevi ile, standart giriş akımından n değişkenine 3 değeri alınmış olsun. Bu durumda programın ekran çıktısı şu şekilde olur:

Eğer uygun case ifadesi bulunduğunda yalnızca bu ifadeye ilişkin deyim(ler)in yürütülmesi istenirse break kontrol deyiminden faydalanılır. break deyiminin kullanılmasıyla, döngülerden olduğu gibi switch deyiminden de çıkılabilir. Daha önce verilen örnekteki koda break deyimlerini ekliyoruz:

Yukarıdaki kodda scanf işlevi ile, standart giriş akımından n değişkenine yine 3 değeri alınmış olsun. Bu durumda programın ekran çıktısı şu şekilde olur:

Uygulamalarda, switch deyiminde çoğunlukla her case ifadesi için bir break deyimi kullanılır. Tabi böyle bir zorunluluk yoktur.
switch deyiminin ana bloğu tek bir bilinirlik alanı (scope) kabul edilir. Bir case etiketini birden fazla deyimin izlemesi durumunda bu deyimlerin bloklanmasına gerek yoktur. case ifadelerinin belirli bir sırayı izlemesi gibi bir zorunluluk yoktur. switch parantezi içindeki tamsayı ifadesinin değerine eşit bir case ifadesi bulunamaz ise switch deyiminden bir şey yapılmadan çıkılır.

default case

default bir anahtar sözcüktür. switch deyimi gövdesine yerleştirilen default anahtar sözcüğünü ‘:’ atomu izler. Oluşturulan bu case‘e default case denir.
switch parantezi içindeki ifadenin değerine eşit bir case ifadesi bulunamazsa programın akışı default case içine girer. Daha önceki örnek kodda yer alan switch deyimine default case ekliyoruz:

default case tipik olarak sonuncu case yapılsa da bu bir zorunluluk değildir. default case, switch deyimi gövdesi içinde herhangi bir sıradaki case olabilir. Bir switch deyiminde birden fazla default case bulunması geçerli değildir.

switch parantezi içindeki ifadenin sayısal değerine eşit bir case ifadesi bulunana kadar, tüm case ifadeleri yukarıdan aşağıya doğru sırayla sınanır. case ifadelerinin oluşma sıklığı ya da olasılığı hakkında elde bir bilgi varsa, olasılığı ya da sıklığı yüksek olan case ifadelerinin daha önce yazılması gereksiz karşılaştırma sayısını azaltabilir, okunabilirliği artırır.

case ifadelerinin, tamsayı türünden (integral types) sabit ifadesi olması gerekir. Sabit ifadeleri, derleme aşamasında derleyici tarafından net sayısal değerlere dönüştürülebilir:

Yukarıdaki case ifadesi geçerlidir. Çünkü 1 + 3 bir sabit ifadesidir. Ama,

Yukarıdaki case ifadesi geçersizdir. Derleyici, derleme aşamasında sayısal bir değer hesaplayamaz.

Yukarıdaki case ifadesi geçerlidir. ‘a’ bir karakter sabitidir (character literal). case ifadesi tamsayı türünden bir sabit ifadesidir.

Yukarıdaki case ifadesi geçersizdir. “a” bir string sabitidir (string literal). Bir string sabiti tamsayı tamsayı sabiti değildir ve case ifadesi olarak kullanılamaz.

Yukarıdaki case ifadesi geçersizdir. 3.5 bir gerçek sayı sabitidir.

C’de kendisi const nesneler sabit ifadesi gereken yerde kullanılamazlar. C++ dilinde sabit ifadesiyle ilk değerlerini almış const nesneler sabit ifadesi gereken yerlerde kullanılabilirler. Aşağıdaki switch deyimi C’de geçersiz C++ dilinde geçerlidir:

Bir switch deyiminde aynı değerde birden fazla case ifadesinin bulunması geçersizdir. Yani tüm case ifadeleri farklı değerlerde olmalıdır:

switch kontrol deyimi yerine bir else if merdiveni yazılabilir. Yani switch deyimi olmasaydı, yapılmak istenen iş, bir else if merdiveni ile de gerçekleştirilebilirdi. Ancak bazı durumlarda else if merdiveni yerine switch deyimi kullanmak kodun okunmasını kolaylaştırır. Örneğin:

Yukarıdaki else if merdiveni ile aşağıdaki switch deyimi işlevsel olarak eşdeğerdir:

else if merdivenindeki son basamakta yer alan else kısmının switch deyimindeki default case karşılığı olduğunu görebiliyor musunuz? Her switch deyiminin yerine aynı işi görecek şekilde bir else if merdiveni yazılabilir. Ama her else if merdiveni karşılığı bir switch deyimi yazılamaz. switch parantezi içindeki ifadenin bir tamsayı türünden olması gerektiğini hatırlayalım. case ifadeleri de tamsayı türlerinden sabit ifadesi olmak zorundadır. switch deyimi, tamsayı türünden bir ifadenin değerinin değişik tamsayı değerlerine eşitliğinin sınanması ve eşitlik durumunda farklı işlerin yapılması için kullanılır. Oysa else if merdiveninde her türlü karşılaştırma söz konusu olabilir. Örnek:

Yukarıdaki else if merdiveninin yerine doğrudan bir switch deyimi yazılamaz.

switch deyimi bazı durumlarda else if merdivenine göre çok daha okunabilir bir yapı oluşturur. Yani switch deyiminin kullanılması her şeyden önce kodun daha kolay okunabilmesini, anlaşılmasını, değiştirilebilmesini sağlar.  switch deyiminin debug edilmesi else if merdivenine göre daha kolaydır. Bazı derleyicilerin switch deyimi karşılığı else if merdivenine göre daha verimli kod üretebildikleri bilinmektedir.

Birden fazla case ifadesi için aynı işlemlerin yapılması şöyle sağlanabilir:

Bunu yapmanın daha kısa bir yolu yoktur. Bazı kodlayıcılar kaynak kodun yerleşimini aşağıdaki gibi düzenler:

Aşağıdaki programı önce inceleyin, sonra derleyerek çalıştırın:

printSeason işlevi, bir ayın sıra numarasını, yani yılın kaçıncı ayı olduğu bilgisini alıyor. Bu ay yılın hangi mevsimi içinde ise, o mevsimin ismini ekrana yazdırıyor. Aynı iş bir else if merdiveniyle nasıl yapılabilirdi? Her if deyiminin koşul ifadesi içinde “mantıksal veya” işleci kullanılabilirdi:

case ifadeleri olarak sembolik sabitlerin kullanılması çok sık karşılaşılan bir durumdur:

case ifadeleri olarak karakter sabitleri de kullanılabilir:

case etiketlerini izleyen tamsayı ifadelerinin numaralandırma sabitleri (enumaration constants) olması çok sık karşılaşılan bir durumdur:

case ifadelerini izleyen deyimlerin sayısının fazla olması kodun okunmasını zorlaştırır. Bu durumda, yapılacak işlemlerin tanımlanacak işlev çağrılarına dönüştürülmesi iyi bir tekniktir:

Yukarıdaki örnekte case ifadesi olarak kullanılan ADD_RECORD, DELETE_RECORD, FIND_RECORD daha önce tanımlanmış sembolik sabitlerdir. Her bir case için yaptırılacak işlemler birer işlev içinde sarmalanmış.

switch deyimi, başka bir switch deyiminin ya da bir döngü deyiminin gövdesini oluşturabilir:

Yukarıdaki main işlevinde switch deyimi, dıştaki while döngüsünün gövdesini oluşturuyor. switch deyimi, döngü gövdesindeki tek deyim olduğundan, dıştaki while döngüsünün bloklanmasına gerek yoktur. Tabi while döngüsünün bloklanması bir hataya neden olmaz.
Ancak case ifadeleri içinde yer alan break deyimiyle yalnızca switch deyiminden çıkılır. switch deyimini kapsayan while döngüsünün de dışına çıkmak için case ifadesi içinde goto deyimi kullanılabilir.

Şimdi de aşağıdaki programı inceleyin. Programda displayDate isimli bir işlev tanımlanıyor. İşlev gün, ay ve yıl değeri olarak aldığı bir tarih bilgisini İngilizce olarak

yukarıdaki formatta ekrana yazdırıyor:

İşlevin tanımında iki ayrı switch deyimi kullanılıyor. İlk switch deyimiyle, gün değerini izleyen (th, st, nd, rd) sonekleri, ikinci switch deyimiyle, aylara ilişkin kısaltmalar (Jan, Feb, Mar…) yazdırılıyor.
case ifadelerini izleyen deyimlerden biri break deyimi olmak zorunda değildir. Bazı durumlarda break deyimi özellikle kullanılmaz. Uygun bir case ifadesi bulunduğunda daha aşağıdaki case etiketlerini izleyen deyimlerin de yapılması özellikle istenir. Aşağıdaki programı derleyerek çalıştırın:

dayOfYear işlevi aldığı gün, ay ve yıl değerinin ilgili yılın kaçıncı günü olduğunu hesaplıyor. İşlev içinde kullanılan switch deyimini dikkatli bir şekilde inceleyin. switch deyiminin parantezi içinde, dışarıdan gelen ay değerinin 1 eksiği kullanılıyor. Hiçbir case içinde bir break deyimi kullanılmıyor. Uygun bir case ifadesi bulunduğunda, daha aşağıda yer alan tüm case içindeki deyimler de yapılır. Böylece, dışarıdan gelen ay değerinden daha düşük olan her bir ayın kaç çektiği bilgisi, gün toplamını tutan sum değişkenine katılıyor.

Necati Ergin

C ve Sistem Programcıları Derneğinde eğitmen olarak çalışıyor.

Bunlar da ilginizi çekebilir

switch deyimi” için 2 yorum

  1. std::launch::deferred,
    std::launch::async,
    std::future,
    std::bind,
    std::promise
    C++ Functors,
    rvalue, lvalue, xvalue, glvalue, prvalue gibi anlaşılması zor kavramlar için de bilgilerinizi bizimle paylaşırsanız seviniriz Necati Hocam.
    Not: Sitesiniz ülkemizde c++ konusunda giriş düzeyi dışında Türkçe kaynak bulunamama problemine çözüm üretmeye başlamıştır. Teşekkür ederiz. Umarım yazıların arası çok açılmadan yeni yazılar gelmeye devam eder.

  2. Merhaba İbrahim Bey,
    İlginiz için çok teşekkür ederim. Geçen hafta boyunca devam eden kurumal bir eğitim programı yüzünden yazılara bir süre ara vermek zorunda kaldım. Bir aksilik olmaz ise 2017 yılının sonuna kadar C ve C++ dillerine ilişkin tüm konuları farklı farklı yazılarla ele alacağım.

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Kod Eklemek İçin Okuyun