Kau*_*kar 104 c arrays function parameter-passing space-efficiency
C中两个函数有什么区别?
void f1(double a[]) {
//...
}
void f2(double *a) {
//...
}
Run Code Online (Sandbox Code Playgroud)
如果我要在一个相当长的数组上调用这些函数,这两个函数的行为会不同,它们会占用更多的空间吗?
Joh*_*ode 110
首先,一些标准:
6.7.5.3函数声明符(包括原型)
...
7参数声明为'' 类型数组''应调整为''限定指向 类型 '',其中类型限定符(如果有)是指定的那些内的[与]所述阵列型推导.如果关键字static也出现在数组类型派生的[和]中,那么对于每次对函数的调用,相应的实际参数的值应该提供对数组的第一个元素的访问,其中至少有与该大小指定的元素一样多的元素.表达.
因此,简而言之,任何函数参数声明T a[]或T a[N]进行处理,就好像它被宣布T *a.
那么,为什么数组参数被视为声明为指针?原因如下:
6.3.2.1左值,数组和功能指示器
...
3除了当它是的操作数sizeof操作者或一元&运算符,或者是用于初始化数组文本的字符串,其具有输入""的阵列的表达类型 ' '被转换成类型的表达式'’指针键入指向阵列对象的初始元素,不是左值'’.如果数组对象具有寄存器存储类,则行为未定义.
给出以下代码:
int main(void)
{
int arr[10];
foo(arr);
...
}
Run Code Online (Sandbox Code Playgroud)
在调用中foo,数组表达式arr不是任何一个sizeof或的操作数&,因此根据6.2.3.1/3 ,它的类型从"10元素数组int" 隐式转换为"指向int".因此,foo将接收指针值,而不是数组值.
因为6.7.5.3/7,你可以写foo为
void foo(int a[]) // or int a[10]
{
...
}
Run Code Online (Sandbox Code Playgroud)
但它将被解释为
void foo(int *a)
{
...
}
Run Code Online (Sandbox Code Playgroud)
因此,这两种形式是相同的.
6.99.5.3/7中的最后一句是用C99引入的,基本上意味着如果你有一个参数声明
void foo(int a[static 10])
{
...
}
Run Code Online (Sandbox Code Playgroud)
对应的实际参数a必须是一个至少包含 10个元素的数组.
Tho*_*nin 28
差异纯粹是语法上的.在C中,当数组表示法用于函数参数时,它会自动转换为指针声明.