C/C++中的逻辑运算符及其优先级

5
我最近接触到一段代码。
// 解决除零错误的程序。
int a=0;
int b=100;

int c= a==0 || b/a ;

printf("Hello");

//输出:你好

我的理论: 根据运算符优先级,操作符 / 的优先级高于 ||。所以 b/a 必须首先被执行,我们应该得到一个运行时错误。

我猜发生的是:

短路运算符 || 评估 LHS a==0,它是 true,因此不执行 b/a。

我的理论错了吗?我相信这是非常简单的事情,但现在我就是想不出来。


请告诉我为什么要编写那种需要费尽心思才能弄清楚其工作原理的代码?这是愚蠢的,无法维护,因此是垃圾!请告诉我编写这样的代码有什么意义。 - Ed Heal
@EdHeal 这实际上很常见。唯一让我不爽的是,当赋值给 c 时,(a==0) 被视为 int 0 而不是 boolean false,但我相信这本来就是 C 语言的问题。 - GolezTrol
@EdHeal 我没有写过这段代码,我是在看一些程序时看到的。 - Desert Ice
1
@GolezTrol a == 0 的值为1/true。从boolint存在隐式转换,因此int c = boolean_expression;等同于int c = boolean_expression ? 1 : 0; - Daniel Fischer
@DanielFischer,谢谢 - 大联合球迷 :)。 - Desert Ice
@DanielFischer 我知道。我是在回应Ed Heals关于“愚蠢、难以维护的代码”的说法。我认为代码相当清晰,除了我不喜欢隐式转换,特别是在像C这样的强类型语言中。但我不认为这真的是一种转换。在C中,布尔值似乎只是整数,其中0为false,其他值为/评估为true。当您查看输出的目标代码时,我无法想象实际上正在进行转换。 - GolezTrol
2个回答

8

优先级并不意味着计算顺序,仅表示分组(括号)。

||的第一操作数计算之后,存在一个序列点(旧术语),因此无论这些操作数是什么,都必须在第二个操作数之前计算||的第一操作数。由于在这种情况下表达式a == 0 || b / a的整体结果由第一个操作数确定,第二个操作数根本不会被计算。


1
+1. 这被称为短路求值 - GolezTrol
非常棒的信息,感谢 @GolezTrol 和 Daniel Fischer。我一直以为这只是我忽略了的一些简单语法问题。 - Desert Ice
2
当老师们解释运算符优先级时,一定有什么根本性的错误,因为很多人都会认为它与评估顺序有关。也许需要某种组织来漫游世界各地的课堂,找到那些说“首先评估最高优先级运算符”(或任何基本错误)的人,将他们捆绑在车里,驱车前往秘密基地进行再教育。 - Steve Jessop

3
< p > / 的优先级高于 ||,这意味着表达式的计算顺序为:

int c= (a==0) || (b/a) ;

而不是

int c= (a==0 || b)/a ;

尽管如此,由于逻辑评估被短路了,只有在 a!=0 的情况下才会评估 b/a


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接