长度已知的数组术语C / C ++

时间:2015-05-02 09:29:19

标签: c

在C中,您可以在已知长度的结构中本地定义数组。

例如:

{
    int foo[8];
    assert(sizeof(foo) == sizeof(int[8]));
    ...

在结构中使用时,数组大小也是已知的。

struct MyStruct { int foo[8]; };
void func(struct MyStruct *mystruct)
{
    assert(sizeof(mystruct->foo) == sizeof(int[8]));

但是,当作为函数的参数传递时,这相当于int *

void func(int foo[8])
{
    assert(sizeof(foo) == sizeof(int[8]));  /* will fail */

这当然是正确的,并且可以预料,我的问题是 - 在提到差异时使用的术语是什么?

例如,这条评论的正确完成是什么?

/* This macro will only work correctly when ____ */
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))

4 个答案:

答案 0 :(得分:4)

正如你所说,在C中,指向数组的指针被传递给一个函数,因此你无法使用sizeof运算符找到它的大小。

评论开头是错误的,应该是:

/* This macro will only work correctly if 'a' is an array type */

答案 1 :(得分:2)

传递给函数时,衰减转换为指针。评论可能是:

/* This macro will only work correctly when the array is not decayed */

答案 2 :(得分:2)

函数参数不能包含数组类型。声明

void func(int foo[8])

只是

的语法糖
void func(int *foo)

丢弃任何大小的信息(声明int foo[static 8]除外) - 类型仍将调整为int*,但编译器可能会将大小信息用于优化目的。)

请注意,除了静态已知大小的数组外,还有动态大小的可变长度数组和未知大小的不完整数组。后者只能出现在外部声明中(因为存储要求未知)或在结构中作为灵活的数组成员出现。

对于可变长度数组,必须在运行时计算sizeof,如果数组不完整,则应该无法编译。

因此,如果您想要具体,您的评论可以写成:

  

这个宏只有在' a'有完整的数组类型   特别是不是函数参数,因为它们具有指针类型。

答案 3 :(得分:1)

/ *这个宏只有在" a"是一个完整的类型数组 * /

因为您不能将sizeof用于不完整的类型:

struct T {
    int a;
    int arr[]; /* Flexible array */
};

int main(void)
{
    struct T x;

    /* invalid application of ‘sizeof’ to incomplete type ‘int[]’ */    
    printf("%zu\n", ARRAY_SIZE(x.arr)); 
    return 0;
}