C++ switch kullanımı

switch yapısı, C++ dilinde bir değişkenin belirli değerlerine göre farklı işlemler yapılmasını sağlar. Aşağıdaki örnekte, değişken “x” için belirli değerleri kontrol eden bir switch yapısı verilmiştir:

int x = 2;

switch (x) {
    case 1:
        cout << "x değeri 1" << endl;
        break;
    case 2:
        cout << "x değeri 2" << endl;
        break;
    case 3:
        cout << "x değeri 3" << endl;
        break;
    default:
        cout << "x değeri 1, 2 veya 3 değil" << endl;
}

Bu örnekte, eğer x değeri 1 ise “x değeri 1” yazdırılır, x değeri 2 ise “x değeri 2” yazdırılır, x değeri 3 ise “x değeri 3” yazdırılır ve x değeri 1, 2 veya 3 değilse “x değeri 1, 2 veya 3 değil” yazdırılır.

switch yapısının kullanımında dikkat etmeniz gereken birkaç nokta var:

  • switch yapısındaki “case” satırlarında belirtilen değerler mutlaka sabit değerler olmalıdır. Örneğin, aşağıdaki kod hatalıdır:
int y = 2;

switch (y) {
    case y+1: // y+1 değeri değişken olduğu için hata verir
        cout << "y değeri 3" << endl;
        break;
}

break” ifadesi switch yapısının bir “case” bloğunun sonunda kullanılır ve switch yapısının çalışmasını sonlandırır. Eğer “break” ifadesi kullanılmazsa, switch yapısındaki diğer “case” blokları da çalıştırılır. Örneğin, aşağıdaki kod çalıştırıldığında “x değeri 2” ve “x değeri 3” yazdırılır:

int x = 2;

switch (x) {
    case 2:
        cout << "x değeri 2" << endl;
    case 3:
        cout << "x değeri 3" << endl;
}

C++ continue kullanımı

continue anahtar kelimesi, C++ dilinde bir döngünün bir sonraki iterasyonuna geçilmesini sağlar.

Döngülerde continue Kullanımı

Bir döngü içerisinde continue anahtar kelimesi kullanılarak, o döngünün kalan kısmı atlanıp bir sonraki iterasyona geçilebilir. Örneğin, aşağıdaki örnekte, döngü içerisindeki sayı 10’a eşit olduğu zaman döngünün kalan kısmı atlanır ve bir sonraki iterasyona geçilir:

#include <iostream>

int main()
{
    for (int i = 0; i < 100; i++)
    {
        if (i == 10)
        {
            continue;
        }
        std::cout << i << " ";
    }

    std::cout << std::endl;

    return 0;
}

Bu örnekte, i değişkeni 0 ile 99 arasında bir sayı olacak şekilde döngüde değiştirilir. Eğer i değişkeni 10’a eşitse, continue anahtar kelimesi çalıştırılır ve döngünün kalan kısmı atlanır ve bir sonraki iterasyona geçilir. Bu örnekte, ekrana “0 1 2 3 4 5 6 7 8 9 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99” yazdırılır. 10 yazdırılmaz.

Not: continue anahtar kelimesi sadece bir döngü içinde kullanılabilir. switch yapılarında kullanılamaz.

C++ break kullanımı

break anahtar kelimesi, C++ dilinde bir döngü veya bir switch yapısından çıkılmasını sağlar.

Döngülerde break Kullanımı

Bir döngü içerisinde break anahtar kelimesi kullanılarak, o döngüden çıkılabilir.

Aşağıdaki örnekte, döngü içerisindeki bir sayı 10’a eşit olduğu zaman döngüden çıkılır:

#include <iostream>

int main()
{
    for (int i = 0; i < 100; i++)
    {
        std::cout << i << " ";
        if (i == 10)
        {
            break;
        }
    }

    return 0;
}

Bu örnekte, i değişkeni 0 ile 99 arasında bir sayı olacak şekilde döngüde değiştirilir. Eğer i değişkeni 10’a eşitse, break anahtar kelimesi çalıştırılır ve döngüden çıkılır. Bu örnekte, ekrana “0 1 2 3 4 5 6 7 8 9 10” yazdırılır.

