传递数组和数组指针之间的差异到C中的函数

C中的两个函数有什么区别?

void f1(double a[]) {
   //...
}

void f2(double *a) {
   //...
}

如果我在一个相当长的数组上调用函数,这两个函数会有不同的行为,他们会在堆栈上占用更多的空间吗?

首先,一些standardese

6.7.5.3 Function declarators (including prototypes)

7 A declaration of a parameter as ‘‘array of type’’ shall be adjusted to ‘‘qualified pointer to
type’’, where the type qualifiers (if any) are those specified within the [ and ] of the
array type derivation. If the keyword static also appears within the [ and ] of the
array type derivation, then for each call to the function, the value of the corresponding
actual argument shall provide access to the first element of an array with at least as many
elements as specified by the size expression.

因此,简而言之,声明为T a []或T a [N]的任何函数参数被视为被声明为T * a。

那么,为什么数组参数被视为是被声明为指针?这里是为什么:

6.3.2.1 Lvalues, arrays, and function designators

3 Except when it is the operand of the sizeof operator or the unary & operator, or is a
string literal used to initialize an array, an expression that has type ‘‘array of type’’ is
converted to an expression with type ‘‘pointer to type’’ that points to the initial element of
the array object and is not an lvalue. If the array object has register storage class, the
behavior is undefined.

给出以下代码:

int main(void)
{
  int arr[10];
  foo(arr);
  ...
}

在调用foo中,数组表达式arr不是sizeof或&的操作数,因此其类型根据6.2.3.1/3被隐式地从“10元数组int”转换为“指针到int” 。因此,foo将接收指针值,而不是数组值。

因为6.7.5.3/7,你可以写foo as

void foo(int a[]) // or int a[10]
{
  ...
}

但它将被解释为

void foo(int *a)
{
  ...
}

因此,这两种形式是相同的。

6.7.5.3/7中的最后一句是用C99引入的,基本上意味着如果你有一个参数声明

void foo(int a[static 10])
{
  ...
}

对应于a的实际参数必须是具有至少10个元素的数组。

http://stackoverflow.com/questions/5573310/difference-between-passing-array-and-array-pointer-into-function-in-c

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:传递数组和数组指针之间的差异到C中的函数