Bugünkü Konular Döngüler ve Akış Diyagramları C de Döngü Tanımlama while döngüsü do-while döngüsü for döngüsü Döngülerde kullanılan yardımcı ifadeler break continue goto
Neden Döngüler? Bazen bazı kodların tekrarlanmasını isteriz bazen de koşul sağlandıkça bazı kodların tekrarlanmasını isteriz. Örneğin “an” ifadesini hesaplamak istiyoruz. “a” bir gerçek sayı ve “n” bir tam sayı ve >=0 olsun. Örnek, 35 i hesapla. 35 = 3*3*3*3*3
an yi nasıl hesaplarız? kuvvet alalım ve ilk değeri 1 olsun. a sayısını kendisiyle çarp ve her çarpma işleminde bir say. Sayacın ilk değeri = 0 Sayaç “n” olunca “a” sayısını “n” defa kendisiyle çarpmışız demektir.
an Hesaplama Algoritması Kullanıcıdan “a” ve “n” girmelerini iste Sayacı 0 a eşitle Kuvveti 1 e eşitle /* kuvvet = a0 = 1 */ (sayac < n) olduğu sürece tekrarla 4.1. kuvvet = kuvvet * a; /* şimdi kuvvet = asayac */ 4.2. sayac++; Kuvveti yazdır
an Hesaplama Akış Diyagramı sayac = 0 Start kuvvet = 1 sayac < n? Kullanıcıdan “a” ve “n” girmelerini iste Kuuveti yazdır H End E kuvvet *= a; sayac++;
C de döngü yapıları “sayac” “n” değerine ulaşana kadar 4.1 ve 4.2 nin tekrarlamalarını istiyoruz. Bunun anlamı 4.1 ve 4.2 basamaklarını koşul sağlandıkça bir döngü içinde çalışacak. C programlama dili üç döngü yapısını destekliyor: while döngüsü do-while döngüsü for döngüsü
while İfadesi While döngüsü koşul sağlandıkça çalışır. Ta ki test edilen koşul false olursa döngü biter. Döngünün kaç defa çalışacağı bilinmediği durumlarda kullanılır. Syntax: koşul Y N ifade1 ifade2 ... while(koşul) { ifade1; ifade2; ... }
an Hesaplamak için Kod int sayac; int n; double a; double kuvvet; printf(“a değerini gir: “); scanf(“%lf”, &a); printf(“n değerini gir: “); scanf(“%d”, &n); sayac = 0; kuvvet = 1; /* kuvvet = a0 */ while (sayac < n){ kuvvet *= a; sayac++; } printf(“a^n: %lf\n”, kuvvet); sayac = 0 Start kuvvet = 1 sayac < n? Kullanıcıdan “a” ve “n” girmelerini iste Kuvveti yazdır H End E kuvvet *= a; sayac++;
a = 3 ve n = 5 için kod izlemesi int sayac; int n; double a; double kuvvet; printf(“a değeri: “); scanf(“%lf”, &a); printf(“n değeri: “); scanf(“%d”, &n); sayac = 0; kuvvet = 1; while (sayac < n){ kuvvet *= a; sayac++; } printf(“a^n: %lf\n”, kuvvet); a n sayac kuvvet 3 5 1 Test: 0 < 5? True 1 3 Test: 1 < 5? True 2 9 Test: 2 < 5? True 3 27 Test: 3 < 5? True 4 81 Test: 4 < 5? True 5 243 Test: 5 < 5? False
an Hesaplama: Alternatif Kod int i; int n; double a; double kuvvet; printf(“a değeri gir: “); scanf(“%lf”, &a); printf(“n değeri gir: “); scanf(“%d”, &n); i = 0; kuvvet = 1; while (i < n){ kuvvet *= a; i++; } printf(“a^n is: %lf\n”, kuvvet); int i; int n; double a; double kuvvet; printf(“a değeri gir: “); scanf(“%lf”, &a); printf(“n değeri gir: “); scanf(“%d”, &n); i = 0; kuvvet = 1; while (i++ < n) kuvvet *= a; printf(“a^n is: %lf\n”, kuvvet);
1+2+3+..+N işlemini hesaplama Kullanıcıdan “n” sayısını iste i = 1 /* İterasyon değişkeni*/ toplam = 0 /* geçerli toplam*/ (i <= n) olduğu sürece tekrarla 4.1. toplam += i; 4.2. i++; Toplamı yazdır
1+2+3+..+N Hesaplamak için Akış Diyagramı ve Kod Start toplam = 0 i <= n? Kullanıcıdan “n” sayısını iste Toplamı yazdır H End E toplam += i; i++; int i; int n; int top = 0; printf(“n değerini gir: “); scanf(“%d”, &n); i = 1; while (i<= n){ top += i; i++; } printf(“Toplam = %d\n”, top);
n=5 için Kod izleme n i top int i; int n; int top = 0; printf(“n değeri: “); scanf(“%d”, &n); i = 1; while (i<= n){ top += i; i++; } printf(“Toplam =%d\n”, top); 5 1 Test: 1 <= 5? True 2 1 Test: 2 <= 5? True 3 3 Test: 3 <= 5? True 4 6 Test: 4 <= 5? True 5 10 Test: 5 <= 5? True 6 15 Test: 6 <= 5? False
1+2+3+..+N: Alternatif Kod int i; int n; int i; int top = 0; int n; printf(“n girin: “); scanf(“%d”, &n); i = 1; while (i<= n){ top += i; i++; } printf(“Toplam= %d\n”, top); int i; int n; int top = 0; printf(“n girin: “); scanf(“%d”, &n); i = 1; while (i<= n) top += i++; printf(“Toplam= %d\n”, top);
Sayıların Kareleri Tablosunu Oluşturma Girilen n sayısına kadar 1, 2, 3, 4, .., n sayıların karesini veren bir tablo oluşturalım. n = 6 için görünüm aşağıdaki gibi olacak +-----+-----+ | i | i*i | | 1| 1| | 2| 4| | 3| 9| | 4| 16| | 5| 25| | 6| 36|
Kareler Tablosu için Kod int i; int n; printf(“n değeri gir: “); scanf(“%d”, &n); printf(“+-----+-----+\n”); printf(“| i | i*i |\n”); i = 1; while (i <= n){ printf(“|%5d|%5d|\n”, i, i*i); i++; } /* end-while */ i = 1 Start i <= n? Kullanıcıdan n değerini iste Tablonun alt çizgisini yazdır H End E (i, i*i) yazdır i++; Başlığı yazdır
n=4 için kod izleme printf(“+-----+-----+\n”); printf(“| i | i*i |\n”); i = 1; while (i <= n){ printf(“|%5d|%5d|\n”, i, i*i); i++; } n i 4 1 Test: 1 <= 4? True 2 Test: 2 <= 4? True 3 Test: 3 <= 4? True 4 +-----+-----+ | i | i*i | | 1| 1| | 2| 4| | 3| 9| | 4| 16| Test: 4 <= 4? True 5 Test: 5 <= 4? False
Bir başka while örneği int i = 0; printf(“C programlamayı nasıl buldun?\n”); while(i < 10) { printf(“C Programlama çok zevkli!\n”); i++; } 10 defa tekrarlar (0 dan 9’a kadar) Aynı mesajı 10 defa yazar
Ve başka bir while örneği int i = 20; printf(“C programlamayı nasıl buldun?\n”); while(i < 10) { printf(“C Programlama çok zevkli!\n”); i++; } 0 defa tekrarlar (i = 20, 10’dan küçük değil) Hiç mesaj yazmayacak
do while ifadesi While döngüsü, döngünün başında -başlamadan önce- karşılaştırma durumuna göre çalışır. Bazı durumlarda döngü bir kere çalıştıktan sonra devam edip etmemeye karar vermek isteriz. Bu durumlarda do while döngüsü kullanılır. Bu demek oliyorki döngünün gövdesi en az bir kere çalışıyor. Syntax: karşılaştırma Y N ifade1 ifade2 ... do { ifade1; ifade2; ... } while(karşılaştırma);
Şifre Sorma(1) Örneğin, kullanıcı doğru şifreyi girene kadar kullanıcıdan şifre girmesini isteyelim /* while kullanarak …*/ #define PASSWD 123456 int passwd; printf(“Şifreyi girin: “); scanf(“%d”, &passwd); while (passwd != PASSWD){ } printf(“şifre OK\n”); Burda şifreyi en az bir kere soruyoruz! While döngüsü kullanmak ile printf/scanf ifadelerini tekrarlıyoruz.
Şifre Sorma(2) do-while ile aynı döngü #define PASSWD 123456 int passwd; do { printf(“Şifreyi girin: “); scanf(“%d”, &passwd); } while(passwd != PASSWD); printf(“Şifre OK\n”); while döngüsü ile karşılaştırma gayet açık
do while Örnek Bir pozitif tam sayı iste int no; do { printf(“Bir pozitif tam sayı gir: “); scanf(“%d”, &no); } while(no <= 0);
do while örnek: char opsiyon = 'x'; do{ printf(“Opsiyonlardan birini seçin: \n"); printf("(a) Not hesapla\n"); printf("(b) Ortalama hesapla\n"); printf("(c) Notları yazdır\n"); printf("(q) çıkış \n"); opsiyon = getchar(); getchar(); /*‘\n’ koyar */ if (opsiyon == 'a') ... else if (opsiyon == 'b') ... else if (opsiyon == 'c') ... } while(opsiyon != ‘q’);
do while örnek: int i = 0; printf(“C Programlamayı nasıl buldun?\n”); printf(“C Programlama çok zevkli!\n”); i++; } while(i < 10); 10 defa tekrarlar (0 dan 9 a kadar) Aynı mesajı 10 defa tekrarlar
do while örnek: int i = 20; printf(“C Programlamayı nasıl buldun?\n”); printf(“C Programlama çok zevkli!\n”); i++; } while(i < 10); 1 kere tekrarlar (i = 20 için) Aynı mesajı bir kere yazar
while ile do while arasındaki fark nedir? Döngüye koymak için kontrol eder Döngüden çıkarmak için kontrol eder. Döngü çalışabilir veya çalışmaz Döngü en az bir kere çalışır
for Döngüsü Daha sık kullanılır Döngünün belli bir sayıda çalışmasını istiyorsak kullanırız. Örneğin döngünün N defa çalışmasını istiyoruzdur. Syntax: for(başlangıç değerleri;karşılaştırma;değiştirme listesi) { ifade1; ifade2; ... }
for akış diyagramı, ve while eşiti değiştir kontrol Y N İlk değer ifade1 ifade2 ... for(ilk değer;kontrol;değiştir) { ifade1; ifade2; ... } İlk değer; while(kontrol) { ifade1; ifade2; ... değiştir; }
Bir başka for Örneği Problem: 1 den 10’a kadar sayıları yazdır output: Başla int say; for(say = 1; say <= 10; say++) { printf("%d ",say); } printf("\n"); say = 1 say <= 10 Y Sayıyı yazdır N 1 2 3 4 5 6 7 8 9 10 output: say++ Bitir
for ifadesinin kullanımı for döngüsü; artırma veya azaltma miktarı belli ise kullanılması en iyi tercih olacaktır. for (i=0; i<N; i++) … 0 dan N-1 e kadar sayar for (i=1; i<=N; i++) … 1 den N e kadar sayar for (i=N-1; i>=0; i--) … N-1 den 0 a kadar sayar for (i=N; i>=1; i--) … N den 1 e kadar sayar
for Örnek: an Hesaplama i kuvvet 3 5 1 1 kuvvet = 1; for(i=1; i<=N; i++){ kuvvet *= a; } Test: 1 <= 5? True 2 3 Test: 2 <= 5? True Start i++ End Kuvveti yazdır i <= N Y N i = 1 kuvvet *=a; 3 9 Test: 3 <= 5? True 4 27 Test: 4 <= 5? True 5 81 Test: 5 <= 5? True 6 243 Test: 6 <= 5? False
Kareler Tablosu Yazdırma printf(“+-----+-----+\n”); printf(“| i | i*i |\n”); for (i=1; i <= n; i++){ printf(“|%5d|%5d|\n”, i, i*i); } +-----+-----+ | i | i*i | | 1| 1| | 2| 4| | 3| 9| | 4| 16| | 5| 25| | 6| 36| n=6 için Output
Bir başka for örneği Problem: 1+2+3+4+…+N işlemini hesapla top = 0; for(i=1; i<=N; i++){ top += i; } İlk değer (i=1), kontrol(i<=N) ve değiştir(i++) ifadelerin her biri opsiyoneldir ve yazılmayabilir. top=0; i =0; for(; i<=N;){ top += i++; } top=0; i=1; for(; i<=N; i++){ top += i; } top=0; for(i=1; i<=N;){ top += i++; }
İç içe döngüler Döngüleri bir biri içinde kullanabiliriz Çoğu programlarda bu durum gerekiyor. Örnek: çarpım tablosunu yazdıralım +---+---+---+---+---+---+---+---+---+---+---+ | * | 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| | 1| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| | 2| 2| 4| 6| 8| 10| 12| 14| 16| 18| 20| | 3| 3| 6| 9| 12| 15| 18| 21| 24| 27| 30| | 4| 4| 8| 12| 16| 20| 24| 28| 32| 36| 40| | 5| 5| 10| 15| 20| 25| 30| 35| 40| 45| 50|
Çarpım Tablosunu Ekrana Yazdırma int i, j; /* Başlığı yazdıralım*/ printf(“+---+---+---+---+---+---+---+---+---+---+---+\n”); printf(“| * |”); for (j=1; j<=10; j++) printf(“%3d|”, j); printf(“\n+---+---+---+---+---+---+---+---+---+---+---+\n”); /* Tablo yazdır. i satırları, j sütunları ifade edecek */ for (i=1; i <= 10; i++){ printf(“|%3d:|“, i); /* i için tablonun bir satırını yazdır*/ for (j=1; j <= 10; j++){ printf(“%3d|”, i*j); } /*for-içerdeki */ printf(“\n”); } /*for-dışardaki */ /* Tablonun alt çizgisini yazdır*/
Çarpım Tablosu (daha sade) int i, j; for (i=1; i <= 10; i++){ printf(“i: %d: “,i); for (j=1; j <= 10; j++){ printf(“%5d”, i*j); } /* for-içerdeki */ printf(“\n”); } /* for-dışardaki */
Döngü içinde break & continue switch ifadesinde break kodunun bizi switch ifadesi dışına attığını görmüştük. Benzer bir şekilde, break döngü içinde kullanıldığın da bizi geçerli döngünün dışına atar.
Bir dizi sayının toplamını hesaplamak için kod: int toplam = 0; int n; while (1){ /* sonsuz döngü*/ printf(“bir sayı gir (durmak için -1): "); scanf("%d", &n"); if (n == -1) break; /* döngünün dışına çık */ toplam += n; } printf(“toplam=%d\n", toplam);
N sayısının asal olup olmadığını kontrol etmek için kod: int d; int n; printf(“Bir sayı gir: “); scanf(“%d”, &n); for (d=2; d<n; d++){ if (n%d == 0) break; } if (d<n) printf(“n=%d sayısı %d sayısına bölünüyor\n”,n,d); else printf(“n=%d sayısı asaldır\n”, n);
break (devam) Bazı durumlarda döngünün ortasında döngüden çıkmak için kullanılır. while (1){ printf(“bir sayı girin veya bitirmek için 0:”); scanf(“%d”, &n); if (n == 0) break; printf(“n=%d, n*n*n*=%d\n”, n, n*n*n); }
break (devam) break içinde kullanılan kod bloğunun dışına çıkarır. Böylece iç içe döngüler kullanılmış ise break bir tanesinden çıkarmak için kullanılabilir. while (…){ … switch(…){ break; /* switch ten çıkar (A)dan devam eder*/ } (A) (B)
continue Kontrolü döngünün sonuna alır. Unutmayın, hala döngünün içindeyiz. “continue” basitçe, döngünün gövdesinde kullanılan yerden sonraki kısmı atlar ve kontrolü döngünün sonuna alır. int i; int n = 0; int toplam = 0; while (n<10){ scanf(“%d”, &i); if (i == 0) continue; /*(B) ye geçer */ n++; toplam += i; /*(B)*/ }
goto Kontrolü keyfi olarak kodun içinde işaretlenmiş (etiketlenmiş) bir yere aktarmak için kullanılır. goto katı bir şekilde kullanılması istenmez. Kodu anlaşılmaz ve bakımı zor hale getirir. Ama bazı ciddi durumlarda kullanılabilir. while (…){ … switch(…){ goto dongu_tamam; /* break burada sadece bizi sadece*/ … /* switch ten çıkarabilir */ } dongu_tamam:
Sonsuz Döngüler Sınırsız sayıda tekrar eden döngüler while (1){ … } do{ … } while (1); for (;;){ … } Peki bu tür döngülerden nasıl çıkabiliriz? Basitçe döngünün bir yerlerine “break” koyarak. while (1){ printf(“Bir sayı gir (durmak için 0): “); scanf(“%d”, &n); if (n == 0) break; printf(“n=%d, n*n*n*=%d\n”, n, n*n*n); }