C++中逻辑或表达式与对应条件判断语句的行为等价性咨询
C++中逻辑或表达式与对应条件判断语句的行为等价性咨询
嘿,这个问题问得特别实在!咱们来掰扯清楚这两段代码的行为到底一不一样。
首先先拆解原代码的逻辑:
原代码是这么写的:
bool a(); bool b(); a() || b() || std::clog << "whine about something" << std::endl;
C++里的逻辑或||是有短路求值特性的——意思是只要前面某个表达式返回true,后面的所有表达式都不会执行了。所以这段代码的执行流程是:
- 先调用
a(),如果返回true,直接结束,b()和后面的日志输出全跳过; - 如果
a()返回false,再调用b(),要是b()返回true,同样跳过后面的日志; - 只有当
a()和b()都返回false的时候,才会执行那行std::clog的输出。
再看你改写后的代码:
if (!a() && !b()) { c(); // Replacement to the clog bit. }
这里的逻辑与&&同样有短路求值:
- 先算
!a(),也就是a()返回false的时候这个值才是true,这时候才会去判断!b(); - 只有当
a()和b()都返回false时,!a() && !b()才会是true,才会调用c()。
那结论很明确:这两段代码的行为完全一致!
不管是原代码还是你改后的代码,c()(对应原代码的日志操作)都只会在a()和b()都返回false的时候执行;而且两者的短路行为也完全匹配——原代码里a()为true时不会调用b(),你改后的代码里!a()为false时,&&的短路特性会直接跳过!b()的判断,也就是不会调用b(),和原代码一模一样。
至于你提到的C版本问题,从C03/11转到C17完全不影响这个结果,因为逻辑或、逻辑与的短路求值规则是C标准从一开始就定死的,这么多年没改过。
另外说句题外话,你这个改写其实比原代码好太多了!原代码把输出操作硬塞在逻辑表达式里,可读性特别差,改成if语句的写法直观多了,后续维护起来也方便,给你点个赞~
备注:内容来源于stack exchange,提问作者Gregorio Litenstein
相关产品推荐
相关产品推荐

