为什么sizeof(param_array)是指针的大小?

我想获得一个数组的长度,例如int array[] = {1, 2, 3, 4} 。 我用sizeof来做到这一点。

 int length(int array[]) { return sizeof(array) / sizeof(int); } int main() { int array[] = {1, 2, 3, 4}; printf("%d\n", length(array)); // print 1 printf("%d\n", sizeof(array) / sizeof(int)); // print 4 } 

那么,为什么函数lengthsizeof(array)返回array的指针大小呢? 但在functionmain ,它的作品。

而且,我应该如何修改length函数来获得数组的长度?

一个特殊的C规则说,对于函数参数,数组types被调整为指针types。 这意味着:

int length(int array[]);

相当于

int length(int *array);

所以当你计算数组的大小时,实际上是在计算指针的大小。

(C99,6.7.5.3p7)“将参数声明为”数组types“应该被调整为”合格的指向types的指针“,其中types限定符(如果有的话)是在数组[和]内指定的types推导“。

将数组传递给函数时,数组会衰减为指针。

正如其他answerers已经注意到,一个函数声明采取一个数组编译相同,如果它拿一个指针。

我所见过的最常用的方法是使用#define,但是如果使用模板玩技巧,则可以使您的函数正常工作。

 template <size_t _Size> inline int length(int(& array)[_Size]) { //return sizeof(array) / sizeof(int); return _Size; }; int array[] = {1, 2, 3, 4}; printf("%d\n", length(array)); // print 4 

对于长度为4的数组,这将被编译为一个长度为4的数组,并且返回一个静态4的方法。这也有一个好处,如果您尝试传递不是数组的东西,编译器会给一个错误,而#define方法不。

 int* foo = array; printf("%d\n", length(foo)); // error C2784: 'int length(int (&)[_Size])' : could not deduce template // argument for 'int (&)[_Size]' from 'int *' // test.cpp(56) : see declaration of 'length' 

在主程序中,编译器知道数组的长度。 在子程序中,它不是。 特别是在子程序中, int[]types的参数与int *types的参数相同。 另一方面,在主程序中, arraytypes为int[4] 。 (你可以通过尝试在side mainarray赋值另一个值来进行testing,编译器会报错)

C不存储有关variables的数组大小的运行时元数据。 你将不得不把它存储在某个地方。

在方法长度的上下文中,types为int []的variables只是一个指向内存块的指针。 这就是为什么大小与系统上任何其他指针的大小相同的原因。

sizeof在编译时访问数组(就像在你的main函数中一样),它将返回数组占用的字节数。

如果你想要知道传递的数组的真实大小,那么必须像大家所说的那样传递这些信息。 但是它也可以通过内置的信息来获得对数组的引用:

 int length(int n, int (* array)[n]) { return sizeof(*array) / sizeof(int); } int main() { int array[] = {1, 2, 3, 4}; printf("%d\n", length(4, &array)); // print 1 printf("%d\n", sizeof(array) / sizeof(int)); // print 4 } 

但是,我不知道你究竟有多好,因为这个尺寸已经提供了。 但是在这种情况下,您会发现sizeof操作符正如您所希望的那样工作。

因为内部长度可变的数组与外部不一样。 你必须在main函数中保存sizeof(array)/ sizeof(int)。

要修改你的代码,使length可以得到数组的长度,把它变成一个macros:

 #define length(x) (sizeof(x)/sizeof(*x)) 

对于你的代码示例,这将会像你期望的一样。

请注意,这只会在静态分配的数组上工作,并且只在使用原始数组进行调用时(使用指向数组的指针时不起作用)。 这是因为当你编写sizeof(x) ,其中x是一个指向数组的指针时,编译器将从字面上解释它。 在评估sizeof之前,它没有任何方法将x映射回它指向的数组。