预期变量没有变化,但一元运算符即使在 false if 语句中也能工作。为什么这样?

Expected no change in variable but unary operator works even in false if statement. Why so?

#include<stdio.h>
int main(){
    int y=15;
    if(y++>19 && y++!=21 && y++>21)
    printf("%d",y);
    else
    printf("%d",y);
    return 0;
}

我预计输出为 15 甚至 18,但它给出了 16,我不知道为什么。

此处 y++>19 ==> y 与 19 进行比较,然后由于后缀 ++ 而递增。 因此,y++>19 实际上被评估为 15>19,然后 y 递增并变为 16.

因为 15>19 为假,所以条件 y++!=21 && y++>21 的其余部分不被评估,控制转到 else 条件并打印 y。由于上面的 y 已经变为 16,因此它打印 16.

请注意,在短路评估中,A && B && C,如果 A 被评估为真,则只有 B 被评估。 如果 A 和 B 都被评估为真,那么只有 C 被评估。

因此,在您的情况下,由于 A 为假,因此没有对 B 和 C 进行进一步评估,控件只是输入它的其他部分并打印 y。

我建议阅读有关 运算符优先级 的内容(同时阅读 关联性 )。通常每种语言都有一个解释功能的规范,C 也是如此。网上资源比比皆是,一本学习 C 的好书是 K&R,很好的解释和有趣的练习。

我将引导您完成这个示例:

int y=15; // y is assigned the value 15, the return of the assignment is discarded (you will encounter that fact sooner or later surely)

if语句可以描述成(y++>19) && (y++!=21) && (y++>21)来表达清楚。 && 运算符是短路的:即一旦可以确定最终结果,就不会评估其余部分。具体来说,在这种情况下,一旦看到 false0,它就会停止计算并 return false.

y++>19 有两个运算符,后缀递增(优先级较高)和 大于 (优先级较低)。后缀首先递增 return 值,然后递增它,因此有效地评估 15>19 并且 y 递增到 16。现在记住短路。程序停止对该表达式求值,因为最终结果不会改变。程序进入 else 部分并打印分配给 y 的值,即 16.

线路中有几件事情正在发生

if(y++>19 && y++!=21 && y++>21)

&& 运算符(连同 ||?: 和逗号运算符)强制从左到右计算,这意味着 y++ > 19 在计算之前计算y++ != 21,将在 y++ > 21 之前计算。它还引入了一个 序列点 ,因此 y++ > 19 的所有副作用将在 y++ != 21 被评估之前应用。

&& 运算符 短路 - y++ != 21 将仅在 y++ > 19 计算为非零(true), 并且 y++ > 21 将仅在两个先前表达式的计算结果都为非零时才被计算。

后缀 ++ 运算符产生操作数的当前值(因此 y++ 计算为 15);作为 副作用 ,它会增加操作数,因此在计算 y++ > 19 之后,y 会增加到 16,即使整个表达式计算至 false (0).

这是你写的,只是一点点 shorter and faster:

#include<stdio.h>
int main(){
    int y = 15;
    y++;    // y = y + 1; means value of variable y equals 16 at this point
    if(y != 21 && y > 19)  // now you check this 16 != 21 && 16 > 19 which is false 
    printf("%d", y);
    else   // continue here directly 
    printf("%d", y);  // print value of variable y
    return 0;   // exit success
}

是的,结果总是16。如果这不是您所期望的,请确保更正您的第一个陈述 if(y != 21 && y > 19) .

希望这能帮助您更正您的 IF 语句(我的建议)。

我可以向您推荐以下两个视频,以便在编写此类语句之前正确理解赋值、逻辑和比较运算符,因为:

false AND true -> false
true AND false -> false

(1) 算术运算符程序 https://www.youtube.com/watch?v=oaO2eT46Mm8

(2) ComparisonOperator 程序 https://www.youtube.com/watch?v=ovKVOj3xNsA

(3) 逻辑运算符程序 https://www.youtube.com/watch?v=kclf0PQnxrI

点赞修正后的答案。