运算符是命令编译器对一个或多个操作数执行某种运算的符号,操作数是运算符操作的对象。C语言拥有异常丰富的运算符,首先C语言提供了基本运算符,这些运算符在大多数编程语言中都有,分为以下几类:算术运算符、关系运算符、逻辑运算符、赋值运算符。但是C语言不止包括这些运算符,本节只介绍最为常用的算术运算符,在后面章节将陆续介绍其他更多的运算符。
在C语言中,算术运算包括一元运算(++和--、+(取正)和-(取负))和二元运算(+、-、*、/、%)。
试试看:整数除法运算和模运算。
输入两个整数,分别代表糖果的个数和小朋友的个数,要求输出平均每个孩子能得到多少颗糖果,不能平均分配的还有几颗。
/*程序2-6:分糖果*/
candies / kids将两个整型变量进行除法运算,candies % kids将两个整型数据进行求模运算,这两个运算都属于算术运算。
使用算术运算需要注意以下几点:
(1)两个整数相除,结果为整数。例如:1/2的值是0,9/4的值是2;
(2)%模运算。%模运算是求余数的运算,只能在两个整数之间进行。例如:5%6的值是5,-9%4的值是-1,100%4的值是0。模运算结果的符号与第一个操作数相同;
(3)“*”乘号不能省略,5*a不能写成5a;
(4)双目运算符两侧操作数的类型要相同。
算术运算在程序中的应用很重要,程序2-7可以看到一个三位正整数各位数字之和可以通过简单的算术运算求出。
解决问题:求一个三位正整数各位数字之和。
调用函数scanf()输入一个三位正整数,求出这个三位正整数各个数位上的数字之和,然后调用函数printf()输出结果。
解题思路:
可以利用整数除法运算和模运算分离出每一位数字,然后相加。
/*程序2-7:求一个三位正整数各位数字之和*/
程序2-7中结合除法和模运算求一个整数各个数位上的数字,是在进行相关运算时经常用到的方法。表达式d1=(n / 10)%10和表达式d2=(n / 100)%10,都充分利用了C语言中“两个整数相除,结果为整数”这一特点。若n=123,则n/10的结果是12,然后12%10,得到数字2。
但整数相除结果为整数这一特点经常会给初学者带来困扰。程序2-4中,语句
celsius=5 * (fahr-32)/ 9;
如果写成:
celsius=5 / 9 * (fahr-32);
则得不到正确结果。对任何输入,程序的输出都是0.00,原因就是5/9的值是0。如果改为:
celsius=5.0 / 9 * (fahr-32);
则运算结果正确。
下面通过一个程序来说明如何解决整数除法运算的问题。
试试看:分析如下程序错误的原因。
该程序的功能是:输入两个整数,输出两个整数的和、差、积和商,要求商是浮点数,保留2位小数。
/*程序2-8:分析程序输出结果错误的原因*/
结果分析:
输入8和5,前3个输出函数的执行都没有问题,但到最后一个输出时,程序运行结果与预先设想的得到一个小数1.60的结果不同。原因依然是整数除法带来的问题:因为变量a、b都定义成整数,那么语句:
printf("%.2f\n",a / b);
计算a/b就是整数相除,结果一定是整数,8/5的结果是1,printf()函数中的格式字符串%.2f与a/b(结果是整数)的类型不匹配,将产生无意义的结果甚至无法完成输出任务。可将
printf("%.2f\n",a / b);
改为:
printf("%.2f\n",1.0 * a / b);
因为1.0是浮点类型,浮点类型与整型数据混合运算的结果是浮点类型,详见下节内容。
在执行算术运算时,通常要求操作数具有相同数据类型(相同的字节数和相同的存储方式)。计算机运算器可以直接将两个32位整数相加,但不可能将一个16位整数和一个32位整数直接相加,也不可能将一个32位整数和一个32位浮点数直接相加。
但C语言允许在表达式中混合使用基本类型,当然在这种情况下C语言编译器需要对某些操作数进行类型转换,以便硬件可以对表达式进行计算。例如,int类型数据和double类型数据进行加法运算时,编译器将把int类型数据转换为double格式。因为编译器可以自动完成这些转换而无需程序员介入,所以这类转换称为自动转换。当然C语言也提供了强制类型转换运算,允许程序员来控制类型转换。总之,类型转换的方式有以下3种:
1.常用算术转换
当算术运算、关系运算或逻辑运算的两个操作数类型不同时,精度低的自动向精度高的转换,这称为类型提升。下面几种常用数据类型从低级到高级排序为:
char→int→float→double
例如:
double a=1.0 / 2;
编译器将操作数2由int类型转换为double类型,然后进行double类型的除法运算。
2.赋值时类型转换
在执行赋值运算时,C语言编译器会遵循另一条简单的转换规则:把赋值运算符右侧表达式的值转换为赋值运算符左侧变量的类型。例如:
double a=1;/*把1.0赋给a*/
int i=1.5;/*把1.5转换为整型得1,赋给i*/
不同类型数据之间的赋值运算,如果右侧的数据类型高于左侧时,将会丢失一部分数据,从而造成数据精度的降低,或者发生数据溢出,导致结果错误。
3.类型转换运算符
一般格式为:(类型名)表达式
类型转换后仅产生一个指定类型的数据继续参加运算,这种类型转换操作并不改变操作数本身。例如:
double a=2.5;
int n;
n=(int)a;
最后一行代码意为读取双精度变量a的值,转换成int型数据2赋给n,n的值为2,而a的数据类型依然是double型数据,值依然是2.5。