plazma - amatör bilgisayar kültürü

C++ Kursu 3

Bilgem 'Nightlord' Çakır

1. Do-While Döngüsü

Geçen sayıda gördüğümüz while döngüsüne çok benzeyen bir yapı ile karşı karşıyayız

do
{
  Komut1;
  Komut2;
  Komut3;
} while ( kosul );

Bu döngü de tıpkı while döngüsünde olduğu gibi koşul doğru olduğu müddetçe verilen kod bloğunu çalıştıracaktır. While döngüsünden tek farkı ise kod bloğunun en az bir kere çalışacak olması. Bunun sebebi, while döngüsünde koşul kontrolü en başta yapılırken, do-while döngüsünde kontrolün sonda yapılıyor olması.

2. For Döngüsü

Anlatım sırası olarak önce while ve do-while yapılarını anlatmamızın sebebi onların if ile olan benzerlikleri idi. Aslında en sık kullanılan döngü tipi belkide for döngüsüdür. Gelin bir göz atalım.

for( int i = 0; i < 5; ++i)
{
  Komut1;
  Komut2;
  Komut3;
}

Burada for satırı önemli. Bu satırda parantez içinde kalan bölüm döngünün nasıl çalışacağını tanımlıyor. Bu bölüm kendi içinde aslında üç parçaya bölünmüştür. Bu üç parçayı iki adet noktalı virgul (;) ayırıyor

  1. int i = 0 : başlangıç bölümü. Burada i adında bir döngü sayacı tanımlanmış

  2. i < 5 : döngüye devam koşulu

  3. ++i : döngü. Burada döngü sayacı 1 artırılmış. ++ operatörü böyle kullanılarak, tamsayı cinsinden bir değişkenin değerini bir artırabilir. Burada ++i yazmak yerine i = i + 1 da yazabilirdik, aynı şey olurdu.

Döngüler konusunda hatırlamamız gereken son şey her üç döngü yapısından da break komutu ile çıkabileceğimiz.

3. If-Else if bloklarına alternatif: Switch – case

Eger bir değişkeni alıp bu değişkenin değerine göre çok sayıda kod bloğundan birini çalıştırmak istiyorsak (örneğin menü komutu işleme vs gibi senaryolarda), bunu geçen bölümde gördüğümüz gibi if-else if blokları ile yapabiliyoruz. Ancak bunu yapmanın (belki) biraz daha kolay bir yolu da switch case yapısını kullanmaktır.

switch( degisken )
{
  case 1:
    komut1;
    komut2;
    break;
  case 2:
    komut3;
    break;
  case 3:
    komut4;
    komut5
    break;
  default:
    komut6;
    break;
}

Burada değişkenin değeri 1 ise komut1 ve komut2 çağırılır. Değer 3 ise komut4 ve komut5 çağırılır. Eğer değer 1, 2, veya 3’ ten farklı bir değer ise de komut6 çağırılır. Burada dikkat edeceğiniz bir diğer şey break komutları. Eğer break komutları konulmazsa program akışı bir alttaki case bloğundaki komutlardan çalışmaya devam eder. Bu da genellikle istenmeyen bir durumdur. Eğer bu istenen bir durum ise bile genelde kodu okumayı ve anlamayı zorlaştıracağı için tavsiye etmiyorum.

4. Döngü Örneği

Döngüleri kullanarak bir örneğe bakalım:

#include <iostream>

int main()
{
  // kac sinav oldugunu al
  std::cout << “Kac sinav oldu? ”;
  int kacSinav;
  std::cin >> kacSinav;

  // dongu ile notlari al ve topla
  int toplam = 0;
  for(int i=0; i<kacSinav; ++i)
  {
    int not;
    std::cout << “sinav notu: ”;
    std::cin >> not;
    toplam = toplam + not;
  }

  // sonucu hesapla ve goster
  int ortalama = toplam / kacSinav;
  std::cout << “Yapilan ” << kacSinav
    << “ sinavin ortalamasi: ” << ortalama
    << std::endl;
}

Şu ana kadar öğrendiklerimizi kullanarak nispeten faydalı küçük programcıklar yazabilmeye başladık.

Bu program bir ögrencinin sınavlardan aldığı notların ortalamasını hesaplayan bir program. Bunun için ilk başta kullanıcıdan kaç sınavın ortalamasını almak istediği bilgisini alıyor ve kacSınav isimli değişkene saklıyor. Ardından kacSınav kere dönen bir döngü içinde kullanıcıdan sınav notlarını almaya başlıyor. Her notu aldığında toplam adlı değişkene o notu ekliyor. Bu sayede toplam değişkeninde o zamana kadar girilen sınav notlarının toplamı “birikiyor”. Döngü ile kacSınav kadar sınav notu alınıp toplam değişkeninde biriktirildikten sonra programın son bölümüne geliyoruz. Burada toplam değer kacSınav sayısına bölünerek ortalama hesaplanıyor ve bu sonuç kullanıcıya gösteriliyor.

