【问题标题】:Why the size of array is calculated incorrectly when done from inside a function?为什么从函数内部计算数组的大小不正确?
【发布时间】:2021-04-10 00:04:09
【问题描述】:

当我在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

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

【问题讨论】:

    标签: arrays c function pointers sizeof


    【解决方案1】:

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

    所以,如果

    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 章

    除非它是sizeof 运算符、_Alignof 运算符或一元&amp; 运算符的操作数,或者是用于初始化数组的字符串字面量,一个具有 类型的表达式' 类型的数组被转换为类型为 'pointer to type' 的表达式,它指向数组对象的初始元素并且不是左值。 [....]

    【讨论】:

    • 这是否意味着main() 中的sizeof(arr) 正在计算完整数组的大小。我的意思是arr 也是指向数组第一个元素的指针,所以为什么它没有返回指向int 的指针的大小,就像在sizeof(int*) 中所做的那样。
    • @Neeraj-Kumar-Coder 不,请注意“像许多其他情况一样”部分,它不是“总是”。我将扩大答案以澄清。
    • 我明白你的意思并理解错误输出的原因。但请清楚我arr 是指向数组第一个元素的指针(如在main() 函数中)那么为什么sizeof(arr) 不返回8 bytes,这是指向int 的指针的大小.
    • 你读过最新的编辑吗?它特别说明了 except 场景,sizeof 运营商就是其中之一。
    猜你喜欢
    • 1970-01-01
    • 2017-04-29
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    • 2013-12-12
    • 1970-01-01
    • 1970-01-01
    • 2012-03-18
    相关资源
    最近更新 更多