switch Yapılarında break Kullanımı

switch yapısı bir değişkenin değerine göre farklı işlemler yapılmasını sağlar. Bir case bloğu içerisinde break anahtar kelimesi kullanılarak, o case bloğundan ve o switch yapısından çıkılabilir. Örneğin:

#include <iostream>

int main()
{
    int x = 1;

    switch (x)
    {
        case 1:
            std::cout << "x değişkeni 1'e eşittir." << std::endl;
            break;
        case 2:
            std::cout << "x değişkeni 2'ye eşittir." << std::endl;
            break;
        default:
            std::cout << "x değişkeni 1 veya 2 değildir." << std::endl;
            break;
    }

    return 0;
}

C++ while döngüsü

While döngüsü, bir koşul doğru olduğu sürece döngü içerisindeki kod bloğunu tekrar eden bir yapıdır. Koşul doğru değilse, döngüden çıkılır ve program devam eder.

While döngüsünün yapısı şu şekildedir:

while (koşul) {
  // Döngü içerisindeki kod burada yazılır
}

Koşul, bir ifade olup, bu ifade doğru (true) veya yanlış (false) değerini döndürebilir. Koşul doğru olduğu sürece, döngü içerisindeki kod bloğu tekrar edilir. Koşul yanlış olduğunda, döngüden çıkılır ve program devam eder.

Örneğin, bir sayının 10’a kadar olan çift sayılarını yazdırmak için aşağıdaki gibi bir while döngüsü kullanabilirsiniz:

#include <iostream>

int main() {
  int sayi = 0;
  while (sayi <= 10) {
    std::cout << sayi << std::endl;
    sayi += 2;
  }
  return 0;
}

Bu program çıktısında, 0, 2, 4, 6, 8 ve 10 sayılarını görebilirsiniz. While döngüsünün koşulu “sayi <= 10” olduğu için, döngü içerisindeki kod bloğu 6 defa tekrar edilmiştir.

C++ for döngüsü

“For” döngüsü, belli bir koşulu sağladığı sürece bir dizi kodu tekrar etmek için kullanılır. Örneğin, bir dizi içinde gezinmek isteyebilirsiniz veya belirli bir sayıda işlem yapmak isteyebilirsiniz. “For” döngüsünün yapısı şöyle görünür:

for (başlangıç koşulu; bitiş koşulu; artış/azalış) {
  // döngü içerisinde çalıştırılacak kod
}

Başlangıç koşulu, döngünün ilk kez çalıştırılacağı zaman uygulanır. Bitiş koşulu, döngünün her bir adımda kontrol edilir ve eğer doğru değilse döngü sona erer. Artış/azalış, her döngü adımından sonra uygulanır ve döngünün devam etmesi için gereklidir.

Örnek olarak, bir dizi içinde gezinmek isteyelim:

#include <iostream>
using namespace std;

int main()
{
   // Dizimiz
   int dizi[5] = {1, 2, 3, 4, 5};

   // Dizinin tüm elemanlarını ekrana yazdırma
   for (int i = 0; i < 5; i++)
   {
      cout << dizi[i] << endl;
   }

   return 0;
}

Bu örnekte, “for” döngüsü “int i = 0” ile başlar ve “i < 5” koşulu doğru olduğu sürece devam eder. Döngü her adımda, “i” değişkeninin değerini bir artırır ve ekrana “dizi[i]” değerini yazdırır. Bu şekilde, dizinin tüm elemanları ekrana yazdırılır.

C++ comments (açıklama satırları)

Yazılan kod satırları hakkında açıklamalar yapmak ya da kod satırlarını geçersiz kılmak amacıyla kullanılır.

Kodlar satırları arasında, yazılan kodların mahiyeti hakkında bilgiler vermek, açıklamalar yapmak, programın geliştirilme sürecinde anahtar rol oynamaktadır. Aynı satırlara yeniden dönüldüğünde, yazılan kodun ne işe yaradığını anlamlı cümleler ile bildirmek hiç şüphesiz, analiz sürecini en aza indirecektir. Belki de en önemlisi, kod satırlarının bir sonraki yazılımcı tarafından kolayca anlaşılarak sürdürülebilmesi de mümkün olacaktır.

