В моем понимании, поскольку p равно [0], & p и & a [0] должны иметь одинаковое значение.
p
и a[0]
действительно имеютодинаковое значение, но это не значит, что они идентичны.Также как если у вас есть 2 переменные i
и j
, определенные как int i = 0, j = 0;
, это правда, что i
и j
имеют одно и то же значение, но, очевидно, имеют разные адреса.
Обратите внимание, что вашкод имеет неопределенное поведение, потому что %d
не является подходящим спецификатором преобразования для указателя на int
.Вы должны %p
и передать указатель на (void*)
или %llu
и указатель на (unsigned long long)(uintptr_t)p
.uintptr_t
определено в <stdint.h>
.
Вот исправленная версия:
#include <stdio.h>
int main(void) {
int a[4][2] = { {11, 12}, {21, 22}, {31, 32}, {41, 42} };
int *p = a[0];
printf(" *p: %d\n", *p);
printf(" p: %p\n", (void*)p);
printf(" a[0]: %p\n", (void*)a[0]);
printf(" &p: %p\n", (void*)&p);
printf("&a[0]: %p\n", (void*)&a[0]);
printf(" a: %p\n", (void*)a);
return 0;
}
Вывод:
*p: 11
p: 0x7fff5144d950
a[0]: 0x7fff5144d950
&p: 0x7fff5144d948
&a[0]: 0x7fff5144d950
a: 0x7fff5144d950
Как видите, массив a
имеет тот же адрес, что и его первая строка a[0]
, и это также адрес a[0][0]
, на который указывает p
.
&a[0]
отличается от a[0]
: тот же адрес, но отличаетсятип: a[0]
- это массив 2 int
, &a[0]
- это адрес массива 2 int
.&a[0] + 1
указывает на a[1]
, тогда как a[0] + 1
указывает на a[0][1]
.
Извините, я не могу объяснить это в более простых терминах, очень сложно принять адрес массива: вы можетедостичь довольно продвинутого уровня программирования на C без необходимости понимать эти тонкости.Просто помните, что массивы затухают как указатели на их первый элемент в большинстве контекстов выражений (кроме как в качестве аргумента для sizeof
) и никогда не используют оператор addressof (&
) для массива.