Untuk memahami ini sepenuhnya , Anda harus memahami konsep berikut:
Array bukanlah penunjuk!
Pertama-tama (Dan sudah cukup diberitakan), array bukanlah pointer . Sebaliknya, di sebagian besar penggunaan, mereka 'membusuk' ke alamat ke elemen pertama mereka, yang dapat ditetapkan ke penunjuk:
int a[] = {1, 2, 3};
int *p = a; // p now points to a[0]
Saya berasumsi ini bekerja dengan cara ini sehingga konten array dapat diakses tanpa menyalin semuanya. Itu hanya perilaku tipe array dan tidak dimaksudkan untuk menyiratkan bahwa keduanya adalah hal yang sama.
Array multidimensi
Array multidimensi hanyalah cara untuk 'mempartisi' memori dengan cara yang dapat dipahami dan dioperasikan oleh kompiler / mesin.
Misalnya, int a[4][3][5]
= sebuah array yang berisi 4 * 3 * 5 (60) 'potongan' memori berukuran integer.
Keuntungan menggunakan int a[4][3][5]
vs biasaint b[60]
adalah sekarang mereka 'dipartisi' (Lebih mudah untuk bekerja dengan 'chunks' mereka, jika diperlukan), dan program sekarang dapat melakukan pemeriksaan terikat.
Faktanya, int a[4][3][5]
disimpan persis seperti int b[60]
di memori - Satu- satunya perbedaan adalah bahwa program sekarang mengelolanya seolah-olah mereka adalah entitas terpisah dengan ukuran tertentu (Secara khusus, empat grup dari tiga grup lima).
Perlu diingat: Keduanya int a[4][3][5]
dan int b[60]
sama dalam memori, dan satu-satunya perbedaan adalah bagaimana mereka ditangani oleh aplikasi / kompiler
{
{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}
}
Dari sini, Anda dapat dengan jelas melihat bahwa setiap "partisi" hanyalah sebuah array yang dipantau oleh program.
Sintaksis
Sekarang, array secara sintaksis berbeda dari pointer . Secara khusus, ini berarti kompilator / mesin akan memperlakukannya secara berbeda. Ini mungkin tampak tidak sulit, tapi lihat ini:
int a[3][3];
printf("%p %p", a, a[0]);
Contoh di atas mencetak alamat memori yang sama dua kali, seperti ini:
0x7eb5a3b4 0x7eb5a3b4
Namun, hanya satu yang dapat ditetapkan ke penunjuk secara langsung :
int *p1 = a[0]; // RIGHT !
int *p2 = a; // WRONG !
Mengapa tidak a
bisa ditetapkan ke penunjuk tapi a[0]
bisa?
Ini, sederhananya, adalah konsekuensi dari array multidimensi, dan saya akan menjelaskan alasannya:
Pada level ' a
', kami masih melihat bahwa kami memiliki 'dimensi' lain untuk dinantikan. Pada tingkatan 'a[0]
', bagaimanapun, kita sudah berada di dimensi teratas, sejauh menyangkut program kita hanya melihat array normal.
Anda mungkin bertanya:
Mengapa penting jika array multidimensi dalam hal membuat penunjuk untuknya?
Cara terbaik untuk berpikir seperti ini:
Sebuah 'decay' dari array multidimensi bukan hanya sebuah alamat, tetapi sebuah alamat dengan data partisi (AKA masih memahami bahwa data dasarnya terbuat dari array lain), yang terdiri dari batas-batas yang ditetapkan oleh array di luar dimensi pertama.
Logika 'partisi' ini tidak bisa ada di dalam pointer kecuali kita menentukannya:
int a[4][5][95][8];
int (*p)[5][95][8];
p = a; // p = *a[0] // p = a+0
Jika tidak, arti properti pengurutan larik akan hilang.
Perhatikan juga penggunaan tanda kurung di sekitar *p
: int (*p)[5][95][8]
- Itu untuk menentukan bahwa kami membuat pointer dengan batas-batas ini, bukan array pointer dengan batas-batas ini:int *p[5][95][8]
Kesimpulan
Mari kita ulas:
- Array membusuk ke alamat jika tidak ada tujuan lain dalam konteks yang digunakan
- Larik multidimensi hanyalah larik larik - Oleh karena itu, alamat yang 'membusuk' akan membawa beban "Saya memiliki sub dimensi"
- Data dimensi tidak bisa ada di penunjuk kecuali Anda memberikannya .
Singkatnya: array multidimensi membusuk ke alamat yang membawa kemampuan untuk memahami isinya.