Platform
CPP

3. Değişkenler

Değişken kavramı ve {} alışkanlığı

resul ekici · Editör, Yazar· 15 Ağustos 2026· 7 dk okuma

Mesela bir yazıyı veya sayıyı saklamak istiyorsun. Kullanıcı kendi ismini girsin ve program o ismi hafızada tutsun istiyorsun. O zaman kullanacağımız şey bir değişken. Farklı bir örnek vererek devam edelim.

Diyelim ki bir yaş tutacağız. Değişken, bellekte bir yere kayıt ettirdiğimiz isim + tür + değer üçlüsünü simgeler.
Tür, o yerin kaç bayt tutacağını ve o baytların nasıl yorumlanacağını söylüyor.
İsim, o yere kodumuzdan ulaşmamızı sağlıyor.
Değer, o anda orada duran bitleri simgeler. Yani “yaş” dediğimiz şey, isimlendirilmiş bir bellek parçası olarak düşünebiliriz.

Örnek değişken isimleri: yas,isim,bakiye,para gibi aklımıza gelebilecek her türlü şey
Örnek değişken türleri: int (tam sayı tutar), string (bir yazı tutar), bool (true false değeri tutar toplam 2 değer)
Örnek değişken değerleri: 15,Ahmet,299.5, 3000000, true

Örnek bir kod:

cpp
#include <iostream>

int main() {
    std::string isim = "Ahmet";
    int yas = 15;
    return 0;
}

gördüğünüz üzere int i direkt kullandık ama string std isim uzayında olduğu için std::string yazdık. Şimdi bu kod çalışıyor ancak bize bişey söylemiyor sadece hafızada girdilerimizi tuttu. Şimdi ekrana bunları nasıl yazdırırız?

cpp
#include <iostream>

int main() {
    std::string isim = "Ahmet";
    int yas = 15;
    std::cout << "Merhaba benim ismim " << isim << ". Yasim " << yas;
    return 0;
}
Output
Merhaba benim ismim Ahmet. Yasim 15

Türkçe karakter kullanmayın henüz. İleride değineceğim. Burada mantık şematiğini çizeyim. Sadece yukarıdaki kodda cout olan satıra odaklanın:

text

  std::cout
      ↓
"Merhaba benim ismim "
      ↓
    isim
      ↓
 ". Yasim"
      ↓
     yas
      ↓
   Cümle : "Merhaba benim ismim Ahmet. Yasim 15"

isim yazan yerde hafızaya bakılır. O değişkenin "Ahmet" yazısını tuttuğu görülür. Ardından "" işaretini görüp içini doğrudan yazar ardından yas değişkeninin değerine bakılır 15 demiştik bu sefer yas yazdığımız yere 15 yazar.

İleri C++ (şablonlar, taşınma semantiği, bellek modeli) yine bu 3lüye dayanır. Burada yanlış alışkanlık edinirsek ileride doğru alışkanlığı edinmek zor olabilir. Bu derste en önemli şey henüz kullanmadık ama değişkeni tanımladığımız anda anlamlı bir değer vermek; ve bunu {} ile yapmak. Yani değişkenleri int sayi = 15; değil de int sayi{15}; şeklinde tutmaktan bahsediyorum birazdan değineceğim.

Bellekte ne durur?

Mesela int yas yazdık. Derleyici stack içinde genelde 4 bayt ayırıyor ve o bölgeye yas diyor. İlk anda o 4 baytın içinde saçma sapan çöp olabiliyor.int yas yazınca sadece tanımlamış oluruz başlatmış değil. Çünkü “Tanımlamak” ile “başlatmak” aynı şey değil. Tanımlamak yeri ayırır; başlatmak o yere bilinen bir değer yazar. Tanımlayıp bırakırsanız o değeri okuduğunuzda bozulabilir. O yüzden hem tanımlamak ardından bir değer sağlayarak başlatmak gerekir.