#include <iostream>

using std::cout;

int main() {

    // bu bir tek satır yorumdur.
    cout << "Hello World"; 
    
    /* Bu da tek satır yorumdur. */

    /*
     * çoklu satır ise
     * bu şekilde kullanılır.
     */


    // yazdığınız kodu, 
    // daha sonra kullanmak için 
    // geçersiz kılabilirsiniz:
  
    /*cout << "Hello World";*/

    return 0;
}

C++ specific namespaces

using namespace std şeklindeki bir ad alanı kullanımı, std namespace içerisinde yer alan tüm varlıkları programımıza çağıracaktır. Bu durum, programımız geliştikçe, performansı olumsuz etkileyecektir.

Ad alanını, içerdiği tüm varlıklarla birlikte çağırmaktansa, sadece kullanacağımız varlıkları çağırmamız daha doğru bir kullanım olacaktır.

Örneğin, sadece cout kullanacağımız bir programda, namespace erişimi using std::cout şeklinde olmalıdır.

#include <iostream>

// using namespace std; //iptal
using std::cout;

/**
* bu şekilde kullanırsak, 
* tüm standart kütüphaneyi (std) 
* yüklememiş oluruz.
*
* gereksiz kullanımın önüne geçer
* ve performansı arttırır.
*
* sadece kullanacağımız varlıkların
* kısayolunu oluşturmuş oluruz.
*
*/

int main() {
    cout << "sadece cout.";
    return 0;
}

C++ namespaces (ad alanları)

Namespace (ad alanları) sınıflar, nesneler ve işlevler gibi varlıkları bir ad altında gruplamaya izin verir. Bu şekilde, global scope, her biri kendi adına sahip “alt kapsamlara” bölünebilir.

Namespace, isim çakışmalarını önlemek amacıyla kullanılır. Özellikle büyük projelerde isim bulmakta zorlanılacağı için namespace kullanılır. Erişim kolaylığı sağladığı gibi, benzer isimlerdeki varlıkların da birbirlerinden kolayca ayrıştırılmasına olanak sağlar.

Basit bir ad alanı tanımlayalım ve kapsam çözümleme operatörü ( :: ) ile içerisindeki varlığa erişelim.

#include <iostream>

namespace ad_alani
{
    int a = 10;
}

int main(){
    std::cout << ad_alani::a; 
    //ekrana 10 yazar.
}

using

using anahtar kelimesi, kapsam çözümleme operatörünü ( :: ) kullanmamıza gerek kalmadan, ad alanı içerisinde tanımlanan varlığa doğrudan erişir.

#include <iostream>

namespace ad_alani
{
    int a = 10;
}

using ad_alani::a;

int main(){
    std::cout << a; 
    //ekrana 10 yazar.
}

using namespace std

Programdaki std bir ad alanıdır. cout deyimi bu ad alanının içerisinde yer almaktadır.

Programın başında using deyimi ile bir kez std alan adının kullanılacağı bildirilirse, her cout
deyiminden önce std yazılmasına gerek kalmayacaktır.

#include <iostream>

// standart kütüphanesine 
// kısayol oluşturur.
// her seferinde std:: 
// yazmanıza gerek kalmaz.
using namespace std;

int main() {
    cout << "sadece cout";
    return 0;
}

C++ endl vs \n

endl (standart end line) ve \n (new line character) her ikisi de satır başlatır ancak endl her seferinde stream buffer flush işlemi yapar. Türkçe ifadeyle, byte akışı ara belleğini boşaltır. endl, gerek duyulmadıkça, döngülerde ya da program içerisinde sıkça kullanılırsa, her defasında yaptığı buffer flush işlemi sebebiyle performans kaybı yaratır. Program genelinde \n kullanmayı alışkanlık haline getirmeliyiz. endl ise stream buffer flush işlemine ihtiyaç duyulduğu zamanlarda başvurulacak komut olmalıdır.

Peki stream buffer tam olarak ne işe yarar?

