sizeof表现出乎意料

请考虑以下代码:

#include  int main(void) { int a[10]; printf("%d",(int)sizeof(a)); //prints 10*sizeof(int) (40 on my compiler) printf("%d",(int)sizeof(a-3)); //prints sizeof(int) (4 on my compiler) } 

我知道sizeof()是一个编译时运算符,但我很惊讶地看到第二个printf()的输出。 可能是什么原因? 是否将sizeof()的参数从数组类型隐式转换为整数类型?

sizeof运算符不会计算其参数,只会查看其操作数的类型 。

假设你有一个数组类型为“类型为T的数组[N]”。 然后,在大多数情况下,名称a的类型是“指向T的指针”( T * ),指针的值是数组的第一个元素的地址( &a[0] )。 也就是说,数组的名称“衰减”为指向其第一个元素的指针。 在下列情况下不会发生“腐朽”:

  • a与地址( & )运算符一起使用时,
  • 在a的初始化中(在C中分配给数组是非法的),和
  • asizeof运算符的操作数时。

因此, sizeof a给出Nsizeof(T)

当你执行sizeof(a-3)sizeof的操作数类型由表达式a-3确定。 由于a a-3在值上下文中使用 (即,上述三个上下文中没有一个),因此其类型为“指向int的指针”,并且名称a衰减为指向a[0]的指针。 因此,计算a-3是未定义的行为,但由于sizeof不计算其参数,因此a-3仅用于确定操作数的类型,因此代码正常(请参阅上面的第一个链接以获取更多信息)。

从上面可以看出, sizeof(a-3)相当于sizeof(int *) ,在你的计算机上是4。

“转换”是由减法运算符引起的。 您可以使用逗号运算符查看类似的,也许更令人惊讶的结果:

 printf("%zu\n", sizeof(1, a)); 

还将打印sizeof(int *) ,因为逗号运算符导致在值上下文中使用。

(a-3)类型为int* ,它会在平台上打印sizeof(int*) ,它是4。

请注意, sizeof()在C99中不再是编译时常量(由于可变长度数组)。

不,在第二种情况下,参数被解释为一个int*指针,它的机器上的大小也恰好等于4。

sizeof()返回类型的大小,因此类型是重要的。

它也不应该用%d打印。 至少,明确地将它转换为unsigned longunsigned long long并使用适当的格式说明符。 当教C时,我有一个学生通过打印size_t%d得到了错误的答案,正如教科书错误地说的那样。

无论如何, a是一种数组类型。 在C中,如果你几乎用它们做任何事情或大声打喷嚏,数组类型会衰减为指针类型,所以你对a做的几乎任何事都会产生一个指针类型。 正如您所知,增加或减少数字会衰减。 (毕竟,数组不能用于算术,但指针可以。)