当我使用数组名称作为参数调用函数时会发生什么?

时间:2013-03-19 07:57:48

标签: c arrays function pointers

我正在阅读K& R的TCPL,当我读到有关数组和指针的内容时,我在下面写下这个小代码:

#include <stdio.h>
int sum(int a[])
{
    int t = 0;
    int length = sizeof(a) / sizeof(a[0]) ;
//  printf("%d\n",length);
    for(int i = 0; i != length; ++i)
    {
        t += a[i];
    }
    return t;
}
int main()
{
    int b[5] = {1, 2, 3, 4, 5};
    printf("%d\n",sum(b));
    return 0;
}

输出答案是1 NOT 15,然后通过添加printf("%d\n",length);调试此代码,输出长度为1 NOT 5。 TCPL告诉数组名称在数组名称用作参数时转换为指针,但输出答案是错误的,所以我想知道:

  1. 调用带有数组名称作为参数的函数时会发生什么?
  2. a[]中使用的数组sum(int a[])参数是否有存储空间?
  3. 调用数组时我看到两种样式:fun(int a[]); fun(b)fun(int *a);fun(b),有什么区别?
  4. 非常感谢: - )

5 个答案:

答案 0 :(得分:3)

您无法调用函数并传递整个数组;如果使用数组名称作为函数参数,则会将其隐式重写为(“衰减”)指向其第一个元素的指针。它相当于写作

 int sum(int *a) { ... }

因此,在函数sizeof array中,不会给出数组的大小,只给出指向其第一个元素的指针的大小。

那么你怎么知道数组中有多少元素?您需要将此数字显式传递给函数(或定义具有元素数量的宏并在需要时使用它)。

答案 1 :(得分:1)

在声明如下的数组上调用sizeof

 int a[5];

将返回您当前认为它将如何的数组大小(即数组的完整大小字节数 - 在本例中为我机器上的20个字节)。将这样的数组传递给函数时,数组将衰减为指向其第一个元素的指针。因此,当您在函数参数上调用sizeof时,实际上是在指针类型上调用它。如果您声明函数采用int *参数,则错误会更明显,因为您调用sizeof的变量的类型是显式的。

答案 2 :(得分:1)

你的第三个问题涉及问题:就编译器而言,这两者之间没有区别。关于如何传递参数的一切都是一样的。

因此,在回答第二个问题时,a参数没有底层数组的存储空间,也没有复制该数组的成员。分配的唯一存储是int *指针,该指针存储在a中。 (这也有点回答你的第一个问题。)

所以,在你的函数中:

int length = sizeof(a) / sizeof(a[0]) ;

相当于

int length = sizeof(int *) / sizeof(int);

在指针和整数相同的系统上返回1。如果你在64位Linux上运行它,你会得到2,因为指针是64位,而int是32位。

答案 3 :(得分:0)

您的通话没有问题,fun(int a[])fun(int *a)之间没有区别(对于读者来说,您期望数组而不是任何指针更明显)。 Bot参数是指向int的指针。

这里的问题是你如何确定数组的长度。由于方括号为空,编译器无法知道a后面的数组有多长。例如,您可以将数组的长度作为第二个参数提供。注意:调用函数时,sizeof(b)将提供正确的长度,因为编译器知道它的长度。

答案 4 :(得分:-1)

sizeof()运算符不能用于获取动态分配的数组长度。

Here您可以找到sizeof()使用的示例。

当您尝试sizeof(array_ptr)时,实际上会为您指定指针大小

因此,您必须将数组长度作为函数

的参数传递