sizeof操作员解释

Ati*_*hay 0 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));
Run Code Online (Sandbox Code Playgroud)

这是输出

4
H
1
4
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*sop 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);
}
Run Code Online (Sandbox Code Playgroud)

打印(在我的机器上):

4
40
H
Run Code Online (Sandbox Code Playgroud)

因为首先sizeof,即使是在逗号操作符的RHS一VLA,操作数的类型sizeof就是int*,不是VLA,所以(++p, b)不计算.在第二种情况下sizeof,操作数的类型是VLA,它评估,其大小为10*sizeof(int).

  • @Lundin:那不是*评估*操作数,只是解析它.我们知道添加`int`和`char`得到的类型是`int`,而不执行添加本身.见6.5.3.4/2(这也指出我需要编辑我的答案......) (3认同)