【问题标题】:Why does a C-Array have a wrong sizeof() value when it's passed to a function? [duplicate]为什么将 C-Array 传递给函数时 sizeof() 值错误? [复制]
【发布时间】:2011-02-26 09:05:01
【问题描述】:

完整示例:

#include <stdio.h>

void test(int arr[]) {
    int arrSize = (int)(sizeof(arr) / sizeof(arr[0]));
    printf("%d\n", arrSize); // 2 (wrong?!)
}

int main (int argc, const char * argv[]) {
    int point[3] = {50, 30, 12};

    int arrSize = (int)(sizeof(point) / sizeof(point[0]));
    printf("%d\n", arrSize); // 3 (correct :-) )

    test(point);

    return 0;
}

在将它传递给函数之前, sizeof 给了我正确的值。对函数中完全相同的数组执行完全相同的操作会产生奇怪的结果。少了一个元素。为什么?

【问题讨论】:

    标签: c arrays function sizeof


    【解决方案1】:

    因为在 C、C++ 和 Objective-C 中,函数实际上不能有数组参数。它们只能具有看起来像数组参数的参数,但它们不是。在你的例子中,

    void test(int arr[])
    

    编译器看到“有一个参数看起来像一个 int 数组”,并将该参数替换为“指向 int 的指针”。所以你写的函数绝对百分百与

    void test (int* arr)
    

    因此,在函数 sizeof (arr) 内部会给你一个“指向 int 的指针”的大小。

    【讨论】:

      【解决方案2】:

      此外,了解sizeof编译时 进行评估也很重要。既然是这种情况,根据传入的内容来期望 test() 中的不同输出是没有意义的。sizeof 计算是在编译函数时完成的。

      【讨论】:

        【解决方案3】:

        当您将数组传递给 C 中的函数时,数组衰减为指向其第一个元素的指针。当您在参数上使用sizeof 时,您获取的是指针的大小,而不是数组本身。

        如果你需要函数知道数组的大小,你应该把它作为一个单独的参数传递:

        void test(int arr[], size_t elems) {
           /* ... */
        }
        
        int main(int argc, const char * argv[]) {
           int point[3] = {50, 30, 12};
           /* ... */
           test(point, sizeof(point)/sizeof(point[0]));
           /* ... */
        }
        

        还要注意,出于类似的原因(将sizeof 用作指针),sizeof(point)/sizeof(point[0]) 技巧不适用于动态分配的数组,仅适用于堆栈上分配的数组。

        【讨论】:

          【解决方案4】:

          因为数组在作为函数参数传递时是指向指针的 decayed,所以 sizeof 分别为 32 位和 64 位平台提供 4 和 8。

          【讨论】:

            【解决方案5】:

            因为 sizeof() 不会告诉你 C 中数组的大小。它做的事情完全不同。

            sizeof C++ reference

            【讨论】:

            • 如果你仔细看过这个例子,你会发现我没有使用 sizeof 来直接获取数组中的元素个数... sizeof 应该告诉我有多少内存为数组保留......实际上,当元素的大小已知时,它应该与其中的元素数量相匹配。还是我错过了什么?
            • 我的立场是正确的。但如上所述,要小心指针。他们告诉你它们的大小,而不是你指向的类型的大小。
            【解决方案6】:

            因为,当它被传递时,实际上只有指向数组的指针被传递。

            The C Programming FAQ 也回答了您的问题。问题 6.21。

            【讨论】:

            • 要挑剔:它是指向传递的数组的第一个元素的指针。值相同,但类型不同。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-02-04
            • 1970-01-01
            • 2018-01-20
            • 1970-01-01
            • 2020-11-16
            • 1970-01-01
            相关资源
            最近更新 更多