Kontrol Akışı ve Döngüler
Bölüm 3: Kontrol Akışı ve Döngüler
Bir programın akışı, her zaman yukarıdan aşağıya doğru ilerlemez. Bazen belirli koşullara bağlı olarak farklı kod bloklarını çalıştırmamız veya belirli bir kod bloğunu tekrar tekrar çalıştırmamız gerekebilir. İşte bu noktada kontrol akışı ifadeleri devreye girer. Kontrol akışı ifadeleri, programın akışını yönlendirmemizi ve belirli koşullara göre farklı kod bloklarını çalıştırmamızı sağlar. Bu bölümde, C dilinde kullanılan temel kontrol akışı ifadelerini, if-else
yapısını, switch-case
yapısını ve döngüleri (for
, while
, do-while
) inceleyeceğiz.
3.1 if-else
Yapısı: Karar Verme Mekanizması
if-else
yapısı, belirli bir koşul doğruysa bir kod bloğunu, yanlışsa başka bir kod bloğunu çalıştırmamızı sağlar. Koşul, mantıksal bir ifadedir ve sonucu doğru
veya yanlış
olabilir.
if-else
Yapısı Sözdizimi:
if (koşul) {
// Koşul doğruysa çalışacak kod bloğu
} else {
// Koşul yanlışsa çalışacak kod bloğu
}
Örnek: Sayının Pozitif, Negatif veya Sıfır Olduğunu Kontrol Etme
int sayi;
("Bir sayı girin: ");
printf("%d", &sayi);
scanf
if (sayi > 0) {
("Sayı pozitiftir.\n");
printf} else if (sayi < 0) {
("Sayı negatiftir.\n");
printf} else {
("Sayı sıfırdır.\n");
printf}
Daha Fazla if-else
Örneği:
- Kullanıcının girdiği sayının çift mi tek mi olduğunu kontrol etme:
int sayi;
("Bir sayı girin: ");
printf("%d", &sayi);
scanf
if (sayi % 2 == 0) {
("Sayı çifttir.\n");
printf} else {
("Sayı tektir.\n");
printf}
- Kullanıcının girdiği iki sayıdan büyük olanı bulma:
int sayi1, sayi2;
("Birinci sayıyı girin: ");
printf("%d", &sayi1);
scanf
("İkinci sayıyı girin: ");
printf("%d", &sayi2);
scanf
if (sayi1 > sayi2) {
("Birinci sayı daha büyüktür.\n");
printf} else if (sayi2 > sayi1) {
("İkinci sayı daha büyüktür.\n");
printf} else {
("Sayılar eşittir.\n");
printf}
- Kullanıcının girdiği notlara göre harf notu hesaplama:
int not;
("Notunuzu girin: ");
printf("%d", ¬);
scanf
if (not >= 90) {
("Harf notunuz: AA\n");
printf} else if (not >= 80) {
("Harf notunuz: BA\n");
printf} else if (not >= 70) {
("Harf notunuz: BB\n");
printf} else if (not >= 60) {
("Harf notunuz: CB\n");
printf} else if (not >= 50) {
("Harf notunuz: CC\n");
printf} else {
("Harf notunuz: FF\n");
printf}
3.2 Ternary Operatörü: Koşullu İfadeleri Kısaltmak
Ternary operatörü (?:
), if-else
yapısının kısa bir alternatifidir ve tek bir satırda koşullu ifadeler yazmamızı sağlar.
Ternary Operatörü Sözdizimi:
? ifade1 : ifade2 koşul
koşul
: Değerlendirilmek üzere bir mantıksal ifade.ifade1
:koşul
doğru ise değerlendirilecek ifade.ifade2
:koşul
yanlış ise değerlendirilecek ifade.
Örnek: En Büyük Sayıyı Bulma
int sayi1 = 10;
int sayi2 = 20;
int enBuyuk = (sayi1 > sayi2) ? sayi1 : sayi2; // Ternary operatörü
("En büyük sayı: %d\n", enBuyuk); // Çıktı: En büyük sayı: 20 printf
Bu örnekte, sayi1 > sayi2
koşulu doğru ise enBuyuk
değişkenine sayi1
değeri, yanlış ise sayi2
değeri atanır.
Ternary Operatörünün Avantajları:
- Kısa ve Öz:
if-else
yapısına göre daha kısa ve okunaklı olabilir. - Tek Satırda Koşullu Atama: Değişkenlere koşullu olarak değer atamak için pratik bir yöntem.
Örnek: Sayının Tek mi Çift mi Olduğunu Kontrol Etme
int sayi = 7;
char *sonuc = (sayi % 2 == 0) ? "Çift" : "Tek";
("%d sayısı %s'tir.\n", sayi, sonuc); // Çıktı: 7 sayısı Tek'tir. printf
3.3 switch-case
Yapısı: Çoklu Seçenekler Arasında Gezinme
switch-case
yapısı, bir değişkenin değerine bağlı olarak farklı kod bloklarını çalıştırmamızı sağlar. Değişkenin değeri, case
etiketleri ile karşılaştırılır ve eşleşen case
bloğu çalıştırılır.
switch-case
Yapısı Sözdizimi:
switch (değişken) {
case değer1:
// Değişkenin değeri değer1 ise çalışacak kod bloğu
break;
case değer2:
// Değişkenin değeri değer2 ise çalışacak kod bloğu
break;
// ...
default:
// Hiçbir case etiketi eşleşmezse çalışacak kod bloğu
}
Örnek: Haftanın Gününü Yazdırma
int gun;
("Haftanın gününü girin (1-7): ");
printf("%d", &gun);
scanf
switch (gun) {
case 1:
("Pazartesi\n");
printfbreak;
case 2:
("Salı\n");
printfbreak;
case 3:
("Çarşamba\n");
printfbreak;
case 4:
("Perşembe\n");
printfbreak;
case 5:
("Cuma\n");
printfbreak;
case 6:
("Cumartesi\n");
printfbreak;
case 7:
("Pazar\n");
printfbreak;
default:
("Geçersiz gün!\n");
printf}
Daha Fazla switch-case
Örneği:
- Hesap Makinesi:
char operator;
float sayi1, sayi2, sonuc;
("İki sayı girin: ");
printf("%f %f", &sayi1, &sayi2);
scanf
("Operatörü girin (+, -, *, /): ");
printf(" %c", &operator);
scanf
switch (operator) {
case '+':
= sayi1 + sayi2;
sonuc ("Sonuç: %.2f\n", sonuc);
printfbreak;
case '-':
= sayi1 - sayi2;
sonuc ("Sonuç: %.2f\n", sonuc);
printfbreak;
case '*':
= sayi1 * sayi2;
sonuc ("Sonuç: %.2f\n", sonuc);
printfbreak;
case '/':
if (sayi2 == 0) {
("Sıfıra bölme hatası!\n");
printf} else {
= sayi1 / sayi2;
sonuc ("Sonuç: %.2f\n", sonuc);
printf}
break;
default:
("Geçersiz operatör!\n");
printf}
- Ayları Yazdırma:
int ay;
("Ay numarasını girin (1-12): ");
printf("%d", &ay);
scanf
switch (ay) {
case 1:
("Ocak\n");
printfbreak;
case 2:
("Şubat\n");
printfbreak;
// ... diğer aylar ...
default:
("Geçersiz ay!\n");
printf}
3.3 Döngüler: Tekrarlayan İşlemler için Pratik Çözümler
Döngüler, belirli bir kod bloğunu tekrar tekrar çalıştırmamızı sağlar. C dilinde üç temel döngü türü vardır: for
, while
ve do-while
.
3.3.1 for
Döngüsü: Belirli Sayıda Tekrar
for
döngüsü, belirli bir sayıda tekrar yapmak için kullanılır. Döngü değişkeninin başlangıç değeri, bitiş koşulu ve artış miktarı belirtilir.
for
Döngüsü Sözdizimi:
for (başlangıç_değeri; bitiş_koşulu; artış_miktarı) {
// Tekrarlanacak kod bloğu
}
i++
ve i--
Operatörleri
i++
operatörü,i
değişkeninin değerini her adımda 1 artırır.i--
operatörü,i
değişkeninin değerini her adımda 1 azaltır.
Örnek: 1’den 10’a Kadar Sayıları Yazdırma
for (int i = 1; i <= 10; i++) {
("%d ", i);
printf}
("\n"); printf
Daha Fazla for
Döngüsü Örneği:
- Çift Sayıları Yazdırma:
for (int i = 2; i <= 20; i += 2) {
("%d ", i);
printf}
("\n"); printf
- Geri Sayım Yapma:
for (int i = 10; i >= 1; i--) {
("%d ", i);
printf}
("Kalkış!\n"); printf
- Yıldızlardan Üçgen Oluşturma:
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= i; j++) {
("*");
printf}
("\n");
printf}
3.3.1.1 İç İçe for
Döngüleri
for
döngülerini iç içe kullanarak daha karmaşık işlemler gerçekleştirebiliriz. İç içe döngülerde, dış döngünün her bir iterasyonu için iç döngü tamamen çalışır.
Örnek: Çarpım Tablosu
#include <stdio.h>
int main() {
for (int i = 1; i <= 10; i++) {
for (int j = 1; j <= 10; j++) {
("%d x %d = %d\n", i, j, i * j);
printf}
("\n");
printf}
return 0;
}
Bu program, 1’den 10’a kadar olan sayılar için çarpım tablosunu oluşturur. Dış döngü ( i
değişkeni ile kontrol edilir) her satırı temsil ederken, iç döngü ( j
değişkeni ile kontrol edilir) her satırdaki çarpım işlemlerini gerçekleştirir. i * j
işleminin sonucu, her bir çarpımın sonucunu verir. printf("\n");
satırı ise her satırdan sonra bir boş satır ekler, böylece çarpım tablosu daha okunaklı olur. ### 3.3.2 while
Döngüsü: Koşul Doğru Olduğu Sürece Tekrar
while
döngüsü, belirli bir koşul doğru olduğu sürece tekrar yapar. Döngüye girmeden önce koşul kontrol edilir.
while
Döngüsü Sözdizimi:
while (koşul) {
// Tekrarlanacak kod bloğu
}
Örnek: Kullanıcı 0 Girinceye Kadar Sayıları Toplama
int sayi, toplam = 0;
("Bir sayı girin (0 girmek döngüyü sonlandırır): ");
printf("%d", &sayi);
scanf
while (sayi != 0) {
+= sayi;
toplam ("Bir sayı girin (0 girmek döngüyü sonlandırır): ");
printf("%d", &sayi);
scanf}
("Toplam: %d\n", toplam); printf
Daha Fazla while
Döngüsü Örneği:
- Kullanıcının Girdiği Sayıların Ortalamasını Hesaplama:
int sayi, sayac = 0, toplam = 0;
float ortalama;
("Bir sayı girin (0 girmek döngüyü sonlandırır): ");
printf("%d", &sayi);
scanf
while (sayi != 0) {
+= sayi;
toplam ++;
sayac("Bir sayı girin (0 girmek döngüyü sonlandırır): ");
printf("%d", &sayi);
scanf}
if (sayac > 0) {
= (float)toplam / sayac;
ortalama ("Ortalama: %.2f\n", ortalama);
printf} else {
("Hiç sayı girilmedi.\n");
printf}
- Rastgele Sayı Üretme (Belirli Bir Koşul Sağlanana Kadar):
#include <stdlib.h>
#include <time.h>
int main() {
int rastgeleSayi;
(time(NULL)); // Rastgele sayı üreteci başlatılıyor
srand
while (1) {
= rand() % 100; // 0 ile 99 arasında rastgele sayı üretir
rastgeleSayi ("Rastgele Sayı: %d\n", rastgeleSayi);
printfif (rastgeleSayi == 50) {
("50 bulundu! Döngü sonlandırılıyor.\n");
printfbreak;
}
}
return 0;
}
3.3.3 do-while
Döngüsü: En Az Bir Kere Tekrar
do-while
döngüsü, while
döngüsüne benzer, ancak koşul kontrolü döngü bloğu çalıştırıldıktan sonra yapılır. Bu nedenle, döngü bloğu en az bir kere çalıştırılır.
do-while
Döngüsü Sözdizimi:
do {
// Tekrarlanacak kod bloğu
} while (koşul);
Örnek: Kullanıcı Geçerli Bir Sayı Girinceye Kadar Tekrar Sorma
int sayi;
do {
("1 ile 10 arasında bir sayı girin: ");
printf("%d", &sayi);
scanf} while (sayi < 1 || sayi > 10);
("Geçerli sayı: %d\n", sayi); printf
Daha Fazla do-while
Döngüsü Örneği:
- Kullanıcıdan Şifre İsteme (Doğru Girilene Kadar):
char sifre[20];
do {
("Şifreyi girin: ");
printf("%s", sifre);
scanf
if (strcmp(sifre, "gizli_sifre") != 0) {
("Şifre yanlış! Tekrar deneyin.\n");
printf}
} while (strcmp(sifre, "gizli_sifre") != 0);
("Şifre doğru.\n"); printf
- Menü Seçeneklerini Sunma (Kullanıcı Çıkış Yapana Kadar):
int secim;
do {
("Menü:\n");
printf("1. Seçenek 1\n");
printf("2. Seçenek 2\n");
printf("3. Çıkış\n");
printf("Seçiminizi yapın: ");
printf("%d", &secim);
scanf
switch (secim) {
case 1:
// Seçenek 1 işlemleri
("Seçenek 1 seçildi.\n");
printfbreak;
case 2:
// Seçenek 2 işlemleri
("Seçenek 2 seçildi.\n");
printfbreak;
case 3:
("Çıkış yapılıyor...\n");
printfbreak;
default:
("Geçersiz seçim!\n");
printf}
} while (secim != 3);
3.3.4 break
İfadesi: Döngüyü Sonlandırmak
break
ifadesi, bir döngüyü (for
, while
veya do-while
) hemen sonlandırmak için kullanılır. break
ifadesine ulaşıldığında, döngü sona erer ve program akışı döngüden sonraki ifadeye geçer.
Örnek: break
İfadesi ile Döngüyü Sonlandırma
for (int i = 1; i <= 10; i++) {
if (i == 5) {
break; // i değeri 5 olduğunda döngü sonlandırılır
}
("%d ", i);
printf}
("\n"); // Çıktı: 1 2 3 4 printf
Bu örnekte, for
döngüsü normalde 1’den 10’a kadar olan sayıları yazdırır. Ancak, i == 5
koşulu sağlandığında, break
ifadesi çalışır ve döngü sona erer. Bu yüzden çıktı sadece 1, 2, 3 ve 4 olur.
3.3.5 continue
İfadesi: Döngünün Bir Sonraki Adımına Geçmek
continue
ifadesi, döngünün mevcut iterasyonunu sonlandırır ve döngünün bir sonraki adımına geçer. continue
ifadesine ulaşıldığında, döngü bloğunun geri kalanı atlanır ve döngü koşulunun kontrolüne geri dönülür.
Örnek: continue
İfadesi ile Tek Sayıları Atlama
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
continue; // i değeri çift ise, bu iterasyon atlanır
}
("%d ", i);
printf}
("\n"); // Çıktı: 1 3 5 7 9 printf
Bu örnekte, for
döngüsü 1’den 10’a kadar olan sayıları yazdırır. Ancak, i % 2 == 0
koşulu sağlandığında (yani i
çift olduğunda), continue
ifadesi çalışır ve döngü bloğunun geri kalanı atlanır. Bu yüzden çıktı sadece tek sayıları (1, 3, 5, 7, 9) içerir.
3.4 Sonuç
Bu bölümde, programın akışını kontrol etmek için kullanılan temel kontrol akışı ifadelerini öğrendik. if-else
yapısı ile karar vermeyi, switch-case
yapısı ile çoklu seçenekler arasında gezinmeyi, döngüler ile tekrarlayan işlemleri nasıl yapacağımızı ve break
ve continue
ifadeleri ile döngü akışını nasıl kontrol edeceğimizi gördük.