C语言的语法基础
2.3 运算符与表达式
C语言有很丰富的运算符,总结如下:
1.算术运算符: + (加), –(减), *(乘), /(除), %(求余)
2.关系运算符: >(大于), <(小于), <=(小于等于),
>=(大于等于), ==(等于), !=(不等)
3.逻辑运算符: !(逻辑非), &&(逻辑与), (逻辑或)
4.位运算符: ~(按位取反), &(位与), |(位或),
∧ (异或), <<(左移), >>(右移)
5.条件运算符: ? :
6.指向结构体成员运算符: ->
7.结构体成员运算符(分量运算符): .
8.自增1,自减1运算符: ++ , --
9.类型转换运算符: (类型)
10.指针,取地址运算符: *(指针运算符), &(取地址运算符)
11.下标运算符: [ ]
12.赋值运算符: =, *=,+=,-=,/=,%=,>>=,<<=,&=,∧=,|=
13.逗号运算符: ,
14.长度运算符: sizeof( )
15.负号运算符: -
16.括号运算符: ( )
本章只介绍算术运算符、增1与减1运算符、关系、逻辑及条件运算符、位运算符、赋值运算符、类型转换运算符、逗号运算符和长度运算符。
2.3.1算术运算
1.算术运算符
C语言的算术运算符有以下5种:
+ ( 双目运算两数相加,如5+6,单目运算取正值,如 +15 )
- ( 双目运算两数相减,如5-6,单目运算取负值,如 -19 )
* ( 双目运算符,两数相乘, 如 5*6 )
/ ( 双目运算符,两数相除, 如 15/6 )
% ( 双目运算符,取模或求余数,两个数必须都是整数,如 15%6 值为3)
所谓单目运算符是指对一个运算对象进行操作。例如: -19。双目运算符是对两个运算对象进行操作,这两个运算对象分别放在操作符的左边和右边。如:5+6。
2.算术运算符的优先级和结合方向
计算机语言中的运算符与数学中的运算符类似,都有优先级和结合方向。C语言的算术运算符的优先级如下(同一行上的运算符,优先级相同):
( ) 圆括号 高
+、- 单目运算符,取正、取负
*、/、% 双目运算符,乘、除、取模
+、- 双目运算符,加、减 低
上面所有双目算术运算符的结合方向都是“从左到右”,而单目运算符取正“+”和取负“-”的结合方向是“从右到左”。
3.算术运算表达式
C语言的算术表达式是由算术运算符把运算对象连接起来,构成合法的式子。运算对象包括常量、变量和函数。算术表达式的值为整数或实数。如 3*x+1.0/y-10*sqrt(x) 。
在对算术表达式进行运算时,应注意以下几点:
(1) 算术表达式中可以使用多层圆括号,左、右括号必须配对。运算时先计算出内层括号表达式的值,由内向外计算表达式的值。
(2) 取模运算符%两侧的运算对象必须是整数,运算结果是两数相除后所得的余数。在多数机器上,取模后值的符号与运算符左侧运算对象的符号相同。例如:5%3值为2,-5%3 值为-2,5%(-3) 值为 2; 实数不能参与取模运算,如5%1.5是非法的算术表达式。
(3) 整数除:两个整数相除后值等于商的整数部分(小数部分没有四舍五入), 例如 1/2 为整数除,其值为0。
(4)实数除:两个相除的数中至少有一个是实数,相除后的值等于(商本身)实数,如 1.0/2 (或 1/2.0 或 1.0/2.0) 均为实数除,值都是0.5。
例如表达式(-16/3*2+1)%6的值是 -3,先计算圆括号内的值,单目运算符“-”优先级高于其它双目运算符,先计算整数除–16/3值为 –5, 然后-5*2+1值为 –9, 最后-9%6值为-3。
4.各类数值型数据的混合运算
在C语言中允许整型、实型、字符型数据进行混合运算。例如
1.23+'A'+456%'B'
是合法的C表达式。不同类型的数值型数据进行混合运算时,先要把低数据类型向高数据类型转换,成为同一类型后才进行运算。转换的规则如下图2.6:
高 long double
↑
double ← float
↑
long
↑
unsigned
↑
低 int ← char,short
图2.6 不同类型的数值型数据进行混合运算时类型的转换规则
图中向左的横向箭头表示必须进行的转换,如两个float型的数据相加,也要先把这两个float数据转换成double型数据,然后再进行运算,以提高精度。向上的纵向箭头表示不同类型数据混合运算时,先要进行的数据类型转换。例如表达式123.456+543-'A' ,运算时先把整型数据543转换成double型数据后,与123.456相加值为666.456(double型数据),然后把字符'A'转换成65.0(double型数据)再进行相减运算,最后结果为601.456(double型数据)。
2.3.2增1与减1运算
增1运算符“++”使运算对象的值增1, 而减1运算符“--”则使运算对象的值减1。它们都是单目运算符,其运算对象必须是变量,不能是常量和表达式。例如语句i++;相当于语句i=i+1;又如语句i--;相当于语句i=i-1;
增1与减1运算符可以作前缀运算符,这时是先使运算对象值增1或减1之后,再使用运算对象。例如 i=1;j=++i;则变量i的值先增1变成2,然后把i的值赋给变量j,j的值为2。同样的若有语句 i=1;j=--i;执行后i的值为0,j的值为0。
增1与减1运算符也可以作后缀运算符,这时是先使用运算对象,再使运算对象值增1或减1。例如 i=1;j=i++;则先把i的值赋给变量j,j的值为1,然后变量i的值再增1变成2。同样的若有语句 i=1;j=i--;执行后i的值为0,j的值为1。
增1与减1运算符如果仅仅只进行自加、自减运算,没有使用运算对象的值,作前缀运算符与作后缀运算符运算结果一样。如语句 i--;与语句 --i;效果一样,都等同于语句i=i-1;
“++” 和 “--”运算符的结合方向是“从右到左”。例如 i=1; j=-i++;由于取负运算符“-”和增1运算符“++”的优先级相同,结合方向是“从右到左”,即相当于-(i++),又由于是后缀运算符,则先取出i的值使用,把-i的值赋值给j, 变量j的值为-1,然后使i的值增1变成2。
应尽量避免在一个表达式中多次用“++” 和 “--” 运算符,这样写出的表达式可读性差,不同的编译系统也可能给出不同的运算结果。例如 i=1;j=++i+i++;k=i++*++i;可使用临时变量过渡一下,分解成多条语句来完成类似的功能。例如上面三条语句可以改成如下五条语句:
i=1;
t=++i; /* 执行后,i值为2, t值为2。 */
j=t+i++; /* 执行后,j值为4, i值为3。 */
t=++i; /* 执行后,i值为4, t值为4。 */
k=(i++)*t; /* 执行后,k值为16,i值为5。 */
变量t作为临时变量,把“++”运算符只写在一个表达式中,这样程序可读性好,不同的编译系统给出的运算结果都相同。以上程序段运行后,变量i,j,k的值分别是5,4 ,16。
发表评论