Bagaimana cara sizeof bekerja dengan dereferensi ini dari pointer ke array?

9

Di sini saya memiliki pointer ptrke array arr4 bilangan bulat. ptrmenunjuk ke seluruh array. ptr[0]atau *ptrmenunjuk ke elemen pertama array, jadi menambahkan 1 untuk ptr[0]memberikan alamat elemen kedua array.

Saya tidak mengerti mengapa menggunakan sizeof(ptr[0])memberikan ukuran seluruh array, 16 byte, bukan hanya ukuran elemen pertama, 4 byte, (sebagai ptr[0]poin ke elemen pertama dalam array).

int arr[4] = {0, 1, 2, 3};
int (*ptr)[4] = &arr;
printf("%zd", sizeof(ptr[0])); //output is 16
Abd-Elrahman Mohamed
sumber
Bukankah seharusnya baris kedua int *ptr = arr;? Itu akan membuatnya menunjuk ke awal (elemen pertama) array, yang setara dengan &arr[0].
Andreas Wenzel
1
@ AndreasWenzel Bukankah seharusnya baris kedua int *ptr = arr;? Sebenarnya tidak. int (*ptr)[4]menciptakan ptrsebagai penunjuk ke array penuh dari empat intnilai. Sintaksis pointer seperti itu diperlukan untuk mengalokasikan array true-multidimensional secara dinamis. "Array 2 dimensi" yang dibuat dengan malloc()loop bersarang dan digambarkan secara keliru sebagai array multidimensi adalah benar-benar array pointer 1-ke beberapa array 1-d. Lihat stackoverflow.com/questions/42094465/…
Andrew Henle

Jawaban:

6

OP: ptr[0]menunjuk ke elemen pertama dalam array.

Ketik kebingungan. ptr[0]adalah sebuah array.

ptr adalah pointer ke array 4 int .
ptr[0], seperti *ptrmenghormati pointer ke array .
sizeof(ptr[0])adalah ukuran array.


Dengan sizeof(ptr[0]), ptr[0]tidak menimbulkan "ekspresi dengan tipe '' pointer to type '' yang menunjuk ke elemen awal dari objek array" konversi. (c11dr §6.3.2.1 3). Dengan sizeof, ptr[0]adalah sebuah array.

chux - Pasang kembali Monica
sumber
1
@ Abd-ElrahmanMohamed Setuju "Tapi ptr [0] [0] adalah bilangan bulat yang tidak menunjuk ke bilangan bulat". "ptr [0] adalah alamat elemen pertama dalam array" tidak benar.
chux - Reinstate Monica
1
@ Abd-ElrahmanMohamed ya, nilainya sama tetapi jenisnya berbeda. ptr [0] memiliki tipe array dan &ptr[0][0]memiliki int *tipe
Green Tree
1
@ chux ptr[0](secara implisit dikonversi ke int *) akan mengevaluasi ke alamat elemen int pertama.
Green Tree
1
@chux tentang sizeof - benar, saya salah mengerti konteks apa yang Anda katakan
Green Tree
1
@ Abd-ElrahmanMohamed Itu tidak. printf("someforamt", ptr[0] , ptr[0]+1)melakukan sesuatu yang berbeda dari sizeof(ptr[0]). Dalam ptr[0]kasus pertama melewati konversi yang tidak sah. Dengan sizeof(ptr[0]), ptr[0]tidak.
chux - Reinstate Monica
5

ptrdi sini adalah tipe pointer to an array of 4 int elementsdan tipe array memiliki ukuran 16 pada platform Anda (sizeof (int) * (jumlah elemen)).

Saya tidak bisa mengerti mengapa menggunakan sizeof (ptr [0]) memberikan ukuran seluruh array 16 byte bukan ukuran hanya elemen pertama 4 byte

karena sistem tipe C memiliki tipe array. Di sini keduanya arrdan *ptrmemilikinya. Apa yang Anda nyatakan bahwa Anda miliki. Untuk mendapatkan sizeof int di sini Anda harus sizeof (ptr [0] [0]) - di mana ptr [0] mengevaluasi ke array.

Pohon hijau
sumber
2

dengan int (*ptr)[4] = &arr ;Anda memiliki pointer ke array empat bilangan bulat dan menunjuk ke arr.

ptrsekarang menunjuk ke arr, seperti penunjuk ganda. Kita dapat mengakses elemen arrmenggunakan ptr[0][x]mana xbisa 0untuk 4.

Begitu sizeof(ptr[0])juga dengansizeof(arr)

rsonx
sumber
2

Menurut definisi, ptr[0]sama dengan *(ptr + 0)yang pada gilirannya sama dengan *ptr. Selanjutnya, ptrdiinisialisasi dengan &arr, begitu *ptrjuga *&arrdan itu adil arr. Perhatikan bahwa penyimpanan menengah &arrdi ptrtidak tidak melakukan salah pembusukan array, sehingga kesetaraan dipertahankan dan tidak ada informasi jenis yang hilang.

Perhatikan bahwa semua ini dihitung pada waktu kompilasi, hanya untuk menghindari perangkap tambahan ini.

Ulrich Eckhardt
sumber