25

我已经读过 C 中的 sizeof 运算符是在编译时解释的,并且由于在编译时编译器知道数组大小及其类型,sizeof 能够计算数组占用的字节数。但是 sizeof 如何为以下代码工作:

 #include<stdio.h>
 #include<string.h>
 int main()
 {
    int n;
    scanf("%d",&n);
    int a[n];
    int s=sizeof(a);
    printf("%d",s);
    return 0;
 }

这里的数组大小在编译时是未知的,那么它是如何正常工作的呢?

4

6 回答 6

28

sizeof在 C89 中总是在编译时计算。由于 C99 和可变长度数组,当可变长度数组是sizeof操作数中表达式的一部分时,它是在运行时计算的。

sizeof操作数的评估也是如此:如果操作数是可变长度数组类型,则在 C89 中不对其进行评估,但在 C99 中对其进行评估。例如:

int n = 5;
sizeof (int [n++]); 

// n is now 6
于 2012-04-09T19:08:14.103 回答
15

由于您正在应用sizeof一个可变长度数组,其大小在编译时并不完全已知,因此编译器必须生成代码以在运行时完成其中的一部分。

gcc 4.6.3 的高级优化器将您显示的代码转换为

scanf ("%d", &n);
t12 = (long unsigned int) n;
t13 = t12 * 4;
__builtin_alloca (t13);
t16 = (unsigned int) t12;
t17 = t16 * 4;
s18 = (int) t17;
printf ("%d", s18);

这是否解释了引擎盖下发生的事情?(不要被看起来很傻的临时变量数量吓到——这是程序在我要求中间代码转储时处于静态单一赋值形式的产物。)

于 2012-04-09T19:09:23.687 回答
8

来自 C99 标准:

6.5.3.4

运算符产生其sizeof操作数的大小(以字节为单位),它可以是表达式或带括号的类型名称。大小由操作数的类型决定。结果是一个整数。如果操作数的类型是变长数组类型,则计算操作数;否则,不计算操作数,结果是一个整数常量。

于 2012-04-09T19:11:54.333 回答
4

在这种情况下,sizeof()在运行时进行评估。编译器,因为它知道 的大小a基于n数组声明时的值,所以生成代码以使用适当的值n来返回 的合理值sizeof()

在 C99 中,并非所有的使用都sizeof()可以在编译时完全评估并简化为运行时常量。

于 2012-04-09T19:06:15.073 回答
2

Regardless of whether sizeof is computed at compile time or runtime (or more formally speaking, whether its result is an integer constant expression), the result of sizeof is purely based on the type of its argument and not any hidden data accompanying the variable-length array itself. Of course when sizeof is applied to a variably-modified type, the generated program must keep track of that size somewhere. But it might simply recompute it if the expression was simple enough and the variables it originally derived the length from cannot have changed. Or, it could store the size of the type somewhere (essentially in a hidden local variable), but this would not be connected to the VLA object in any observable way (for example, if you pass a pointer to the first element of the VLA to another function, that pointer cannot be used to recover the VLA length).

于 2012-04-09T19:25:14.377 回答
2

我已经读过 C 中的 sizeof 运算符在编译时被解释

sizeof除 VLA 外,在所有情况下都在编译时确定。对于 VLA,sizeof在运行时进行评估。

于 2012-04-09T19:08:06.227 回答