【问题标题】:Using sizeof() on an array passed to a function [duplicate]在传递给函数的数组上使用 sizeof() [重复]
【发布时间】:2014-11-24 00:41:37
【问题描述】:

我有一个关于 C sizeof() 函数的简短问题。我将一个数组传递给一个函数,在该函数内部,我想检查数组的大小。然而,不管输入数组的大小,在函数内部,它似乎总是大小为 4。例如:

void checkArraySize(char data[])
{
    int internalSize = sizeof(data); //internalSize is reported as 4
}

void main(void)
{
    char data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
    int externalSize = sizeof(data); //externalSize is reported as 8

    checkArraySize(data);                                             
}

作为代码状态的cmets,在调用checkArraySize()这样的函数之前,我检查了数组的大小,结果显示为8。但是,当我在函数内部检查数组的大小时,它只报告为有 4 个元素(无论输入数组的大小如何,它都会报告 4 个元素)。

当我看到这样的问题时,通常是因为我对该主题的理解存在差距。所以,我确定我只是错过了传递数组的工作原理。如果没有,有什么想法为什么会发生这种情况?

注意:这是在 PIC32 上,所以我使用的是 Microchip 的 MPLAB X IDE 和 XC32 编译器。

【问题讨论】:

  • 顺便说一句:sizeof 不是函数,而是运算符。这就是为什么你可以在类型(使用括号)和表达式(不需要括号)上使用它。除非它是可变修改的类型,否则不会计算参数,因此结果是编译时常量表达式。 (如果你没有说你在嵌入式系统上,我会建议你 main 总是返回 int。不过,在独立环境中事情更加多样化。)

标签: c arrays function pic32


【解决方案1】:
void checkArraySize(char data[])

将被翻译成

void checkArraySize(char* data)

因此,代码计算指针的大小。 4 是您计算机中的指针大小。 在 64 位系统中,它会输出 8。

【讨论】:

    【解决方案2】:

    C 中的数组总是通过引用传递。这就是为什么你每次都得到指针大小,而不是实际大小。

    要在 C 中使用数组作为参数,您应该使用数组传递数组的大小。

    我将你的程序修改为工作状态:

    typedef unsigned char BYTE;
    
    void checkArraySize(BYTE data[], int sizeOfArray)
    {
        int internalSize = sizeOfArray;   
        printf("%d", internalSize );                  
    }
    
    void main(void)
    {
        BYTE data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
        int externalSize = sizeof(data)/sizeof(BYTE);                   //it would return number of elements in array
    
        checkArraySize(data, externalSize);                                             
    }
    

    通过引用表示仅发送数组第一个元素的地址。如果您在函数 checkArraySize 内更改任何内容,此更改也会反映到原始数组。检查上面修改的例子。

    typedef unsigned char BYTE;
    
    void checkArraySize(BYTE data[])
    {
        int internalSize = sizeof(data);   
        printf("%d\n", internalSize );     
        data[3]=  0x02;             //internalSize is reported as 4
    }
    
    void main(void)
    {
        BYTE data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
        int externalSize = sizeof(data);                   //externalSize is reported as 8
        printf("Value before calling function: 0x%x\n",data[3]);
        checkArraySize(data);  
        printf("Value after calling function: 0x%x\n",data[3]);
    }
    

    输出将是:

    Value before calling function: 0x4
    4
    Value after calling function: 0x2
    

    【讨论】:

    • 引用传递?
    • @tristan 通过引用传递在这里只发送数组第一个元素的地址。如果您甚至在函数 checkArraySize 内更改任何内容,此更改也会反映到原始数组。我在答案中添加了示例。
    • C 没有“参考”。它的数组衰减到我认为的指针。
    【解决方案3】:

    数组在 C 和 C++ 中是不可复制的。因此,这些语言的发明者不得不在他们的第一个元素上添加一些从数组到指针的非直观的自动类型转换,以便为程序员提供一种将数组作为参数传递给函数的方法。

    在此类参数上使用 sizeof 运算符(不是函数)返回指针类型的大小而不是数据大小。

    额外的美分 sizeof 运算符在编译而不是运行时扩展。从另一端传递给函数的数组可能有不同的大小。所以将这样的数组转换为指针还有另一种解释:sizeof 在编译时无法解析不同数组的大小。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-26
      • 2014-01-10
      • 1970-01-01
      • 2017-05-28
      • 1970-01-01
      • 1970-01-01
      • 2020-07-28
      相关资源
      最近更新 更多