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]的函数参数都将被视为as though,而声明为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从"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.

C++相关问答推荐

新的memaligning函数有什么用?

为什么静态说明符为内联函数生成外部定义?

GCC不警告隐式指针到整数转换'

C指针地址和转换

如何在IF语句中正确使用0.0

仅在给定的大小和对齐方式下正确创建全局

自定义变参数函数的C预处置宏和警告 suppress ?

平均程序编译,但结果不好

X64:并发写入布尔数组

如何使解释器存储变量

FRIDA-服务器成为端口扫描的目标?

在句子中转换单词的问题

在C中包装两个数组?

为什么会导致分段故障?(C语言中的一个程序,统计文件中某个单词的出现次数)

为什么会出现此错误?二进制表达式的操作数无效

如何使用calloc和snprintf

被调用方函数内部的C-Struct变量,它是指针还是无关紧要

变量值不正确的问题

Ubuntu编译:C中的文件格式无法识别错误

在C中定义函数指针?