Q我可以使用显式括号来强制所需的求值顺序,并控制这些副作用吗?即使我不这样做,优先级不是也规定了它吗?
A一般不行。
运算符优先级和显式括号仅对表达式的求值施加部分排序。在表达式
f() + g() * h()虽然我们知道乘法会先于加法发生,但无法确定三个函数中哪一个会被先调用。换句话说,优先级只部分地指定了求值顺序,其中“部分地”强调的是不包括操作数的求值。
括号告诉编译器哪些操作数与哪些运算符配对;它们不强制编译器先求值括号内的所有内容。向上述表达式添加显式括号使其变为
f() + (g() * h())不会改变函数调用顺序。同样,向问题 3.2 中的表达式添加显式括号使其变为
(i++) * (i++) /* WRONG */不会有任何作用(因为++的优先级高于*);无论有无括号,表达式都保持未定义状态。
当您需要确保子表达式求值的顺序时,您可能需要使用显式临时变量和单独的语句。
参考:K&R1 第 2.12 节第 49 页,第 A.7 节第 185 页
K&R2 第 2.12 节第 52-3 页,第 A.7 节第 200 页