这是一个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有关。
答案 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
运算符是一个编译器函数(例如,在编译时计算为常量)。
sizeof(a,b)
就像sizeof(b)
)