【问题标题】:Miscalculation of array size inside a function函数内部数组大小计算错误
【发布时间】:2011-02-10 18:53:52
【问题描述】:

以下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中计算的数组大小正确,而在函数内部却是错误的?

【问题讨论】:

    标签: c arrays


    【解决方案1】:

    因为在main 中有一个数组,而在函数中有一个指向该数组的指针。

    int doStuff(int afm[])
    

    等价于

    int doStuff(int *afm)
    

    【讨论】:

    • 谢谢大卫。我应该写什么呢?
    • Argote 的回答告诉你。函数doStuff 没有关于数组长度的信息。您需要将该信息连同指向数组的指针一起传递给函数。
    【解决方案2】:

    除了 David Heffernan 的回答(这是正确的)之外,您还应该有另一个参数,即传递给您的 doStuff 方法的数组长度。

    【讨论】:

    • +1 我将“size”更改为“length”,因为使用长度比使用尺寸更正常(我相信这就是您的意思)。
    【解决方案3】:

    来自 C 语言标准(草案n1256):

    6.3.2.1 左值、数组和函数指示符
    ...
    3 除非它是sizeof 运算符或一元& 运算符的操作数,或者是 用于初始化数组的字符串字面量,类型为“array of type”的表达式是 转换为类型为“pointer to type”的表达式,它指向 数组对象并且不是左值。如果数组对象有寄存器存储类,则 行为未定义。

    记住那段话,因为 C 编程中胃灼热的最大来源之一是 C 如何处理数组表达式。

    调用doStuff(afm1);时,表达式afm1隐式从“int的9元素数组”类型转换为“指向int的指针”,表达式的值与&afm1[0]相同.所以doStuff 接收的是一个指针值,而不是一个数组。

    在函数参数声明的上下文中,T a[]T a[N] 都被解释为 T *a

    6.7.5.3 函数声明符(包括原型)
    ...
    7 将参数声明为“type 数组”应调整为“qualified pointer to type'',其中类型限定符(如果有)是在 [] 的 数组类型推导。如果关键字static 也出现在[] 的 数组类型推导,然后对函数的每次调用,对应的值 实际参数应提供对数组的第一个元素的访问,其中至少有 由 size 表达式指定的元素。

    由于doStuff 接收一个指针 值而不是一个数组,sizeof 技巧不起作用。通常,您必须明确告诉函数您要传递给它的数组有多大;您无法从指针值本身确定。

    因此,当您从 main 呼叫 doStuff 时,您需要执行类似的操作

    doStuff(afm1, sizeof afm1/sizeof *afm1);
    ...
    int doStuff(int *afm, size_t afmsize)
    {
      ...
    }
    

    【讨论】:

      猜你喜欢
      • 2017-04-29
      • 2021-04-10
      • 2023-02-17
      • 1970-01-01
      • 1970-01-01
      • 2010-10-17
      • 1970-01-01
      • 2015-06-08
      相关资源
      最近更新 更多