1、第第3章章程序设计方法学基础程序设计方法学基础基本运算基本运算哈尔滨工业大学哈尔滨工业大学C运算符(运算符(Operator)的分类)的分类根据运算性质根据运算性质赋值运算符赋值运算符算术运算符算术运算符增和减增和减类型强转类型强转关系运算符关系运算符逻辑运算符逻辑运算符位运算符位运算符n根据运算所需的对象(操作数个数)根据运算所需的对象(操作数个数)一元(单目)运算符一元(单目)运算符二元(双目)运算符二元(双目)运算符三元(三目)运算符三元(三目)运算符3.1 算术运算算术运算最基本的数学运算最基本的数学运算算术表达式算术表达式:操作数操作数3.1 算术运算算术运算最基本的数学运算最基本的
2、数学运算算术表达式算术表达式除法除法(Division)浮点数浮点数除法除法(Floating Division)na or b or both are floats整数整数除法除法(Integer Division)na and b are integers3.1 算术运算算术运算最基本的数学运算最基本的数学运算操作数必须是操作数必须是整数,整数,返回返回a与与b相除之后的相除之后的余数(余数(Remainder)(1)提取数字的最低位。例如,123%10即可得到123的最低位3。(2)判断一个数能否被另一个数整除。例如,若m%n的结果为0,则m能被n整除。(3)判断一个数是否为偶数。例如,
3、若m%2的结果为0,则m为偶数。(4)生成一个指定范围内的随机数。求余(求余(Modulus)也称也称a a对对b b取模取模3.1 算术运算算术运算最基本的数学运算最基本的数学运算问题:输出一个三位整数的个位、十位和百位数字问题:输出一个三位整数的个位、十位和百位数字关键:如何分离关键:如何分离个位、十位、百位个位、十位、百位数字?数字?3.1 算术运算算术运算最基本的数学运算最基本的数学运算n对对p求模取余:求模取余:H(k)=k%p将一个大范围的自然数集合映射到一个只有将一个大范围的自然数集合映射到一个只有p个元素的小集合上个元素的小集合上随机函数随机函数rand()生成一个在生成一个在
4、032767之间的随机数之间的随机数问题:如何生成一个指定范围(如问题:如何生成一个指定范围(如1100)内的随机数?)内的随机数?magic=rand()%100;/099magic=rand()%100+1;/11003.1 算术运算算术运算最基本的数学运算最基本的数学运算常用的标准数学函数常用的标准数学函数#include 函数名功能exp(x)ex函数名功能exp(x)expow(x,y)xy函数名功能exp(x)expow(x,y)xysqrt(x)x的平方根,(x=0)函数名功能exp(x)expow(x,y)xysqrt(x)x的平方根,(x=0)fabs(x)|x|函数名功能e
5、xp(x)expow(x,y)xysqrt(x)x的平方根,(x=0)fabs(x)|x|log(x)lnx,(x0)函数名功能exp(x)expow(x,y)xysqrt(x)x的平方根,(x=0)fabs(x)|x|log(x)lnx,(x0)log10(x)lgx,(x0)函数名功能exp(x)expow(x,y)xysqrt(x)x的平方根,(x=0)fabs(x)|x|log(x)lnx,(x0)log10(x)lgx,(x0)sin(x)sinx,x为弧度值函数名功能exp(x)expow(x,y)xysqrt(x)x的平方根,(x=0)fabs(x)|x|log(x)lnx,(x
6、0)log10(x)lgx,(x0)sin(x)sinx,x为弧度值cos(x)cosx,x为弧度值3.1 算术运算算术运算最基本的数学运算最基本的数学运算3.2 赋值运算赋值运算用变量保存计算结果用变量保存计算结果赋值运算符和数学中的等号有何区别?赋值运算符和数学中的等号有何区别?有方向性有方向性左值和右值类型应一致左值和右值类型应一致(1)(1)赋值表达式语句(赋值表达式语句(Expression Statement)变量变量 =表达式表达式 ;(2)定义定义变量的同时为变量赋值变量的同时为变量赋值初始化(初始化(Initialize)类型类型 变量变量=表达式表达式;3.2 赋值运算赋值
7、运算用变量保存计算结果用变量保存计算结果赋值运算符的赋值运算符的结合性结合性?n(2)多重赋值()多重赋值(Multiple Assignment)变量变量1 =变量变量2 =表达式表达式 赋值运算符的赋值运算符的优先级优先级?n(1)简单赋值()简单赋值(Simple Assignment)变量变量 =表达式表达式 一种简写的且执行效率更高的赋值一种简写的且执行效率更高的赋值n(3)复合的赋值()复合的赋值(Combined Assignment)变量变量1 运算符运算符op=表达式表达式 3.3增增1和减和减1运算符运算符增增1运算符运算符(Increment)+使变量的值增加使变量的值增
8、加1个单位个单位减减1运算符运算符(Decrement)-使变量的值减少使变量的值减少1个单位个单位操作数只能是变量,不能是表达式,自增自减运算n一元运算符一元运算符前缀前缀(prefix)+n-n后缀后缀(postfix)n+n-n=n+1 n=n 1 n=n+1 n=n 1作为作为前缀前缀(prefix)运算符时运算符时+n,-n先对先对n增增1/减减1,然后再使用,然后再使用n的值的值用增1和减1运算生成的代码运行速度更快3.3增增1和减和减1运算符运算符作为作为后缀后缀(postfix)运算符时运算符时n+,n-先使用先使用n的值,然后再对的值,然后再对n增增1/减减13.3增增1和减
9、和减1运算符运算符i5j?46前缀与后缀对变量和表达式的影响前缀与后缀对变量和表达式的影响mnn5m?36操作数的值是相同的但表达式的值是不同的3.3增增1和减和减1运算符运算符printf(%d,-n+);printf(%d,-n);n5屏幕输出-56printf(%d,-(n+);printf(%d,-n);3.3增增1和减和减1运算符运算符printf(%d,-n+);printf(%d,-n);n5屏幕输出-56printf(%d,(-n)+);printf(%d,-(n+);printf(%d,-n);3.3增增1和减和减1运算符运算符优点优点增增1和减和减1运算生成的代码效率更高一
10、些运算生成的代码效率更高一些问题:过多的增问题:过多的增1 1和减和减1 1运算混合会产生什么结果?运算混合会产生什么结果?可读性差,例如可读性差,例如(+n)+(+n),(n+)+(n+)不同编译器产生的运行结果不同不同编译器产生的运行结果不同n良好的程序设计风格提倡良好的程序设计风格提倡n在一行语句中,在一行语句中,一个变量只出现一次增一个变量只出现一次增1 1或减或减1 1运算运算3.3增增1和减和减1运算符运算符3.4.1 自动类型转换与类型提升自动类型转换与类型提升3.4.23.4 混合数据类型运算中的类型转换混合数据类型运算中的类型转换算术表达式中算术表达式中问题:问题:相同相同类
11、型数据的运算结果的类型是什么?类型数据的运算结果的类型是什么?还是该类型还是该类型例如,整数除法例如,整数除法3.4.1自动类型转换与类型提升自动类型转换与类型提升根据参与运算的操作数类型根据参与运算的操作数类型从低级别向高级别自动转换从低级别向高级别自动转换算术表达式中算术表达式中问题:问题:不同不同类型数据的运算结果的类型是什么?类型数据的运算结果的类型是什么?取值范围较大取值范围较大的那种类型的那种类型例如,浮点数除法例如,浮点数除法C编译器将所有操作数都转换成取值范围较大的操作数的类型编译器将所有操作数都转换成取值范围较大的操作数的类型类型提升(类型提升(Type Promotion)
12、3.4.1自动类型转换与类型提升自动类型转换与类型提升Example:int total,number;float aver;aver=total/number;total15number2 aver?7.000000整数除法整数除法3.4.2“呼风唤雨呼风唤雨”的强制类型转换的强制类型转换不同类型不同类型的数据的运算结果的类型?的数据的运算结果的类型?int number;float total,aver;aver=total/number;total15number2 aver?7.500000浮点数除法浮点数除法3.4.2“呼风唤雨呼风唤雨”的强制类型转换的强制类型转换不同类型不同类型的
13、数据的运算结果的类型?的数据的运算结果的类型?int number;float total,aver;aver=total/number;total15number2 aver?7.500000 如何避免这种如何避免这种隐式隐式的自动类型转换的自动类型转换,以,以显式显式地表明地表明程序员的意图?程序员的意图?3.4.2“呼风唤雨呼风唤雨”的强制类型转换的强制类型转换Example:int total,number;float aver;aver=(float)total/number;total15number2 aver?将一个表达式的类型强将一个表达式的类型强制转换为用户指定的类制转换为
14、用户指定的类型型7.500000n(类型类型)表达式表达式 一元一元运算符运算符3.4.2“呼风唤雨呼风唤雨”的强制类型转换的强制类型转换Example:int total,number;float aver;aver=(float)total/number;total15number2 aver?7.500000不改不改变变total的类型和值的类型和值3.4.2“呼风唤雨呼风唤雨”的强制类型转换的强制类型转换Example:int total,number;float aver;aver=(float)total/number;total15number2 aver?7.000000(fl
15、oat)(total/number)结果如何结果如何?3.4.2“呼风唤雨呼风唤雨”的强制类型转换的强制类型转换3.4.3自动类型转换的安全隐患自动类型转换的安全隐患数值溢出数值溢出何为数值溢出?为什么会发生数值溢出?何为数值溢出?为什么会发生数值溢出?任何类型都只能用有限的位数来存储数据,表数范围有限任何类型都只能用有限的位数来存储数据,表数范围有限向变量赋的值向变量赋的值超出了其类型的表数范围超出了其类型的表数范围 精度损失精度损失从高精度向低精度转换时,会损失什么信息从高精度向低精度转换时,会损失什么信息?低精度的数据位数比高精度的少,容纳不下高精度的所有信息低精度的数据位数比高精度的少
16、,容纳不下高精度的所有信息舍入(舍入(Round),也称,也称截断(截断(Truncation)【例例3.1】整数数值溢出整数数值溢出运算结果超出了运算结果超出了long所能表示的数的所能表示的数的上界上界,进位到达了最前面的进位到达了最前面的符号位(符号位(0 01 1)Code:Blocks下给出的警告integer overflow in expression#include int main(void)long a;a=200*300*400*500 printf(%ldn,a);return 0;3.4.3自动类型转换的安全隐患自动类型转换的安全隐患这个程序的运行结果为:-88490
17、1888【例例3.2】#include int main(void)short a;int b=65537;a=b;printf(%hd,%dn,a,b);return 0;3.4.3自动类型转换的安全隐患自动类型转换的安全隐患#include int main(void)short a;int b=32767;a=b;printf(%hd,%dn,a,b);return 0;【例例3.3】1,65537-32768,327683.4.3自动类型转换的安全隐患自动类型转换的安全隐患#include int main(void)unsigned short a=8;unsigned short
18、b=10;printf(%hun,a-b);return 0;【例例3.3】65534做无符号整数减法时,如果被减数小于减数,也会发生溢出做无符号整数减法时,如果被减数小于减数,也会发生溢出【例例3.4】精度损失实例分析精度损失实例分析3.4.3自动类型转换的安全隐患自动类型转换的安全隐患#include int main(void)float a=10.2;float b=9;float c;c=a-b;printf(%fn,c);/%f表示默认将结果保留表示默认将结果保留6位小数来输出位小数来输出 printf(%.7fn,c);/%.7f表示将结果保留表示将结果保留7位小数来输出位小数来
19、输出 return 0;1.2000001.1999998#include int main()long a=123456789;float b;double c=123456789123.456765;b=a;printf(%ldn,a);printf(%fn,b);printf(%fn,c);b=c;printf(%fn,b);return 0;【例【例3.5】有效数字有效数字(Significant Digit):从左边第一个非:从左边第一个非0的数字起,到精确到的位数为止,的数字起,到精确到的位数为止,其间的所有数字其间的所有数字3.4.3自动类型转换的安全隐患自动类型转换的安全隐患C
20、ode:Blocksfloat23位尾数位尾数67位位double52位尾数位尾数16位位#include int main()long a=123456789;float b;double c=123456789123.456765;b=a;printf(%ldn,a);printf(%fn,b);printf(%fn,c);b=c;printf(%fn,b);return 0;【例【例3.5】定点整数可准确表示定点整数可准确表示123456789,而单精度浮点数则只能近似表示,而单精度浮点数则只能近似表示123456789Code:Blocks3.4.3自动类型转换的安全隐患自动类型转换的安全隐患3.5位运算及其应用位运算及其应用3.5位运算及其应用位运算及其应用36/53本章知识树本章知识树Q&A