↑↓ seç · Enter aç · Esc kapat

Mutlu Tekin
Mutlu Tekin
← Yazılar

Bölüm 3 — Konu 10: Aritmetik, Atama, Karşılaştırma, Mantıksal Operatörler

2 dk okuma #dart
Dizi · 10/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 8 başlık
  1. 1. Aritmetik Operatörler
  2. 2. Bileşik Atama Operatörleri (Compound Assignment)
  3. 3. Karşılaştırma Operatörleri
  4. 4. Mantıksal Operatörler
  5. 5. Operatör Önceliği (Precedence)
  6. 6. is ve is! — Tip Kontrolü Operatörleri
  7. 🎯 Bu Dersten Çıkarılması Gerekenler
  8. 📝 Ödevler

Bölüm 3'e hoş geldin — bu bölümde gerçek anlamda "mantık kurmaya" başlıyoruz. İlk durağımız, tüm kontrol akışının (if, döngüler vb.) temelini oluşturan operatörler.

1. Aritmetik Operatörler

dart
void main() {
  int a = 10;
  int b = 3;

  print(a + b);  // 13 — toplama
  print(a - b);  // 7  — çıkarma
  print(a * b);  // 30 — çarpma
  print(a / b);  // 3.3333333333333335 — bölme, HER ZAMAN double döner
  print(a ~/ b); // 3  — tam sayı bölmesi (integer division)
  print(a % b);  // 1  — mod (kalan)
}

Bölüm 2'de ~/ ve %'e kısaca değinmiştik, burada pekiştirelim:

dart
void main() {
  print(17 ~/ 5); // 3 — 17'nin 5'e tam bölümü
  print(17 % 5);  // 2 — kalan

  // Doğrulama: (bölüm * bölen) + kalan = orijinal sayı
  print((3 * 5) + 2); // 17 ✓
}

Artırma/Azaltma operatörleri:

dart
void main() {
  int sayac = 5;

  sayac++; // sayac = sayac + 1
  print(sayac); // 6

  sayac--; // sayac = sayac - 1
  print(sayac); // 5

  print(sayac++); // 5 yazdırır, SONRA artırır (post-increment)
  print(sayac);   // 6

  print(++sayac); // ÖNCE artırır, SONRA 7 yazdırır (pre-increment)
  print(sayac);   // 7
}

Bu ++x ile x++ farkı sık karıştırılır: x++ önce mevcut değeri kullanır, sonra artırır. ++x önce artırır, sonra yeni değeri kullanır.

2. Bileşik Atama Operatörleri (Compound Assignment)

dart
void main() {
  int puan = 100;

  puan += 10; // puan = puan + 10
  print(puan); // 110

  puan -= 20; // puan = puan - 20
  print(puan); // 90

  puan *= 2;  // puan = puan * 2
  print(puan); // 180

  puan ~/= 3; // puan = puan ~/ 3
  print(puan); // 60
}

Bunlar, puan = puan + 10 yazmanın kısayoludur — Dart'a özgü değil, C ailesindeki hemen her dilde bulunur.

3. Karşılaştırma Operatörleri

dart
void main() {
  int a = 10;
  int b = 20;

  print(a == b); // false — eşit mi?
  print(a != b); // true  — eşit değil mi?
  print(a < b);  // true  — küçük mü?
  print(a > b);  // false — büyük mü?
  print(a <= b); // true  — küçük veya eşit mi?
  print(a >= b); // false — büyük veya eşit mi?
}

Bunların hepsi bir bool sonuç döndürür — bu yüzden genelde if koşullarında kullanılırlar (bir sonraki konuda işleyeceğiz).

Önemli detay — == ile nesne karşılaştırması:

dart
void main() {
  String isim1 = "Ahmet";
  String isim2 = "Ahmet";
  print(isim1 == isim2); // true — içerik karşılaştırılır
}

Dart'ta == operatörü, ilkel tipler (int, double, String, bool) için içerik karşılaştırması yapar (Java'daki gibi referans karşılaştırması değil). Kendi yazacağın sınıflar için bu davranışı özelleştirebilirsin — bunu Bölüm 6'da göreceğiz.

4. Mantıksal Operatörler

dart
void main() {
  bool ogrenciMi = true;
  bool calisiyorMu = false;

  print(ogrenciMi && calisiyorMu); // false — VE (AND): ikisi de true olmalı
  print(ogrenciMi || calisiyorMu); // true  — VEYA (OR): en az biri true olmalı
  print(!ogrenciMi);               // false — DEĞİL (NOT): tersini alır
}