5. Diziler

Şimdiye kadar değişkenleri hep tek tek tanımladık ve kullandık. Bazen aynı tipten olan ve birbiriyle anlamsal olarak da bağlantılı değişken grupları tanımlarız. Örneğin bir sınıftaki öğrencilerin matematik yazılısından aldığı notlar, veya bir futbol oyununda bir takımdaki oyuncuların attığı goller gibi. Bu durumlarda “dizi” kullanabiliriz. Diziler şöyle tanımlanır

int attigiGoller[11];

Bu şekilde takımdaki 11 oyuncunun gol sayısını saklamak için 11 adet tamsayi tipinde değişken oluşturabiliriz. Bu değişkenlerin herbirine tek tek ulaşmak için “indeksleme” kullanılır. İndeksleme [ ] operatörü ile yapılır. Örneğin:

attigiGoller[0] = 2;
attigiGoller[3] = 3;

diyerek ilk oyuncunun 2 gol attığını, 4. Oyuncunun ise 3 gol attığını söyleyebiliriz. Dikkat etmeniz gereken nokta indekslemenin 0’dan başladığıdır. Yani yukarıdaki örnekte indeks değeri 0 ile 10 arasında olabilir. 11 ve yukarısı olamaz. Eğer 11 veya yukarısında bir değer kullanırsanız, programınızda öngörülemez hatalar olur (donma, programdan çıkma vs).

Aynı şekide dizi elemanlarından okurken de indeksleme kullanılır.

std::cout << “Altinci oyuncunun gol sayisi”
  << attigiGoller[5] << std::endl;

Dizileri istersek birden fazla boyutlu da yapılabilir. Örneğin

Int sinavNotlari[10][3];

Gibi bir dizi kullanarak 10 öğrencilik bir sınıfta 3 sınavın sonuçlarını saklayabileceğimiz toplam otuz değişkeni tanımlayabiliriz. Bu sayede örneğin dördüncü öğrencinin 2. Sınavdan aldığı notu girmek için

sinavNotlari[3][1] = 80;

gibi bir satır yazabiliriz. Yine indekslemenin her iki boyutta da 0’dan başladığını unutmayın (o yüzden [4][2] yerine [3][1] kullandık)

Şimdi bir önceki örnek programımızı dizileri kullanarak daha da geliştirmeye çalışalım. Programımız tek öğrencinin sınav notları yerine bir sınıftaki bütün öğrencilerin notlarını işlesin. Ama dizi kullanımını daha kolay gösterebilmek için sınav sayısını ve öğrenci sayısını şimdilik sabitleyelim. 10 öğrenci ve 3 sınav olsun.

#include <iostream>

int main()
{
  // dongu ile notlari al
  int sinavNotlari[10][3];

  for(int o=0; o<10; ++o)
  {
    for(int i=0; i<3; ++i)
    {
      std::cout << “sinav notu: ”;
      std::cin >> sinavNotlari[o][i];
    }
  }

  // sonuclari hesapla ve goster
  int sinifToplam = 0;
  for(int o=0; o<10; ++o)
  {

    // bir ogrencinin notlarini topla
    int ogrenciToplam = 0;
    for(int i=0; i<3; ++i)
    {
      ogrenciToplam += sinavNotlari[o][i];
    }

    // ogrencinin ortalamasini goster
    int ogrenciOrtalama = ogrenciToplam / 3;
    std::cout<<”ogrenci ”<< o 
      <<” ortalamasi: ” << ogrenciOrtalama
      << std::endl;

    // sinif ortalamasi icin biriktir
    sinifToplam += ogrenciOrtalama;
  }

  // sinif ortalamasini goster
  int sinifOrtalama = sinifToplam / 10
  std::cout << “Sinif ortalamasi: ” << sinifOrtalama
    << std::endl;
}

Yukarıda programımızı geliştirip bir sınıftaki bütün öğrencilerin sınavlardaki notlarını alıp her bir öğrenci için ortalama hesaplayan ve bununla da kalmayıp sonra bütün sınıfın not ortalamasını hesaplayan bir hale getiriyoruz.

Ayrıca programda

sinifToplam += ogrenciOrtalama;

gibi komutlar var. Bunlar da aslında sık rastlanan komutlardır. Bu komut

sinifToplam = sinifToplam + ogrenciOrtalama;

ile aynıdır. Bu işlemler çok sık kullanıldığı için +=, -= gibi operatörler geliştirilmiştir. Bu operatörler soldaki argümanı sağdaki argüman ile istenen işleme sokup sonucu tekrar soldaki argümana atarlar.

Böylece daha önce tek öğrencinin notlarını alıp ortalamasını hesaplayan programımızı, dizileri kullanarak n öğrencinin m sınavda aldığı notlardan ortalamalarını hesaplayan ve bunları raporlayan bir hale getirdik.

Bir sonraki bölümde işaretçiler, bellek yönetimi ve fonksiyonlardan bahsedeceğiz.

plazma - (2006 - 2011)