考虑以下代码:
int y, x; y = 2; x = 0;
x!=0&&y/x>5我的讲师关于C的教科书为“算术、关系和逻辑运算符的优先等级”提供了一个表,使用这个表来评估上述表达式中的运算符,我得到以下优先级:
(1)是/,因此,首先做y/x
(2) is >,(3) is !=,(4) is &&。
如果我使用这个优先级层次结构计算上面的代码,那么要计算的第一个子费用是:y/x,它是2/ 0,或者是未定义的.
给出的答案是0。
随后,教科书还指出,根据ANSI C标准,将始终首先计算&&的左边的操作数,只有当这个值为0时,才会对右边的操作数进行评估。
这是否意味着,在表达式中出现逻辑和(&)(或逻辑或())以及算术运算符和关系运算符时,我实际上需要将整个表达式的术语分为两组--左侧的术语和右边的&&,然后才开始将“算术、关系和逻辑运算符的优先层次”应用于包含在整体‘左操作数’中的运算符?
这将导致将上述表达式计算为:
(x!=0) && (y/x>5)
从左操作数开始,(x!=0),这是(0!=0),这是false,所以0,因此不会进行进一步的计算。
--
如果是这样的话,为什么&&运算符在优先级层次中的表现如此之低,如果它包含在表达式中决定了必须首先做什么?
发布于 2021-02-06 17:54:28
在这种情况下,你遇到了所谓的“短路评估”。将您的状态if (x != 0 && y / x > 5)想象为if (somethingIsTrue && somethingIsTrue)。为了实现这一点,它必须成为if (true && true)。在短路评估中,它看到x !=0是假的,并立即停止在那里进行计算,因为无论在它之后发生了什么,第一件事是假的,所以它永远不可能是真的。
是的,就你的观点而言,你可以把它看作是将表达式分割成组,在&&和\{e76f}语句之间。每个单独的表达式都被求值为true或false,然后将其看作是在&&和x语句之间的一组true或false语句。因此,对于像if (blah1 && blah2 || blah3)这样的东西,不管是什么blah1、blah2和blah3,它们都将被评估为true或false。然后你就会看到它是如何发展成if (true && true || false)之类的。
另外,不要把头撞在墙上,试图记住优先规则。它们中的大多数都是直观的,当您编写更多的程序时,您将掌握正确的做事方法。
发布于 2021-02-06 18:04:36
运算符的优先级说明了如何解释表达式x!=0&&y/x>5。把它想象成设置牙套。所以编译器会将您的表达式读取为(x!=0) && ((y/x)>5)。请注意,优先级最高的操作符首先得到大括号,优先级较低的操作符随后得到大括号。
现在正在进行评估。从外部到内部进行评估。最外面的操作符是优先级最低的&&。它有两个操作数,左边的和右边的。现在标准上说,首先要评估左边的那个。如果是false,则&&返回false (快捷方式)。如果是true,则需要计算正确的操作数。
这个有保证的评估顺序的好处是,您现在可以安全地编写例如if (x!=0 && y/x>10)或if (pointer!=NULL && pointer->data != 3)。
https://stackoverflow.com/questions/66079974
复制相似问题