sizeof float数组,结果不同,有什么解决方法吗?

时间:2016-02-06 15:07:51

标签: c arrays function

我目前正在创建一个具有固定大小的float数组作为输入的函数:

char foo(float fArr[3]) {
}

在我调用该函数之前,我测试了float数组输入的大小。

float fArr[3];
int s = sizeof(fArr);
char result;
result = foo(fArr);

这给了我s=12

但是当我试图在函数本身中移动检查时:

char foo(float fArr[3]) {
    int s = sizeof(fArr);
    //do something
}

但这给了我s=4

我在这里有两个问题:

  1. 为什么会这样?

  2. 我想要的是检查用户是否给出了足够大小的float数组。有没有办法通过函数本身的签名强制执行此操作,而无需来自调用者的其他信息?

  3. 例如,我们可以使签名具有其他信息:

    char foo(float *fArr, int size_fArr);
    

    然后我们称之为

    float fArr[3];
    char result;
    result = foo(fArr, sizeof(fArr));
    

    但是如果可能的话,我希望通过使用函数签名来避免这种情况,而无需来自调用者的其他信息,例如sizeof(fArr)

2 个答案:

答案 0 :(得分:3)

您不能让编译器以这种方式验证大小:char foo(float fArr[3])。 编译器将其解释为char foo(float *fArr)并完全忽略指定的数组元素的数量。在函数体中,sizeof(fArr)计算指针的大小,在您的体系结构上为4个字节。

您在问题中提到的替代方案是可能的,尽管指定元素的数量而不是指针参数指向的数组的字节大小更为惯用。你会以这种方式传递这些信息:

float fArr[3];
char result;
result = foo(fArr, sizeof(fArr) / sizeof(fArr[0]));

在C99中,为您的目的提供了扩展语法:

char foo(float fArr[static 3]) { ... }

这指定fArr是指向至少3 float s的数组的指针。请注意,sizeof(fArr)仍然是函数内指针的大小。这是一个例子:

#include <stdio.h>

int size(float arr[static 3]) {
    return sizeof(arr);
}

int main(void) {
    float arr1;
    float arr2[2];
    float arr3[3];
    float arr4[4];
    float *arr2p = arr2;

    printf("size(arr1) = %d\n", size(&arr1));
    printf("size(arr2) = %d\n", size(arr2));
    printf("size(arr2p) = %d\n", size(arr2p));
    printf("size(arr3) = %d\n", size(arr3));
    printf("size(arr4) = %d\n", size(arr4));

    return 0;
}

使用clang -std=c99进行编译会生成以下诊断信息:

arrsta.c:4:22: warning: sizeof on array function parameter will return size of 'float *' instead of 'float[static 3]' [-Wsizeof-array-argument]
        return sizeof(arr);
                      ^
arrsta.c:3:20: note: declared here
    int size(float arr[static 3]) {
                   ^
arrsta.c:15:37: warning: array argument is too small; contains 2 elements, callee requires at least 3 [-Warray-bounds]
        printf("size(arr2) = %d\n", size(arr2));
                                    ^    ~~~~
arrsta.c:3:20: note: callee declares array parameter as static here
    int size(float arr[static 3]) {
                   ^  ~~~~~~~~~~
2 warnings generated.

正如你所看到的,如果给你一个关于潜在sizeof(arr)混淆的有用警告,如果你传递一个太短的数组就会抱怨,但是如果你传递一个指针则不会,即使这个指针也是如此显然没有指向足够大小的数组。不完美,但总比没有好。

答案 1 :(得分:1)

由于

char foo(float fArr[3]){ }

转换为

char foo(float * fArr) { }