答案 0 :(得分:9)
是的,您链接到的消息中讨论的情况是使用C运算符优先的主要问题。
从历史上看,C的开发没有&&
。为了执行逻辑AND操作,人们将使用按位AND,因此a==b AND c==d
将用a==b & c==d
表示。为此,==
的优先级高于&
。尽管后来在语言中添加了&&
,但&
的优先级仍然低于==
。
通常,人们喜欢写(x&y) == 1
之类的表达式要比x & (y==1)
更为频繁。因此,如果&
的优先级比==
高,那就更好了。因此,人们对C运算符优先级的这一方面不满意。
这通常适用于&
,^
和|
的优先级低于==
,!=
,<
,{{1 }},>
和<=
。
答案 1 :(得分:4)
有一个明确的优先权规则是无可争议的。 规则是如此明确,以至于强类型系统(例如Pascal),错误的优先级将在编译时给出明确的语法错误。 C的问题在于,由于其类型系统是自由放任的,因此错误证明是更多的逻辑错误,导致错误而不是在编译时可捕获的错误。
让○□成为两个类型的运算符
○:α×α→β
□:β×β→γ
和α和γ是不同的类型。
然后
x○y□z可以仅表示(x○y)□z,且具有类型分配
x:α,y:α,z:β
而x○(y□z)将是类型错误,因为○只能取一个α,而右边的子表达式只能产生一个非α的γ。
现在让我们
在大多数情况下,C都能正确处理
(==):数字×数字→布尔值
(&&):布尔值×布尔值→布尔值
so &&应该在==以下并且是
类似
(+):数字×数字→数字
(==):数字×数字→布尔值
,因此(+)必须高于(==),这再次正确
但是对于按位运算符
&/ |的两个位模式(又称为数字)产生一个数字
即
(&),(|):数字×数字→数字
(==):数字×数字→布尔值
因此是典型的掩码查询,例如。 x & 0x777 == 0x777
只有将(&)视为算术运算符,即(==)以上,才有意义-
C鉴于上述类型规则,将其置于错误的下方
我当然已经在数学/类型推断方面表达了以上观点
在更实用的C术语中,x & 0x777 == 0x777
自然地分为
x & (0x777 == 0x777)
(在无显式括号的情况下)
这样的分组何时可以合法使用?
我(个人)不相信有任何
IOW Dennis Ritchie对这些优先顺序是错误的非正式声明可以给予更正式的理由
答案 2 :(得分:1)
错误听起来可能太刺耳了。普通人通常只关心诸如+-*/^
之类的基本运算符,如果这些运算符不能像他们的数学编写方式那样工作,则可能称为 错误 。幸运的是,这些在C语言中是“有序的”(除了不存在的幂运算符)
但是,有些其他运营商可能无法像许多人期望的那样工作。例如,按位运算符的优先级低于比较运算符,后者已经由Eric Postpischil提到。这虽然不太方便,但仍然不是很“错误”,因为以前没有为它们定义任何标准。它们是上个世纪计算机诞生时发明的。
另一个示例是移位运算符 << >>
,其优先级低于+-
。移位被认为是乘法和除法,因此人们可能希望移位应该比+-
更高。编写x << a + b
可能会使许多人认为它是 x * 2 a + b ,直到他们查看优先级表为止。除了(x << 2) + (x << 4) + (y << 6)
之外,不如没有括号的简单加法
在其他语言中,有很多“错误”优先级的真实示例
-100/-100*10 = 0
^
优先级错误:Why does =-x^2+x for x=3 in Excel result in 12 instead of -6? 答案 3 :(得分:0)
这取决于哪个优先顺序约定被视为“正确”。没有任何物理法则(或土地法则)要求优先级一定。它是随着时间的流逝而发展的。
在数学中,运算符优先级通常被视为“ BODMAS”(括号,阶,除,乘,加,减)。括号放在首位,减号放在最后。Ordering Mathematical Operations | BODMAS Order of operations
编程中的运算符优先级需要更多的规则,因为运算符更多,但是您可以弄清楚它与BODMAS的比较方式。
正如您所看到的,一元加法和减法处于2级-高于乘法和除法处于3级。这可能会使数学家在表面上阅读时感到困惑,因为后缀/后缀的递增和递减优先。 >
在这种情况下,始终值得考虑在数学代码中添加括号(即使在语法上不必要的地方),以确保向人类读者清楚您的意图。通过这样做,您将一无所获(尽管您可能会被一个严格的代码审查员激怒了,您可以在其中审查有关代码风险管理的内容)。您可能会失去可读性,但是在调试时,意图总是更加重要。
是的,您提供的链接就是一个很好的例子。由此导致无数昂贵的生产错误。