计算函数内的数组大小

以下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) { ... }