C 当我以数组名作为参数调用函数时会发生什么?
我正在阅读K&R的TCPL,当我阅读有关数组和指针的内容时,我在下面编写了以下小代码:C 当我以数组名作为参数调用函数时会发生什么?,c,arrays,function,pointers,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]; } retu
#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;
}
#包括
整数和(整数a[]
{
int t=0;
int length=sizeof(a)/sizeof(a[0]);
//printf(“%d\n”,长度);
for(int i=0;i!=length;++i)
{
t+=a[i];
}
返回t;
}
int main()
{
int b[5]={1,2,3,4,5};
printf(“%d\n”,和(b));
返回0;
}
输出答案是1而不是15,然后我通过添加printf(“%d\n”,length)调试此代码代码>输出长度为1而不是5。
TCPL告诉我们,当数组名用作参数时,数组名会转换为指针,但输出答案是错误的,所以我想知道:
使用数组名作为参数调用函数时会发生什么
sum(int a[])
中使用的数组a[]
参数是否有存储
我在调用数组时看到两种样式:fun(inta[]);fun(b)
和fun(int*a);乐趣(b)
,有什么区别
非常感谢:-)您不能调用函数并传递整个数组;如果使用数组名作为函数参数,它将被隐式重写为指向其第一个元素的指针(“decays to”)。这相当于写作
int sum(int *a) { ... }
因此,在函数中,sizeof array
,不提供数组的大小,只提供指向其第一个元素的指针的大小
那么如何知道数组中有多少个元素呢?您需要将这个数字显式地传递给函数(或者定义一个包含元素数量的宏,并在需要时使用它)。您不能调用函数并传递整个数组;如果使用数组名作为函数参数,它将被隐式重写为指向其第一个元素的指针(“decays to”)。这相当于写作
int sum(int *a) { ... }
因此,在函数中,sizeof array
,不提供数组的大小,只提供指向其第一个元素的指针的大小
那么如何知道数组中有多少个元素呢?您需要将这个数字显式地传递给函数(或者用元素的数量定义一个宏,并在需要时使用它)。在声明如下的数组上调用sizeof
int a[5];
将以您当前认为的方式返回数组的大小(即以字节为单位的数组的完整大小-在我的机器上为20字节)。当您将这样的数组传递给函数时,该数组将衰减为指向其第一个元素的指针。因此,当您在函数参数上调用sizeof
时,实际上是在指针上调用它。如果您将函数声明为接受int*
参数,那么错误会更明显,因为您调用的sizeof
变量的类型是显式的 在声明如下的数组上调用sizeof
int a[5];
将以您当前认为的方式返回数组的大小(即以字节为单位的数组的完整大小-在我的机器上为20字节)。当您将这样的数组传递给函数时,该数组将衰减为指向其第一个元素的指针。因此,当您在函数参数上调用sizeof
时,实际上是在指针上调用它。如果您将函数声明为接受int*
参数,那么错误会更明显,因为您调用的sizeof
变量的类型是显式的 您的第三个问题触及了问题的核心:就编译器而言,这两个问题没有区别。关于论点是如何传递的,一切都是一样的
因此,在回答第二个问题时,a
参数没有底层数组的存储,也没有复制该数组的成员。唯一分配给int*
指针的存储,该指针存储在a
中。(这也多少回答了你的第一个问题。)
因此,在您的功能中:
int length = sizeof(a) / sizeof(a[0]) ;
相当于
int length = sizeof(int *) / sizeof(int);
在指针和整数大小相同的系统上返回1。如果你在64位Linux上运行这个程序,你会得到2,因为指针是64位的,整数是32位的。你的第三个问题触及了问题的核心:就编译器而言,这两者之间没有区别。关于论点是如何传递的,一切都是一样的
因此,在回答第二个问题时,a
参数没有底层数组的存储,也没有复制该数组的成员。唯一分配给int*
指针的存储,该指针存储在a
中。(这也多少回答了你的第一个问题。)
因此,在您的功能中:
int length = sizeof(a) / sizeof(a[0]) ;
相当于
int length = sizeof(int *) / sizeof(int);
在指针和整数大小相同的系统上返回1。如果您在64位Linux上运行此函数,您将得到2,因为指针是64位的,int是32位的。您的调用没有问题,而且fun(int a[])
和fun(int*a)
之间没有区别(读者更清楚地看到,您需要的是数组,而不是任何指针)。Bot参数是指向int的指针
这里的问题是如何确定数组的长度。由于方括号是空的,编译器无法知道a
后面的数组有多长。例如,可以将数组的长度作为第二个参数提供。注意:调用函数时,sizeof(b)
将提供正确的长度,因为编译器知道它的长度。您的调用没有问题,fun(int a[])
和fun(int*a)
(读者应该更清楚地看到,您需要的是数组而不是任何指针)。Bot参数是指向int的指针
你这里的问题是你如何决定