sizeof操作员解释

时间:2011-08-09 11:11:12

标签: c

这是一个C代码段

char *p="Hello World";
int a;
char b;
printf("%d\n",sizeof(p++));
printf("%c\n",*p);

printf("%d",sizeof(a,b));
printf("%d",sizeof(b,a));

这是输出

4
H
1
4

任何人都可以解释为什么p没有增加,这里使用逗号运算符是什么。我读到它与VLA有关。

2 个答案:

答案 0 :(得分:10)

p没有增加,因为sizeof不评估其操作数,它只使用表达式的类型。

sizeof是一个运算符,它将一个表达式作为其操作数,不是一个带括号的参数列表。因此,在sizeof(a,b)中,单个操作数为(a,b)。因此sizeof(a,b)中的逗号是逗号运算符 - 与printf("%c\n", *p)中的逗号不同,它是参数分隔符而不是逗号运算符。

评估时,逗号运算符首先计算其左侧,然后计算右侧。操作员的结果是右侧的结果。因此,虽然未评估(a,b),但表达式的类型是右侧的类型。因此sizeof(a,b)相当于sizeof(b)。真的,这里没有“使用”逗号运算符,至少没有用处。除了测试你阅读它的能力之外,这是毫无意义的。

它与VLA(可变长度数组)无关。

与VLA有什么关系,当sizeof应用于VLA时, 被定义为评估表达式(C99中的6.5.3.4/2)。 VLA的大小当然在编译时是不知道的。

但是,当在逗号运算符的RHS上使用时,VLA的名称就像任何其他数组一样衰减到指针。这是6.3.2.1/3:有三种情况,数组不会衰减,“sizeof的操作数”是其中之一,但“逗号运算符的RHS”不是。所以:

#include <stdio.h>
int main() {
    int a = 10;
    int b[a]; // VLA
    const char *p = "Hello";
    printf("%d\n", sizeof(++p, b));
    printf("%d\n", sizeof b);
    printf("%c", *p);
}

打印(在我的机器上):

4
40
H

因为在第一个sizeof中,即使逗号运算符的RHS上有VLA,sizeof的操作数类型也是int*,而不是VLA,所以(++p, b)未被评估。在第二个sizeof中,操作数的类型是VLA, 被评估,其大小为10*sizeof(int)

答案 1 :(得分:1)

sizeof运算符是一个编译器函数(例如,在编译时计算为常量)。

  1. 这意味着:忽略p ++,只使用p的类型。
  2. 当有逗号时,使用最后一个参数(例如,sizeof(a,b)就像sizeof(b)