Neden for Döngüsü
Bir switch bir dalı seçip yalnızca bir kez çalıştırır. Ama gerçek programların bir şeyi tekrar tekrar yapması gerekir: her puanı yazdırmak, bir sayı listesini toplamak, bir ızgaranın 10 satırını çizmek. for döngüsü, kodu bilinen sayıda tekrarlamak için C++'ın işçi atıdır ve kontrolünüzdeki yerleşik bir sayaca sahiptir.
Bir for döngüsünün ihtiyaç duyduğu her şey tek bir derli toplu başlıkta bulunur, böylece "kaç kez ve nasıl" hikâyesinin tamamı bir bakışta görünür.
Üç Parçalı Başlık
Bir for döngüsünün başlığında noktalı virgülle ayrılmış üç parça vardır: bir başlatıcı, bir koşul ve bir güncelleme.
for (initializer; condition; update) {
// gövde - koşul doğru olduğu sürece çalışır
}
Bunlar belirli bir sırada çalışır: başlatıcı başta bir kez çalışır; ardından koşul her yinelemeden önce kontrol edilir; gövde yalnızca koşul true ise çalışır; ve güncelleme her yinelemenin sonunda, koşul tekrar kontrol edilmeden hemen önce çalışır.
Burada int i = 0 bir kez çalışır. Sonra i < 5 kontrol edilir: geçerli olduğu sürece gövde yazdırır ve i++ sayacı artırır. i değeri 5 olduğunda koşul false olur, böylece döngü çıkar ve done yazdırılır. Gövde tam olarak 5 kez çalışır ve i, 0'dan 4'e kadar değerleri alır.
Sayacı başlık içinde bildirmek (int i = 0) i'yi döngüye kapsamlandırır - kapanış parantezinden sonra var olmaz, ki tam da istediğiniz şey budur.
Yukarı, Aşağı ve Adımlarla Sayma
Güncelleme kısmı i++ ile sınırlı değildir. Aşağı sayabilir, herhangi bir miktarda adım atabilir veya bir dizi indeksi üzerinde döngü kurabilirsiniz.
İlk döngü i > 0 olduğu sürece çalışır ve her seferinde azalarak 5 4 3 2 1 yazdırır. İkincisi her geçişte 2 ekler ve 10 dahil etmek istediğimiz bir değer olduğu için <= 10 kullanır. Koşulunuzu güncellemenizle eşleştirin: aşağı sayma > veya >= ile, yukarı sayma < veya <= ile gider.
Bir Dizi Üzerinde Döngü
Bir sayma döngüsünün en yaygın kullanımı, bir dizi üzerinde indeksle dolaşmaktır. Sayaç aynı zamanda okuduğunuz konum görevi görür.
Koşulun i <= n değil, i < n olduğuna dikkat edin. 5 elemanlı bir dizinin geçerli indeksleri 0'dan 4'e kadardır; indeks 5 sonun ötesindedir. scores[5] okumak tanımsız davranıştır - çöp yazdırabilir, çökebilir ya da çalışıyormuş gibi görünüp belleği sessizce bozabilir. i < n kalıbı, sıfır tabanlı herhangi bir dizi için güvenli varsayılandır.
Yalnızca değerlere ihtiyacınız varsa ve indekse değilse, aralık tabanlı for daha temizdir. Gerçekten konuma ihtiyacınız olduğunda klasik indeksli döngüye başvurun.
break ve continue
İki anahtar kelime, döngünün ortasında akışı değiştirmenize olanak tanır. break döngüden hemen çıkar; continue mevcut yinelemenin geri kalanını atlar ve güncellemeye atlar.
İlk döngü 7'yi bulduğu anda durur ve geri kalanını hiç kontrol etmez. İkincisi, i çift olduğunda gövdenin yazdırmasını atlamak için continue kullanır - güncelleme i++ yine de çalışır, böylece döngü ilerlemeye devam eder. İnce bir tuzak: continue güncellemeye atlar; bu yüzden sayacı başlık yerine gövde içinde güncellenen bir döngüde continue'ya güvenirseniz, o güncellemeyi yanlışlıkla atlayıp sonsuza dek dönebilirsiniz.
İç İçe Döngüler
Izgaralar, tablolar veya çiftlerle çalışmak için bir for'u başka bir for'un içine koyun. İç döngü, dış döngünün her tek adımı için tamamen çalışır.
Bu, 3x3'lük bir çarpım ızgarası yazdırır. Dış döngü bir row sabitler, iç döngü o satır için her col'u tarar, sonra bir satır sonu satırı bitirir. Sayaçlara farklı isimler verin (i/i değil, row/col) - aynı ismi yeniden kullanmak dıştakini gölgeler ve şaşırtıcı hatalar üretir. Maliyete de dikkat edin: bir n-döngüsünü başka bir n-döngüsünün içine yerleştirmek gövdeyi n * n kez çalıştırır ki bu hızla birikir.
Sık Yapılan Hatalar
Birkaç tuzak, C++'taki for döngüsü hatalarının çoğunu açıklar:
- Bir-eksik/bir-fazla: sıfır tabanlı bir boyutla
i <= n, sonun ötesinde bir eleman okur.i < nkullanın. - İşaretsiz taşma (underflow): işaretsiz bir türle aşağı saymak asla negatife düşmez.
for (size_t i = n - 1; i >= 0; i--)sonsuza dek döner, çünkü işaretsiz bir değer içini >= 0her zaman doğrudur -ideğeri0ikeni--çok büyük bir pozitif sayıya sarar. Aşağı sayımlar için işaretli birintkullanın ya da koşulu yeniden yazın. - Sayacı gövde içinde değiştirmek:
i'yi başlığın yanı sıra gövdede de değiştirmek döngü sayısını öngörülemez hâle getirir. Tek bir yer seçin.
// BUG: infinite loop - unsigned i is never < 0
for (size_t i = n - 1; i >= 0; i--) {
process(arr[i]);
}
Kayan noktalı sayaçlar bir başka sessiz tehlikedir: for (double x = 0.0; x != 1.0; x += 0.1), 0.1 tam olarak depolanamadığı için asla tam olarak 1.0'a ulaşmayabilir. Tam sayı sayımıyla döngü kurup değeri içeride hesaplayın ya da != yerine < kullanın.
Sıradaki: while Döngüleri
for döngüsü, sayıyı önceden bildiğinizde parlar. Ama bazen sabit bir adım sayısı olmadan bir koşul değişene kadar tekrarlamanız gerekir - dosya sonuna kadar giriş okumak, başarana kadar yeniden denemek. Bu, başlığı yalnızca bir koşula indirgeyen while döngüsünün işidir. Sıradaki sayfa odur.
Sıkça Sorulan Sorular
C++'ta for döngüsü nasıl yazılır?
Başlığa noktalı virgülle ayrılmış üç parça koyun: bir başlatıcı, bir koşul ve bir güncelleme. for (int i = 0; i < 5; i++) { cout << i; } gövdeyi i 0, 1, 2, 3, 4 değerlerini alacak şekilde çalıştırır. Koşul false olur olmaz döngü durur.
C++'ta for döngüsü ile aralık tabanlı for döngüsü arasındaki fark nedir?
Klasik bir for, sizin kontrol ettiğiniz bir indeks sayacı verir (for (int i = 0; i < n; i++)); konuma ihtiyaç duyduğunuzda ya da özel bir adımla ilerlemek istediğinizde bu gerekir. Aralık tabanlı for (for (int x : v)) indeksi gizler ve size her bir elemanı doğrudan verir - sadece değerlere ihtiyacınız olduğunda daha temizdir.
C++ for döngüm neden bir fazla ya da bir eksik çalışıyor?
Bu, klasik bir-eksik/bir-fazla (off-by-one) hatasıdır. Sıfır tabanlı bir boyutta < yerine <= kullanmak fazladan bir yineleme çalıştırır ve dizinin sonunun ötesini okur; son değeri dahil etmek isterken < kullanmak ise bir eksik çalıştırır. Boyutu n olan bir dizi için güvenli kalıp for (int i = 0; i < n; i++)'dir.