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