cpp
int ham;          // tanımlandı, başlatılmadı — problemli olabilir
int yas = 21;     // kopya başlatma
int boy(175);     // doğrudan başlatma
int kilo{72};     // küme ile başlatma — modern varsayılan

Aynı int ancak ilkinde (int ham;) başlatılmadı diğerlerinde ise üç farklı başlatma söz konusu. Modern C++ dördüncüyü ister diyebiliriz.

Neden başlatılmamış değişken yasak? (int ham;)

Eskiden int skor; yazılır, sonra bir değer veririm denirdi. Şimdi şöyle ki: başlatılmamış bir değişkeni okumak tanımsız davranış (undefined behavior) dır. Program yanlış sayı basabilir, bazen çalışabilir bazen de çöker, yalnızca derlemede bile bozulabilir. Derleyici altın tepside sunmayacak her şeyi. Yani mantık şu: saçma sapan çöp okumadan, ya gerçek değeri vermek ya da bilerek sıfırlamak (yani çöp yerine 0 yazsın).

Mesela

cpp
int skor;          // çöp tutar
std::cout << skor; // yanlış: çöp okursun

int skor{};        // 0
std::cout << skor; // doğru

Kural

Yerel değişkeni (int skor;) gibi bırakma. Ya hemen gerçek değeri ver, ya {} ile sıfırla.

Üç başlatma yazımı (tanımladık ancak başlatma çeşitleri nelerdir?)

C++ içinde 3 tane yöntem var. Hepsinden bahsedeceğm ancak birinden devam edeceğim. Diyelim ki 5 sayısını tutacağız. Üç yol da çalışıyor gibi duruyor. Modern pratikte üçüncüyü varsayılan olarak kullanacağım.

  • int x = 5; kopya başlatma. Okunur ama daraltmaya (narrowing) izin verebilir. bunun ne demek olduğundan bahsedicem
  • int x(5); doğrudan başlatma. İşlev bildirimiyle karışabilir (most vexing parse).
  • int x{5}; küme başlatma. Daraltmayı reddeder, en az sürprizlidir.

Neden modern C++ {} ister?

{} iki şeyi birden çözer. Birincisi *daraltma: daha büyük veya kesirli bir değeri, kendisi için normalde uygun olmayan bir türe sessizce sıkıştırmamızı engellemek için. İkincisi *ayrıştırma: int x(); bir değişken değil, “int döndüren x adında işlev/fonksiyon” diye okunabilir. int x{}; her zaman değişken olduğunu bize gösterir. Mesela 3.14yi inte vermeyi deniyoruz. Eskiden çoğu derleyici uyarıyla 3.14 ü direkt 3 yapardı. Şimdi {} ile hata bekleriz. Çünkü hata çıkarsın ki 3.14 ü 3 yapmadan bize neler döndüğünü gösterin.

Yani demek istediğim şey şu: int dediğimiz şey bir tam sayı tutan değişken türü. Biz böyle bir değişken oluşturup içine 3.14 değerini yani kesirli bir değer verirsek {} haricindeki diğerleri bunu 3 e yuvarlar. Bundan haberimiz olmazsa belki de bu hesap hatasına yol açar. O yüzden eğer int c{3.14} kullanırsak int değeri olduğu için bunu yuvarlamadan hata çıkartır. Mesela

cpp
int a = 3.14;   // çoğu derleyicide uyarıyla 3 olur — bilgi kaybı yani daraltma dediğimiz şey
int b(3.14);    // aynı daraltma
int c{3.14};    // hata: narrowing. Modern C++ bunu istemez.

int t{};        // 0, değişken
int u();        // işlev bildirimi! most vexing parse yani u() yu ileride göreceğimiz şekilde fonksiyon sanabilir. 

{} daraltmayı derleme hatasına çevirir. Diğerleri gibi sayıyı manipüle etmez

