我有一个关于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);
}
作为代码状态中的注释,在我调用像checkArraySize()这样的函数之前,我检查了数组的大小,它显示为8。但是,当我检查函数内部数组的大小时,它只报告有4个元素(无论输入数组的大小,它都报告4个元素)。
很多时候,当我看到这样的问题时,那是因为我对这个主题的理解存在着差距。所以,我肯定我遗漏了一些传递数组的工作原理。若否,有何想法解释为何会出现这种情况?
注意:这是在PIC32上,所以我使用的是Microchip的MPLAB X IDE和XC32编译器。
数组始终通过引用传递。这就是为什么每次都得到指针大小,而不是实际大小的原因。
若要在C语言中使用array作为参数,应将size of array与array一起传递。
我把你的程序修改成工作状态:
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
void checkArraySize(char data[])
将被翻译为
void checkArraySize(char* data)
因此,代码计算指针的大小。4是计算机中的指针大小。在64位系统中,它将输出8。
数组在C和C++中是不可复制的东西。因此,这些语言的发明者不得不在他们的第一个元素上添加从数组到指针的非直观的自动类型转换,以便为程序员提供一种将数组作为参数传递给函数的方法。
对这样的参数使用sizeof运算符(不是函数)返回指针类型的大小而不是数据大小。
额外的美分sizeof运算符是在编译过程中展开的,而不是在运行时展开的。另一方面,传递给函数的数组可能具有不同的大小。因此,将这些数组转换为指针有另一种解释:sizeof在编译期间无法解析不同数组的大小。