Selam,
Kaldığım yerden eğitimime devam ediyorum. Bugün öğrenmeye çalışacağım konu, döngüler ve break
ve continue
. break
‘i geçen derste hafif öğrenmiştim zaten. C programlama dilinde kullanılan birden fazla döngü var:
for
while
do while
Döngüler, adından da anlaşıldığı gibi belirli komutları tekrar tekrar çalıştırmamızı sağlar. Tabii ki belirli koşulları sağladığı sürece… Ne zaman, ne kadar, nasıl, niçin olacağını belirleyip, kontrol edebiliyoruz.
for
döngüsüfor(başlangıç değeri; koşul; arttırma / azaltma) { //koşul sağlandıkça çalışacak kodlar }
Yukarıda for
döngüsünün genel yapısı var. Daha açıklayıcı olması için hemen basit bir örnek yapalım:
#include <stdlib.h> #include <stdio.h> int main(void) { int i; for (i=0; i<5; i++) { printf("Selamn"); } return 0; }
Örnekteki kodlar çalıştığı zaman ekrana 5 kere “Selam” yazılacak. for
döngüsünün çalışma mantığı c4learn‘deki resimle daha iyi anlaşılabilir.
Basitçe bir for
döngüsü bu şekilde işliyor. Şimdi de basit bir faktöriyel hesabı yapan programı for
döngüsüyle yapalım:
#include <stdlib.h> #include <stdio.h> int main(void) { int faktoriyel, i, sonuc = 1; faktoriyel = 5; for(i = 1; i <= faktoriyel; i++) { sonuc *= i; printf("%d!: %dn",i, sonuc); } return 0; }
Çıktı:
1!: 1 2!: 2 3!: 6 4!: 24 5!: 120
Basit bir faktöriyel hesabı bu şekilde oluyor. sonuc
değişkeninin ilk değeri 1 çünkü faktöriyel hesaplaması 1’den başlar. Eğer ilk değer ataması yapmazsak, int
veri tipinin varsayılan değeri 0 olduğu için, ilk değer 0 alınırdı ve sonuç hep 0 olurdu. Aynı şekilde, i
değişkeni de 1’den başlayarak faktöriyeli bulunacak sayıya kadar birer birer artıyor.
Yukarıdaki faktöriyel hesabını farklı bir şekilde daha yapabiliriz. Yukarıda, 1’den başlayarak 5’e kadar olan sayıları çarpmıştık. Bu örnekte 5’ten başlayarak 1’e kadar sayıları çarpalım:
for ( i = faktoriyel; i>=1; i--) { sonuc *= i; printf("i: %d, sonuc: %dn", i, sonuc); }
Çıktı:
i: 5, sonuc: 5 i: 4, sonuc: 20 i: 3, sonuc: 60 i: 2, sonuc: 120 i: 1, sonuc: 120
Şimdi bu zamana kadar öğrendiğim tüm bilgilerle faktöriyel hesabı yapan bir program yazmayı deniyorum. Programın amacı kullanıcıdan bir sayı alacak ve bu sayının faktöriyel değerini hesaplayacak. Bu arada negatif sayıların faktöriyel değerleri hesaplanmıyor ve 0!’in sonucu 1’e eşit.
#include <stdlib.h> #include <stdio.h> int main(void) { int sayi, i; unsigned long int faktoriyel = 1; //sonuç negatif olamayacağı için sadece pozitif sayıları tutan veri tipini kullandım printf("Lütfen, faktoriyeli hesaplanacak sayıyı girin: "); scanf("%d", &sayi); if(sayi < 0) //girilen sayı negatifse { printf("Negatif sayıların faktöriyeli hesaplanamıyor."); } else if( (sayi == 0) || (sayi == 1) ) //girilen sayı 0 ya da 1 ise sonuç 1'e eşit olacak. { printf("%d!: 1", sayi); } else // 0 veya 1 haricinde girilen pozitif sayılar için hesaplama { for ( i = 2; i<=sayi; i++) { faktoriyel *= i; } printf("%d!: %lun", sayi, faktoriyel); } return 0; }
Şöyle de biraz fantezi yapabiliriz 🙂
#include <stdlib.h> #include <stdio.h> int main(void) { int sayi, i; unsigned long int faktoriyel = 1; //sonuç negatif olamayacağı için sadece pozitif sayıları tutan veri tipini kullandım printf("Lütfen, faktoriyeli hesaplanacak sayıyı girin: "); scanf("%d", &sayi); if(sayi < 0) //girilen sayı negatifse uyarı verecek { printf("Negatif sayıların faktöriyeli hesaplanamıyor."); } else //pozitif sayılar için işleme devam { switch(sayi) { // 0 ve 1 için sonuç 1 olacaktır. case 0: case 1: printf("%d!: 1n", sayi); break; // 0 ve 1 haricindeki değerler için hesap yapmalıyız default: for ( i = 2; i<=sayi; i++) { faktoriyel *= i; } printf("%d!: %lun", sayi, faktoriyel); } } return 0; }
for
döngüsü bu kadar değil tabii ki. Farklı şekillerde yazılmış birçok for döngüsü oluşturulabilir. c4learn üzerinde 8 farklı şekilde yazılmış for döngüsü mevcut. Kullanım senaryoları, en sık yapılan hatalar da açıklanmış. İçlerinden birini burada da paylaşıyorum.
for (i=0,j=90; i<100 && j>60; i++,j--)
Görüldüğü üzere başlangıç değerleri, koşullar, arttırma / azaltma birden fazla değişken ile yapılabiliyor.
while
İlk olarak while
‘ın genel yapısına göz atalım:
while(//koşul) { //komutlar }
while
döngüsünde koşulumuzun doğru olup olmadığı girişte kontrol ediliyor. Eğer doğruysa döngü çalışacak. Koşulun yanlış olması durumda ise döngüye hiç giriş yapılmaz.
while(1) { puts("Bu döngü sonsuza kadar gidiyor..."); }
Örneğin yukarıdaki döngümüz sonsuza kadar devam edecektir. Çünkü koşulumuz 0’dan farklı olduğu için her zaman doğru demektir. c4learn‘de while
ile düşülen sonsuz döngülere örnekler verilmiş. Basit ama gözden kaçan hatalar her zaman olabilir. Dikkat etmek gerek. Şimdi de while
ile ilgili bir örnek yapalım:
#include <stdlib.h> #include <stdio.h> int main(void) { int sayi, sayac = 0; printf("Lütfen bir değer girin: "); scanf("%d", &sayi); printf("<<< 0 - %d arasındaki çift sayılar >>>", sayi); while (sayac <= sayi) //girilen sayıdan küçük ve eşit oldukça döngü devam edecek { if( (sayac % 2) == 0) //sayac değerinin 2 ile bölümünden kalan 0 ise o anki sayac değeri çift sayı demektir { printf("n%d", sayac); //o anki sayac değerini ekrana yazdırıyorum } sayac++; //sayac değerini 1 arttırıyorum } return 0; }
5 değerini girdiğimizde elde ettiğimiz çıktı:
Lütfen bir değer girin: 5 <<< 0 - 5 arasındaki çift sayılar >>> 0 2 4
do while
while
ile hemen hemen aynı ama arasında ufak bir fark var. while
, girişte koşulu kontrol ediyordu. do while
ise çıkışta koşulu kontrol ediyor. Yani bu demektir ki, koşul doğru ya da yanlış olsun, döngü en az 1 kere çalışacaktır.
do while
‘ın genel yapısı:
do { //komutlar } while( //koşul);
Basit bir örnekle başlıyorum:
#include <stdlib.h> #include <stdio.h> #define TRUE 1 #define FALSE 0 int main(void) { do { puts("Selam"); } while(FALSE); return 0; }
Yukarıdaki örnekte koşul yanlış olmasına karşın ekrana bir kere “Selam” yazılacaktır. Çünkü önce kod blokları ( { } ) arasındaki komutlar çalışacak, daha sonra while
içindeki koşul kontrol edilecektir. Koşul yanlış olduğu için döngü sonlanacaktır.
Daha iyi anlamak için basit bir kullanıcı adı ve şifre kontrolü yapan program yazıyorum:
#include <stdlib.h> #include <stdio.h> int main(void) { int kullaniciAdi = 123, sifre = 123, girilenKullaniciAdi, girilenSifre; do { printf("nKullanıcı adınızı girin: "); scanf("%d", &girilenKullaniciAdi); printf("nSifreyi girin: "); scanf("%d", &girilenSifre); } while( !( (kullaniciAdi == girilenKullaniciAdi) && (sifre == girilenSifre) ) ); return 0; }
Program çalışmaya başladığı zaman, ilk olarak kullanıcı adı ve şifre girilmesini istiyor. while
içinde, girilen değerleri mevcut değerler ile karşılaştırıyor.
13. satırda koşulu kontrol ediyoruz. Hem kullanıcı adının hem de şifrenin doğru olması gerek. Her ikisinin de doğru olduğunu varsayarsak (1 && 1) = 1 olacağından, döngü devam edecektir. Bunu önlemek için koşulun başına !
ekleyerek döngüden çıkmasını sağlıyorum.
Kullanıcı adı ya da şifreden birisi yanlışsa, ya da ikisi de yanlışsa (1 && 0) = 0 ya da (0 && 0) = 0 yapacağı için koşulun başındaki ! ile koşulları tekrar 1 yaparak döngüye devam ediyoruz.
break
ve continue
break
break
‘i, önceki derste switch
ile beraber görmüştüm zaten. Komutları sonlandırmaya yarıyordu. Evet, break
‘in işi bu. Bir şeyleri sonlandırmak. Mesela döngümüz 1453 kere daha dönecek ama istisnai bir durum olduğu için o anda döngüden çıkmamız lazım. Bu durumda break
devreye giriyor. Şöyle ki:
int sayac = 0; while(sayac < 100) { printf("sayaç değeri: %dn", sayac); if(sayac == 5) { printf("sayaç %d olduğu için döngü sonlandı.", sayac); break; } sayac++; }
Çıktı:
sayaç değeri: 0 sayaç değeri: 1 sayaç değeri: 2 sayaç değeri: 3 sayaç değeri: 4 sayaç değeri: 5 sayaç 5 olduğu için döngü sonlandı.
Döngü için koşul, sayacın 100’den küçük olduğu durumlarda devam etmesiydi ama 6. satırdaki koşulda sayacın 5’e eşit olması durumda break
komutu devreye girdi ve döngüden tamamen çıkıldı.
continue
continue
, break
ile benzer ama biraz daha insaflı hali. break
, döngüyü tamamen sonlandırıyordu. continue
ise, belirlediğimiz komutları işleme sokmadan döngüye devam ediyor. Şöyle ki:
int sayac = 0; while(sayac < 15) { sayac++; if( (sayac % 5) == 0) { continue; } else { printf("%d-", sayac); } }
Çıktı:
1-2-3-4-6-7-8-9-11-12-13-14-
Yukarıdaki örnekte sayac
değerinin 5 ile bölümünden kalan değer 0 ise, continue
komutu devreye giriyor ve böylece else
içindeki komutlar çalışmıyor.
break
ve continue
komutlarını açıklayan görsellerle bugünkü dersimi noktalıyorum. Kaynağım yine c4learn
break
için görsellerdo while
for
döngüsüfor
döngüsü
while
döngüsü
continue
için görsellerwhile
do while
while
, girişte koşulu kontrol ederken do while
, çıkışta koşulu kontrol eder. yani do while
, koşul ister doğru ister yanlış olsun en az 1 kere çalışır.break
içinde bulunduğu döngüyü kırıp çıkar.continue
belirlenen komutları atlayıp, döngüye devam eder.
Son olarak şu hatırlatmayı tekrar yapmak istiyorum. Bu web sitesinde öğrendiklerimi geliştirmek için çalışıyorum. Eğer hatalı ya da eksik bir şeyler fark ederseniz lütfen bana bildirin.
Senaryo1: 1/x^2 + 3/x^4 + 5/x^6 + 7/x^8 +⋯+ (2n-1)/x^2n serisini hesaplayan program. n değeri pozitif tam sayı ve x reel sayı olacak. (n=3 ve x=1 için sonuç 9 0lmalı)
Senaryo2: Bir okyanusta 1044 tane kelebek balığı, 4544 tane palyaço balığı vardır. 1 yılda kelebek balıkları %5.71, palyoça balıkları 1.07 oranında çoğalıyor. Kaç yıl sonra kelebek balıklarının, palyaço balıklarının sayısını geçeceğini hesaplayan program.
Eğitimim için kullandığım örnekleri bu adresteki github reposunda saklıyorum. Ders başlığıyla eşit olan klasörde kaynak kodları bulabilirsiniz.
#include <stdio.h> #include <stdlib.h> #include <math.h> int main(int argc, char** argv) { int n; float x; do { puts("Enter positive number for n: "); scanf("%d", &n); } while (n <= 0); puts("Enter reel number for x: "); scanf("%f", &x); int count; float result = 0; for (count = 1; count <= (2 * n) - 1; count += 2) { result += count / pow(x, count * 2); //pow(n,m) fonksiyonu bir sayının(n) kuvvetini(m) bulur. //math.h kütüphanesini eklemeyi unutma. //pow(n,m) returns n raised to the power of m. //don't forget to add math.h library. } printf("Result: %f", result); return (EXIT_SUCCESS); }
#include <stdio.h> #include <stdlib.h> #define CHELMON_INC (5.71 / 100) #define ANEMON_INC (1.07 /100) int main(int argc, char** argv) { int chelmonFish = 1042, anemonFish = 4544; int year = 0; while(chelmonFish < anemonFish) { chelmonFish += chelmonFish * CHELMON_INC; anemonFish += anemonFish * ANEMON_INC; year++; printf("%d year laters, chelmons: %d, anemons: %dn", year, chelmonFish, anemonFish); } return (EXIT_SUCCESS); }
Eğer yanlış ya da düzeltilmesi gereken bir nokta farkettiyseniz, lütfen bana bildirin.
Celery ile alakalı "best practice"leri ve faydalı araçları bir araya getiren güzel bir checklist'e denk…
Diziler en temel ve sık kullandığımız araçlardan... Kod yazarken işimizi kolaylaştıracak, daha temiz kod yazmamızı…
listve tuple bilginizi test etmek ister misiniz? realpython.com da keşfettiğim ve Türkçe'ye çevirdiğim mini teste…
Rehberlik sağlaması ve bilgi tazelemesi açısından faydalı olduğunu düşündüğüm bir Toptal blog paylaşımınıTürkçe'ye çevirdim.Devamını okuyunBilmeniz…
Angular componentlerine console üzerinden hızlıca erişmek için kullanılan bir teknik. Unutmamak için kendime not düşüyorum.Devamını…
Geçtiğimiz günlerde keşfettiğim ve oldukça da hoşuma giden repoyu paylaşmak istiyorum: lydiahallie/javascript-questions Genel olarak temel…