目录
1.5 运算符和表达式
1.5.1 算术运算符和表达式
1.5.2 赋值运算符和表达式
1.5.3 逗号运算符和表达式
传送门上一节:C语言程序设计-常量与变量
传送门下一节:C语言程序设计-不带参数的主函数、赋值运算符、数据类型
C语言提供了非常丰富的运算符,由这些运算符可组成相应的表达式。请记住,任何C语言表达式都有一个确定的值。本节将介绍算术运算符、赋值运算符及其相应的表达式,而其他运算符和表达式将在后面陆续介绍。
1、算术运算符
C语言中提供的算术运算符如表1.2所示。
表1.2 算术运算符
从上面例题可以看到,如果+ ,- ,* ,/ 运算符的两侧都是整型,则按整型计算,且运算结果为整型,例如,1/2的结果是0,不是0.5;如果两侧运算量中至少有一个运算量为实型,则先将两个运算量都转化为双精度后计算,且运行结果为双精度型。另外运算符“%”两侧的运算量必须是整型。
使用算术运算符时应注意,在进行+、-、*、/ 算术运算时,系统自动先将数据的类型按一定的规则转换(即统一到同一种数据类型),然后再进行运算,运算结果类型是转换后的类型。图1.9给出了数据类型的转换规则,可根据“垂直降落,向上位移”的原理辅助理解。
图1.9 转换规则
1)垂直降落
如果运算量是char型,则必须先转换成int型,如果运算量是float型,则必须先转换成double型,然后再进行下一步运算。char型的指定地点是位于阶梯最低级的int型,而float型的指定地点是位于阶梯最高级的double型。
2)向上位移
将int型、long型和double型看成是由低到高的3个台阶,如果数据类型相同,也就是处于同一阶层,则系统不进行转换,而直接运算,其运算结果类型是该数据类型。如果数据类型不同,即处于不同阶层,则系统将其中低级别类型的数据统一到高级别类型,然后再运算,而且其运算结果类型是高级别类型。
类型转换通常一步到位。例如,int型或long型与double型进行运算,则先将int型或long型直接转换为double型,然后再对两个double型数据进行运算,其运算结果为double型。再如,int型与long型进行运算时,要先将int型转换为long型,接着再对两个long型数据进行运算,其运算结果为long型。
另外,如果两个运算量是int型和float型,由于系统必须先把float型转换为double型,因此进行运算之前int型也要随之转换为double型,其运算结果也为double型。
2、算术表达式
-2*((a+sqrt(4.0)) -1)是一个算术表达式,其中sqrt(4.0)是利用系统提供的求平方根函数计算4.0的平方根。在C语言中,将由算数运算符、圆括号和运算对象(包括常量、变量、函数等)组成,且符合C语言语法规则的表达式称为算术表达式。算术表达式的计算结果是一个数值。
算术表达式的计算示例如表1.3所示。
表1.3 算术表达式的计算
说明:
(1)一个算术表达式可以有多个运算符,因此对算术表达式进行计算时,要注意运算的先后顺序。优先级越小,运算顺序就越在先,其优先级别也就越高。例如,圆括号、加法和乘法运算符优先级的数值分别为1、4、3,因此表达式2+3*5相当于2+(3*5),其结果为17。对于同一优先级的运算符,一定要按其结合方向进行运算,例如,运算符/和*的优先级都是3,结合方向为自左至右,因此表达式12/2*3相当于(12/2)*3,而不是12/(2*3)。
(2)算术表达式中出现的变量必须有确定的值。
(3)C语言表达式中不能使用数学中的方括号“[ ]”和花括号“{ }”。C语言只允许使用圆括号,且可以用多层形式。
注:
(1)C语言不提供乘方运算符,因此只能用“ * ”计算乘方的值。
(2)在C语言中,不能出现Π,因为它既不是变量,也不是常量,因此改写时根据所需精度用3.14159或3.14等代替。
(3)(a+b)当被除数时圆括号不能省略,例:3.14159*(r*r)/(a+b)。
1.赋值运算符
C语言中提供的赋值运算符有=,+=,-=,*=,/=,%=等,其中后5个运算符是符合的赋值运算符(将在1.6.2节介绍)。赋值运算符的结合方向是由右至左。
2.赋值表达式
用赋值运算符把一个变量和一个C语言表达式连接起来的表达式称为赋值表达式。
赋值表达式的一般形式是:
变量=表达式
例如,i=3*2是赋值表达式,其含义是将3和2的乘积6赋给变量i。
说明:
(1)赋值表达式的处理过程是先计算赋值运算符右边表达式的值,然后把该值赋给左边的变量。
(2)赋值表达式左边必须是变量(代表存储单元),右边可以是C语言的任何合法表达式。假设i中的值为3,则i=i*2是合法的赋值表达式,其处理过程是先计算表达式i*2的值(3*2的值为6),然后把6赋给i。
注意:赋值运算符左边变量代表一个存储单元,而右边出现的变量应理解为该变量中的值,其值必须是事先赋予的。
(3)赋值表达式的值是赋值运算符左边的变量的值,例如,赋值表达式a=3*2的值为6;当b的值为5时,赋值表达式b=b+2的值为7;当a的值为1,b的值为2时,赋值表达式a=b的值是2,但同样当a的值为1,b的值为2时,b=a的值却为1;表达式y=8的值为8,因此赋值表达式x=(y=8)+1的值为9(即8+1)。
(4)由于赋值运算符的结合方向是自右至左,因此x=y=5等价于x=(y=5)。
(5)在合法的赋值表达式中,如果赋值运算符两边的数据类型不一致,则系统先将右边表达式值的类型自动转换成左边变量的类型,然后再进行赋值。赋值时的转换规则参见1.6.1节。在不同数据类型之间进行赋值处理时,容易产生意想不到的错误。例如,将double型数据赋给float型变量时,由于数值范围不同,容易产生数据溢出现象,因此尽量避免使用这种赋值形式。
数据的类型也可以利用强制类型转换的方法,其一般形式为:
(类型名)(表达式)
【例 1.14】编写一个强制类型转换的程序。
#include
int main(void)
{
int i=0,j=0,k=0;
float x=5.8,y=3.7,f=8.56;
i=(int)(x+y); //将x+y的结果9.5(即5.8+3.7)转换成int型
j=(int)x+y; //将从x中取出的值5.8转换成int型后,与y相加
k=(int)f%3;
printf("i=%d,j=%d,k=%d,x=%f\n",i,j,k,x); //x中的值还是5.8
return 0;
}
运行结果:
i=9,j=8,k=2,x=5.800000
程序说明:
(1)强制类型转换运算符(int)类型名外的一对圆括号不可少,例如,将i=(int)(x+y)写成i=int(x+y)是错误的。
(2)(int)(x+y)和(int)x+y的含义不同,因此不要随意去掉(x+y)中的括号。
(3)(int)x的作用是将从x中取出的值5.8转换成整型5,但没把5存入变量x中(即x中的值没变),也没有将x的类型转换成整型。
(4)%为求余运算符,要求两个运算量都是整型,因此f%3是不合法的表达式,但(int)f%3是合法的,因为(int)f的值是整型值8。
1.逗号运算符
C语言中提供的逗号运算符是","。逗号运算符的优先级数值为15,是所有运算符中优先级最低的运算符,逗号运算符的结合方向是自左至右。
2.逗号表达式
用逗号运算符把C语言表达式连接起来的表达式称为逗号表达式。
【例1.15】编写一个使用逗号表达式的程序。
#include
int main(void)
{
int a=0,b=0,x=0,y=0;
a=(x=8,x%5); //将逗号表达式(x=5,x%5)的值赋给a
b=x=8,x%5; //先将赋值表达式x=8的值赋给b,再求x%5的值。
printf("%d,%d,%d\n",a,b,(y=2,y*3)); //输出a,b和表达式(y=2,y*3)的值。
return 0;
}
运行结果:
3,8,6
程序说明:
(1)逗号表达式(x=8,x%5)的求解过程是先将8赋给x,再求8%5的值(值为3)。3是此逗号表达式的值。
(2)程序中a=(x=8,x%5)和b=x=8,x%5的作用不同。a=(x=8,x%5)的求解过程是:先求逗号表达式(x=8,x%5)的值,后给a赋值,这是一个赋值表达式。b=x=8,x%5的求解过程是:先将8赋给变量x,再将赋值表达式x=8的值8赋给b,最后求8%5的值(赋值运算符的优先级比逗号运算符高),即先求解第一个表达式,再求解第二个表达式,这是一个逗号表达式。因此在程序中不要随意添加或舍去圆括号。
(3)程序中的有些逗号作为分隔符使用,例如,在最后一条输出语句中a,b,(y=2,y*3)的前两个逗号是分隔符,后一个才是逗号运算符。
逗号表达式的一般形式为:
表达式1,表达式2,表达式3,...,表达式n
其求解过程是:从表达式1到表达式n按顺序求值。表达式n的值是逗号表达式的值。
传送门来喽~
May our country prosper and the people live a peaceful life!