Все дело в проверке статического типа и арифметике указателей. Возможно, это лучше всего проиллюстрировано на примере конкретного примера.
Рассмотрим это:
#include <stdio.h>
int main(int argc, char *argv[])
{
char x[10];
char *p0 = &x[0]; /* ok */
int *p1 = &x[0]; /* <- type checking, warning #1 */
char (*p2)[10] = &x; /* ok */
int (*p3)[10] = &x; /* <- type checking, warning #2 */
(void)printf("sizeof(char): %ld\n", sizeof(char));
(void)printf("sizeof(int): %ld\n", sizeof(int));
(void)printf("p0: %p, p0+1: %p\n", (void*)p0, (void*)(p0+1));
(void)printf("p1: %p, p1+1: %p\n", (void*)p1, (void*)(p1+1));
(void)printf("p2: %p, p2+1: %p\n", (void*)p2, (void*)(p2+1));
(void)printf("p3: %p, p3+1: %p\n", (void*)p3, (void*)(p3+1));
return 0;
}
Важная: компилировать с -Wall
(gcc -Wall -o test test.c
)
Программа компилируется, но вы получите два предупреждения о несовместимых типов указателей, и это правильно.
% gcc -Wall -o test test.c
test.c: In function ‘main’:
test.c:9:21: warning: initialization from incompatible pointer type [enabled by default]
int *p1 = &x[0]; /* <- type checking, warning #1 */
^
test.c:11:21: warning: initialization from incompatible pointer type [enabled by default]
int (*p3)[10] = &x; /* <- type checking, warning #2 */
^
Теперь запустите программу:
% ./test
sizeof(char): 1
sizeof(int): 4
p0: 0x7fff9f6dc5c0, p0+1: 0x7fff9f6dc5c1 # + 1 char
p1: 0x7fff9f6dc5c0, p1+1: 0x7fff9f6dc5c4 # + 1 int (4 bytes here)
p2: 0x7fff9f6dc5c0, p2+1: 0x7fff9f6dc5ca # + 10 chars
p3: 0x7fff9f6dc5c0, p3+1: 0x7fff9f6dc5e8 # + 10 ints (40 bytes here)
Здесь вы можете наблюдать влияние на стрелочных арифметике: хотя все 4 указатели были инициализированы к тому же значению, одни и те же выходы операции совершенно разные результаты.
Похожий вопрос видел вчера, довольно уверен, что есть где-то в дубликат SO. – Raptor
Также есть 'int * p [10]' – mclaassen
'cdecl' на межтрубках: http://cdecl.org/ – Deduplicator