Как работает sizeof с разыменованием указателя на массив? - PullRequest
7 голосов
/ 27 октября 2019

Здесь у меня есть указатель ptr на массив arr из 4 целых чисел. ptr указывает на весь массив. ptr[0] или *ptr указывает на первый элемент массива, поэтому добавление 1 к ptr[0] дает адрес второго элемента массива.

Я не могу понять, почему с помощью sizeof(ptr[0])дает размер всего массива, 16 байт, а не размер только первого элемента, 4 байта (поскольку ptr[0] указывает на первый элемент в массиве).

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

Ответы [ 4 ]

6 голосов
/ 27 октября 2019

OP: ptr[0] указывает на первый элемент в массиве.

Введите путаницу. ptr[0] - это массив.

ptr - это указатель на массив 4 из int .
ptr[0], как и *ptr, который задерживает указатель намассив .
sizeof(ptr[0]) - размер массива.


При sizeof(ptr[0]), ptr[0] не вызывает "выражение с указателем типа" указатель на тип "это указывает на начальный элемент массива объекта "преобразования. (c11dr §6.3.2.1 3). С sizeof, ptr[0] - это массив.

5 голосов
/ 27 октября 2019

ptr здесь типа pointer to an array of 4 int elements, а тип массива имеет размер 16 на вашей платформе (sizeof (int) * (число элементов)).

Я не могу понятьпочему использование sizeof (ptr [0]) дает размер всего массива 16 байтов, а не размер только первого элемента 4 байта

, потому что система типов C имеет типы массивов. Здесь у arr и *ptr есть это. То, что вы заявляете, что у вас есть. Чтобы получить sizeof здесь, вы должны sizeof (ptr [0] [0]) - где ptr [0] вычисляется как массив.

2 голосов
/ 27 октября 2019

По определению ptr[0] совпадает с *(ptr + 0), что, в свою очередь, совпадает с *ptr. Кроме того, ptr инициализируется с &arr, поэтому *ptr равно *&arr, и это просто arr. Обратите внимание, что промежуточное хранилище &arr в ptr не не выполняет распад любого массива, поэтому сохраняется эквивалентность и информация о типе не теряется.

Обратите внимание, что все это вычисляетсяво время компиляции, просто чтобы избежать этой дополнительной ошибки.

2 голосов
/ 27 октября 2019

с int (*ptr)[4] = &arr ; у вас есть указатель на массив из четырех целых чисел и указатель на обр.

ptr теперь указывает на arr, как двойной указатель. Мы можем получить доступ к элементам arr, используя ptr[0][x], где x может быть от 0 до 4.

Так что sizeof(ptr[0]) совпадает с sizeof(arr)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...