我正在阅读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告诉数组名称在数组名称用作参数时转换为指针,但输出答案是错误的,所以我想知道:
a[]
中使用的数组sum(int a[])
参数是否有存储空间?fun(int a[]); fun(b)
和fun(int *a);fun(b)
,有什么区别?非常感谢: - )
答案 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)
时,实际上会为您指定指针大小。
因此,您必须将数组长度作为函数
的参数传递