我来自Java背景,在C中我对C数组语法有点困惑。
当我在C中初始化数组时,我这样做:
int arr[5];
据我所知,这实际上是一个指向arr的指针,它指向堆栈中数组的第一个元素。
但是我不明白为什么数组初始化看起来不像这样,因为我们收到一个指针:
int* arr[5];
这给了我一些我不明白的东西。也许是5个指针的数组?
另一方面,这完全有效:
int arr[5];
int* p = arr;
那么为什么这样做呢?因为我们实际收到一个指针,所以初始化语法不应该是int *而不是int吗?
答案 0 :(得分:1)
在C语法中,此行声明了一个包含指向int
的5个指针的数组。
int* arr[5];
声明了5个int
的数组。
int arr[5];
上面一行告诉编译器在内存中保留5倍于int
的相邻内存地址&arr[0]
的大小arr
。虽然arr
不是指针,但如果用作名称arr
,它本身会衰减到指向第一个插槽的指针(因此&a[0]
等同于int* p = arr;
)。
p
int
是指向arr
的普通指针,分配给有效的内存地址,与&arr[0]
(或arr++;
)相同
数组和指针不同。第一个区别是'arr'是常量,不能重新分配给其他地址。
例如,以下内容无效
p++;
以下是有效
char arr[7];
char *p = arr;
此外,指针需要在ASM操作下进行额外的解除引用,而数组则不需要
char a = arr[7];
数组索引
比较此行及其ASM说明:
char b = p[7];
0041137E mov al,byte ptr [_array_place + 7(417007h)]
00411383 mov byte ptr [a],al
指针索引:
使用此行及其ASM说明:
export function Newsitem ...
export function Newsitems...
00412DD7 mov eax,dword ptr [ptr_arg]
00412DDA mov cl,byte ptr [eax + 7]
00412DDD mov byte ptr [b],cl
数组可以衰减指向第一个元素的指针。这经常发生,例如当你将它们作为函数参数传递时。在这种情况下,将它们视为被调用函数内的指针。您最终可以将它们标记为constant pointers or pointers to constant or constant pointers to constant。
我希望这可以澄清。