BBS水木清华站∶精华区

发信人: ax.bbs@bbs.ee.nthu.edu.tw. (athena), 信区: test 
标  题: 星星流讲座 0046 
发信站: ☆清华电机☆ (Fri Jul 21 16:03:32 1995) 
 
 
第 7 讲 之 4            运算子的优先顺序 
                        Topic: Operator Precedence (2) 
 
前面所列的表中,层级越高的越优先。例如乘法类算术在加法类算术 
之前,所以 2 + 3 * 4 会先算出 3 * 4 = 12,再计算 2 + 12 的结 
果。同一层级的运算子均具有相同的优先权,这个时候编译器会依据 
该运算子是由左而右或是由右而左的方向来依次计算。比方说,乘法 
类算术是由左而右运算的,那麽: 
 
        3 * 4 / 2 
 
对编译器而言,就是先算出 3 * 4 = 12,再计算 12 / 2 的结果。 
 
C 语言中最高层级的运算子比较值得我们来讨论。首先是函数指示运算 
子,编译器看到小括号的时候,会先去比较一下接在小括号前的是不是 
变数名称,若是则会去检查是否有该函数的存在,这就是函数指示运算 
子的意思。 (所以我们以前提过,我们是可以把函数名字中紧接著的括 
号当做是一个运算子的) 
 
再来是运算式优先权,也就是我们在数学中常用的小括号的用法。 
 
接下来是注标,这是因为阵列的型别必须一开始就确定的缘故。 
 
最後是间接选取和直接选取,也就是我们在这一讲开头所提到的取用结 
构元素的方法。它的运算优先序非常的高,而且是由左而右的,所以现 
在我们很容易可以理解以下的例子: 
 
        struct student 
        { 
            long id; 
            char *name; 
        }; 
 
        struct score 
        { 
            struct student index; 
            int grade; 
        } A; 
 
        struct score *p = &A; 
 
那麽下面四个运算式是同义的: 
 
        A.index.id 
        p->index.id 
        (A.index).id            /* 同一层级的运算子,由方向决定是由左而右 */ 
        (p->index).id 
 
因此 ++p->grade 表示 ++(p->grade),也就是把 grade 这个数加加, 
而非是把 p 移到下一个位置去。那麽同理可得,++p->index.name 是把 
指标 name 的位置向下移一个,而非移动 p 的位置。如果要移动 p 的位 
置那该怎麽办呢?请你想一想。 
 
有三个运算子的性质比较特殊,它们是: 
 
        ,  &&  || 
 
这三个运算子保证它们左边的式子会比右边的式子先算,例如: 
 
        (xx == 22) && (yy == 33) 
 
编译器保证它会先判断 xx == 22 这个条件是否成立,再去判断 yy == 33 
这个条件是否成立。 
 
此外还有一种非常危险的做法,那就是编译器不能判断运算子的优先 
次序,例如: 
 
        a[i] = i++; 
 
指定运算 = 的运算顺序是由右而左的,它的优先序最低,所以最後做。 
a[i] 是注标,优先序最高,所以最先做,编译器先找出 a[i] 的位置。 
++ 的优先序比较高,所以第二个做,但是我们知道 i++ 是先做了再加, 
但是这个时候 a[i] 的位置关系会因为 i++ 而被破坏了,所以编译器不 
能决定你要的是 a[i] 还是 a[i + 1],於是乎就只好随它自己高兴来编 
译罗 (当然它会给你警告)。这种无聊的用法最好别用。 
 
运算子使用的最後一个值得注意的是小括号的使用,小括号在做为强制型 
态转换的用途时,它的优先层级降一级。另外,我们通常会利用小括号来 
控制数值计算的精确度,例如: 
 
        a = b * (c / d); 
 
特别括个括号来控制计算时产生的误差。不过小括号的滥用除了造成程式 
执行效率的降低之外 (当然这和编译器的制作有关系,理论上好的编译器 
应该不受影响),也会降低程式的可读性,须斟酌使用。 
 
 
-- 
本文原作者为徐振家,原作刊载於星星神教总坛 ☆清华电机☆ test 板。 
你可以以电子文件的形式将本文自由流传於台湾学术网路,但必须包含此版权声明。 
原作者依中华民国著作权法之规定,享有本文之著作权,请勿抄袭以免触法。 
未经授权任何人不得以任何形式对本文做任何修改及商业上之应用。 
其他网路的转载或其他用途的应用,请先知会作者,并取得其同意。 
对本文有任何疑问或意见请 mail 给 ax.bbs@bbs.ee.nthu.edu.tw,谢谢。 
 
 

BBS水木清华站∶精华区