Làm thế nào để sizeof hoạt động với hội nghị này của một con trỏ tới mảng?


9

Ở đây tôi có một con trỏ ptrtới mảng arr4 số nguyên. ptrchỉ vào toàn bộ mảng. ptr[0]hoặc *ptrtrỏ đến phần tử đầu tiên của mảng, vì vậy, thêm 1 để ptr[0]cung cấp địa chỉ của phần tử thứ hai của mảng.

Tôi không thể hiểu tại sao việc sử dụng sizeof(ptr[0])lại cho kích thước của toàn bộ mảng, 16 byte, chứ không phải kích thước của chỉ phần tử đầu tiên, 4 byte, (như ptr[0]trỏ đến phần tử đầu tiên trong mảng).

int arr[4] = {0, 1, 2, 3};
int (*ptr)[4] = &arr;
printf("%zd", sizeof(ptr[0])); //output is 16

Không phải là dòng thứ hai phải int *ptr = arr;không? Điều đó sẽ làm cho nó trỏ đến điểm bắt đầu (phần tử đầu tiên của) mảng, tương đương với &arr[0].
Andreas Wenzel

1
@AndreasWenzel Không phải là dòng thứ hai int *ptr = arr;? Thật ra, không. int (*ptr)[4]tạo ptrnhư một con trỏ tới một mảng đầy đủ gồm bốn intgiá trị. Cú pháp con trỏ như thế là cần thiết để phân bổ động các mảng đa chiều thực. "Mảng 2 chiều" được tạo ra với các malloc()vòng lặp lồng nhau và được mô tả sai là mảng đa chiều thực sự là mảng 1-d của con trỏ tới nhiều mảng 1-d. Xem stackoverflow.com/questions/42094465/ từ
Andrew Henle

Câu trả lời:


6

OP: ptr[0]trỏ đến phần tử đầu tiên trong mảng.

Kiểu nhầm lẫn. ptr[0]là một mảng.

ptr là một con trỏ tới mảng 4 của int .
ptr[0], giống như trì *ptrhoãn con trỏ đến một mảng .
sizeof(ptr[0])là kích thước của một mảng.


Với sizeof(ptr[0]), ptr[0]không phát sinh "một biểu thức có loại '' con trỏ để nhập '' trỏ đến phần tử ban đầu của đối tượng mảng". (c11dr §6.3.2.1 3). Với sizeof, ptr[0]là một mảng.


1
@ Abd-ElrahmanMohamed Đồng ý "Nhưng ptr [0] [0] là một số nguyên không trỏ đến số nguyên". "Ptr [0] là địa chỉ của phần tử đầu tiên trong mảng" không đúng.
chux - Phục hồi Monica

1
@ Abd-ElrahmanMohamed có, các giá trị giống nhau nhưng các loại khác nhau. ptr [0] có kiểu mảng và &ptr[0][0]int *kiểu
Green Tree

1
@chux ptr[0](được chuyển đổi hoàn toàn thành int *) sẽ đánh giá địa chỉ của phần tử int đầu tiên.
Cây xanh

1
@chux về sizeof - đúng rồi, tôi đã hiểu nhầm ngữ cảnh của những gì bạn nói
Cây xanh

1
@ Abd-ElrahmanMohamed Điều đó không. printf("someforamt", ptr[0] , ptr[0]+1)làm một cái gì đó khác hơn sizeof(ptr[0]). Trong ptr[0]trường hợp đầu tiên trải qua một chuyển đổi không rõ ràng. Với sizeof(ptr[0]), ptr[0]không.
chux - Phục hồi Monica

5

ptrđây là loại pointer to an array of 4 int elementsvà loại mảng có kích thước 16 trên nền tảng của bạn (sizeof (int) * (số lượng từ xa)).

Tôi không thể hiểu tại sao sử dụng sizeof (ptr [0]) cho kích thước của toàn bộ mảng 16 byte chứ không phải kích thước của phần tử đầu tiên 4 byte

bởi vì hệ thống loại C có kiểu mảng. Ở đây cả hai arr*ptrcó nó. Những gì bạn tuyên bố rằng bạn có. Để lấy sizeof int ở đây, bạn nên sizeof (ptr [0] [0]) - trong đó ptr [0] ước tính thành mảng.


2

với int (*ptr)[4] = &arr ;bạn có một con trỏ tới một mảng gồm bốn số nguyên và trỏ đến mảng.

ptrbây giờ đang trỏ đến arr, giống như một con trỏ kép. Chúng ta có thể truy cập vào các yếu tố của arrsử dụng ptr[0][x]nơi xcó thể 0đến 4.

Vì vậy, sizeof(ptr[0])là giống nhưsizeof(arr)


2

Theo định nghĩa, ptr[0]tương tự như *(ptr + 0)lần lượt là giống như *ptr. Hơn nữa, ptrđược khởi tạo với &arr, vì vậy *ptr*&arrvà đó chỉ là arr. Lưu ý rằng việc lưu trữ trung gian &arrtrong ptrkhông không thực hiện bất kỳ phân rã mảng, do đó tương đương được duy trì và không có thông tin loại bị mất.

Lưu ý rằng tất cả điều này được tính toán tại thời gian biên dịch, chỉ để tránh cạm bẫy bổ sung này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.