↑↓ seç · Enter aç · Esc kapat

Mutlu Tekin
Mutlu Tekin
← Yazılar

Bölüm 3 — Konu 14: `for`, `while`, `do-while` Döngüleri

3 dk okuma #dart
Dizi · 14/64 Dart Türkçe Tutorial
  1. Bölüm 1 — Konu 1: Dart Nedir, Nerede Kullanılır, Neden Flutter Bu Dili Seçti
  2. Bölüm 1 — Konu 2: Ortam Kurulumu (Dart SDK, DartPad, Terminal ile Çalıştırma)
  3. Bölüm 1 — Konu 3: İlk Program (`main()`, `print()`, Dosya Yapısı)
  4. Bölüm 1 — Konu 4: Yorum Satırları, Temel Sözdizimi Kuralları
  5. Bölüm 2 — Konu 5: Değişken Tanımlama — `var`, `final`, `const` Farkı
  6. Bölüm 2 — Konu 6: Temel Tipler — `int`, `double`, `String`, `bool`
  7. Bölüm 2 — Konu 7: Tip Çıkarımı (Type Inference) ve Açık Tip Belirtme
  8. Bölüm 2 — Konu 8: `dynamic` ve `Object` — Ne Zaman Kullanılır, Ne Zaman Kaçınılır
  9. Bölüm 2 — Konu 9: Null Safety Temelleri (`?`, `!`, `late`'e Giriş)
  10. Bölüm 3 — Konu 10: Aritmetik, Atama, Karşılaştırma, Mantıksal Operatörler
  11. Bölüm 3 — Konu 11: `if / else if / else`
  12. Bölüm 3 — Konu 12: `switch` / `switch expression` (Modern Dart)
  13. Bölüm 3 — Konu 13: Ternary Operatör, `??`, `??=`, `?.`
  14. Bölüm 3 — Konu 14: `for`, `while`, `do-while` Döngüleri
  15. Bölüm 4 — Konu 16: `List` — Oluşturma, Erişim, Temel Metodlar
  16. Bölüm 4 — Konu 17: `Set` — Benzersiz Eleman Mantığı
  17. Bölüm 4 — Konu 18: `Map` — Key-Value Yapılar
  18. Bölüm 4 — Konu 19: Koleksiyon Üzerinde `for-in`, `forEach`
  19. Bölüm 4 — Konu 20: Spread Operatörü (`...`, `...?`) ve Collection If/For
  20. Bölüm 5 — Konu 21: Fonksiyon Tanımlama, Parametreler (Positional, Named, Optional)
  21. Bölüm 5 — Konu 22: Varsayılan Parametre Değerleri (Derinlemesine)
  22. Bölüm 5 — Konu 23: Arrow Function (`=>`) Sözdizimi
  23. Bölüm 5 — Konu 24: Fonksiyonlar Birinci Sınıf Vatandaş — Değişkene Atama, Parametre Olarak Geçme
  24. Bölüm 5 — Konu 25: Anonim Fonksiyonlar ve Closure Kavramı (Derinlemesine)
  25. Bölüm 5 — Konu 26: Recursion (Özyineleme)
  26. Bölüm 6 — Konu 27: Class Tanımlama, Constructor (Varsayılan, Named, Factory)
  27. Bölüm 6 — Konu 28: Alanlar (Fields), Metodlar, `this` Kullanımı (Derinlemesine)
  28. Bölüm 6 — Konu 29: Initializer List, Constructor Kısayolları (Derinlemesine)
  29. Bölüm 6 — Konu 30: Getter / Setter
  30. Bölüm 6 — Konu 31: Statik Üyeler (`static`)
  31. Bölüm 7 — Konu 32: Kalıtım (`extends`), `super` Kullanımı
  32. Bölüm 7 — Konu 33: Metod Override Etme, `@override`
  33. Bölüm 7 — Konu 34: Soyut Sınıflar (`abstract class`)
  34. Bölüm 7 — Konu 35: Interface Mantığı (`implements`)
  35. Bölüm 7 — Konu 36: Mixin (`with`)
  36. Bölüm 7 — Konu 37: `enum` — Basit ve Gelişmiş (Metotlu Enum'lar)
  37. Bölüm 8 — Konu 38: `try / catch / finally`, `throw`
  38. Bölüm 8 — Konu 39: Özel Exception Sınıfları Yazma
  39. Bölüm 8 — Konu 40: Sound Null Safety Derinlemesine — `late`, `required`, Non-Nullable Varsayılan Davranış
  40. Bölüm 8 — Konu 41: `assert` ile Geliştirme Zamanı Kontrolleri
  41. Bölüm 9 — Konu 42: Generic Sınıflar ve Fonksiyonlar
  42. Bölüm 9 — Konu 43: Generic Sınırlamalar (`<T extends ...>`)
  43. Bölüm 9 — Konu 44: Dart'ın Built-in Generic Koleksiyonları Nasıl Çalışır
  44. Bölüm 10 — Konu 45: `Future` Kavramı, `async`/`await`
  45. Bölüm 10 — Konu 46: `Future.then`, Hata Yönetimi (`catchError`)
  46. Bölüm 10 — Konu 47: `Stream` Temelleri, `async*`, `yield`
  47. Bölüm 10 — Konu 48: `StreamController`, Broadcast Stream
  48. Bölüm 11 — Konu 49: `map`, `where`, `reduce`, `fold`
  49. Bölüm 11 — Konu 50: `sort`, Custom Comparator ile Sıralama
  50. Bölüm 11 — Konu 51: Iterable Kavramı Derinlemesine (Lazy Evaluation)
  51. Bölüm 11 — Konu 52: Cascade Notasyonu (`..`)
  52. Bölüm 12 — Konu 53: `pubspec.yaml`, pub.dev'den Paket Ekleme
  53. Bölüm 12 — Konu 54: Kütüphane Oluşturma, `import`/`export`, `part`/`part of`
  54. Bölüm 12 — Konu 55: Dart'ta Test Yazımı (`test` Paketi, Unit Test Mantığı)
  55. Bölüm 12 — Konu 56: Extension Methods
  56. Bölüm 12 — Konu 57: Dart'ın Derleme Modelleri (JIT vs AOT) ve Bunun Flutter'a Etkisi
  57. Bölüm 13 — Konu 59: Dart 3 Pattern Matching — Records, Destructuring, Sealed Classes, Exhaustive Switch
  58. Bölüm 13 — Konu 60: `Never` Tipi, `covariant` ve Generic Variance Detayları
  59. Bölüm 13 — Konu 61: Event Loop Derinlemesine — Microtask Queue vs Event Queue
  60. Bölüm 13 — Konu 62: Memory Model & Performans — Garbage Collection, `const` Nesnelerin Bellek Avantajı
  61. Bölüm 13 — Konu 63: Isolate'ler Arası Mesajlaşmanın Maliyeti ve `compute()`'un İç İşleyişi
  62. Bölüm 13 — Konu 64: FFI (Foreign Function Interface) — C Koduna Erişim
  63. Bölüm 13 — Konu 65: Sunucu Tarafında Dart — `dart:io`, `shelf` Paketiyle Basit Bir Backend/CLI Aracı Yazma
  64. Bölüm 13 — Konu 66: Derleyici & Analiz Araçları — `dart analyze`, Custom Lint Kuralları, `build_runner` Mimarisi
Dizinin sayfası →
İçindekiler 11 başlık
  1. for Döngüsü — Klasik Sayaç Tabanlı Döngü
  2. for-in — Koleksiyonlar Üzerinde Gezinme
  3. while Döngüsü — Koşul Önce Kontrol Edilir
  4. do-while Döngüsü — Gövde En Az Bir Kez Çalışır
  5. break — Döngüyü Erken Sonlandırma
  6. continue — Sadece Mevcut İterasyonu Atlama
  7. İç İçe Döngüler (Nested Loops)
  8. Sonsuz Döngü — Dikkatli Kullan
  9. 🎯 Bu Dersten Çıkarılması Gerekenler
  10. 📝 Ödevler
  11. 🏁 Bölüm 3 Tamamlandı!

for Döngüsü — Klasik Sayaç Tabanlı Döngü

dart
void main() {
  for (int i = 0; i < 5; i++) {
    print(i); // 0, 1, 2, 3, 4
  }
}

Yapıyı üç parçaya ayıralım:

  • int i = 0 — başlangıç ifadesi, döngü başlamadan önce bir kere çalışır.
  • i < 5 — koşul, her iterasyon başında kontrol edilir; true olduğu sürece döngü devam eder.
  • i++ — güncelleme ifadesi, her iterasyon sonunda çalışır.

Akış şöyle işler: başlangıç (bir kere) → koşul kontrolü → (true ise) gövde çalışır → güncelleme → koşul kontrolü → ... (false olana kadar tekrar).

Geriye doğru sayma:

dart
void main() {
  for (int i = 10; i > 0; i--) {
    print(i); // 10, 9, 8, ..., 1
  }
}

Adım büyüklüğünü değiştirme:

dart
void main() {
  for (int i = 0; i <= 20; i += 5) {
    print(i); // 0, 5, 10, 15, 20
  }
}

for-in — Koleksiyonlar Üzerinde Gezinme

Koleksiyonları detaylı Bölüm 4'te işleyeceğiz ama for-in yapısını burada tanıyalım, çünkü döngülerin en yaygın kullanım alanlarından biri bu:

dart
void main() {
  List<String> meyveler = ["Elma", "Armut", "Muz"];

  for (var meyve in meyveler) {
    print(meyve); // Elma, Armut, Muz (sırayla)
  }
}

for-in, bir koleksiyonun (liste, set vb.) her elemanı üzerinde, sayaç yönetimiyle uğraşmadan gezinmeni sağlar. Klasik for ile aynı işi de yapabilirsin (for (int i = 0; i < meyveler.length; i++) { print(meyveler[i]); }) ama for-in çok daha okunabilirdir — indeks numarasına ihtiyacın yoksa for-in tercih edilmelidir.

while Döngüsü — Koşul Önce Kontrol Edilir

dart
void main() {
  int sayac = 0;

  while (sayac < 5) {
    print(sayac);
    sayac++;
  }
}

while, koşul true olduğu sürece gövdeyi tekrar tekrar çalıştırır. Koşul, her iterasyondan önce kontrol edilir — eğer koşul baştan false ise, döngü gövdesi hiç çalışmaz:

dart
void main() {
  int sayac = 10;

  while (sayac < 5) {
    print("Bu asla yazdırılmaz");
  }

  print("Döngü bitti"); // doğrudan buraya atlar
}

for mu, while mı kullanmalı?

  • Kaç kere döneceğin önceden belliyse (bir sayaç veya koleksiyon üzerinde) → for
  • Kaç kere döneceğin belirsizse, bir koşul sağlanana kadar devam etmesi gerekiyorsa (örn. kullanıcı doğru şifreyi girene kadar, bir dosyanın sonuna gelene kadar) → while

do-while Döngüsü — Gövde En Az Bir Kez Çalışır

dart
void main() {
  int sayac = 10;

  do {
    print(sayac); // 10 — bir kere çalışır, koşul sonradan kontrol edilir
    sayac++;
  } while (sayac < 5);
}

do-while ile while arasındaki kritik fark: do-while'da koşul, gövde çalıştıktan SONRA kontrol edilir. Bu yüzden koşul baştan false olsa bile, gövde en az bir kere çalışır.

dart
void main() {
  int sayac = 0;

  // while — koşul baştan false, hiç çalışmaz
  while (sayac > 10) {
    print("while: çalışmaz");
  }

  // do-while — koşul baştan false olsa da bir kere çalışır
  do {
    print("do-while: en az bir kere çalışır");
  } while (sayac > 10);
}

Ne zaman do-while kullanılır? Klasik örnek: bir menü sistemi — kullanıcıya en az bir kere seçenekleri göstermen gerekir (henüz hiçbir girdi almadan), sonra kullanıcının girdisine göre devam edip etmeyeceğine karar verirsin.

break — Döngüyü Erken Sonlandırma

dart
void main() {
  for (int i = 0; i < 10; i++) {
    if (i == 5) {
      break; // döngüyü tamamen durdurur
    }
    print(i); // 0, 1, 2, 3, 4
  }
}

break, içinde bulunduğu döngüyü tamamen sonlandırır — kontrol, döngüden sonraki ilk satıra atlar.

continue — Sadece Mevcut İterasyonu Atlama

dart
void main() {
  for (int i = 0; i < 10; i++) {
    if (i % 2 == 0) {
      continue; // çift sayıları atla, döngü devam eder
    }
    print(i); // 1, 3, 5, 7, 9
  }
}

continue, break'ten farklı olarak döngüyü durdurmaz — sadece mevcut iterasyonun geri kalanını atlar ve bir sonraki iterasyona geçer.

break vs continue — Görsel Özet:

dart
void main() {
  print("--- break örneği ---");
  for (int i = 0; i < 5; i++) {
    if (i == 3) break;
    print(i); // 0, 1, 2 (3'e gelince tamamen durur)
  }

  print("--- continue örneği ---");
  for (int i = 0; i < 5; i++) {
    if (i == 3) continue;
    print(i); // 0, 1, 2, 4 (sadece 3 atlanır, döngü devam eder)
  }
}

İç İçe Döngüler (Nested Loops)

dart
void main() {
  for (int i = 1; i <= 3; i++) {
    for (int j = 1; j <= 3; j++) {
      print("i=$i, j=$j");
    }
  }
}

Çıktı, dış döngünün her adımında iç döngünün baştan sona çalışması şeklinde ilerler: i=1,j=1 → i=1,j=2 → i=1,j=3 → i=2,j=1 → ... Bu, örneğin bir 2 boyutlu tablo (satır-sütun) işlerken çok kullanılan bir kalıptır — Flutter'da GridView mantığını anlarken de bu kavram işine yarayacak.

İç içe döngülerde break/continue dikkat gerektirir: break/continue, sadece kendi bulundukları döngüyü etkiler, dıştaki döngüyü değil:

dart
void main() {
  for (int i = 1; i <= 3; i++) {
    for (int j = 1; j <= 3; j++) {
      if (j == 2) break; // sadece İÇ döngüyü durdurur
      print("i=$i, j=$j");
    }
  }
  // Çıktı: i=1,j=1 / i=2,j=1 / i=3,j=1
  // Dış döngü etkilenmez, her i için iç döngü j=2'de durur ama dış döngü devam eder
}

Sonsuz Döngü — Dikkatli Kullan

dart
void main() {
  int sayac = 0;
  while (true) {
    print(sayac);
    sayac++;
    if (sayac >= 5) {
      break; // çıkış koşulu MUTLAKA olmalı
    }
  }
}

while (true) teknik olarak sonsuza kadar çalışır — bir çıkış koşulu (break) koymadıysan, program hiç durmaz ve donar (Flutter'da bu, uygulamanın tamamen kilitlenmesi anlamına gelir). Bu yapı genelde belirli senaryolarda (örneğin bir sunucunun sürekli istek dinlemesi) bilinçli olarak kullanılır, ama her while (true) yazdığında mutlaka bir çıkış yolu olduğundan emin ol.


🎯 Bu Dersten Çıkarılması Gerekenler

  • for: kaç kere döneceğin önceden belliyse kullanılır (başlangıç, koşul, güncelleme).
  • for-in: koleksiyon elemanları üzerinde indeks yönetmeden gezinmeyi sağlar.
  • while: koşul önce kontrol edilir, baştan false ise gövde hiç çalışmaz.
  • do-while: koşul sonra kontrol edilir, gövde en az bir kere çalışır.
  • break: döngüyü tamamen durdurur. continue: sadece mevcut iterasyonu atlar, döngü devam eder.
  • İç içe döngülerde break/continue sadece kendi bulunduğu döngüyü etkiler.
  • while (true) kullanırken mutlaka bir çıkış koşulu (break) olmalı.

📝 Ödevler

  • [ ] for ile 1'den 10'a kadar sayıların toplamını hesapla.
  • [ ] while ile kullanıcıdan alındığını varsaydığın (elle atadığın) bir sayı 0 olana kadar geriye sayan bir döngü yaz.
  • [ ] do-while ile, koşulu baştan false olan ama yine de bir kere çalışan bir örnek yaz, while ile aynı koşulu denediğinde hiç çalışmadığını göster.
  • [ ] 1'den 50'ye kadar olan sayılardan sadece 3'e bölünebilenleri continue kullanarak, 30'dan büyük olanları da break ile durdurarak yazdır.
  • [ ] İç içe iki döngü ile 3x3'lük bir çarpım tablosu (i * j) yazdır.

🏁 Bölüm 3 Tamamlandı!

Artık tüm temel operatörleri, koşullu yapıları (if, switch) ve döngüleri (for, while, do-while) biliyorsun — bu, "mantık kurma" becerisinin temelidir ve buraya kadar öğrendiklerinle artık gerçek algoritmalar yazabilirsin.

Sıradaki durak Bölüm 4 — Koleksiyonlar: List, Set, Map ile veri gruplarını nasıl yöneteceğini öğreneceğiz — bu, neredeyse her Dart/Flutter programının omurgasını oluşturan bir konu.