除非特别说明,下面所示的操作符可用于任意算术类型或者任何可转换为算术类型的数据类型.
+ 一元正号 + expr
- 一元负号 = expr
* 乘法 expr * expr
/ 除法 expr / expr
% 求余 expr % expr
+ 加法 expr + expr
- 减法 expr = expr
expr 为表达式
上面是按优先级来对操作符进行分组.一元操作符优先级最高,其次是乘法除法操作,接着是二元的加减法操作.高优先级的操作符要比低优先级的结合得更紧密.这些算术操作符都是左结合,这就意味着当操作符的优先级相同时,这些操作符从左到右依次与操作数结合.
对于前述表达式 5+10*20/2,考虑优先级和结合性,可知该表达式先做乘法*操作,其操作数为10和20,然后以该操作的结果和2为操作数做除法/操作,其结果最后与操作数5做加法+操作.
一元负号操作符具有直观的含义,它对其操作数取负:
int i=1024;
int k=-i; ..negates the value of its operand
一元正号操作符则返回操作数本身,对操作数不作任何修改
--------------------------------------------------------------我是迷茫的分割线---------------------------------------
警告:溢出和其他算术异常
某些算数表达式的求解结果未定义,其中一部分由数学特性引起,例如除零操作;其他则归咎于计算机特性,如溢出;计算出的数值超过了其类型的表达范围.
考虑某台机器,其short类型为16位,能表示的最大值是32767.假设short类型只有16位,下面的复合赋值操作将会溢出:
//max value if shorts are 8 bits
short short_value=32767;
short ival=1;
//this calculation overflows
short_value +=ival;
cout<<"short_value: "<<short_value<<endl;
表示32767这个有符号数需17位的存储空间,但是这里仅有16位,于是导致溢出现象的发生,此时,许多系统都不会给出编译时或运行时的警告,对于不同的机器,上述例子的short_value变量真正获得的值不尽相同.在我们的系统上执行该程序后将得到:
short_value=-32768
其值"截断(wrapped around)",将符号位的值由0设为1,于是结果变为负数.因为算术类型具有有限的长度,因此计算后溢出的现象常常发生.
----------------------------------------------------------------我是迷茫的分割线------------------------------------------------
二元+、-操作符也可用于指针值,对指针使用这些操作符的用法在前面介绍过.
算术操作符+、-、*和/具有直观的含义:加减乘除.对两个整数做除法,其结果为整数,如果它的商包括小数部分,则小数部分会被截断:
int ival1=21/6; //integral result obtained by truncating the remainder
int ival2=21/7; //no remainder,result is an integral value
ival1和ival2均被初始化为3.
操作符%称为"求余(remainder)"或"求模(modulus)"操作符,用于计算左操作数除于右操作数的余数.该操作符的操作数只能为整型.包括bool、char、short、int和long类型,以及对应的unsigned类型:
int ival=42;
double dval=3.14;
ival%12; //ok:returns 6
ival%dval; //error:floating point operand
如果两个操作数为正,除法/和求模%操作的结果也是正数(或0);如果两个操作数都是负数,除法操作的结果为正数(或0),而求模操作的结果则为负数(或0);如果只有一个操作数为负数,这两种操作的结果取决于机器;求模结果的符号也取决于机器,而除法操作的值则是负数(或0):
21%6; //ok:result is 3
21%7; //ok:result is 0
-21%-8 //ok:result is -5
21%-5 //machine-dependent:result is 1 or -4
21/6; //ok:result is 3
21/7; //ok:result is 3
-21/-8; //ok: result is 2
21/-5; //machine-dependent:result -4 or -5
当只有一个操作数为负数时,求模操作结果值的符号可依据分子(被除数)或分母(除数)的符号而定.如果求模的结果随分子的符号,则除出来的值向零一侧取整;如果求模与分母的符号匹配,则除出来的值向负无穷一侧取整.
习题5.1 在下列表达式中,加入适当的圆括号以标明其计算顺序.编译该表达式并输出其值,从而检查你的回答是否正确.
12/3*4+5*15+24%4/2
((12/3)*4)+(5*15)+((24%4)/2)结果是91,经查无误.
习题5.2 计算下列表达式的值,并指出哪些结果值依赖于机器?
-30*3+21/5
-30+3*21/5
30/3*21%5
-30/3*21%4
依次结果是 -86、-18、0、-2;
最后一个表达式依赖于机器,除操作表达式只有一个负数,结果可以是-2也可以是2
习题5.3 编写一个表达式判断一个int型数值是偶数还是奇数.
ival%2==0,如果是偶数,表达式为真true,如果是奇数,表达式为假false
习题5.4 定义术语"溢出"的含义,并给出导致溢出的三个表达式.
溢出:表达式的求值结果超出了其类型的表示范围
假设int类型为16位,以下表达式都会导致溢出
1000*1000
32766+5
3276*20
以上结果都超过了16位所能表达的数值范围(-32768~32767),导致溢出.