İçin tam Bunu anlamak, sen gerekir aşağıdaki kavramları kavramak:
Diziler işaretçi değildir!
Her şeyden önce (ve yeterince vaaz edilmiştir), diziler işaretçi değildir . Bunun yerine, çoğu kullanımda, bir işaretçiye atanabilen ilk elemanlarına adrese 'bozunurlar':
int a[] = {1, 2, 3};
int *p = a; // p now points to a[0]
Bu şekilde çalıştığını varsayıyorum, böylece dizinin içeriğine hepsini kopyalamadan erişilebilir. Bu sadece dizi türlerinin bir davranışıdır ve aynı şey olduklarını ima etme amacı taşımaz.
Çok boyutlu diziler
Çok boyutlu diziler, hafızayı derleyici / makinenin anlayabileceği ve üzerinde çalışabileceği bir şekilde 'bölümlemenin' bir yoludur.
Örneğin, int a[4][3][5]
= tamsayı boyutlu belleğin 4 * 3 * 5 (60) 'parçalarını' içeren bir dizi.
int a[4][3][5]
Düz vs kullanmanın avantajı int b[60]
, artık 'bölümlenmiş' olmalarıdır (gerekirse 'yığınlarıyla' çalışmak daha kolaydır) ve program artık bağlı denetim gerçekleştirebilir.
Aslında, int a[4][3][5]
depolandığı aynen böyle int b[60]
bellekte - tek fark, belli büyüklükteki ayrı varlıklar iseniz gibi program şimdi yönetir olduğunu (Özellikle, beş üç grup dört grup).
Unutmayın: Hem int a[4][3][5]
ve int b[60]
bellekte aynıdır, tek fark onlar uygulama / derleyici tarafından ele konum nasıl
{
{1, 2, 3, 4, 5}
{6, 7, 8, 9, 10}
{11, 12, 13, 14, 15}
}
{
{16, 17, 18, 19, 20}
{21, 22, 23, 24, 25}
{26, 27, 28, 29, 30}
}
{
{31, 32, 33, 34, 35}
{36, 37, 38, 39, 40}
{41, 42, 43, 44, 45}
}
{
{46, 47, 48, 49, 50}
{51, 52, 53, 54, 55}
{56, 57, 58, 59, 60}
}
Buradan, her "bölümün" sadece programın izlediği bir dizi olduğunu açıkça görebilirsiniz.
Sözdizimi
Şimdi diziler sözdizimsel olarak işaretçilerden farklıdır . Bu, özellikle derleyicinin / makinenin onlara farklı davranacağı anlamına gelir . Bu hiç akıllıca görünmeyebilir, ancak şuna bir bakın:
int a[3][3];
printf("%p %p", a, a[0]);
Yukarıdaki örnek aynı bellek adresini şu şekilde iki kez yazdırır:
0x7eb5a3b4 0x7eb5a3b4
Ancak, bir işaretçiye yalnızca biri doğrudan atanabilir :
int *p1 = a[0]; // RIGHT !
int *p2 = a; // WRONG !
Neden a
bir işaretçiye atanamıyor ama atanabiliyor a[0]
?
Bu, basitçe, çok boyutlu dizilerin bir sonucudur ve nedenini açıklayacağım:
' a
' Düzeyinde, dört gözle bekleyeceğimiz başka bir 'boyutumuz olduğunu görüyoruz. a[0]
Bununla birlikte, ' ' seviyesinde, zaten en üst boyuttayız, bu nedenle program söz konusu olduğunda, sadece normal bir diziye bakıyoruz.
Şunları soruyor olabilirsiniz:
Dizinin bir işaretçi yapma açısından çok boyutlu olması neden önemlidir?
Bu şekilde düşünmek en iyisidir:
Çok boyutlu bir diziden gelen bir 'bozulma' sadece bir adres değil, aynı zamanda birinci boyutun ötesinde dizi tarafından belirlenen sınırlardan oluşan bölüm verileri içeren bir adrestir (AKA, yine de temel verilerinin diğer dizilerden yapıldığını anlar).
Bu 'bölümleme' mantığı, biz belirtmedikçe bir işaretçi içinde var olamaz:
int a[4][5][95][8];
int (*p)[5][95][8];
p = a; // p = *a[0] // p = a+0
Aksi takdirde, dizinin sıralama özelliklerinin anlamı kaybolur.
Ayrıca, etrafındaki parantez kullanımına dikkat edin *p
: int (*p)[5][95][8]
- Bu, bu sınırlara sahip bir işaretçi dizisi değil, bu sınırlarla bir işaretçi yaptığımızı belirtmek içindir:int *p[5][95][8]
Sonuç
Hadi gözden geçirelim:
- Diziler, kullanılan bağlamda başka bir amaçları yoksa adreslere bozulur.
- Çok boyutlu diziler yalnızca dizilerden oluşan dizilerdir - Bu nedenle, "bozulmuş" adres "alt boyutlarım var" yükünü taşıyacaktır.
- Siz ona vermediğiniz sürece boyut verileri bir işaretçide var olamaz .
Kısaca: çok boyutlu diziler, içeriklerini anlama yeteneği taşıyan adreslere bozunur.