数组衰减为指针作为函数参数

问题描述 投票:0回答:2

我知道 c 编译器认为以下函数定义相同

void test(int* array);   // all converted to first one
void test(int array[]);
void test(int array[3]);

在 C99 标准中

除非它是 sizeof 运算符或一元 & 的操作数 运算符,或者是用于初始化数组的字符串文字,一个 类型为“类型数组”的表达式被转换为 类型为“指向类型的指针”的表达式指向初始值 数组对象的元素并且不是左值。如果数组对象 有寄存器存储类,行为未定义。

我的问题是在

int array[]
衰减为一个指针之后,那么它也是一个左值作为函数调用中的局部变量,是否违反了转换后的指针不应该是左值的标准?

arrays c pointers implicit-conversion
2个回答
1
投票

我的问题是在 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() );

那是你不能增加返回的指针。


0
投票

没问题,因为这里有两件事在起作用:将数组参数调整为指针,以及如何设置函数参数。

您给出的三个声明的等效性在C标准的第6.7.6.3p7节中有详细说明

将参数声明为“类型数组”应调整为 ‘‘qualified pointer to type’’,其中类型限定符(如果有的话)是 那些在数组类型推导的

[
]
中指定的。如果 关键字static也出现在数组类型的
[
]
中 推导,然后对于函数的每次调用, 相应的实际参数应提供对第一个的访问 一个数组的元素,其元素的数量至少与 尺寸表达

所以这意味着在上述所有情况下,参数

array
的类型都是
int *

然后是如何填充参数。这是在 6.5.2.2p4 中关于函数调用的规定:

参数可以是任何完整对象类型的表达式。在 准备调用函数,评估参数,并且 每个参数都分配了相应参数的值

所以给出以下内容:

int a[5];
test(a);

在内部,有一个赋值,即

array = a
从传递的参数值到函数的实际参数。

© www.soinside.com 2019 - 2024. All rights reserved.