Konu Tarihi:
Değişkenlerin kapsamı, programlama dillerinin ilk ortaya çıkmasından beri temel bir kavramdır. C++'da kapsam kuralları, yeni standartların ortaya çıkmasıyla (yerel bildirimlerden, anonim ad alanları, lambda ifadeleri ve try/catch bloklarına kadar) önemli ölçüde geliştirilmiştir.
Sorun:
Kapsamın yanlış anlaşılması, derleme veya çalışma zamanı hatalarına yol açabilir; örneğin, isim çakışmalarına, değişkenlerin kazara gizlenmesine, bellek sızıntılarına ve başlatılmamış değerlerle karşılaşılmasına neden olabilir.
Çözüm:
C++'da kapsamın ana seviyeleri şunlardır:
Tanımlayıcı arama kurallarını (name lookup) hatırlamak önemlidir: derleyici en "yakın" tanımı arar, ardından yukarı çıkar.
Kod örneği:
#include <iostream> void func() { int x = 1; { int x = 2; // dıştaki x değişkenini gizler std::cout << x << '\n'; // Çıktı: 2 } std::cout << x << '\n'; // Çıktı: 1 } int x = 10; // global değişken int main() { func(); std::cout << x << '\n'; // Çıktı: 10 }
Anahtar özellikler:
Bir fonksiyonun dışında tanımlanan başlık dosyasındaki bir değişken link zamanı hatasına neden olabilir mi?
Evet! Eğer değişken sadece int value olarak tanımlanmışsa (extern olmadan ve C++17'deki inline-değişkenlerle inline başlangıç olmadan), bu birden fazla tanım oluşturacak ve bağlantı aşamasında çoklu tanım hatasına neden olacaktır.
Kod örneği:
// myheader.h int globalVar = 5; // KÖTÜ: tanım, bildirim değil
İç içe blokta aynı isimde bir değişken tanımlanırsa ne olur?
İçteki değişken, dıştaki değişkeni "gizler" ve tüm erişimler, iç blok sona erene kadar bu değişkene yönlendirilir.
Fonksiyon başlığında tanımlanan bir değişken, diğer fonksiyonlarda erişilebilir mi?
Hayır. Fonksiyonun gövdesinin içinde tanımlanan (ve belirlenen) değişkenler, yalnızca o fonksiyonun yürütülmesi sırasında geçerli olup dışında erişilemezler.
Proje için durumu saklamak üzere, başlık dosyası aracılığıyla birden fazla kaynak dosyada tanımlanan global bir değişken kullanılıyor.
Artıları: Her yerden kolayca ulaşılabilir.
Eksileri: Hata ayıklama zorluğu, çoklu tanım (linker hatası), thread güvenliği eksikliği, beklenmeyen değerler.
Yerel değişkenlerin kullanılması, durumu fonksiyon parametreleri aracılığıyla iletmek, global değişkenlerin neredeyse hiç olmaması veya yalnızca ad alanı üzerinden encapsulation ile extern olarak kullanılması.
Artıları: Kodun şeffaflığı, bağımlılıkların kontrolü, test etme kolaylığı.
Eksileri: Bazen, global değişkenlerden daha fazla kod gerektirebilir.