今天,我在使用C语言时遇到了一个奇怪的问题,我无法理解背后的原因。
如果我有一个这样的函数(假设32位架构):
void printSize(char array[6]) {
printf("%zd\n", sizeof array);
}我将返回4,这是指针的大小。我期望得到6,这是在函数原型中显式声明的大小。
我知道数组是通过引用传递的,底层类型是一个指针。我假设将数组的长度放在原型中将为编译器提供返回6所需的信息。
为什么C要这样做?此外,如果编译器甚至不能执行sizeof(),返回该大小,那么在原型中放置一个大小的意义是什么?
发布于 2019-12-20 02:08:45
您观察到的行为是由C standard强制执行的。第6.7.6.3p7节关于“函数声明符”的声明:
将参数声明为‘’类型‘’的数组应调整为‘’指向类型‘’的限定指针‘’,其中类型限定符(如果有)是在和数组类型派生中指定的那些限定符。如果关键字static也出现在数组类型派生的和中,则对于函数的每次调用,相应的实际参数的值应提供对数组的第一个元素的访问,该元素的数量至少与size表达式指定的元素数量相同。
所以编译器这样做的原因是因为标准规定他们必须这样做。此外,从实用的角度来看,这意味着您不能将实际的指针传递给这样的函数。考虑将一个数组传递给一个参数类型为int *的函数,然后再传递给一个参数类型为int [5]的函数,或者一个动态分配的数组,即int *arr = malloc(5 * sizeof(int));
另外,请注意,这只适用于多维数组的第一个维度。这意味着:
void foo(int arr[4][5])等同于
void foo(int (*arr)[5])但不是:
void foo(int **arr)发布于 2019-12-20 02:09:30
数组不是“按引用传递”的。C中没有任何东西是“通过引用传递”的。所有的东西都是通过值传递的。
当数组作为参数“传递”给函数时,它会衰减为指向数组第一个元素的指针。
因此,sizeof array返回4 (字节),因为这就是你的实现中指针的大小。
允许您声明数组参数大小的功能主要用于文档。如果你看到一个函数原型,比如void printSize(char array[6]);,你可以假设这个函数只会访问数组的第一个6元素,尽管这个函数不需要严格遵守这一点(如果不严格遵守,编译器也不会抱怨)。
https://stackoverflow.com/questions/59414711
复制相似问题