基本运算符
加减乘除+、-、*、/运算符遵循数学运算规则及优先级顺序,这些运算符需要两个操作数。
9 + 10 // 常量 + 常量
a - 20 // 变量 - 常量
a * b // 变量 * 变量
可以使用多个运算符构建复杂的表达式,如:
10 + b * d / 2
运算符(+、-)也可以作为符号运算符:
- 负号可以用于指示或改变一个值的代数符号。
- 正号不改变它的操作数的值或符号,但可以用来强调某些数值的方向性,如坐标点正负。
可以看到,同一运算符可以有多种语义,如 '-',可以表达相减与负号的含义。
- 表达相减语义时,需要两个操作数,如:a-b,我们将它归属于双目运算符。
- 表达负号语义时,需一个操作数,我们称之为单目运算符。
除法运算符(/)代表两数相除,整型与浮点型除法运算有很大的不同。
- 浮点类型的除法运算得出一个浮点数结果。
- 整数除法运算则产生一个整数结果,不会有小数部分。
这就是说,两个int类型的数据做除法时,结果是其商。当出现不能被整除的情况时,并不会得到小数部分,1/2的结果是0而非0.5,3/2会得到1,这个过程被称为截尾。当需要保留小数部分时,就需要两个浮点类型(如:double)的数值进行运算。除法运算的结果正负取舍和算数一样,符号相同为正,相异为负。
取模运算
取模运算符(%),仅用于整型类型,结果是两个数相除的余数,也可称为求余运算符,如:
- 2 % 3 读作“对2除以3取模”,模为2。
- 6 % 3 结果为0。
当操作数中有负数时,取模结果的 正负和被除数符号相同。 即:
- 如果第一个操作数为负数,那么得到的模也为负数。
- 如果第一个操作数为正数,那么得到的模也为正数。
取模是一个非常有用的运算,像我们在网页上看到的一些表格文件,奇偶行以两种不同的背景色交替填充,这可以使用取模运算来控制,方法是使用当前行号与2取模,根据结果进行颜色选择并填充。
#include <stdio.h>
int main()
{
printf( "-3 / 16 = %d\n", -3/16 );
printf( "16 / -3 = %d\n", 16/-3 );
printf( "-3 %% 16 = %d\n", -3%16 );
printf( "16 %% -3 = %d\n", 16%-3 );
return 0;
}

代码展示了除法与取模运算的符号方向。注意取模运算的输出,在printf()的格式化字符串中,两个连续的%号使得程序转义输出了一个%号。 这是因为%号自身是格式控制符的一部分,因此需要连续输入两个%号以表示转义输出自身。最后,在做除法与取模运算时,始终提醒自己:0不能为除数!。
括号运算符
圆括号()运算符可用于改变表达式的运算优先级。
x + y * 3 // 先求值 y*3,再将 x 与之相加
(x + y) * 3 // 先求值 x+y, 将和与3相乘
(a + (b - c)) * d // 先求值b-c,再求值a + (b-c),最后是上两步的结果与d相乘
逗号表达式
逗号运算符可以将两个或多个表达式连接起来,构成表达式列表,列表中的表达式自左向右逐个求值,整个逗号表达式的值就是最后那个表达式的值。如:
2, 3 // 表达式的值是 3
2, b, c+5 // 表达式的值是 c+5
int a = (3, 5); // a的初始值是5。
优先级
我们已经学习了 =、+、-、*、/、%、()、, 运算符,从算术运算符的角度讲,当它们应用到表达式中时,求值顺序依赖于优先级,这里给出由高到低的排序。
- ()
- *、/、%
- +、-
- =
- ,
另一个容易被忽略的是结合性:
- ()、+、-、*、/ 都是从左向右结合,如: a+b、(c/d-2)。
- = 是从右向左结合,a=3; 表示将右侧的字面量赋值给左侧的变量。
- +、- 作为符号运算符时,结合性是从右向左,如: +5、-5,表示将字面量取正或取负。
练习
1 编写一组运用加减乘除运算的程序。
2 在程序中加入除0的代码,运行程序看看是什么结果。
3 编程求数值a的平方与立方,注意选择合适的数据类型。
4 在程序中编写几条空语句,看看它们对程序的影响。
5 编写复杂语句,理解括号运算符对表达式求值的影响。