0

我正在阅读 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 回答 5

3

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

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

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

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

于 2013-03-19T08:01:17.890 回答
1

调用sizeof声明如下的数组

 int a[5];

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

于 2013-03-19T08:04:09.990 回答
1

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

因此,在回答您的第二个问题时,该a参数没有基础数组的存储空间,也没有复制该数组的成员。分配的唯一存储空间是用于int *指针,并且该指针存储在a. (这在某种程度上也回答了您的第一个问题。)

因此,在您的功能中:

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

相当于

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

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

于 2013-03-19T08:05:16.120 回答
0

fun(int a[])您的调用没有问题,and 之间也没有区别fun(int *a)(希望读者更明显的是您期望的是数组而不是任何指针)。Bot 参数是一个指向 int 的指针。

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

于 2013-03-19T08:06:51.530 回答
-1

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

在这里您可以找到sizeof()使用示例。

当您尝试这样做sizeof(array_ptr)时,它实际上是给您指针的大小

因此,您必须将数组长度作为函数的参数传递

于 2013-03-19T08:30:39.010 回答