Hocama ek olarak; belirtmeliyim ki D'ye geçince, (her ne kadar static dizi kavramı olsa da) biz dizileri dynamic arkadaşlar olarak görürsek işimiz kolaylaşır...:)
Eğer işaretçi aritmetiği kullanıyorsak, bu sevimli arkadaşların sağı solu belli olmayacağı için denetimi D'nin verdiği araçlar ile gerçekleştirmekte fayda görüyorum. Aslında yeni başlayan arkadaşların, "bu dilim ne ki?" gibi soruları kendine soracağından adım gibi eminim. Hatta cevabı bir şekilde bulmasına rağmen ancak bir kaç deneme ile kavramak mümkün olabilir...
Öyleyse biraz kodlardan konuşalım:
size_t boyutu = 10;
size_t[] test = new size_t[boyutu];
test[9] = test.length; // aslında son elemana 10 yazacak!
assert(boyutu == test.length);
test.writeln; // [0, 0, 0, 0, 0, 0, 0, 0, 0, 10]
writeln(test.capacity()); // 15
size_t[] ekle = [ 11, 12, 13, 14, 15, 16 ];
test ~= ekle;
writeln(test.capacity()); // 31
Öncelikle size_t kafanızı karıştırmasın. Bu bizim işlemci ve/veya derleme türüne (32 bit/64 bit) göre belirlenen ve an itibariyle en büyük ulong olabilen bir takma (alias) isimdir. Eğer işletim sisteminiz 32 bit ise bu uint olacaktır. Bunu ''typeid''(test).writeln;'' ile öğrenebilirsiniz. Ama sizin tasarladığınız bir tür örneğin ''struct foo { 'size_t' a; 'bool' b }'' de olabilirdi.
Şimdi, biz ilk olarak bir devingen (dynamic) bir dizi oluşurduk ve buna new işleçi ile 10 eleman yükledik. Hepsi de varsayılan değer olarak 0 aldı. Sanki durağan (static) bir diziymiş gibiler ama değil. Çünkü capacity() ile baktığınızda bunun 15 elemana kadar herhangi bir bellekten yer talep etme davranışı sergilemeden büyüyebileceğini (expand) öğrendik. Yani aslında D, işletim sisteminden 10 tane değil 15 tane eleman talep etti...
Sonraki denemede ise biz, 6 elemanlık bir diziyi sonuna ekliyoruz. Tabi bu aşamadan neler olduğunu bilemeyiz. Çünkü bulunduğu bellek bölgesi ikiye katlanmaya müsait olmayabilir (ki yüksek ihtimalle boş bir yerdir!) ve tüm veriyi taşıyarak 31 elemanlık bir yeri ayırır. Ama dikkat bizim dizinin boyutu şimdi 16 oldu. Peki biz bu verinin son eklediğimiz kısımıyla ilgileniyorsak ve bunu bellekte eleman sayısı kadar yer işgal etmeden kullanmak istiyorsak ne yaparız?
Tabi ki dilim kullanırız:
auto dilim = test[boyutu..$];
dilim.writeln; // [11, 12, 13, 14, 15, 16]
assert(ekle.length == dilim.length);
assert(&test[$-1] == &dilim[$-1]); // her iki hücrenin adresi aynı
Her ne kadar bu da bir dizi gibi görünse de aslında 2 adet işaretçi (pointer)'den oluşan bir özel değişken. Biz bununla ilgili işlem yapmak istediğimizde aslında aynı bellek bölgelerine erişiyoruz. Bunun kanıtı 2. assert() ifadesidir.
Kolay gelsin...
--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]