C语言中这两个函数的区别是什么?
void f1(double a[]) {
//...
}
void f2(double *a) {
//...
}
如果我调用一个非常长的数组上的函数,这两个函数的行为会不会不同,它们会占用堆栈上更多的空间吗?
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 keywordstatic
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]
的函数参数都将被视为as though,而声明为T *a
.
那么,为什么数组参数被视为被声明为指针呢?原因如下:
6.3.2.1 Lvalues, arrays, and function designators
...
3 Except when it is the operand of thesizeof
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从"int
的10元素数组"隐式转换为"指向int
的指针".因此,foo
将接收指针值,而不是数组值.
因为6.7.5.3/7,你可以写foo
个
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
对应的实际参数必须是包含at least个10个元素的array.