以下C程序:
int doStuff(int afm[]);
int main(){
int afm1[9] = {1,2,3,4,5,6,7,8,9}; //size=9
int afmLength = sizeof(afm1)/sizeof(int);
printf("main: Length Of Array=%d\n", afmLength); //9 OK
int k = doStuff(afm1);
system("PAUSE");
return 0;
}
int doStuff(int afm[]){
int afmLength = sizeof(afm)/sizeof(int);
printf("doStuff: Length Of Array=%d\n", afmLength); //1 WRONG
return 1;
}
产生以下输出:
main: Length Of Array=9
doStuff: Length Of Array=1
为什么在main中正确计算数组大小,但在函数内部是错误的?
答案 0 :(得分:7)
因为在main
中你有一个数组并且在函数中你有一个指向该数组的指针。
int doStuff(int afm[])
相当于
int doStuff(int *afm)
答案 1 :(得分:2)
添加David Heffernan的答案(这是正确的),您应该有另一个参数,即传递到doStuff
方法的数组长度。
答案 2 :(得分:0)
来自C语言标准(草案n1256):
6.3.2.1左值,数组和函数指示符
...
3除非它是sizeof
运算符或一元&
运算符的操作数,或者是 用于初始化数组的字符串文字,类型为''数组 type ''的表达式是 转换为类型为''指向 type '的指针的表达式,指向的初始元素 数组对象并不是左值。如果数组对象有寄存器存储类,则 行为未定义。
记住那段,因为C编程中最大的胃灼热源之一是C如何处理数组表达式。
当你调用doStuff(afm1);
时,表达式afm1
被隐式转换为“{-1}}的9元素数组”到“指向int
的指针”,表达式为值与int
相同。那么&afm1[0]
接收的是指针值,而不是数组。
在函数参数声明的上下文中,doStuff
和T a[]
都被解释为T a[N]
:
6.7.5.3函数声明符(包括原型)
...
7参数声明为“ type ”的数组应调整为''限定指针 输入'',其中类型限定符(如果有)是在T *a
和[
内指定的类型限定符。 数组类型推导。如果关键字]
也出现在static
和[
内 数组类型派生,然后对每个函数调用,对应的值 实际参数应提供对至少具有至少数量的数组的第一个元素的访问 size表达式指定的元素。
由于]
收到指针值而不是数组,因此doStuff
技巧不起作用。通常,您必须明确告诉函数您传递给它的数组有多大;你无法从指针值本身确定。
因此,当您从sizeof
致电doStuff
时,您需要执行类似
main