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