在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]))
答案 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;
}