Tamamen performans ile ilgilidir. Adından da anlaşılacağı üzere, standart giriş-çıkış çıkış kütüphanesi olan iostream, akış mantığıyla çalışır. Borudan akan bir su gibi, klavyeden okunan ya da ekrana yazdırılacak her karakter sırasıyla ara belleğe alınır ve daha sonra toplu olarak işlenir. Bir dosyaya yazmayı düşünün. Her karakterin tek tek yazılması pahalı bir işlemdir. Bu nedenle, yazdığınız verileri geçici olarak bir arabellekte depolamak, performans açısından doğru bir yöntemdir. Tamponlama işlemi bittiğinde, tek seferde büyük bir blok yazılarak, performans arttırılmış olur.

Şimdi, aşağıdaki iki örnekte, endl deyiminin ve \n karakterlerinin kullanımlarını inceleyelim.

#include <iostream>
using namespace std;

int main() {
  cout << "Hello World!" << endl;
  cout << "I am learning C++";
  return 0;
}
#include <iostream>
using namespace std;

int main() {
  cout << "Hello World! \n";
  cout << "I am learning C++";
  return 0;
}

Yukarıdaki örneklerde endl ve \n kullanımlarında performans açısından sıkıntı yoktur.

Şimdiyse, döngü içerisinde kullanıldıklarında nelerin gerçekleştiğini görelim.

#include <iostream>
using namespace std;

int main() {
  for (char i='A'; i <= 'Z'; i++)
  {
    cout << i << endl;
  }
  return 0;
}
#include <iostream>
using namespace std;

int main() {
  for (char i='A'; i <= 'Z'; i++)
  {
    cout << i << "\n";
  }
  return 0;
}

Yukarıdaki her iki örnekte, ekrana 26 harf satır satır yazdırıldı. endl kullanımında, biz farkında olmadan, her satırda stream buffer flush işlemi gerçekleştirildi. Derleme ve çalıştırma anında, aralarındaki performans farkını hissetmedik. Bu tarzda, küçük boyutlu işlemlerde farkı hissetmeyiz fakat yüz bin satırdan başlayan bir yazıyı, bir dosyaya yazdırmak istediğimizde performans kaybını gözlemleyebiliriz.

C++ cin

C++ cin (character input)

C++ cin komutu, klavye ve benzeri giriş aygıtlarından karakter okumayı sağlamaktadır. Girilen karakterler, değişkenlere >> operatörü ile aktarılır. C++ cin komutunun kullanılabilmesi için programın üst kısmına (header), standart giriş-çıkış (i/o) kütüphanesi <iostream> şu şekilde dahil edilmelidir:

#include <iostream>

// programın geri kalanı...

Standart giriş-çıkış kütüphanesinin programa nasıl dahil edildiğini anladığımıza göre, artık cin komutunu kullarak, derlenecek programımızı yazabiliriz.

#include <iostream>

int main() {
  
    int sayi;
    std::cin >> sayi;

    std::cout << "girilen sayi: " << sayi;

    return 0;
  
}

Yukarıdaki program çalıştığında, klavyeden bir tam sayı girilmesi beklenecektir. sayı girildikten sonra, cin komutu ile girilen sayı, sayi değişkenine aktarılacaktır ve son olarak cout komutu ile girilen sayı ekranda görüntülenecektir.

program satırlarının yorumlanması

#include <iostream>cin (character input – karakter girişi) komutunun çalışabilmesi için
gerekli olan standart giriş-çıkış (input/output) kütüphanesi yüklendi.
int main() { }C++ programını çalıştıran main (gövde) fonksiyonu oluşturuldu.
int sayiKlavyeden girilecek tam sayının aktarılacağı sayı değişkeni
integer (tam sayı) tipinde oluşturuldu.
std::cinStandart giriş-çıkış kütüphanesinde yer alan,
klavyeden girilen karakteri okuyan cin komutu işlendi.
>> sayicin komutu ile klavyeden okunan değer, sayi değişkenine aktarıldı.
std::outsayi değişkeninde tutulan değer, cout komutu ile ekrana yazdırıldı.
return 0C++ programını çalıştıran main (gövde) fonksiyonu int (integer)
olduğu için, fonksiyon sona erdiğinde sayısal bir değer döndürmelidir.
int main() fonksiyonu için return 0 geleneksel bir kullanımdır.