İsim Alanı
D'de her isim, tanımlandığı noktadan başlayarak hem içinde tanımlandığı kapsamda, hem de o kapsamın içindeki kapsamlarda geçerlidir. Her kapsam bir isim alanı tanımlar.
İçinde tanımlandığı kapsamdan çıkıldığında, isim artık geçersiz hale gelir ve derleyici tarafından tanınmaz:
void main() { int dışSayı; if (birKoşul) { // ← yeni bir kapsam başlatır int içSayı = 1; dışSayı = 2; // ← dışSayı içeride de geçerlidir } // ← içSayı'nın geçerliliği burada son bulur içSayı = 3; // ← derleme HATASI // içSayı'nın geçerli olduğu kapsamdan // çıkılmıştır }
if
koşulunun kapsamı içinde tanımlanmış olan içSayı
o kapsamın dışında geçersizdir. Öte yandan, dışSayı
hem dışarıdaki hem de içerideki kapsamda geçerlidir.
Bir kapsamda tanımlanmış bir ismin içerdeki bir kapsamda tekrar tanımlanması yasal değildir:
int uzunluk = tekSayılar.length; if (birKoşul) { int uzunluk = asalSayılar.length; // ← derleme HATASI }
Kapsamlar deyimlere bağlı olmak zorunda değildir; bir çift küme paranteziyle serbestçe ve bağımsız olarak da tanımlanabilirler:
void main() { // Bu kapsam hiçbir deyime bağlı değildir: { int a; } // Başka bir kapsam: { int a; // Bu 'a', öncekinden farklıdır } }
Ancak, böyle bağımsız kapsamlar modül düzeyinde (kaynak kodun en üst düzeyinde) tanımlanamazlar:
void main() { // ... } { // ← derleme HATASI }
İsimleri kullanıldıkları ilk noktada tanımlamak
Şimdiye kadarki örneklerde de gördüğünüz gibi, isimlerin kullanıldıkları ilk noktadan daha önce tanımlanmış olmaları gerekir:
writeln(sayı); // ← derleme HATASI // sayı henüz bilinmiyor int sayı = 42;
O kodun çalışabilmesi için sayı
'nın writeln
işleminden daha önce tanımlanmış olması gerekir. Kaç satır önce tanımlanacağı programcıya bağlı olsa da, her ismin kullanıldığı ilk noktaya en yakın yerde tanımlanması programcılık açısından daha iyi kabul edilir.
Bunu kullanıcıdan aldığı sayıların ortalamalarını yazdıran bir programın main
işlevinde görelim. Özellikle C dilinden gelen programcılar, kullanılan bütün isimleri kapsamların en başında tanımlamaya alışmışlardır:
int adet; // ← BURADA int[] sayılar; // ← BURADA double ortalamaDeğer; // ← BURADA write("Kaç sayı gireceksiniz? "); readf(" %s", &adet); if (adet >= 1) { sayılar.length = adet; // ... burada asıl işlemler yapılıyor olsun... } else { writeln("HATA: En az bir sayı girmelisiniz!"); }
Bunun karşıtı olarak, isimleri olabildiğince geç tanımlamak önerilir. Aynı programı bu tavsiyeye uyarak şöyle yazabiliriz:
write("Kaç sayı gireceksiniz? "); int adet; // ← BURADA readf(" %s", &adet); if (adet >= 1) { int[] sayılar; // ← BURADA sayılar.length = adet; double ortalamaDeğer; // ← BURADA // ... burada asıl işlemler yapılıyor olsun... } else { writeln("HATA: En az bir sayı girmelisiniz!"); }
Bütün değişkenleri bir arada en başta tanımlamak yapısal olarak daha iyi olsa da, değişkenleri geç tanımlamanın da bir kaç önemli yararı vardır:
- Hız: Her değişken tanımının program hızı açısından bir bedeli vardır. D'de bütün değişkenler ilklendikleri için, belki de hiç kullanılmayacak olan değişkenleri en baştan ilklemek, o işlem için geçen zamanın boşa gitmesine neden olabilir.
- Hata riski: Değişkenlerin tanımları ile kullanımları arasına giren her satır, program hataları açısından ufak da olsa bir risk taşır: bir örnek olarak,
uzunluk
gibi genel bir ismi olan bir değişken aradaki satırlarda yanlışlıkla başka bir uzunluk kavramı için kullanılmış, ve asıl kullanılacağı yere gelindiğinde değeri çoktan değişmiş olabilir. - Okuma kolaylığı: Kapsamdaki satırlar çoğaldıkça, alttaki satırlarda kullanılan bir değişkenin tanımının programın yazıldığı ekranın dışında kalma olasılığı artar; değişkenlerin tanımlarını görmek veya hatırlamak için sık sık metnin üst tarafına gitmek ve tekrar geri gelmek gerekebilir.
- Kod değişikliği: Program kodları sürekli olarak gelişim halindedirler: programa ekler yapılır, programın bazı olanakları silinir, farkedilen hataları giderilir, vs. Bu işlemler sırasında çoğu zaman bir grup satırın hep birden başka bir işlev olarak tanımlanması istenebilir.
Böyle durumlarda, o kod satırlarında kullanılan bütün değişkenlerin kullanıldıkları ilk yerde tanımlanmış olmaları, hepsinin birden başka bir yere taşınmalarına olanak sağlar.
Örneğin yukarıdaki bu tavsiyeye uyan programın
if
kapsamındaki bütün satırlar hep birden programın başka bir noktasına taşınabilirler.Oysa değişkenlerini C'deki gibi tanımlayan bir programda, taşınacak olan kod satırlarında kullanılan değişkenlerin de teker teker seçilerek ayrı ayrı taşınmaları gerekir.