if-else ve Koşullu Operatör
Programlar her zaman düz bir çizgide ilerlemez. Bazen bir yol ayrımına gelirsin: "Kullanıcı doğru şifreyi girdi mi? Evet ise giriş yap, hayır ise hata göster." İşte if-else yapısı tam olarak bu yol ayrımlarını yönetir.
Bir trafik ışığı düşün. Yeşilse geç, kırmızıysa dur, sarıysa yavaşla. Programlama da aynı mantıkla çalışır — koşullara bakarsın ve ona göre bir yol seçersin. Bu derste C++'ta karar verme mekanizmalarının tamamını öğreneceksin.
if Yapısı — En Temel Karar
if ifadesi, bir koşulun doğru (true) olup olmadığını kontrol eder. Koşul doğruysa süslü parantez içindeki kod çalışır. Değilse o blok tamamen atlanır.
#include <iostream>
using namespace std;
int main() {
int sicaklik = 35;
if (sicaklik > 30) {
cout << "Hava çok sıcak, bol su iç!" << endl;
}
cout << "Program devam ediyor." << endl;
return 0;
}Burada sicaklik > 30 koşulu doğru olduğu için mesaj ekrana yazdırılır. Eğer sicaklik değeri 25 olsaydı, if bloğunun içi atlanacak ve direkt "Program devam ediyor." yazacaktı.
Koşul İfadesi Ne Döndürür?
C++'ta koşullar her zaman bool tipinde değerlendirilir — ya true ya false. Karşılaştırma operatörlerini hatırlayalım:
| Operatör | Anlam | Örnek |
|---|---|---|
== | Eşit mi | x == 5 |
!= | Eşit değil mi | x != 0 |
< | Küçük mü | x < 10 |
> | Büyük mü | x > 3 |
<= | Küçük eşit mi | x <= 100 |
>= | Büyük eşit mi | x >= 18 |
⚠️ Dikkat:
=ile==karıştırma! Tek=atama yapar, çift==karşılaştırma yapar.if (x = 5)yazmak x'e 5 atar ve her zaman true döner — bu çok yaygın bir hatadır.
if-else — İki Yollu Karar
Bazen "koşul doğru değilse şunu yap" demek istersin. İşte else bunun için var.
#include <iostream>
using namespace std;
int main() {
int yas = 16;
if (yas >= 18) {
cout << "Ehliyet alabilirsiniz." << endl;
} else {
cout << "Ehliyet için yaşınız yetmiyor." << endl;
}
return 0;
}if ve else birbirini tamamlar. Koşul doğruysa if bloğu çalışır, değilse else bloğu çalışır. İkisi aynı anda asla çalışmaz.
Bu yapıyı günlük hayattan şöyle düşün: "Yağmur yağıyorsa şemsiye al, yağmıyorsa güneş gözlüğü tak." İki seçenek var ve birini mutlaka seçiyorsun.
else if — Çoklu Karar Zinciri
Bazen iki seçenek yetmez. Not hesaplama, fiyat kategorisi belirleme gibi durumlar birden fazla koşul gerektirir. İşte else if ile zincirleme koşullar yazabilirsin.
#include <iostream>
using namespace std;
int main() {
int puan = 73;
if (puan >= 90) {
cout << "Not: A" << endl;
} else if (puan >= 80) {
cout << "Not: B" << endl;
} else if (puan >= 70) {
cout << "Not: C" << endl;
} else if (puan >= 60) {
cout << "Not: D" << endl;
} else {
cout << "Not: F (Kaldı)" << endl;
}
return 0;
}Burada dikkat edilmesi gereken önemli bir nokta var: koşullar yukarıdan aşağıya sırayla kontrol edilir ve ilk doğru olan çalışır. Puan 73 olduğunda program önce >= 90 kontrol eder (hayır), sonra >= 80 (hayır), sonra >= 70 (evet!) ve "Not: C" yazdırır. Geri kalan koşullara bakmaz bile.
Bu yüzden sıralama önemli. Eğer >= 60 koşulunu en üste koysaydın, 73 puan alan öğrenci D alırdı — çünkü ilk eşleşen koşul çalışır.
Mantıksal Operatörlerle Koşul Birleştirme
Birden fazla koşulu tek bir if içinde birleştirebilirsin. C++'ta üç mantıksal operatör var:
| Operatör | Anlam | Açıklama | ||
|---|---|---|---|---|
&& | VE (AND) | İki koşul da doğruysa true | ||
| `\ | \ | ` | VEYA (OR) | En az biri doğruysa true |
! | DEĞİL (NOT) | Koşulun tersini alır |
#include <iostream>
using namespace std;
int main() {
int yas = 25;
bool ehliyetVar = true;
if (yas >= 18 && ehliyetVar) {
cout << "Araba kullanabilirsiniz." << endl;
}
int sicaklik = 5;
if (sicaklik < 0 || sicaklik > 40) {
cout << "Aşırı hava koşulları!" << endl;
}
bool kapali = false;
if (!kapali) {
cout << "Dükkan açık." << endl;
}
return 0;
}&& operatörü her iki koşulun da doğru olmasını ister. || operatörü ise en az birinin doğru olmasını yeterli görür. ! operatörü ise true'yu false, false'u true yapar.
💡 Short-circuit evaluation: C++ mantıksal operatörlerde kısa devre değerlendirmesi yapar.
&&kullanıyorsan ve ilk koşul false ise, ikinci koşula bakmaz bile — çünkü sonuç zaten false olacak. Aynı şekilde||kullanıyorsan ve ilk koşul true ise ikinciye bakmaz. Bu davranış performans için faydalıdır ve bazen bilinçli olarak kullanılır.
Ternary Operatör (?:) — Tek Satırda Karar
Basit if-else yapılarını tek satıra sıkıştırmak istiyorsan ternary operatör (koşullu operatör) kullanabilirsin. Söz dizimi:
koşul ? doğruysa_değer : yanlışsa_değer#include <iostream>
using namespace std;
int main() {
int yas = 20;
// Klasik if-else ile
string mesaj1;
if (yas >= 18) {
mesaj1 = "Yetişkin";
} else {
mesaj1 = "Çocuk";
}
// Ternary operatör ile — aynı iş, tek satır
string mesaj2 = (yas >= 18) ? "Yetişkin" : "Çocuk";
cout << mesaj1 << endl; // Yetişkin
cout << mesaj2 << endl; // Yetişkin
return 0;
}Ternary operatör özellikle değişken ataması veya fonksiyon argümanı gibi yerlerde kullanışlıdır. Ama karmaşık koşullarda okunabilirliği bozar — o yüzden sadece basit durumlar için kullan.
// Güzel kullanım — kısa ve anlaşılır
int minimum = (a < b) ? a : b;
// Kötü kullanım — okuması zor
int sonuc = (x > 0) ? ((x > 100) ? 100 : x) : ((x < -100) ? -100 : x);
// Bunu if-else ile yazmak çok daha okunabilir olur⚠️ Dikkat: Ternary operatörü iç içe kullanmaktan kaçın. Bir ternary'nin içine başka bir ternary koymak kodu okunmaz hale getirir. Kural basit: tek satırda rahat okunmuyorsa if-else kullan.
Nested if — İç İçe Koşullar
Bir if bloğunun içine başka bir if koyabilirsin. Buna nested if (iç içe if) denir.
#include <iostream>
using namespace std;
int main() {
int yas = 25;
bool ogrenciMi = true;
if (yas >= 18) {
cout << "Yetişkin." << endl;
if (ogrenciMi) {
cout << "Öğrenci indirimi uygulanır." << endl;
} else {
cout << "Tam fiyat uygulanır." << endl;
}
} else {
cout << "18 yaş altı giriş yasaktır." << endl;
}
return 0;
}Nested if'ler bazen gereklidir ama fazla derinleşirse kodun okunabilirliği ciddi şekilde düşer. Genel kural: 3 seviyeden fazla iç içe if kullanma. Daha fazlası gerekiyorsa, koşulları fonksiyonlara böl veya mantıksal operatörlerle birleştir.
Nested if'i Düzleştirme — Early Return
Özellikle fonksiyonlarda, iç içe if'ler yerine "erken çıkış" (early return) stratejisi kullanabilirsin:
#include <iostream>
#include <string>
using namespace std;
// Kötü — derin iç içe yapı
string kategori_kotuOrnek(int yas, bool uye) {
string sonuc;
if (yas >= 0) {
if (yas < 18) {
sonuc = "Cocuk";
} else {
if (uye) {
sonuc = "Yetiskin Uye";
} else {
sonuc = "Yetiskin";
}
}
} else {
sonuc = "Gecersiz";
}
return sonuc;
}
// İyi — düz ve okunabilir
string kategori_iyiOrnek(int yas, bool uye) {
if (yas < 0) return "Gecersiz";
if (yas < 18) return "Cocuk";
if (uye) return "Yetiskin Uye";
return "Yetiskin";
}İkinci versiyon çok daha temiz, değil mi? Her koşul bir kapı gibi — geçemezsen geri dönersin. Geçebilirsen bir sonraki kapıya ilerlersin.
if with Initializer (C++17)
C++17 ile birlikte if ifadesinin içinde bir değişken tanımlayıp aynı anda koşul kontrolü yapabilirsin. Bu özelliğe if with initializer denir.
#include <iostream>
#include <map>
#include <string>
using namespace std;
int main() {
map<string, int> notlar = {{"Ali", 85}, {"Ayse", 92}};
// C++17 öncesi — değişken dışarıda kalıyor
auto it = notlar.find("Ali");
if (it != notlar.end()) {
cout << "Ali'nin notu: " << it->second << endl;
}
// 'it' burada hâlâ erişilebilir — gereksiz yere scope'u kirletiyor
// C++17 ile — değişken sadece if bloğunda yaşar
if (auto it2 = notlar.find("Ayse"); it2 != notlar.end()) {
cout << "Ayse'nin notu: " << it2->second << endl;
}
// 'it2' burada artık erişilemez — temiz scope
return 0;
}Söz dizimi: if (tanımlama; koşul). Noktalı virgülle ayrılan iki kısım var — birincisi değişkeni tanımlar, ikincisi koşulu kontrol eder.
Bu özellik özellikle şu durumlarda faydalı:
map/set find işlemlerinde iterator'ı scope'a hapsetmek
Fonksiyon çağrısı sonucunu kontrol edip kullanmak
Geçici değişkenlerin scope kirliliğini önlemek
#include <iostream>
#include <string>
using namespace std;
int hesaplaYas(int dogumYili) {
return 2026 - dogumYili;
}
int main() {
// Fonksiyon sonucunu hem kontrol et hem kullan
if (auto yas = hesaplaYas(1990); yas >= 18) {
cout << "Yas: " << yas << " - Giris izni var." << endl;
}
// 'yas' burada mevcut değil
// String uzunluk kontrolü
string isim = "Tolgahan";
if (auto len = isim.length(); len > 5) {
cout << isim << " uzun bir isim (" << len << " karakter)" << endl;
}
return 0;
}💡 İpucu:
ifwith initializer, C++17 ve sonrasında çalışır. Derleyicinde-std=c++17veya daha üstünü kullandığından emin ol. Modern C++ projelerinde bu özellik çok yaygın ve kodun okunabilirliğini artırır.
Koşullarda Yaygın Hatalar
Yeni başlayanların en sık düştüğü tuzakları özetleyelim:
1. Atama ile Karşılaştırmayı Karıştırmak
int x = 10;
// YANLIŞ — x'e 5 atar, her zaman true olur
if (x = 5) {
cout << "Bu her zaman çalışır!" << endl;
}
// DOĞRU — x'in 5'e eşit olup olmadığını kontrol eder
if (x == 5) {
cout << "x beştir." << endl;
}2. Süslü Parantez Unutmak
int x = 10;
// TEHLİKELİ — sadece ilk satır if'e bağlı
if (x > 5)
cout << "x büyük" << endl;
cout << "Bu her zaman çalışır!" << endl; // if'in dışında!
// GÜVENLİ — her zaman süslü parantez kullan
if (x > 5) {
cout << "x büyük" << endl;
cout << "Bu da sadece koşul doğruysa çalışır." << endl;
}3. Floating-Point Karşılaştırması
double a = 0.1 + 0.2;
// YANLIŞ — floating-point hassasiyet sorunu
if (a == 0.3) {
cout << "Eşit" << endl; // Bu çalışmayabilir!
}
// DOĞRU — epsilon ile karşılaştır
if (abs(a - 0.3) < 1e-9) {
cout << "Yaklaşık eşit" << endl;
}Ondalıklı sayılar bilgisayarda tam olarak temsil edilemez. Bu yüzden == yerine bir tolerans değeri (epsilon) kullanmak gerekir.
Gerçek Dünya Örneği — Giriş Doğrulama
Öğrendiklerimizi bir araya getirelim:
#include <iostream>
#include <string>
using namespace std;
int main() {
string kullaniciAdi;
string sifre;
cout << "Kullanıcı adı: ";
cin >> kullaniciAdi;
cout << "Şifre: ";
cin >> sifre;
if (kullaniciAdi.empty() || sifre.empty()) {
cout << "Kullanıcı adı ve şifre boş olamaz!" << endl;
} else if (kullaniciAdi == "admin" && sifre == "1234") {
cout << "Hoş geldiniz, yönetici!" << endl;
} else if (kullaniciAdi == "user" && sifre == "abcd") {
cout << "Hoş geldiniz, kullanıcı!" << endl;
} else {
cout << "Hatalı kullanıcı adı veya şifre." << endl;
}
return 0;
}Bu örnekte sırasıyla: boş giriş kontrolü, yönetici girişi, normal kullanıcı girişi ve hatalı giriş senaryolarını ele aldık. Gerçek bir uygulamada şifreler düz metin olarak karşılaştırılmaz ama mantık aynıdır.
Özet
if tek koşul kontrol eder — doğruysa bloğu çalıştırır, değilse atlar
else if'in alternatifidir — koşul yanlışsa çalışır
else if ile zincirleme koşullar yazabilirsin — ilk doğru olan çalışır, gerisine bakılmaz
Ternary operatör (
?:) basit if-else'leri tek satıra sıkıştırır ama karmaşık durumlar için uygun değildirNested if yerine mümkünse early return veya mantıksal operatörlerle düzleştirme tercih et
if with initializer (C++17) değişkeni if scope'una hapsetmenin temiz yoludur:
if (auto x = expr; koşul)
AI Asistan
Sorularını yanıtlamaya hazır