Saya belajar bahasa pemrograman C, saya baru saja mulai belajar array dengan pointer. Aku punya masalah dalam pertanyaan ini, saya berharap bahwa output harus 5
tapi 2
, Bisa tolong jelaskan mengapa?
int main(){
int arr[] = {1, 2, 3, 4, 5};
char *ptr = (char *) arr;
printf("%d", *(ptr+4));
return 0;
}
Diasumsikan little endian arsitektur di mana int 32 bit (4 byte), masing-masing byte int arr[]
terlihat seperti ini (least significant byte di bawah alamat. Semua nilai-nilai dalam hex):
|01 00 00 00|02 00 00 00|03 00 00 00|04 00 00 00|05 00 00 00
char *ptr = (char *) arr;
Sekarang, ptr
poin untuk byte pertama - karena anda telah dicor untuk char*
, itu diperlakukan sebagai array char dan seterusnya:
|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0
^
+-- ptr
Kemudian, *(ptr+4)
mengakses elemen kelima dari char array dan mengembalikan sesuai char
nilai:
|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5|0|0|0
^
+-- *(ptr + 4) = 2
Oleh karena itu, printf()
cetakan 2
.
Pada Big Endian sistem, urutan byte dalam setiap int
dibalik, sehingga
|0|0|0|1|0|0|0|2|0|0|0|3|0|0|0|4|0|0|0|5
^
+-- *(ptr + 4) = 0
It's karena ukuran char
adalah satu, dan ukuran int
adalah empat. Ini berarti bahwa menambahkan 4
ke ptr
membuat hasil point untuk entri kedua dalam int
hotel.
Jika anda disusun ini pada besar endian sistem anda akan dicetak 33554432 sebaliknya.
int main(){
int arr[] = {1,2,3,4,5};
char *ptr = (char *) arr;
printf("%d",*(ptr+4));
return 0;
}
Masing-masing kasus arr
memiliki `sizeof(int) ukuran (yang mungkin menjadi 4 pada implementasi).
Sejak ptr adalah pointer ke
char, [pointer aritmetika][1] membuat
ptr + 4poin 4 byte setelah
&arr[0], yang mungkin menjadi
&arr1`.
Dalam memori, sepertinya sesuatu seperti:
Address | 0 1 2 3 | 4 5 6 7 | ...
Value | arr[0] | arr[1] | ...
Apa yang anda lakukan pasti tidak dianjurkan dalam kode produksi, tapi pasti bagus untuk pemahaman pointer, gips, dll. dalam proses pembelajaran, sehingga untuk anda ini adalah contoh besar. Jadi, mengapa anda dapatkan 2. Hal ini karena array adalah sebuah array int, yang tergantung pada arsitektur memiliki ukuran yang berbeda (dalam kasus anda, sizeof(int)
4). Anda mendefinisikan ptr
sebagai pointer char, char memiliki ukuran 1 byte. Pointer aritmatika (yang's apa yang anda lakukan ketika anda menulis ptr+4
) bekerja sama dengan ukuran benda penunjuk referensi, dalam kasus anda dengan karakter. Dengan demikian ptr+4
adalah 4 byte yang dimulai dari awal array, dan dengan demikian di posisi ke-2 dari int
hotel. Yang itu. Mencoba ptr+5
, anda harus mendapatkan 0.
Pada 32 bit platform, int
adalah empat kali ukuran dari char
. Ketika anda menambahkan 4 untuk ptr
, anda menambahkan 4 kali ukuran apa ptr poin untuk ptr (yang itu sendiri adalah lokasi memori). Itu terjadi untuk menjadi alamat dari elemen kedua dalam int
hotel.
Pada 64 bit platform, int
adalah delapan kali ukuran char
; dan output anda akan sangat berbeda.
Untuk memotong cerita panjang pendek, kode anda tidak portabel, (juga lihat Joachim Pileborg's jawaban re endianness) tapi lucu untuk membongkar.
int main(){
int arr[] = {1,2,3,4,5};
char *ptr = (char *) arr;
printf("%d",*(ptr+4));
return 0;
}
Bayangkan arr
disimpan di alamat 100
(benar-benar bodoh address). Jadi, anda harus:
arr[0]
disimpan pada alamat 100.
arr[1]
disimpan di alamat 104. (ada's adalah +4 karena jenis int
)
arr[2]
disimpan di alamat 108.
arr[3]
disimpan di alamat 112. Dll dll.
Sekarang anda'kembali melakukan char *ptr = (char *) arr;
, jadi ptr
= 100 (sama seperti arr
).
Pernyataan berikutnya adalah menarik, khususnya argumen kedua dari printf
: *(ptr+4)
.
Menjaga dalam pikiran saya bahwa ptr
= 100. Jadi ptr + 4
= 104, alamat yang sama bahwa arr[1]
! Sehingga akan mencetak nilai dari arr[1]
, yang adalah 2.