数组名称常量或指针是什么时候?

时间:2013-10-18 04:50:29

标签: c arrays function pointers

在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
}

4 个答案:

答案 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]类型的值。