İleri seviyede std::vector<int> v{1, 2, 3}; gibi yapıcıları da aynı sözdizimiyle kuracağız o yüzden şuan zorlanmanız daha iyi. Şimdi int x{5} öğrendin, yarın nesne kurmayı öğrenirken daha basit geleceğini düşünüyorum. Bu yüzden bu seride hemen hemen her yerde {} kullanacağız. Yani şuana kadar "yeni bir isim görünce yanında bir değer de görünsün"i anlamış olmanızı beklerim.

auto ile {} tuzakları

Değişken oluştururken illa değişken türünü belirtmen gerekmiyor. Mesela auto kullanırsan verdiğin değere göre otomatikmen kendisini şekillendiriyor. Mesela int a = 5 yerine auto a = 5 yapabilirsin. auto türü sağ taraftaki değerden türünü (ileride rvalue olarak anlatcam) çıkarıyor. auto x = 5; bir int. Ama auto x{5}; ile auto x = {5}; aynı şey değil. İkincisi std::initializer_list<int> yani bir liste o olabiliyor. Modern pratik: auto kullanırken = ile tek değer ver ancak listeyi auto ile kullanma. Bu kısmı tamamen anlaman gerekmiyor. Sadece auto üstünden geçmek istedim

cpp
auto a = 5;      // int, net şekilde
auto b = 5.0;    // double, net şekilde
auto c{5};       // int, çoğunlukla (test ettim int kesin diyebiliriz)
auto d = {5};    // initializer_list — çoğu zaman bunu oluşturmazsın zaten hönkürtme

O yüzden auto yu dikkatli kullan

Değişkeni nasıl tutmalıyız?

İleri seviyeye giden biri için değişken tutma yöntemleri uzun değil o kadar. Eskiden “zaten tanımladım, biyerlerde kullanırım” tarzında bi yaklaşım vardı. Hatayı ve okunabilirliği de en aza indirmek için dar kapsam, hemen başlatmak, değişmeyecekse kilitlemek en doğrusudur.

  • Mümkün olan en dar kapsamda tanımla. Döngüden önce “ileride lazım olur” diye değişken açma.
  • Tanıdığın anda başlat. {} varsayılanın olsun. (önemli)
  • Değişmeyecekse const yap. const int kapasite{16}; hem belge hem derleyici kilididir. (constant yani sabit)
  • Anlamlı isim ver: n, tmp, data2 değil; ogrenci_sayisi, satir.
  • Türü bilinçli seç. Yaş için double kullanma; adet için int veya std::size_t. (double ondalıklı sayıları temsil eder) (double ve std::size_t bir değişkendir int gibi, kafanız karışmasın)

Kötü ve iyi örnek farkı

cpp
// Eski / gevşek
int n;
n = 10;
double x = 10;   // daraltma riski, yanlış tür
int flag = 1;    // bool olması gereken şey

// Modern
const int kayit_sayisi{10}; //kayit sayisi değişmeyecek mesela
const double sicaklik{10.0}; //ondalikli değerde de değişmeyecek mesela
const bool aktif{true}; //aktif olmayı false yapılmayacak yani bir sabit
auto etiket = std::string{"ok"}; //burda da etiketin string olduğunu biz söyledik yoksa derleyici farklı bi tür sanabilirdi. ama gerek yok std::string isim{"Ahmet"}; de kullanabiliriz

Yukarı taraf belirsiz ve geç başlıyor. Aşağı taraf dar, başlatılmış, const ve okunaklı.

int x{0}; yazmak “süslü parantez seviyorum” demek değil. Derleyiciye “bu bir değişkendir, daraltma yok, çöp yok” demek. İleri C++’ta sağlam bir kod mimarı olmak istiyorsan bilmelisin.

Alıştırma

Diyelim ki bir veri tutacağız: bir yaş (int) ancak {} ile başlat. Sonra yaşa 3.5 vermeyi dene ve derleyicinin neden hata verdiğine bak sonra düzeltip bak mesela int yerine double kullanarak.

Editör · Yazarresul ekici
cpp