← Kursa Dön
📄 Text · 15 min

Operatörler

Operatörler programlamanın "fiilleri"dir. Değişkenler isimse, operatörler onlarla bir şey yapmanı sağlar — topla, karşılaştır, birleştir, kaydır. Matematik dersindeki +, -, × işaretlerini düşün: C++ bunları alıp çok daha geniş bir araç setine dönüştürmüş.

Bu derste C++'ın tüm temel operatör ailelerini, nasıl çalıştıklarını ve operatör önceliğini öğreneceksin.


Aritmetik Operatörler

En temel operatörler — matematikteki dört işlem artı mod (kalan) operatörü:

OperatörİşlemÖrnekSonuç
+Toplama7 + 310
-Çıkarma7 - 34
*Çarpma7 * 321
/Bölme7 / 32 (tam sayı!)
%Mod (kalan)7 % 31
#include <iostream>

int main() {
    int a = 17, b = 5;

    std::cout << "Toplam:  " << a + b << std::endl;  // 22
    std::cout << "Fark:    " << a - b << std::endl;  // 12
    std::cout << "Carpim:  " << a * b << std::endl;  // 85
    std::cout << "Bolum:   " << a / b << std::endl;  // 3 (tam sayi bolme!)
    std::cout << "Kalan:   " << a % b << std::endl;  // 2

    return 0;
}

Tam Sayı Bölmesi Tuzağı

int / int işlemi her zaman tam sayı sonuç verir — ondalık kısım kesilir, yuvarlanmaz:

#include <iostream>

int main() {
    int x = 7, y = 2;

    std::cout << "7 / 2 = " << x / y << std::endl;  // 3, 3.5 degil!

    // Ondalikli sonuc istiyorsan en az bir taraf double olmali
    double sonuc = static_cast<double>(x) / y;
    std::cout << "7.0 / 2 = " << sonuc << std::endl;  // 3.5

    // veya direkt double literal kullan
    std::cout << "7.0 / 2.0 = " << 7.0 / 2.0 << std::endl;  // 3.5

    return 0;
}

⚠️ Dikkat: 7 / 2 yazdığında sonuç 3 olur, 3.5 değil! Bu, yeni başlayanların en sık düştüğü tuzaklardan biridir. Ondalıklı sonuç istiyorsan en az bir tarafı double yap.

Mod Operatörü (%)

Mod operatörü bölme işleminden kalanı verir. Sadece tam sayılarla çalışır:

#include <iostream>

int main() {
    // Cift/tek kontrolu
    for (int i = 1; i <= 10; i++) {
        if (i % 2 == 0) {
            std::cout << i << " cift" << std::endl;
        } else {
            std::cout << i << " tek" << std::endl;
        }
    }

    // Saat hesabi: 25 saat = 1 gun 1 saat
    int toplam_saat = 25;
    int gun = toplam_saat / 24;
    int kalan_saat = toplam_saat % 24;
    std::cout << gun << " gun " << kalan_saat << " saat" << std::endl;

    return 0;
}

Mod operatörü çift/tek kontrolü, döngüsel hesaplamalar (saat, gün) ve sayı basamak işlemlerinde çok kullanılır.


Artırma ve Azaltma (Increment / Decrement)

++ bir artırır, -- bir azaltır. Prefix (önce) ve postfix (sonra) olmak üzere iki kullanımı var:

#include <iostream>

int main() {
    int x = 5;

    // Prefix: once artir, sonra kullan
    std::cout << "++x: " << ++x << std::endl;  // 6 (once 6 oldu, sonra yazildi)

    // Postfix: once kullan, sonra artir
    std::cout << "x++: " << x++ << std::endl;  // 6 (once 6 yazildi, sonra 7 oldu)
    std::cout << "x simdi: " << x << std::endl; // 7

    // Tek basina kullanildiginda fark yok
    int a = 10;
    a++;  // 11
    ++a;  // 12
    std::cout << "a: " << a << std::endl;

    return 0;
}

💡 İpucu: Tek başına kullanıldığında ++x ve x++ arasında sonuç farkı yok. Ama bir ifade içinde kullanıldığında sıra önemli. Genel tavsiye: prefix (`++x`) tercih et — özellikle iterator'larda daha verimli olabilir.


Karşılaştırma Operatörleri

İki değeri karşılaştırır ve bool (true/false) sonuç döner:

OperatörAnlamÖrnekSonuç
==Eşit mi5 == 5true
!=Eşit değil mi5 != 3true
<Küçük mü3 < 5true
>Büyük mü5 > 3true
<=Küçük veya eşit mi5 <= 5true
>=Büyük veya eşit mi3 >= 5false
#include <iostream>

int main() {
    int x = 10, y = 20;

    std::cout << std::boolalpha;
    std::cout << "x == y: " << (x == y) << std::endl;  // false
    std::cout << "x != y: " << (x != y) << std::endl;  // true
    std::cout << "x < y:  " << (x < y) << std::endl;   // true
    std::cout << "x >= y: " << (x >= y) << std::endl;   // false

    // Dikkat: = atama, == karsilastirma!
    // if (x = 5)  — ATAMA yapar, karsilastirma degil!
    // if (x == 5) — Dogru kullanim

    return 0;
}

⚠️ Dikkat: = (atama) ile == (karşılaştırma) karıştırmak çok yaygın bir hatadır. if (x = 5) yazarsan, x'e 5 atar ve koşul her zaman true olur. Derleyici uyarısı açıksa seni uyarır.

Spaceship Operatörü <=> (C++20)

C++20 ile gelen üç yönlü karşılaştırma operatörü tek seferde küçük, eşit veya büyük olduğunu söyler:

#include <iostream>
#include <compare>

int main() {
    int a = 5, b = 10;

    auto sonuc = a <=> b;

    if (sonuc < 0) {
        std::cout << "a < b" << std::endl;
    } else if (sonuc == 0) {
        std::cout << "a == b" << std::endl;
    } else {
        std::cout << "a > b" << std::endl;
    }

    // String karsilastirma
    std::string s1 = "Ahmet";
    std::string s2 = "Mehmet";
    auto str_cmp = s1 <=> s2;

    if (str_cmp < 0) {
        std::cout << s1 << " sozlukte once gelir" << std::endl;
    }

    return 0;
}

Spaceship operatörü özellikle sınıflarda sıralama tanımlarken çok kullanışlı. Tek bir operatör tanımlayınca derleyici <, >, <=, >=, ==, != operatörlerini otomatik oluşturabilir.


Mantıksal Operatörler (Logical Operators)

Mantıksal operatörler bool değerlerle çalışır ve bool sonuç döner:

OperatörAnlamÖrnekSonuç
&&VE (AND)true && falsefalse
`\\`VEYA (OR)`true \\false`true
!DEĞİL (NOT)!truefalse

Doğruluk Tablosu

ABA && BA \\B!A
truetruetruetruefalse
truefalsefalsetruefalse
falsetruefalsetruetrue
falsefalsefalsefalsetrue
#include <iostream>

int main() {
    int yas = 25;
    bool ogrenci = true;
    double bakiye = 150.0;

    // VE — her iki kosul da dogru olmali
    if (yas >= 18 && yas <= 65) {
        std::cout << "Calisma yasinda" << std::endl;
    }

    // VEYA — en az biri dogru olmali
    if (ogrenci || yas < 18) {
        std::cout << "Indirimli bilet" << std::endl;
    }

    // DEGIL — kosulu tersine cevirir
    if (!ogrenci) {
        std::cout << "Ogrenci degil" << std::endl;
    }

    // Birlesik kosul
    if (yas >= 18 && bakiye >= 100.0 && !ogrenci) {
        std::cout << "Tam fiyat ode" << std::endl;
    }

    return 0;
}

Kısa Devre Değerlendirmesi (Short-Circuit Evaluation)

Mantıksal operatörler "tembel"dir — sonucu belirleyecek kadar değerlendirir ve durur:

#include <iostream>

int main() {
    int x = 0;

    // && icin: ilk kosul false ise ikinciye bakmaz
    if (x != 0 && (10 / x > 2)) {
        std::cout << "Bu calismaz" << std::endl;
    }
    // x == 0 oldugu icin 10/x hesaplanmaz — sifira bolme hatasi olmaz!

    // || icin: ilk kosul true ise ikinciye bakmaz
    bool sonuc = true || (1 / 0 > 0);  // 1/0 hesaplanmaz
    std::cout << std::boolalpha << sonuc << std::endl;

    return 0;
}

Bu davranış hem performans avantajı sağlar hem de güvenlik için kullanılır. Null pointer kontrolü yapıp sonra erişmek gibi durumlarda çok işe yarar.


Bitwise (Bit Düzeyinde) Operatörler

