#arrays #c #pointers #memory-address
#массивы #c #указатели #адрес памяти
Вопрос:
итак, я изучал массивы и указатель на массив, и я нашел этот код. Мне было интересно, почему адрес последнего — FE14, разве он не должен быть адресом первого элемента плюс (размер типа данных), который равен 4, так что я должен быть FE04?
#include <stdio.h>
int main()
{
int arr[5];
printf("%pn",arr); //----> the output FE00
printf("%pn",arr 1); //----> the output FE04
printf("%pn",amp;arr); //----> the output FE00
printf("%pn",amp;arr 1); //----> the output FE14
}
Комментарии:
1. В качестве дополнительного примечания приведите указатели к типу
void *
перед их печатью с помощью спецификатора%p
формата. Кроме того,arr
иamp;arr[0]
это одно и то же.
Ответ №1:
Это сбивает с толку из-за того, что массивы C могут распадаться на выражения указателей.
С arr
помощью and arr 1
тип данных указателя равен int
, который в вашей системе равен 4 байтам, поэтому вы видите разницу в 4 байта между FE00
и FE04
.
При amp;arr
использовании and amp;arr 1
тип данных указателя int[5]
равен 20 байтам, поэтому вы видите разницу в 20 байтов между FE00
и FE14
Это разница 0x14
, которая:
1 * 16^1 4 * 16^0
= 1 * 16 4 * 1
= 16 4
= 20
Если вы измените размер вашего int arr[5]
адреса с 5 целых на 500, скажем, вы увидите большую разницу между amp;arr
и amp;arr 1
.
Комментарии:
1. спасибо за ваш ответ, я не знал, что amp;arr будет 20 байт.
Ответ №2:
printf("%pn", arr 1);
В этом коде arr
это целочисленный указатель, поэтому arr 1
результат arr 1 * sizeof(int)
равен 4.
printf("%pn",amp;arr 1);
В этом случае amp;arr
это указатель на массив из 5 int
, что amp;arr 1
приводит к amp;arr 1 * sizeof(int[5])
, что равно 20 (14 в шестнадцатеричном формате)