在Nick Parlante的一份文件中,它说,数组名称是常量,即数组基址的行为类似于const指针。
e.g
{
int array[100], i;
array = NULL; //cannot change base address
array = &i; // not possible
}
但与此同时为什么这是有效的:
void foo(int arrayparm[]){
arrayparm = NULL; // says it changes the local pointer
}
答案 0 :(得分:3)
函数参数声明与函数声明中的正式声明是C不同:
void foo(int arrayparm[])
^^^^^^^^^ is pointer not array
arrayparm
是指针,但不是数组,其类型为int*
。这相当于:
void foo(int *arrayparm)
在功能foo
中,您可以修改arrayparm
。
而在正式声明中(在副功能中),例如
int array[100];
array
不是指针,但它是一个常量,类型是char[100]
,它不是可修改的左值。
答案 1 :(得分:2)
数组衰减为函数中的指针。数组名称是non-modifable lvalue
。这意味着,您可以这样做:
int x=10,y=20;
int *p = &x; // <---- p Now points to x
p = &y; // <---- p Now points to y
但不这个:
int arr[10], x=10;
arr = &x; // <----- Error - Array name is a non-modifiable lvalue.
由于数组会立即衰减为指针,因此数组实际上永远不会传递给函数。为方便起见,任何“看起来像”数组的参数声明,例如
f(a)
char a[];
编译器将视为指针,因为如果传递数组,函数将接收到该函数:
f(a)
char *a;
此转换仅在函数形式参数声明中保持,而不是其他地方。如果这种转换困扰你,请避免它;许多人得出的结论是,它造成的混乱超过了声明“看起来像”调用和/或函数内使用的小优势。
参考文献:K&amp; R I Sec。 5.3 p。 95,Sec。 A10.1 p。 205; K&amp; R II Sec。 5.3 p。 100,Sec。 A8.6.3 p。 218,Sec。 A10.1 p。 226;
答案 2 :(得分:1)
当数组名称作为函数参数传递时,它“衰减”为指针。所以你可以像对待普通指针一样对待它。
参考:C FAQ what is meant by the ``equivalence of pointers and arrays'' in C?
答案 3 :(得分:0)
数组类型不能在C中分配。这只是一个设计决策。 (可以使数组类型的赋值将一个数组复制到另一个数组上,比如结构的赋值。他们只是选择不执行此操作。)
C99标准,6.5.16第2段:
赋值运算符左边应有一个可修改的左值 操作数。
C99标准,6.3.2.1第1段:
......可修改的左值是一个没有数组类型的左值, ...
另外,即使数组类型是可分配的,NULL
也不是int[100]
类型的值。