Bir for döngüsü, kurulum ve adım döngü başlığında yazılı olarak, bir koşul doğru olduğu sürece bir bloğu tekrarlar. Sayarken kullanılacak döngüdür: sabit sayıda tekrar ya da bir dizinin her indeksi.
Çıktı:
Lap 1 of 5
Lap 2 of 5
Lap 3 of 5
Lap 4 of 5
Lap 5 of 5
Üç Kısım Nasıl Çalışır
for (initializer; condition; iterator) sabit bir sırayla çalışır:
- Başlatıcı (
int i = 1) her şeyden önce bir kez çalışır. - Koşul (
i <= 5) kontrol edilir. False ise döngü biter ve gövde bir daha çalışmaz. - Gövde çalışır.
- Yineleyici (
i++) çalışır, sonra kontrol 2. adıma döner.
Koşul her yinelemeden önce kontrol edildiği için bir for döngüsü sıfır kez çalışabilir: for (int i = 10; i < 5; i++) gövdesine hiç girmez. Yukarıdaki döngü şu while döngüsü gibi davranır:
int i = 1;
while (i <= 5)
{
Console.WriteLine($"Lap {i} of 5");
i++;
}
İki biçim tek bir ayrıntıda farklıdır: bir for gövdesindeki continue yine de yineleyiciyi çalıştırır; bu while sürümünde ise i++'nın üzerinden atlardı, bu yüzden döngü aynı i'yi tekrar test eder ve sonsuza kadar dönebilirdi. Başlatıcıda bildirilen bir değişken yalnızca döngünün içinde var olur. Sonrasında son değerine ihtiyacınız varsa onu döngüden önce bildirin: int i; for (i = 0; ...; i++) { }.
Geriye Saymak ve Adım Atlamak
Yineleyici herhangi bir ifade olabilir. Geriye saymak için azaltın, adım atlamak için birden fazla ekleyin ya da geometrik bir dizi için çarpın:
Çıktı:
3... 2... 1... liftoff
00 15 30 45
1 10 100 1000
Yineleyicinin koşulu false yapmaya doğru ilerlediğinden emin olun. for (int i = 0; i < 10; i--) 10'dan uzaklaşarak sayar ve yalnızca i iki milyar yinelemeden sonra başa sardığında durur.
Bir Dizide İndeksle Dolaşmak
Diziler Length, listeler Count sunar ve geçerli indeksler 0'dan bunun bir eksiğine kadardır. İndeks size foreach'in vermediği bir şey verir: konuma, komşulara erişim ve geri yazma hakkı.
Çıktı:
#1: 17.99
#2: 4.50
#3: 38.25
#4: 7.43
item 1 vs item 0: down
item 2 vs item 1: up
item 3 vs item 2: down
Son döngü 1'den başlar, çünkü her elemanı kendinden öncekiyle karşılaştırır. Diziler sayfası dizilerin kendilerini oluşturmayı, sıralamayı ve kopyalamayı ele alır.
Birkaç Döngü Değişkeni
Başlatıcı aynı tipte birkaç değişken bildirebilir ve yineleyici virgülle ayırarak birkaçını güncelleyebilir. Klasik kullanım, birbirine doğru yürüyen iki indekstir:
Çıktı:
racecar is a palindrome: True
9, 1, 8, 3
İki değişken tek bir bildirimde aynı tipi paylaşmalıdır: int left = 0, right = 10 çalışır, int i = 0, string s = "" çalışmaz.
İç İçe Döngüler
Bir döngünün içindeki döngü, dış döngünün her yinelemesi için tüm aralığını bir kez çalıştırır. Tablolar ve ızgaralar tipik durumdur:
Çıktı:
1 2 3 4
2 4 6 8
3 6 9 12
4 8 12 16
İç gövde 16 kez çalışır (4 × 4). İç içelik işi hızla çoğaltır: her biri 10.000 öğe üzerinde dönen iç içe iki döngü 100 milyon yinelemedir. İç döngüdeki bir break yalnızca iç döngüden çıkar; break ve continue sayfası ikisinden birden nasıl çıkılacağını gösterir.
Sonsuz Döngüler: for(;;)
Başlığın üç kısmı da isteğe bağlıdır. Koşul olmadan döngü, içindeki bir şey onu terk edene kadar çalışır:
Çıktı:
Month 1: 70 left
Month 2: 40 left
Month 3: 10 left
Overdrawn in month 4: -20
for (;;) ve while (true) aynı şeye derlenir; kod tabanınız hangisini kullanıyorsa onu seçin.
Bir Fazla (Off-by-One) Hataları
En yaygın for hatası bir adım fazla giden bir koşuldur:
Çıktı:
Ada
Grace
Linus
IndexOutOfRangeException at index 3
3 elemanlı bir dizinin indeksleri 0, 1 ve 2'dir, bu yüzden doğru koşul i < names.Length'tir. Ayna hata, 0 indeksini hiç ziyaret etmeyen i > 0 ile geriye saymaktır. Bir List<T> üzerinde aynı hata bunun yerine ArgumentOutOfRangeException fırlatır.
Dolaşırken Öğe Silmek
İleri doğru bir döngü içinde bir List<T>'ten silmek, sonraki her elemanı bir konum aşağı kaydırır; bu yüzden döngü her silmeden hemen sonraki elemanı atlar:
Çıktı:
forward: 5, 0, 3, 7
backward: 5, 3, 7
İleri döngü geride bir 0 bıraktı: 1 indeksi silindikten sonra ikinci sıfır 1 indeksine kaydı, ama i++ zaten 2 indeksine geçmişti. Geriye doğru dolaşmak bundan kaçınır, çünkü silmeler yalnızca zaten ziyaret ettiğiniz elemanları kaydırır. Tek satırlık bir alternatif olarak stock.RemoveAll(x => x == 0) aynı işi yapar. Bir foreach döngüsü silmeye hiç izin vermez; InvalidOperationException fırlatır.
Kayan Noktalı Sayaçlar
Eşitlik test eden double döngü sayaçlarından kaçının. 0.1'in tam bir ikili temsili yoktur, bu yüzden onu on kez eklemek tam olarak 1.0 üretmez:
for (double x = 0; x != 1.0; x += 0.1) // never ends: x skips past 1.0
{
}
Bunun yerine bir tamsayıyla sayın ve değeri ondan hesaplayın: for (int i = 0; i <= 10; i++) { double x = i / 10.0; }.
for ile foreach
| İhtiyaç | Kullanın |
|---|---|
| Her elemanı sırayla okumak | foreach |
İndeks ya da komşular (i - 1, i + 1) | for |
| Bir dizi elemanına atama yapmak | for |
| 2'şer atlamak, geriye gitmek | for |
Dolaşırken bir List'ten silmek | for, geriye doğru |
İndeksleyicisi olmayan bir koleksiyon (HashSet, Dictionary, LINQ sonuçları) | foreach |
| Koleksiyon olmadan bir şeyi N kez tekrarlamak | for |
Dizilerde iki döngü de esasen aynı koda derlenir, bu yüzden hıza göre değil okunabilirliğe göre seçin.
Sıkça Sorulan Sorular
C#'ta for döngüsünün sözdizimi nedir?
for (initializer; condition; iterator) { body }, örneğin for (int i = 0; i < 5; i++) { ... }. Başlatıcı bir kez çalışır, koşul her yinelemeden önce kontrol edilir ve yineleyici her yinelemeden sonra çalışır. Döngü, koşul ilk kez false olduğunda biter.
C#'ta geriye doğru nasıl döngü kurulur?
Son indeksten başlayıp azaltın: for (int i = items.Length - 1; i >= 0; i--). > 0 değil >= 0 olduğuna dikkat edin, yoksa ilk eleman atlanır. Geriye doğru dolaşmak, dolaşırken bir List'ten öğe silmenin de güvenli yoludur.
C#'ta foreach yerine ne zaman for kullanmalıyım?
İndekse ihtiyaç duyduğunuzda (komşuları karşılaştırmak, bir diziye geri yazmak ya da birden fazla adım atlamak için), bir koleksiyonu dolaşmak yerine saydığınızda ya da bir listeden öğe sildiğinizde for kullanın. Her elemanı sırayla okumak için foreach kullanın; daha kısadır ve yanlış yapılacak bir indeksi yoktur.
C#'ta sonsuz döngü nasıl yazılır?
for (;;) { ... } ya da while (true) { ... }. Bir for başlığının üç kısmı da isteğe bağlıdır ve eksik bir koşul true sayılır. Çıkış koşulunuz sağlandığında döngüden break ya da return ile çıkın.
for döngümde neden IndexOutOfRangeException alıyorum?
Koşul indeksin uzunluğa ulaşmasına izin veriyor: i <= array.Length, son elemanın bir ötesi olan array[array.Length]'i ziyaret eder. Geçerli indeksler 0'dan Length - 1'e kadardır, bu yüzden koşul i < array.Length olmalıdır (ya da bir List için i < list.Count; bu durumda ArgumentOutOfRangeException fırlatılır).