Здесь у меня есть указатель 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
int *ptr = arr;
? Это указало бы на начало (первый элемент) массива, что эквивалентно&arr[0]
.int *ptr = arr;
? Вообще-то, нет.int (*ptr)[4]
создаетptr
как указатель на полный массив из четырехint
значений. Подобный синтаксис указателя необходим для динамического выделения многомерных массивов. «2-мерные массивы», созданные с помощью вложенныхmalloc()
циклов и ошибочно описанные как многомерные массивы, на самом деле являются 1-мерными массивами указателей на несколько 1-мерных массивов. См. Stackoverflow.com/questions/42094465/…Ответы:
Типа путаницы.
ptr[0]
это массив.ptr
является указателем на массив 4 междунар . Вродеptr[0]
как*ptr
задерживает указатель на массив .sizeof(ptr[0])
это размер массива.С
sizeof(ptr[0])
,ptr[0]
не вызывает преобразования «выражение с типом« указатель на тип », который указывает на начальный элемент объекта массива». (c11dr §6.3.2.1 3). Сsizeof
,ptr[0]
это массив.источник
&ptr[0][0]
имеетint *
типptr[0]
(неявно преобразуется вint *
) будет вычислять адрес первого элемента int.printf("someforamt", ptr[0] , ptr[0]+1)
делает что-то другое, чемsizeof(ptr[0])
. Вptr[0]
первом случае происходит неявное преобразование. Сsizeof(ptr[0])
,ptr[0]
не делает.ptr
здесь типpointer to an array of 4 int elements
и тип массива имеет размер 16 на вашей платформе (sizeof (int) * (число элементов)).потому что система типов C имеет типы массивов. Вот так
arr
и*ptr
есть. То, что вы заявляете, что у вас есть. Чтобы получить sizeof здесь, вы должны sizeof (ptr [0] [0]) - где ptr [0] вычисляется как массив.источник
у
int (*ptr)[4] = &arr ;
вас есть указатель на массив из четырех целых чисел и указывающий на обр.ptr
теперь указывает наarr
, как двойной указатель. Мы можем получить доступ к элементам сarr
помощьюptr[0][x]
которыхx
можно было бы0
с4
.Так
sizeof(ptr[0])
же, какsizeof(arr)
источник
По определению,
ptr[0]
это то же самое,*(ptr + 0)
что, в свою очередь, то же самое, что и*ptr
. Кроме того,ptr
инициализируется&arr
, так*ptr
это*&arr
и простоarr
. Следует отметить , что промежуточное хранение&arr
вptr
вовсе не выполняет никакого распада массива, так что эквивалентность сохраняется и никакой информации типа не теряется.Обратите внимание, что все это вычисляется во время компиляции, просто чтобы избежать этой дополнительной ошибки.
источник