计算函数内的数组大小
以下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中正确计算数组大小,但在函数内部是错误的?
因为在main
你有一个数组,并且在函数中你有一个指向该数组的指针。
int doStuff(int afm[])
相当于
int doStuff(int *afm)
添加David Heffernan的答案(这是正确的),你应该有另一个参数,它是传递给你的doStuff
方法的数组长度。
从C语言标准(草案n1256 ):
6.3.2.1左值,数组和函数指示符
…
3除非它是sizeof
运算符或一元&
运算符的操作数,或者是用于初始化数组的字符串文字,否则将类型为”array of type ”的表达式转换为类型为”指针的表达式键入 ”指向数组对象的初始元素,而不是左值。 如果数组对象具有寄存器存储类,则行为未定义。
记住那段,因为C编程中最大的胃灼热源之一是C如何处理数组表达式。
当你调用doStuff(afm1);
,表达式afm1
隐式地从类型“9-element array of int
”转换为“指向int
”,表达式的值与&afm1[0]
。 所以doStuff
接收的是指针值,而不是数组。
在函数参数声明的上下文中, T a[]
和T a[N]
都被解释为T *a
:
6.7.5.3函数声明符(包括原型)
…
7参数声明为” 类型数组”应调整为”限定指向类型 ”,其中类型限定符(如果有)是在数组类型派生的[
和]
中指定的那些。 如果关键字static
也出现在数组类型派生的[
和]
中,那么对于每次对函数的调用,相应的实际参数的值应该提供对数组的第一个元素的访问,其中元素的数量至少与指定的元素一样多。按大小表达。
由于doStuff
接收指针值而不是数组,因此sizeof
技巧不起作用。 通常,您必须明确告诉函数您传递给它的数组有多大; 你无法从指针值本身确定。
所以,当你从main
调用doStuff
时,你需要做类似的事情
doStuff(afm1, sizeof afm1/sizeof *afm1); ... int doStuff(int *afm, size_t afmsize) { ... }