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

xia*_*owl 13 c

我想得到一个数组的长度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
}
Run Code Online (Sandbox Code Playgroud)

那么,为什么sizeof(array)in函数length返回指针大小array?但在功能方面main,它确实有效.

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

oua*_*uah 21

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

int length(int array[]);

相当于

int length(int *array);

因此,当您计算sizeof数组时,实际上是在计算指针的大小.

(C99,6.7.5.3p7)"参数声明为"类型数组"应调整为"限定类型的指针",其中类型限定符(如果有)是在数组的[和]内指定的那些类型推导."

  • ...这意味着你不能重写`length()`来按你的意愿工作 - 如果一个函数需要知道一个数组的大小,它需要作为一个单独的参数传递给该函数. (6认同)

tsk*_*zzy 5

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


Dav*_*Yaw 5

正如其他回答者所指出的那样,声明采用数组的函数的编译方式与采用指针的方式相同.

我看过你做长度方法的最常见的方法是使用#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
Run Code Online (Sandbox Code Playgroud)

使用长度为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'
Run Code Online (Sandbox Code Playgroud)

  • 问题标记为C,而不是C ++。 (2认同)