c - && 是否在评估右侧较高级别的运算符之前强制评估左侧的关系算术运算符(C99)?
问题描述
考虑以下代码:
int y, x; y = 2; x = 0;
x!=0&&y/x>5
我的讲师关于 C 的教科书为“算术、关系和逻辑运算符的优先级层次结构”提供了一个表格,使用该表格来评估上述表达式中的运算符我得到以下优先级:
(1) 是 /,因此,先做 y/x
(2) 是 >,(3) 是 !=,(4) 是 &&。
如果我使用此优先级层次结构评估上述代码,则要评估的第一个子表达式是:y / x 即 2 / 0,或未定义...
给出的答案是 0。
后来,教科书还指出,根据 ANSI C 标准,&& 左边的操作数总是首先被计算,只有当它为 0 时,右边的操作数才会被计算。
这是否意味着每当逻辑和(&&) (或逻辑或(||) 就此而言)与算术和关系运算符一起出现在表达式中时,实际上我需要将整个表达式的术语分为两组- && 左侧的术语和右侧的术语,然后才开始将“算术、关系和逻辑运算符的优先级层次结构”应用于整个“左手操作数”中包含的运算符?
这将导致上述表达式被评估为:
(x!=0) && (y/x>5)
从左操作数 (x!=0) 开始,即 (0!=0),它为假,因此为 0,因此不会进行进一步的评估。
--
如果是这种情况,如果 && 运算符包含在表达式中指示必须首先做什么,为什么它会出现在优先级层次结构中如此低的位置?
解决方案
在这种情况下,您会遇到所谓的“短路评估”。把你的情况想象if (x != 0 && y / x > 5)
成if (somethingIsTrue && somethingIsTrue)
。为了使它成为现实,它必须成为if (true && true)
。在短路评估中,它看到 x !=0 为假并立即停止评估,因为无论后面发生什么,第一件事都是假的,所以它永远不会是真的。
是的,就您的观点而言,您可以将其视为将表达式分成 && 和 || 之间的组 陈述。这些单独的表达式中的每一个都被评估为真或假,然后将其视为 && 和 || 之间的一堆真或假语句。陈述。因此,对于类似的东西if (blah1 && blah2 || blah3)
,无论 blah1、blah2 和 blah3 是什么,它们都会被评估为真或假。然后你就会看到它是如何发挥作用的if (true && true || false)
或类似的东西。
顺便说一句,不要把头撞到墙上试图记住优先规则。它们中的大多数都是直观的,随着您的编程更多,您将掌握正确的做事方式。
推荐阅读
- haskell - 在 Esqueleto 中加入子查询的结果
- azure-devops - RestApi 获取 VSTS 中测试用例的附件详细信息
- c# - sql server 实体框架 WPF 数据库第一个过程与选择返回列表
- apache-kafka - Apache骆驼Kafka异常处理
- ruby-on-rails - 尝试使用带有 Watir 的代理...(Rails)
- css - 在css中动态添加顶部?
- android - 带彩色频闪的屏幕闪光灯
- c# - 如何按照以下标准生成密码
- java - 从排序的arraylist构建BST的问题
- vb.net - 如何销毁 vb.net formUI 中的变量?