从头学C(23)运算符优先级与求值次序

0

第二章 类型、运算符与表达式 >> 2.12 运算符优先级与求值次序

下表总结了所有运算符的优先级和结合性,同一行的各个运算符拥有相同的优先级。有一些运算符之前的章节没有接触到,但后面的章节都会详细讲述。

运算符优先级

+和-用作一元运算符时,是作为符号位,*作为一元运算符是通过指针间接访问数据,&作为一元运算符是取对象地址(上图漏了,它是和!  ~  ++等位于同一优先级)。

要注意位运算符(&  ^  |)比运算符==和!=优先级低,因此,位测试表达式中,比如:

if((x & MASK) == 0)
    ...

其中的位测试表达式就必须用圆括号括起来才行。

下面再来看看求值顺序,C语言中没有规定同一运算符中多个操作数的计算顺序(当然&&  ||  ?: 和 , 运算符除外),因此类似

x = f() + g();

的表达式,f()和g()谁先计算是不一定的。如果函数f或g有可能会改变另一个函数所使用的变量,那么要特别注意x的结果会依赖这两个函数的计算顺序。

而且C语言中也没有指定函数各个参数的求值顺序,因此下列的语句:

printf("%d %d\n", ++n, power(2, n));   /* 错误! */

在不同的编译器中可能会产生不同的结果。为了避免这种错误,可以改成下面的方式:

++n;
printf("%d %d\n", n, power(2, n));

还有一个典型的令人困惑的例子:

a[i]= i++;

除了编译器,恐怕没人知道数组下标i是使用旧的值,还是使用新的值。不同的编译器可能会解释为不同的结果。

总之,在任何一种编程语言中,如果代码的执行结果与求值顺序相关,则都是不好的程序设计风格。因此在不确定是否会出现这种问题的情况下,最好不要尝试运用这类特殊的实现方式。

Leave A Reply