Bitwise operatörler sayıların ikili (binary) gösterimlerinde tek tek bitlerle çalışır. Düşük seviyeli programlama, bayrak (flag) yönetimi ve performans optimizasyonlarında kullanılır.

Bir sayıyı ikilik düzende düşün: 5 = 00000101, 3 = 00000011.

OperatörAnlamÖrnek (5, 3)Sonuç
&AND (VE)5 & 31 (00000001)
`\`OR (VEYA)`5 \3`7 (00000111)
^XOR (ÖZEL VEYA)5 ^ 36 (00000110)
~NOT (DEĞİL)~5-6 (tüm bitler tersine)
<<Sola kaydırma5 << 110 (00001010)
>>Sağa kaydırma5 >> 12 (00000010)
#include <iostream>
#include <bitset>

int main() {
    int a = 5;   // 00000101
    int b = 3;   // 00000011

    std::cout << "a & b  = " << (a & b)  << " (" << std::bitset<8>(a & b)  << ")" << std::endl;
    std::cout << "a | b  = " << (a | b)  << " (" << std::bitset<8>(a | b)  << ")" << std::endl;
    std::cout << "a ^ b  = " << (a ^ b)  << " (" << std::bitset<8>(a ^ b)  << ")" << std::endl;
    std::cout << "a << 1 = " << (a << 1) << " (" << std::bitset<8>(a << 1) << ")" << std::endl;
    std::cout << "a >> 1 = " << (a >> 1) << " (" << std::bitset<8>(a >> 1) << ")" << std::endl;

    return 0;
}

Sola/Sağa Kaydırma — Çarpma ve Bölme Kısayolu

Sola 1 bit kaydırma sayıyı 2 ile çarpar, sağa 1 bit kaydırma 2'ye böler:

#include <iostream>

int main() {
    int x = 10;

    std::cout << "x:      " << x << std::endl;       // 10
    std::cout << "x << 1: " << (x << 1) << std::endl; // 20 (x2)
    std::cout << "x << 2: " << (x << 2) << std::endl; // 40 (x4)
    std::cout << "x >> 1: " << (x >> 1) << std::endl; // 5  (/2)

    return 0;
}

Pratik Kullanım: Bayrak (Flag) Yönetimi

Bitwise operatörler en çok "bayrak" (flag) sistemi olarak kullanılır. Birden fazla true/false durumunu tek bir sayıda saklarsın:

#include <iostream>

// Her bayrak bir bit pozisyonunda
constexpr int READ    = 1;  // 001
constexpr int WRITE   = 2;  // 010
constexpr int EXECUTE = 4;  // 100

int main() {
    int izinler = 0;

    // Bayrak ekle (set)
    izinler |= READ;
    izinler |= WRITE;
    std::cout << "Izinler: " << izinler << std::endl;  // 3 (011)

    // Bayrak kontrol et
    if (izinler & READ) {
        std::cout << "Okuma izni var" << std::endl;
    }
    if (izinler & EXECUTE) {
        std::cout << "Calistirma izni var" << std::endl;
    } else {
        std::cout << "Calistirma izni YOK" << std::endl;
    }

    // Bayrak kaldir (clear)
    izinler &= ~WRITE;
    std::cout << "Write kaldirildi: " << izinler << std::endl;  // 1 (001)

    return 0;
}

Bu desen işletim sistemi dosya izinlerinden, oyun programlamadaki durum yönetimine kadar her yerde karşına çıkar.


Atama Operatörleri

Basit atama (=) ve bileşik atama (compound assignment) operatörleri:

OperatörEşdeğeriÖrnek
=x = 5
+=x = x + yx += 3
-=x = x - yx -= 3
*=x = x * yx *= 3
/=x = x / yx /= 3
%=x = x % yx %= 3
<<=x = x << yx <<= 2
>>=x = x >> yx >>= 2
&=x = x & yx &= mask
`\=``x = x \y``x \= flag`
^=x = x ^ yx ^= mask
#include <iostream>

int main() {
    int x = 10;

    x += 5;   // x = 15
    x -= 3;   // x = 12
    x *= 2;   // x = 24
    x /= 4;   // x = 6
    x %= 4;   // x = 2

    std::cout << "Sonuc: " << x << std::endl;

    return 0;
}

Bileşik atama operatörleri hem daha kısa hem de bazı durumlarda daha verimli kod üretir. x = x + 5 yerine x += 5 yazma alışkanlığı edin.


Ternary (Koşullu) Operatör

if-else'in tek satırlık versiyonu. Üç operand aldığı için "ternary" (üçlü) denir:

#include <iostream>

int main() {
    int yas = 20;

    // kosul ? dogru_deger : yanlis_deger
    std::string durum = (yas >= 18) ? "Yetiskin" : "Cocuk";
    std::cout << durum << std::endl;

    int a = 15, b = 25;
    int buyuk = (a > b) ? a : b;
    std::cout << "Buyuk olan: " << buyuk << std::endl;

    // Ic ice ternary — okunabilirligi dusurur, DIKKATLI kullan
    int not_degeri = 85;
    std::string harf = (not_degeri >= 90) ? "A" :
                       (not_degeri >= 80) ? "B" :
                       (not_degeri >= 70) ? "C" : "F";
    std::cout << "Harf notu: " << harf << std::endl;

    return 0;
}

Ternary operatör basit koşullarda güzel çalışır. Ama iç içe kullanınca okunabilirlik düşer — karmaşık durumlarda if-else tercih et.


Virgül Operatörü

Virgül operatörü birden fazla ifadeyi sıralar, sonuncunun değerini döner. Çok nadir kullanılır:

#include <iostream>

int main() {
    int x = (1, 2, 3);  // x = 3 (son ifadenin degeri)
    std::cout << "x: " << x << std::endl;

    // for dongusunde bazen kullanilir
    for (int i = 0, j = 10; i < j; i++, j--) {
        std::cout << "i=" << i << " j=" << j << std::endl;
    }

    return 0;
}

Virgül operatörünü for döngüsü dışında neredeyse hiç kullanmazsın. Görürsen ne olduğunu bil yeter.


Operatör Öncelik Tablosu

Operatörlerin hangi sırayla değerlendirildiği çok önemlidir. Matematikte çarpma toplamadan önce gelir — C++'ta da benzer bir hiyerarşi var:

ÖncelikOperatörlerYön
1 (en yüksek)::Sol→Sağ
2() [] -> . ++(postfix) --(postfix)Sol→Sağ
3++(prefix) --(prefix) ! ~ +(tekli) -(tekli) *(deref) &(adres) sizeofSağ→Sol
4* / %Sol→Sağ
5+ -Sol→Sağ
6<< >>Sol→Sağ
7<=>Sol→Sağ
8< <= > >=Sol→Sağ
9== !=Sol→Sağ
10& (bitwise AND)Sol→Sağ
11^ (bitwise XOR)Sol→Sağ
12`\` (bitwise OR)Sol→Sağ
13&& (mantıksal AND)Sol→Sağ
14`\\` (mantıksal OR)Sol→Sağ
15?: (ternary)Sağ→Sol
16= += -= *= /= %= vb.Sağ→Sol
17 (en düşük), (virgül)Sol→Sağ
#include <iostream>

int main() {
    int sonuc;

    // Carpma toplamadan once
    sonuc = 2 + 3 * 4;    // 2 + 12 = 14, 20 degil!
    std::cout << "2 + 3 * 4 = " << sonuc << std::endl;

    // Parantez her seyi yener
    sonuc = (2 + 3) * 4;  // 5 * 4 = 20
    std::cout << "(2 + 3) * 4 = " << sonuc << std::endl;

    // Karsilastirma ve mantiksal
    bool b = 5 > 3 && 2 < 4;  // (5 > 3) && (2 < 4) = true && true = true
    std::cout << std::boolalpha << "5 > 3 && 2 < 4: " << b << std::endl;

    return 0;
}

💡 İpucu: Tüm tabloyu ezberlemeye çalışma. Emin olmadığın her yerde parantez kullan. a + b * c yerine a + (b * c) yazmak hiçbir şeye mal olmaz ama okunabilirliği artırır.


Özet

  • Aritmetik operatörler (+, -, *, /, %) temel matematik işlemlerini yapar; tam sayı bölmesi ondalığı keser

  • Karşılaştırma operatörleri (==, !=, <, >) bool sonuç döner; = (atama) ile == (eşitlik) karıştırma

  • Mantıksal operatörler (&&, ||, !) koşulları birleştirir; kısa devre değerlendirmesi yapar

  • Bitwise operatörler (&, |, ^, <<, >>) bit düzeyinde çalışır; bayrak yönetiminde çok kullanılır

  • Bileşik atama (+=, -=, *=) kısayoldur ve kodun okunabilirliğini artırır

  • Öncelik kurallarını ezberlemek yerine şüpheli yerlerde parantez kullan