Merhaba,
Bunu şurda Ali hoca sayesinde öğrendim ve dilerseniz kitaptaki bu bölümden ayrıntısına girebilirsiniz. Ama önce şu örneklere göz atın:
int[] dizi = new int[3];
"@×".writeln(dizi.ptr); // @×9ABCDEF00xxx
dizi[1] = 1;
assert(dizi == [ 0, 1, 0]);
Buraya kadar her şey bildiğiniz gibi basit. Önce 3 elemanlı dinamik bir dizi oluşturduk. Otomatik 0 ile init olduğundan 0 değere sahip üyelerden 2.'sine klasik bir biçimde 1 yazdık...
int * birGösterge = &dizi[1];
"@×".writeln(birGösterge); // @×9ABCDEF00xxx+4
Artık değeri 1 olan ve dizi'nin 2. elemanı gösteren bir göstergemiz var. Bunu adreslerden anlayabilirsiniz. Hatta bunlar da basit, değil mi!😀
birGösterge[1] = 2;
assert(dizi == [ 0, 1, 2]);
"@×".writeln(&birGösterge[1]);// @×9ABCDEF00xxx+8
Şimdi, janjanlı kısım başlıyor. Gösterge bir sonrakine erişebilmesi için adrese bir nevi +4 eklemişiz gibi köşeli parantez kullanabiliyoruz. Böylece typeof, sizeof gibi şeylerle uğraşmıyoruz!
assert(dizi.capacity == 3);
dizi ~= 3;
assert(dizi.capacity == 7);
Ancak devam etmeden önce dinamik dizinin kapasitesine bir bakalım. İddia ediyorum ki 7'den küçük, program assert'lere takılmazsa yüksek ihtimalle yeni eleman eklendiğinde dizi başka yere taşınacak. Evet, ilk dikkatlerinizi çekeceğim kısıma geliyoruz:
birGösterge[2] = 41; // Dikkat 1: etkisiz!
assert(dizi == [ 0, 1, 2, 3]);
"@×".writeln(dizi.ptr); // @× ???
writefln("%-(%s, %)", dizi); // 0, 1, 2, 3
Dizinin kapasitesi 3'den fazla olsaydı, (örneğin 4) o zaman son eklenen ile değerleri 0, 1, 2, 41, 3 olacaktı.
int * ortası = &dizi[3];
dizi.length = 7;
// Dikkat 2: doğru adresi gösterirler...
ortası[1] = 2;
ortası[2] = 1;
writefln("%-(%s, %)", dizi); // 0, 1, 2, 3, 2, 1, 0
Ama dizinin ortasını gösteren yeni bir gösterge doğru adresleri gösterecek. Bunu denemek için dizinin uzunluğunu olası kapasite kadar yükseltip 5 ve 6. elemanları değiştiriyoruz.
İlginç değil mi?