将a+;b+;c按如下方式操作:a+;c+;B
众所周知:求值的顺序是由优先级和关联性决定的。 对于本例,关联性确定a+b,然后结果加上c。这就是符合ANSI C标准的编译器所做的(不考虑优化)。但它会像标题中前面的方式一样进行评估吗?在哪个编译器中?在K&R公司将a+;b+;c按如下方式操作:a+;c+;B,c,C,众所周知:求值的顺序是由优先级和关联性决定的。 对于本例,关联性确定a+b,然后结果加上c。这就是符合ANSI C标准的编译器所做的(不考虑优化)。但它会像标题中前面的方式一样进行评估吗?在哪个编译器中?在K&R公司 a + b + c == c + b + a 顺序无关紧要 它被称为 顺序无关紧要 它被称为让我把这个扔给你: 让我把这个扔给你: 数学术语中方程的结构(在a+(b*c)中,我们谈论的b*c首先被计算)不一定与编译器计算参数的顺序有关 此实例中的实际执行顺序是未定义的IIRC。C
a + b + c == c + b + a
顺序无关紧要
它被称为
顺序无关紧要
它被称为让我把这个扔给你:
让我把这个扔给你:
数学术语中方程的结构(在
a+(b*c)
中,我们谈论的b*c
首先被计算)不一定与编译器计算参数的顺序有关
此实例中的实际执行顺序是未定义的IIRC。C只保证由序列点分隔的表达式的顺序保持不变,并且+运算符不是序列点
大多数编译器都会做你期望的事情-生成先计算a然后计算b然后计算c的代码用数学术语(在
a+(b*c)
我们所说的b*c
首先被计算)的等式结构不一定与编译器计算参数的顺序有关
此实例中的实际执行顺序是未定义的IIRC。C只保证由序列点分隔的表达式的顺序保持不变,并且+运算符不是序列点
大多数编译器都会按照您的期望执行—生成先计算a,然后计算b,然后计算c的代码。只要最终结果相同,编译器就可以自由地重新安排内容 例如:
1 + b + 1
可轻松转换为:
b + 2
编译器可以自由地重新安排事情,只要最终结果相同 例如:
1 + b + 1
可轻松转换为:
b + 2
:
6.5表达方式…
3运算符和操作数的分组由语法指示。74)除非另有规定 稍后(对于函数调用
()
,和&
,|
,?:
和逗号运算符),计算顺序
子表达式的类型和副作用发生的顺序都未指定。
…
74)语法指定表达式计算中运算符的优先级,这是相同的 作为本款主要子条款的顺序,最高优先级优先。因此,例如 允许用作二进制
+
运算符(6.5.6)操作数的表达式是中定义的表达式
6.5.1至6.5.6。例外情况是作为一元运算符操作数的强制转换表达式(6.5.4)
(6.5.3),以及包含在以下任何一对运算符之间的操作数:分组
括号()
(6.5.1),下标括号[]
(6.5.2.1),函数调用括号()
(6.5.2.2),以及
条件运算符?:
(6.5.15)。在每个主要子类中,运算符具有相同的优先级。左关联性或右关联性无效 在每个子条款中,用其中讨论的表达式的语法表示。 我的。表达式
a+b+c
将被计算为(a+b)+c
;也就是说,c
的结果将添加到a+b
的结果中。必须先计算a
和b
,然后才能计算a+b
,但a
、b
和c
可以按任意顺序计算 :
6.5表达方式…
3运算符和操作数的分组由语法指示。74)除非另有规定 稍后(对于函数调用
()
,和&
,|
,?:
和逗号运算符),计算顺序
子表达式的类型和副作用发生的顺序都未指定。
…
74)语法指定表达式计算中运算符的优先级,这是相同的 作为本款主要子条款的顺序,最高优先级优先。因此,例如 允许用作二进制
+
运算符(6.5.6)操作数的表达式是中定义的表达式
6.5.1至6.5.6。例外情况是作为一元运算符操作数的强制转换表达式(6.5.4)
(6.5.3),以及包含在以下任何一对运算符之间的操作数:分组
括号()
(6.5.1),下标括号[]
(6.5.2.1),函数调用括号()
(6.5.2.2),以及
条件运算符?:
(6.5.15)。在每个主要子类中,运算符具有相同的优先级。左关联性或右关联性无效 在每个子条款中,用其中讨论的表达式的语法表示。
我的。表达式
a+b+c
将被计算为(a+b)+c
;也就是说,c
的结果将添加到a+b
的结果中。必须先计算a
和b
,然后才能计算a+b
,但a
、b
和c
可以按任意顺序计算我试着强调你认为是评价顺序和编译器认为是什么的区别。
从数学上说,在表达式a+b*c
中,乘法在加法之前求值。当然,这一定是因为我们需要知道向a
添加什么
但是,编译器不必考虑在表达式“<代码> > <代码>之前评估表达式<代码> B*C.<代码>。您可能会认为,由于乘法具有更高的优先级,因此编译器将首先查看表达式的该部分。实际上,对于编译器将首先决定做什么,没有任何保证。它可以计算
a