Рассмотрим эту программу, работающую на 64-битной машине (Mac под управлением MacOS Mojave 10.14.6, если быть точным с GCC 9.2.0):
#include <stdio.h>
int main(void)
{
int A[100][50];
printf("Size of void * = %zu and size of int = %zu\n", sizeof(void *), sizeof(int));
printf("Given 'int A[100][50];\n");
printf("Size of A = %zu\n", sizeof(A));
printf("Size of A[0] = %zu\n", sizeof(A[0]));
printf("Size of A[0][0] = %zu\n", sizeof(A[0][0]));
putchar('\n');
printf("Address of A[0] = %p\n", (void *)A[0]);
printf("Address of A[0] + 0 = %p\n", (void *)(A[0] + 0));
printf("Address of A[0] + 1 = %p\n", (void *)(A[0] + 1));
printf("Difference = %td\n", (void *)(A[0] + 1) - (void *)(A[0] + 0));
putchar('\n');
printf("Address of &A[0] = %p\n", (void *)&A[0]);
printf("Address of &A[0] + 0 = %p\n", (void *)(&A[0] + 0));
printf("Address of &A[0] + 1 = %p\n", (void *)(&A[0] + 1));
printf("Difference = %td\n", (void *)(&A[0] + 1) - (void *)(&A[0] + 0));
return 0;
}
Вывод:
Size of void * = 8 and size of int = 4
Given 'int A[100][50];
Size of A = 20000
Size of A[0] = 200
Size of A[0][0] = 4
Address of A[0] = 0x7ffee5b005e0
Address of A[0] + 0 = 0x7ffee5b005e0
Address of A[0] + 1 = 0x7ffee5b005e4
Difference = 4
Address of &A[0] = 0x7ffee5b005e0
Address of &A[0] + 0 = 0x7ffee5b005e0
Address of &A[0] + 1 = 0x7ffee5b006a8
Difference = 200
Следовательно, можно сделать вывод, что A[0]
является массивом 50 int
- это не «указатель указателя». Тем не менее, при использовании в выражении, таком как A[0] + 1
, оно «распадается» на «указатель на int
» (указатель на тип элемента массива), и, следовательно, A[0] + 1
- это значение на одно целое число дальшемассив.
Последний блок вывода показывает, что адрес массива имеет другой тип - int (*)[50]
в случае A[0]
.