c - C 中运算符优先级的含义

标签 c operator-precedence

我知道这个话题已经出现过无数次了,但我需要一点时间。

我曾多次尝试理解这一点,也在评估顺序的背景下。我一直在寻找一些明确的例子来理解操作。优先级,我在这里找到了一个:http://docs.roxen.com/pike/7.0/tutorial/expressions/operator_tables.xml我想知道的是那里给出的示例(我已将它们粘贴在下面)是否正确。

1+2*2                  =>  1+(2*2)
1+2*2*4                =>  1+((2*2)*4)
(1+2)*2*4              =>  ((1+2)*2)*4
1+4,c=2|3+5            =>  (1+4),(c=(2|(3+5)))
1 + 5&4 == 3           =>  (1 + 5) & (4 == 3)
c=1,99                 =>  (c=1),99
!a++ + ~f()            =>  (!(a++)) + (~(f()))
s == "klas" || i < 9   =>  (s == "klas") || (i < 9)
r = s == "sten"        =>  r = (s == "sten")

例如,1+2*2*4 真的是 1+((2*2)*4) 或者也可能是,1+(2*(2*4)) 根据 C 规范。任何帮助或进一步引用示例都会很有用。再次感谢。

最佳答案

虽然这些例子来自不同的语言,但我认为它们与 C 中的运算符优先级相同。一般来说,您最好使用 C 语言的引用,例如 C 标准,或摘要例如 Wikipedia 中的那个.

但是,我不认为这实际上是您要问的。运算符优先级对求值顺序没有影响。所有运算符优先级所做的只是向您展示如何为表达式添加括号。 C 编译器可以按照它希望的任何顺序来计算操作。如果可以证明代数恒等式对于所有有效输入都具有相同的结果,也允许使用代数恒等式(对于浮点计算通常不是这种情况,但对于无符号整数计算通常是这样)。

编译器需要生成具有特定评估顺序的代码的唯一情况是:

  1. 短路 bool 运算符 &&|| :必须首先评估左侧参数,并且在某些情况下可能不会评估右侧参数;

  2. 所谓三元运算符?: :必须首先评估左侧参数(在 ? 之前);随后,将评估另外两个运算符之一。请注意,该运算符分组到右侧,这表明分组和评估顺序之间没有关系。即pred_1 ? action_1() : pred_2 ? action_2() : pred_3 ? action_3()pred_1 ? action_1() : (pred_2 ? action_2() : pred_3 ? action_3()) 相同,但它是 pred_1必须首先对其进行评估。

  3. 逗号运算符, :必须首先评估左边的参数。 这与函数调用中使用逗号不同。

  4. 函数参数必须在调用函数之前求值,尽管未指定参数的求值顺序,也未指定生成函数的表达式的求值顺序。

    <

最后一个短语指的是这样的示例:

// This code has Undefined Behaviour. DO NOT USE
typedef void(*takes_int_returns_void)(int);
takes_int_returns_void fvector[3] = {...}
//...
//...
(*fvector[i++])(i);

在这里,编译器可以选择递增 i在它评估函数的参数(或其他不太令人愉快的可能性)之前或之后,因此您实际上不知道该函数将使用什么值来调用。

1+2*2*4为例,编译器必须生成将产生 17 的代码。它如何做到这一点完全取决于编译器。此外,如果全部x , yz都是无符号整数,编译器可以编译 1 + x*y*z它想要的任何乘法顺序,甚至重新排序为 y*(x*z) .

关于c - C 中运算符优先级的含义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18946613/

相关文章:

math - Julia 提供错误的数值结果

语法 : How to add a level of precedence

c - 破译 qwert 密码

c - 堆或堆栈结构中的静态数组?

c - 切换到C编程

c - 为什么这些构造使用增量前和增量后未定义的行为?

c - 在函数 `_start' : (. text+0x20) 中:对 `main' 的 undefined reference

函数可以定义在main()之后吗?

javascript - OOP 语言中的变量重新分配

c - 期待 SIGSEGV ,但正在正常工作