C中的哪个运算符具有错误的优先级?

问题描述 投票:9回答:4

在K&R C(2E)的“ Introduction”部分中,有以下段落:

C和其他任何语言一样,都有其瑕疵。一些运算符的优先级有误; ...

这些是哪个运算符?他们的优先级有何错误?

this是这些情况之一吗?

c operators operator-precedence
4个回答
9
投票

[有一个明确的优先规则是无可争议的。该规则非常明确,以至于对于[[强类型系统(例如Pascal),错误的优先级将在编译时给出明确的语法错误。 C的问题在于,由于其类型系统是自由放任的,因此错误被证明是更多的逻辑错误,导致错误而不是在编译时可捕获的错误。

规则

让○□成为两个运算符类型>

○:α×α→β□:β×β→γ和α和γ是不同的类型。

然后

x○y□z可以

only mean

(x○y)□z,且具有类型分配x:α,y:α,z:β
而x○(y□z)将是类型错误,因为○只能取一个α,而右边的子表达式只能产生一个非α的γ

现在开始

将此应用于C

在大多数情况下,C正确无误

(==):数字×数字→布尔值(&&):布尔值×布尔值→布尔值

所以&&应该在==以下并且是这样

类似]

(+):数字×数字→数字(==):数字×数字→布尔值

所以(+)必须在(==)以上,这再次是正确的]

但是对于按位运算符而言>

&/ |的两个位模式(又称为数字)产生一个数字即(&),(|):数字×数字→数字(==):数字×数字→布尔值

以及典型的遮罩查询,例如x & 0x777 == 0x777仅在将(&)视为算术运算符时才有意义,即在(==)

以上

C根据上述类型规则将其置于错误的下面

我当然已经在数学/类型推断方面表达了以上内容

在更实用的C术语中,x & 0x777 == 0x777自然地分组为x & (0x777 == 0x777)(没有明确的括号)

这样的分组什么时候可以合法使用?我(个人)不相信有任何

IOW Dennis Ritchie的非正式陈述,即这些优先顺序是错误的,可以给出更正式的理由

是的,您链接到的消息中讨论的情况是C语言中运算符优先的主要问题。

从历史上看,C开发时没有&&。为了执行逻辑与运算,人们将使用按位与,因此a==b AND c==d将用a==b & c==d表示。为方便起见,==的优先级高于&。尽管&&是后来添加到语言中的,但&的优先级仍低于==

[通常,人们比(x&y) == 1更喜欢编写诸如x & (y==1)的表达式。因此,如果&的优先级高于==,那会更好。因此,人们对C运算符优先级的这一方面不满意。

这通常适用于优先级低于&^|==!=<><=>=

Wrong

听起来可能有点刺耳。普通人通常只关心诸如+-*/^之类的基本运算符,如果这些运算符不像他们在数学上的书写方式那样工作,则可以称为wrong
。幸运的是,这些在C语言中是“按顺序排列的”(不存在的幂运算符除外)但是,还有其他一些运营商可能无法像许多人期望的那样工作。例如,

位运算符

的优先级低于比较运算符的优先级,Eric Postpischil已经提到过。这是[[不太方便,但仍然不是很“错误”,因为以前没有为它们定义任何标准。它们是上个世纪计算机诞生时才发明的
另一个例子是移位运算符 << >>,其优先级低于+-。移位被认为是乘法和除法,因此人们可能希望移位应处于比+-高的水平。写x << a + b可能会使许多人认为它是

x * 2 a

+ b,直到他们查看优先级表为止。此外,(x << 2) + (x << 4) + (y << 6)也比不带括号的简单加法不方便在其他语言中,有许多“错误”优先级的真实示例

一个例子是T-SQL,其中-100/-100*10 = 0

  • 取决于哪个优先顺序约定被视为“正确”。没有任何物理法则(或土地法则)要求优先级一定。它是通过实践不断发展而来的。
    在数学中,运算符优先级通常被视为“ BODMAS”(括号,阶,除法,乘法,加法,减法)。括号在前,减号在后。Why is it that Microsoft Excel says that 8^(-1^(-8^7))) = 8 instead of 1/8? Ordering Mathematical Operations | BODMAS

    编程中的运算符优先级需要更多规则,因为会有更多运算符,但是您可以弄清楚它与BODMAS的比较方式。

    ANSI C优先级方案如图所示:Order of operations

    如您所见,一元加法和减法在第2级-高于乘法和除法在第3级。这可能会使数学家在表面上阅读时感到困惑,因为后缀/后缀的递增和递减的优先级可能会令人困惑。

    在这种情况下,始终值得考虑在数学代码中添加括号,即使在语法上不必要的情况下,也要确保向人类读者表明您的意图是明确的。通过这样做,您将一无所获(尽管您可能会被一个严格的代码审查员激怒了,您可以在其中审查有关代码风险管理的内容)。您可能会失去可读性,但是调试时,意图总是更加重要。

    是的,您提供的链接就是一个很好的例子。由此导致无数昂贵的生产错误。


  • 14
    投票
    是的,您链接到的消息中讨论的情况是C语言中运算符优先的主要问题。

    从历史上看,C开发时没有&&。为了执行逻辑与运算,人们将使用按位与,因此a==b AND c==d将用a==b & c==d表示。为方便起见,==的优先级高于&。尽管&&是后来添加到语言中的,但&的优先级仍低于==


    2
    投票

    Wrong

    听起来可能有点刺耳。普通人通常只关心诸如+-*/^之类的基本运算符,如果这些运算符不像他们在数学上的书写方式那样工作,则可以称为wrong

    1
    投票
    在数学中,运算符优先级通常被视为“ BODMAS”(括号,阶,除法,乘法,加法,减法)。括号在前,减号在后。Why is it that Microsoft Excel says that 8^(-1^(-8^7))) = 8 instead of 1/8? Ordering Mathematical Operations | BODMAS
    © www.soinside.com 2019 - 2024. All rights reserved.