我知道 c 编译器认为以下函数定义相同
void test(int* array); // all converted to first one
void test(int array[]);
void test(int array[3]);
在 C99 标准中
除非它是 sizeof 运算符或一元 & 的操作数 运算符,或者是用于初始化数组的字符串文字,一个 类型为“类型数组”的表达式被转换为 类型为“指向类型的指针”的表达式指向初始值 数组对象的元素并且不是左值。如果数组对象 有寄存器存储类,行为未定义。
我的问题是在
int array[]
衰减为一个指针之后,那么它也是一个左值作为函数调用中的局部变量,是否违反了转换后的指针不应该是左值的标准?
我的问题是在 int array[] 衰减为指针之后,然后它也是 左值作为函数调用中的局部变量,是否违反了 转换后的指针不应该是左值的标准?
引号意味着在将数组隐式转换为指向其第一个元素的指针之后,该指针不是 lavlue。例如,如果您编写 example
,编译器将发出错误int a[10];
++a;
在此表达式
++a
中,数组指示符 a
被隐式转换为指向其第一个元素的指针,但指针不是左值。你可能不会增加它。如果你会写 intead
int a[10];
int *p = a;
++p;
那么表达式
++p
是正确的,因为p
是一个左值。
至于那样的功能
void test(int array[]);
然后将传递的数组转换为指向其第一个元素的指针,并且该指针不是左值。但是指针是用来初始化被编译器调整为int *类型的函数的参数的。当然,参数是函数中的左值。
类似地,如果您有一个返回数组的函数,该数组被转换为指向其第一个元素的指针,例如
int * test( void )
{
static int a[10];
return a;
}
然后返回的指针又不是左值。例如你可能不会写
printf( "%p\n", ( void * )++test() );
那是你不能增加返回的指针。
没问题,因为这里有两件事在起作用:将数组参数调整为指针,以及如何设置函数参数。
您给出的三个声明的等效性在C标准的第6.7.6.3p7节中有详细说明:
将参数声明为“类型数组”应调整为 ‘‘qualified pointer to type’’,其中类型限定符(如果有的话)是 那些在数组类型推导的
和[
中指定的。如果 关键字static也出现在数组类型的]
和[
中 推导,然后对于函数的每次调用, 相应的实际参数应提供对第一个的访问 一个数组的元素,其元素的数量至少与 尺寸表达]
所以这意味着在上述所有情况下,参数
array
的类型都是int *
。
然后是如何填充参数。这是在 6.5.2.2p4 中关于函数调用的规定:
参数可以是任何完整对象类型的表达式。在 准备调用函数,评估参数,并且 每个参数都分配了相应参数的值
所以给出以下内容:
int a[5];
test(a);
在内部,有一个赋值,即
array = a
从传递的参数值到函数的实际参数。