c 中运算符与“后缀递减”和“逻辑与”运算符的关联性

rap*_*Dev 5 c side-effects operator-precedence sequence-points post-increment

免责声明:我不这样编码,我只是想了解c语言是如何工作的!!!!

输出是12。

该表达式(a-- == 10 && a-- == 9)从左到右计算,a 仍然是 10,a-- == 10但 a 是 9 a-- == 9

1)增量后评估的时间是否有明确的规则?从这个例子来看,它似乎在 && 之前但在 == 之后进行评估。是不是因为&&逻辑运算符构成了a-- == 10一个完整的表达式,所以a执行完后就更新了?

2)同样对于c / c ++,某些运算符(例如前缀递减)从右到左发生,因此a == --a首先将a递减到9,然后比较9 == 9。c / c ++这样设计有原因吗?我知道对于 Java,情况正好相反(它从左到右计算)。

#include <stdio.h>

int main() {
    int a = 10;
    if (a-- == 10 && a-- == 9)
        printf("1");
    a = 10;
    if (a == --a)
        printf("2");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

dbu*_*ush 3

逻辑&&运算符包含第一个操作数和第二个操作数的计算之间的序列点。部分原因是,作为--左侧一部分的任何副作用(例如由操作员执行的副作用)在评估右侧之前就已完成。

C 标准第 6.5.13p4 节中有关逻辑 AND 运算符的详细信息如下:

与按位二元 & 运算符不同,&& 运算符保证从左到右求值;如果对第二操作数求值,则在第一操作数和第二操作数的求值之间存在序列点。如果第一个操作数比较等于 0,则不计算第二个操作数。

在这个表达式的情况下:

(a-- == 10 && a-- == 9)
Run Code Online (Sandbox Code Playgroud)

首先将 (10)的当前值与 10 进行比较。这是正确的,因此然后评估右侧,但不会在左侧进行a递减的副作用之前进行评估。a然后,将当前值a(现在为 9)与 9 进行比较,看是否相等。这也是正确的,因此整个表达式的计算结果为 true。a在执行下一条语句之前,在右侧完成的递减的副作用已经完成。

然而这个表达式:

if (a == --a)
Run Code Online (Sandbox Code Playgroud)

a涉及在没有序列点的同一表达式中进行读取和写入。这会调用未定义的行为