Kısa devre değerlendirmesi (Short-circuit evaluation):

dart
bool pahaliIslem() {
  print("pahaliIslem çağrıldı");
  return true;
}

void main() {
  bool sonuc = false && pahaliIslem();
  // "pahaliIslem çağrıldı" YAZDIRILMAZ!
  // Çünkü && operatöründe sol taraf false ise, sağ taraf hiç değerlendirilmez

  print(sonuc); // false
}

Bu davranış önemli bir performans/mantık aracıdır: && operatöründe sol taraf false ise, Dart sağ tarafı hiç çalıştırmaz (çünkü sonucun zaten false olacağı belli). Benzer şekilde || operatöründe sol taraf true ise sağ taraf çalıştırılmaz.

Bu, null kontrolü gibi durumlarda pratik bir kullanım sağlar:

dart
void main() {
  String? isim;

  if (isim != null && isim.length > 3) {
    print("Uzun isim");
  } else {
    print("Kısa isim veya null");
  }
}

isim != null false ise, isim.length > 3 kısmı hiç çalıştırılmaz — bu sayede isim null olsa bile hata almayız (eğer sıra tersine çevrilseydi, yani isim.length > 3 && isim != null yazsaydık, null olduğunda önce .length'e erişmeye çalışırdı ve hata verirdi).

5. Operatör Önceliği (Precedence)

Matematikte olduğu gibi, Dart'ta da operatörlerin bir öncelik sırası vardır:

dart
void main() {
  int sonuc = 2 + 3 * 4; // çarpma önce yapılır
  print(sonuc); // 14, (2 + (3*4)) — 20 değil!

  int sonuc2 = (2 + 3) * 4; // parantez önceliği değiştirir
  print(sonuc2); // 20
}

Genel öncelik sırası (yüksekten düşüğe, basitleştirilmiş):

  1. () parantezler
  2. !, ++, -- (unary operatörler)
  3. *, /, ~/, %
  4. +, -
  5. <, >, <=, >=
  6. ==, !=
  7. &&
  8. ||
  9. ??
  10. =, +=, -= vb. (atama operatörleri)

Pratik tavsiye: Öncelik sırasını ezbere bilmek yerine, karmaşık ifadelerde her zaman parantez kullan. Bu hem hatayı önler hem de kodu okuyan başka birinin niyetini yanlış anlamasını engeller:

dart
// Belirsiz — önceliği bilmeyen biri yanlış anlayabilir
bool sonuc = a && b || c;

// Net — parantez ile niyet açık
bool sonuc2 = (a && b) || c;

6. is ve is! — Tip Kontrolü Operatörleri

Bölüm 2'de kısaca gördüğümüz is operatörünü burada tam bir mantıksal operatör olarak da hatırlayalım:

dart
void main() {
  Object deger = "Merhaba";

  print(deger is String);  // true
  print(deger is! String); // false — "değil" versiyonu
  print(deger is int);     // false
}

🎯 Bu Dersten Çıkarılması Gerekenler

  • Aritmetik: + - * / ~/ %, ~/ tam sayı bölmesi yapar, / her zaman double döner.
  • x++ mevcut değeri kullanıp sonra artırır, ++x önce artırıp yeni değeri kullanır.
  • Bileşik atama: += -= *= ~/= gibi kısayollar.
  • Karşılaştırma: == != < > <= >=, hepsi bool döner.
  • Mantıksal: && || !, kısa devre değerlendirmesi önemli bir davranıştır (null kontrollerinde kritik).
  • Operatör önceliği matematikteki gibi işler — belirsiz durumlarda parantez kullan.

📝 Ödevler

  • [ ] İki sayı al (elle tanımla), tüm aritmetik operatörleri (+ - * / ~/ %) uygulayıp sonuçlarını yazdır.
  • [ ] x++ ile ++x arasındaki farkı gösteren, aynı değişkeni her ikisiyle de kullanan bir örnek yaz.
  • [ ] Kısa devre değerlendirmesini kanıtlayan bir örnek yaz: false && pahaliBirFonksiyon() çağrısında fonksiyonun hiç çalışmadığını print ile göster.
  • [ ] Nullable bir değişkenle güvenli bir && zinciri kur (örn. isim != null && isim.length > 5), sırayı bilerek tersine çevirip hatayı gözlemle.
  • [ ] Parantezsiz ve parantezli iki versiyonunu yazdığın bir ifadeyle (2 + 3 * 4 gibi) operatör önceliğinin sonucu nasıl değiştirdiğini göster.

Sıradaki konu: Bölüm 3 — Konu 11: if / else if / else