Konunun geçmişi:
C dilinde küresel ve yerel değişkenler, bellek yönetimi ve kodun kapsamını yönetmek için ortaya çıkmıştır. Küresel değişkenler, modüler programlama öncesinde işlevler arasında veri alışverişinin ana yoluydı, yerel değişkenler ise etkileşimi azaltarak kodun izolasyonunu artırır.
Sorun:
Küresel ve yerel değişkenler arasındaki farkları anlamakta sıklıkla zorluk yaşanır: hayat süreleri, kapsam, başlatma kuralları ve zamanlaması. Küresel değişkenler senkronizasyon ve okunabilirlik sorunlarına yol açarken, yerel değişkenler gerekli verilere erişimin kısıtlanmasına neden olur. Bu farklılıkların yanlış anlaşılması hatalara yol açar ve kodun ölçeklenmesini zorlaştırır.
Çözüm:
Küresel değişkenler, tüm işlevlerin dışında tanımlanır ve extern kullanımıyla tüm dosyalarda erişilebilir. Hayat süreleri tüm program boyunca sürer ve başlatma ya bir kullanıcı değeriyle açıkça ya da (statik değişkenler için) otomatik olarak sıfırlarla yapılır. Yerel değişkenler işlevlerin içinde tanımlanır, hayat süreleri işlev çağrısıyla sınırlıdır ve içeriği otomatik olarak başlatılmaz.
Kod örneği:
int g_var = 42; // Küresel değişken void foo() { int l_var = 5; // Yerel değişken }
Anahtar özellikler:
Yerel bir değişken otomatik olarak sıfırla başlatılır mı, eğer başlangıç değeri verilmemişse?
Hayır. Sadece küresel ve statik değişkenler varsayılan olarak sıfırlarla başlatılır. Yerel değişkenler, açıkça başlangıç değeri verilmedikçe "çöplük" (belirsiz değer) içerir.
Örnek:
void test() { int a; printf("%d ", a); // Belirsiz davranış }
Farklı dosyalardan her zaman küresel bir değişkene erişilebilir mi?
Hayır. Eğer bir değişken, bir işlev dışında statik olarak tanımlanmışsa, yalnızca bu kaynak dosyasında görünür. Küresel görünürlük gerekiyorsa, extern kullanın.
Bir işlev içinde küresel bir değişken tanımlanabilir mi?
Hayır. İşlev içinde tüm tanımlar yereldir. Sadece işlevler dışında küresel değişkenler oluşturulabilir.
Küresel bir değişken, işlevler arasında veri alışverişi için kullanılıyor:
int error_code; void f1() { error_code = 1; } void f2() { if (error_code) ... }
Artıları:
Eksileri:
Tüm değişkenler yerel, veriler işlev parametreleri aracılığıyla iletiliyor:
void f1(int *err) { *err = 1; } void f2(int err) { if (err) ... }
Artıları:
Eksileri: