Адрес первого элемента в статическом объявлении массива - PullRequest
9 голосов
/ 24 июня 2011
int main()
{
    int a[3]={1,10,20};
    printf("%u %u %u \n" ,&a,a,&a[0]);
    return 0;
}

Это печатает одинаковое значение для всех трех.Я понимаю, что a и & a [0] одинаковы, но как & a также одинаковы?

Ответы [ 5 ]

16 голосов
/ 24 июня 2011

Для максимальной совместимости вы всегда должны использовать %p и явно приводить к void* для печати значений указателя с помощью printf.

Когда имя массива используется в контексте выражения, отличном от asоперанд sizeof или унарный & распадается на указатель на свой первый элемент.

Это означает, что a и &a[0] имеют одинаковый тип (int*) и значение.&a - это адрес самого массива, поэтому имеет тип int (*)[3].Объект массива начинается со своего первого элемента, поэтому адрес первого элемента массива будет иметь то же значение, что и адрес самого массива, хотя выражения &a[0] и &a имеют разные типы.

6 голосов
/ 24 июня 2011

Мой C ржавый, но, насколько я знаю, & a - это адрес начала массива, который будет точно соответствовать & a [0], поскольку начало массива - это первый элемент.

Опять же, ржаво с C, поэтому я передам кого-то с большим опытом.

4 голосов
/ 24 июня 2011

Тот факт, что & a в данном случае совпадает с a, является следствием того факта, что a имеет статический размер. Если вы сделаете указатель на массив, то это будет другое число, в то время как два других дали бы тот же результат.

Например:

int main()
{
    int b[3]={1,10,20};
    int* a = b;
    printf("%u %u %u \n" ,&a,a,&a[0]);
    return 0;
}

Пример вывода:

2849911432 2849911408 2849911408

3 голосов
/ 25 июня 2011

&a - это «адрес массива». Это место в памяти, где находится массив, но у него есть специальный тип «указатель на массив».

&a[0] - это «адрес 0-го элемента массива». Поскольку в массиве до 0-го элемента нет ничего, это то же самое место в памяти, но с типом «указатель на».

a - это «массив». Но вы не можете передавать массивы по значению функциям (таким как printf) в C или C ++. Вы можете только притворяться, что делаете это. (В C ++ вы можете передавать массивы по ссылке, но у C нет передачи по ссылке.) Но на самом деле происходит то, что массив «разлагается» на указатель на первый элемент, как если бы вы написали &a[0] .

Это произошло потому, что (я в основном размышляю здесь) в C, было сочтено полезным и желательным: (а) иметь возможность изменять содержимое переданного массива; (б) не нужно копировать целые массивы в стек при вызове функции. Так что C лжет вам и вместо этого помещает указатель на исходный массив в стек Поскольку синтаксис один и тот же, вы никогда не заметите разницу - когда вы пишете a[0] с тем, что вы считаете массивом, но на самом деле указателем, он обращается к наведенной памяти, как если бы это был массив (независимо от того, является ли он массивом или нет). это на самом деле - нет больше способа сказать). В C ++ поведение сохраняется для обратной совместимости.

1 голос
/ 24 июня 2011

В C имя массива указывает на самый первый элемент этого массива.

Итак, указав &a, вы ссылаетесь на адрес памяти этого первого элемента.

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