为什么从函数内部完成时数组的大小计算不正确?

Why the size of array is calculated incorrectly when done from inside a function?

当我在 main() 函数中使用此代码时,数组的大小(或长度)计算正确:

#include <stdio.h>

int main(void)
{
    int arr[] = {2, 5, 9, 8, 4, 5, 1, 2, 8, 5};
    int length = sizeof(arr) / sizeof(arr[0]);
    printf("The number of elements in the array is %d\n", length);
    return 0;
}

输出:

The number of elements in the array is 10

但是当我用一个函数做同样的事情时,输出是错误的:

#include <stdio.h>

int sizeTeller(int array[]);

int main(void)
{
    int arr[] = {2, 5, 9, 8, 4, 5, 1, 2, 8, 5};
    printf("The number of elements in the array is %d\n", sizeTeller(arr));
    return 0;
}

int sizeTeller(int array[])
{
    int len;
    return (len = sizeof(array) / sizeof(array[0]));
}

输出:

The number of elements in the array is 2

你能给我解释一下为什么会这样吗?我更喜欢将所有代码保留在函数中,这就是为什么我在这里尝试相同但输出出错的原因。

这是因为,与许多其他情况一样注意,当数组作为函数参数传递时,它们衰减到指向数组第一个元素的指针。因此,在被调用的函数中,接收到的参数类型是指针,而不是数组。

所以,如果

int sizeTeller(int array[])
{
    int len;
    return (len = sizeof(array) / sizeof(array[0]));
}

等同于

int sizeTeller(int* array)
{
    int len;
    return (len = sizeof(array) / sizeof(array[0]));  // sizeof (int *) / sizeof (int)
}

解决方法:如果你需要传递一个数组作为函数参数,并且需要知道它的大小,你需要在调用者中计算大小并将其作为另一个传递被调用函数的参数。


注意:

引用 C11,章节 6.3.2.1/P3

Except when it is the operand of the sizeof operator, the _Alignof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type 'array of type' is converted to an expression with type 'pointer to type' that points to the initial element of the array object and is not an lvalue. [....]