Jawaban yang lain benar, tetapi tidak satupun dari mereka yang menekankan gagasan bahwa ketiga hal itu mungkin mengandung nilai yang sama , dan karena itu mereka tidak lengkap.
Alasan ini tidak dapat dipahami dari jawaban lain adalah bahwa semua ilustrasi, meskipun bermanfaat dan jelas masuk akal dalam sebagian besar keadaan, gagal untuk menutupi situasi di mana pointer x
menunjuk ke dirinya sendiri.
Ini cukup mudah untuk dibangun, tetapi jelas agak sulit untuk dipahami. Dalam program di bawah ini, kita akan melihat bagaimana kita dapat memaksa ketiga nilai menjadi identik.
CATATAN: Perilaku dalam program ini tidak terdefinisi, tapi saya mempostingnya di sini murni sebagai demonstrasi menarik dari sesuatu yang dapat dilakukan pointer , tetapi tidak boleh .
#include <stdio.h>
int main () {
int *(*x)[5];
x = (int *(*)[5]) &x;
printf("%p\n", x[0]);
printf("%p\n", x[0][0]);
printf("%p\n", x[0][0][0]);
}
Ini mengkompilasi tanpa peringatan di C89 dan C99, dan hasilnya adalah sebagai berikut:
$ ./ptrs
0xbfd9198c
0xbfd9198c
0xbfd9198c
Cukup menarik, ketiga nilai itu identik. Tapi ini seharusnya bukan kejutan! Pertama, mari kita uraikan programnya.
Kami mendeklarasikan x
sebagai pointer ke array 5 elemen di mana setiap elemen bertipe pointer ke int. Deklarasi ini mengalokasikan 4 byte pada tumpukan runtime (atau lebih tergantung pada implementasi Anda; pada pointer mesin saya adalah 4 byte), jadi x
merujuk ke lokasi memori yang sebenarnya. Dalam kelompok bahasa C, isinya x
hanya sampah, sesuatu yang tersisa dari penggunaan lokasi sebelumnya, jadi x
itu sendiri tidak menunjuk ke mana pun — tentu saja tidak untuk mengalokasikan ruang.
Jadi, secara alami, kita dapat mengambil alamat variabel x
dan meletakkannya di suatu tempat, jadi itulah yang kita lakukan. Tapi kita akan pergi ke depan dan memasukkannya ke x sendiri Karena &x
memiliki tipe yang berbeda dengan x
, kita perlu melakukan pemeran sehingga kita tidak mendapatkan peringatan.
Model memori akan terlihat seperti ini:
0xbfd9198c
+------------+
| 0xbfd9198c |
+------------+
Jadi blok 4 byte memori pada alamat 0xbfd9198c
berisi pola bit yang sesuai dengan nilai heksadesimal 0xbfd9198c
. Cukup sederhana.
Selanjutnya, kami mencetak tiga nilai. Jawaban yang lain menjelaskan apa yang dirujuk oleh masing-masing ungkapan, sehingga hubungannya harus jelas sekarang.
Kita dapat melihat bahwa nilainya sama, tetapi hanya dalam arti yang sangat rendah ... pola bit mereka identik, tetapi tipe data yang terkait dengan setiap ekspresi berarti nilainya yang ditafsirkan berbeda. Sebagai contoh, jika kita mencetak x[0][0][0]
menggunakan string format %d
, kita akan mendapatkan angka negatif yang sangat besar, sehingga "nilai" dalam praktiknya berbeda, tetapi pola bitnya sama.
Ini sebenarnya sangat sederhana ... dalam diagram, panah hanya menunjuk ke alamat memori yang sama daripada yang berbeda. Namun, sementara kami dapat memaksakan hasil yang diharapkan dari perilaku yang tidak terdefinisi, hanya saja - tidak terdefinisi. Ini bukan kode produksi tetapi hanya demonstrasi demi kelengkapan.
Dalam situasi yang masuk akal, Anda akan menggunakan malloc
untuk membuat array 5 int pointer, dan lagi untuk membuat int yang diarahkan ke array itu. malloc
selalu mengembalikan alamat unik (kecuali Anda kehabisan memori, dalam hal ini mengembalikan NULL atau 0), jadi Anda tidak perlu khawatir tentang petunjuk referensial diri seperti ini.
Semoga itulah jawaban lengkap yang Anda cari. Anda seharusnya tidak mengharapkan x[0]
,, x[0][0]
dan x[0][0][0]
menjadi sama, tetapi mereka bisa jika dipaksa. Jika ada yang terlintas di kepala Anda, beri tahu saya agar saya bisa mengklarifikasi!
x[0]
,x[0][0]
danx[0][0][0]
memiliki berbagai jenis. Mereka tidak bisa dibandingkan. Apa maksudmu!=
?