《C语言程序设计课件第3章100913.ppt》由会员分享,可在线阅读,更多相关《C语言程序设计课件第3章100913.ppt(28页珍藏版)》请在三一办公上搜索。
1、2023/7/1,1,高级语言程序设计,第三章 表达式与运算符,主讲:计算机学院 朱立华,2023/7/1,3,内容提要,表达式体现对数据的处理,由运算符和运算对象组成 掌握每种运算符的以下知识:对运算对象的要求运算符的结合性运算符的优先级运算结果的特性有多种运算符的复杂表达式的计算顺序及计算结果数据类型的自动转换规则及强制转换的方法,2023/7/1,4,表达式的组成,表达式实现对数据的处理,每个表达式都有唯一的值表达式由运算对象和运算符组成运算对象的种类:常量、变量、有返回值的函数调用、其它表达式例:2 a rand()(2+a)*rand()运算符:共34种,分为15个不同的优先级,可以
2、理解成是不带运算符的最简单表达式,常量表达式,变量表达式,函数表达式,带运算符的表达式,2023/7/1,5,左值与右值,每个表达式都有唯一确定的值,表达式不是左值就是右值 右值:只能出现在赋值号(=)右边的表达式 左值:不是右值的表达式就是左值左值与右值的关系:右值只能出现在赋值号的右边;而左值既可以出现在赋值号的左边,又可以出现在赋值号的右边。左值可以取地址,右值不可以取地址.例:2 a rand()(2+a)*rand()a=b,常量表达式只能作为右值例:a=2;(右值),变量表达式为左值,既可在赋值号左边也可以在右边,例:a=5;(左边)b=a;(右边),此函数表达式为右值例:a=ra
3、nd()右值),此表达式只能作为右值例:b=(2+a)*rand();(右值),赋值表达式只能作为右值例:c=a=b;(右值)(a=b)=c;(出错),2023/7/1,6,算术运算符,算术运算符主要完成数值计算问题,具体如下表所列,例:int a=3,b,c;a+的表达式结果是3,变量a的值是4;+a的表达式结果是4,变量a的值是4;因此,c=a+执行后,c的值是3,a的值是4 b=+a执行后,b的值是4,a的值也是4,例:int a=3;-a结果为-3,但是变量a的值仍为3-2.45是2.45的相反数,例:int a=3,b,c;a-的表达式结果是3,变量a的值是2;-a的表达式结果是2,
4、变量a的值是2;因此,c=a-执行后,c的值是3,a的值是2 b=-a执行后,b的值是2,a的值也是2,例:int a=27,b=5,c;表达式a/b结果是5,而不是5.4表达式27.0/b结果是5.4表达式27.0/5.0结果是5.4,例:int a=27,b=5,c;表达式a%b结果是2,表达式-a%b结果是-2 表达式27.0%b是错误的,例:表达式2+3结果是5表达式2+3.0结果是5.0表达式2.0+3.0结果是5.0,例:表达式3-2结果是1表达式3.0-2结果是1.0表达式3.0-2.0结果是1.0,2023/7/1,7,算术运算符,程序3.1 赋值表达式及算术运算符示例#inc
5、lude#include/包含随机函数rand的声明int main()int a=5,b=6,c=7;printf(“%dn”,rand();/显示随机数print(%dn,a*(b+c)/2-2);/显示算术表达式的值printf(%dn,a=b);/显示赋值表达式即a的值b=rand()%10;/混合表达式赋0至9之间的1个随机数printf(“%dn”,c=a=b);/显示赋值表达式的值即c的值 return 0;,413067,2023/7/1,8,关系运算符,关系运算符主要完成表达式间的比较,比较的结果非真即假,C语言中无逻辑类型,故用1表示真,0表示假任何类型的值,只要不等于0,
6、在需要作出真假判断的场合就代表逻辑真。,结论:关系运算符的优先级低于算术运算符,例:c(a+b)可以写成:ca+b,例:(ab)!=c 可以写成:ab!=c,例:a=(bc)可以写成:a=bc,例:(d=c)=(a+b)用括号表达式的含义清楚,2023/7/1,9,关系运算符,程序3.2 关系运算示例#include#include/包含随机函数rand的声明int main()int a=rand()%10;/产生3个09的随机数 int b=rand()%10;int c=rand()%10,d;printf(“a=%d,b=%d,c=%dn”,a,b,c);/输出 printf(%dn,
7、c=(a+b);return 0;,a=1,b=7,c=410,rand()函数产生一个非负随机整数,产生一个a,b范围的非负随机整数的方法是:a+rand()%(b-a+1),2023/7/1,10,逻辑运算符,逻辑运算符主要完成更复杂的条件判断逻辑表达式的最终结果只有两个:1表示真,0表示假。任何类型的值,只要不等于0,在需要作出真假判断的场合就代表逻辑真,0代表逻辑假,几种运算符的优先级:单目-算术-关系-逻辑与-逻辑或,例:!A 结果为0,!(2+35)结果为1,例:(ab)&(xy)可以写成:ab&xy,例:(a=b)|(x=y)可以写成:a=b|x=y,例:(!a)|(a!=b)可
8、以写成:!a|a!=b,例:表达字符变量ch是大写字母的正确条件为:ch=A&ch=Z,而不是:A=ch=Z,例:表达整型变量y是闰年的正确条件为:y%400=0|y%4=0&y%100!=0,2023/7/1,11,逻辑运算符,逻辑与、逻辑或运算符具有短路功能当第一运算对象的结果就是表达式结果时,第二运算对象不作计算逻辑运算符的真值表及短路说明如下表所示:,逻辑与短路总结:当第一对象的值为假时,第二对象无需计算。因为无论第二对象结果是什么,最终表达式的值肯定为假逻辑或短路总结:当第一对象的值为真时,第二对象无需计算。因为无论第二对象结果是什么,最终表达式的值肯定为真,2023/7/1,12,
9、逻辑运算符,假设已有定义:int a=5,b=6,c=7;下表给出了&和|的短路功能,练习:设有语句:int a=3,b=5,m=0;则执行语句a+b8&(m=a=3)后,m的值为_,整个表达式的值为_,2023/7/1,13,逻辑运算符,程序3.3 逻辑运算示例#include#include/包含随机函数rand的声明int main()int a=1+rand()%50,b=1+rand()%50;int x=rand()/a,y=rand()/b;printf(%d,%d,%dn,a,b,ab);printf(%d,%d,%dn,x,y,xy);printf(%dn,(ab),42,1
10、8,0150,1472,1001,rand()函数产生一个非负随机整数,产生一个a,b范围的非负随机整数的方法是:a+rand()%(b-a+1),2023/7/1,14,自增自减运算符,在算术运算符中已提到单目运算符自增(+)和自减(-)自增自减运算符的几个特殊性:(1)这两种运算符专门用于改变一个变量自身的值(增或减1),因此实质上具有赋值功能,运算对象只能是一个变量。(2)对变量变化的时机取决于运算符与运算对象的相对位置,有前后之分,+a和a为前+(-),a+和a为后+(-)(3)前+或前是指先改变变量的值,再用变化后的值参加运算;后+或后是指先用未变化过的变量的值参加表达式的运算,最后
11、再改变变量的值。共同点就是变量值肯定改变(4)需要区分表达式的值和变量的值,大部分情况下不是一回事,但是如果仅仅改变变量而不用它运算,则前后无区别,2023/7/1,15,自增自减运算符,假设已有定义:int x=8,i=2,j=4;下表列出了有自增自减运算符的表达式的值及变量的值,2023/7/1,16,自增自减运算符,程序3.4 自增自减运算示例#includeint main()int i=5,j=6,k;i+;+j;/相当于i=i+1;j=j+1;printf(i=%d,j=%dn,i,j);i-;-j;/相当于i=i-1;j=j-1;printf(i=%d,j=%dn,i,j);k=
12、(i+)+(+j);/相当于j=j+1;k=i+j;i=i+1;printf(i=%d,j=%d,k=%dn,i,j,k);k=(i-)+(-j);/相当于j=j-1;k=i+j;i=i-1;printf(i=%d,j=%d,k=%dn,i,j,k);return 0;,i=6,j=7i=5,j=6i=6,j=7,k=12i=5,j=6,k=12,2023/7/1,17,位运算符,位运算是对字节或字内的二进制数位进行测试、抽取、设置或移位等操作,是C语言可对硬件编程的体现。运算对象只能是int类型(包括char类型)C中提供6种位运算符,其中的(按位取反为单目运算符),其余5个为双目运算符,具
13、体见下一页多种运算符的优先级:单目-算术乘除取余-算术加减-移位-关系-按位与-按位异或-按位或-逻辑与-逻辑或,2023/7/1,18,152=60 00001111,00,相当于15*22,152=3 00001111,00,相当于15/22,2023/7/1,19,条件运算符,条件运算符是C语言中唯一的1个三目运算符其格式为:表达式1?表达式2:表达式3计算方法及运算结果:先求表达式1得到非0表示真,得到0表示假。如果是真,则条件表达式的值等于表达式2的值(此时表达式3不计算);如果是假,则条件表达式的值等于表达式3的值(此时表达式2不计算)。优先级:13级,仅高于逗号和赋值运算符的优先
14、级结合方向:从右至左,当有条件运算符嵌套时,按照从右至左的顺序结合。先计算第一对象,根据结果再决定后面的运算,2023/7/1,20,条件运算符,对运算对象的要求:可以是任何类型的表达式例:int a=1,b=2,x;则条件运算表达式:ab?(x=6):(x=7)的值是?解析:以上条件表达式根据右结合原则实际上是:ab?(x=6):(x=7)计算顺序:先计算整个条件表达式的第一对象ab,结果为真,则计算第二对象x=5,后面红色括号内的第三对象不再计算,因此整个表达式的结果为5,变量x的值也是5.注意:结合方式与运算顺序并不是一回事!,5,2023/7/1,21,条件运算符,程序3.5 条件运算
15、示例#include#includeint main()int a=rand()%10,b=rand()%10,c,d;c=ab?a:b;d=ab?a:b;printf(a=%d,b=%dn,a,b);printf(c=%d,d=%dn,c,d);return 0;,a=1,b=7c=7,d=1,2023/7/1,22,赋值与复合赋值运算符,赋值运算符是C语言中使变量获得值的运算符,有两大类复合赋值运算符:(1)双目算术运算与赋值运算符一起,构成算术复合赋值运算符(2)双目位运算与赋值运算符一起,构成位复合赋值运算符运算对象:左边只能是变量,右边是一个表达式计算方法及运算结果:表示给该变量空间
16、赋值或修改该变量空间中的值,此时变量也称为左值。赋值运算符右边是一个表达式,其类型最好是与左值类型一致,不一致时自动类型转换.优先级:14级,仅高于逗号的优先级结合方向:从右至左,在连续赋值时,按从右至左的顺序依次 例:设int a=1,b=2,c=5;计算 a=b=c 和(a=b)=c,先计算b=c,b获得值5,该赋值表达式结果为b;此结果作为赋值表达式a=b=c的右值赋给a,因此a=5,最终a,b,c的值均为5,错误!a=b是表达式,不可以作为左值使用!,将复合赋值运算符转换为等效的普通赋值运算符按以下3步:(1)将原复合赋值运算符右边的表达式加圆括号作为1个整体;(2)将原复合赋值运算符
17、左边的变量名连同那个算术运算符或位运算符一起移到赋值号的右边,作为赋值号右边的第一部分置于原复合赋值运算符右边整体之前;(3)将原复合赋值运算符左边的变量名留下,直接跟赋值号,去掉原来的算术运算符或位运算符。例:a*=b+5=a=a*(b+5),2023/7/1,23,赋值与复合赋值运算符,程序3.6 赋值及复合赋值示例#includeint main()int a,b,c;a=b=c=7;/相当于c=7;b=c;a=b c+=a+;/相当于c=c+a;a+;printf(a=%d,c=%dn,a,c);c%=+a;/相当于+a;c=c%a;printf(a=%d,c=%dn,a,c);c*=
18、a-;/相当于c=c*a;a-;printf(a=%d,c=%dn,a,c);return 0;,a=8,c=14a=9,c=5a=8,c=45,2023/7/1,24,逗号运算符,逗号不仅是C语言源程序中的一种分隔符,还是一种运算符。逗号表达式的形式:表达式1,表达式2,,表达式n运算对象:可以是任何类型的表达式计算方法及运算结果:按从左到右的顺序依次计算各表达式的值,最后一个表达式n的结果就是整个逗号表达式的结果.优先级:15级,优先级最低,通常通过加括号提升其优先级结合方向:从左至右 例:设所有变量均为int型,计算 x=a=3,6*a 和 x=(a=3,6*a),这是一个逗号表达式,先
19、计算赋值表达式x=a=3,该表达式的结果为x,变量x和a的值均为3,再计算第二个表达式6*a结果为18,因此逗号表达式最后结果为18,这是一个赋值表达式,先计算圆括号内逗号表达a=3,6*a,该表达式的结果为18,再将该结果赋值给变量x,因此赋值表达式最后结果为18,变量a的值为3,x的值为18,2023/7/1,25,内部类型转换,不同类型进行混合运算需要先转换为同一种类型再计算,这个类型称为目标类型。C语言提供了3种方式的类型转换。(1)不同类型数据混合运算时,由编译器自动完成隐式类型转换 float转为double短存储型转为长存储型 有符号数据转为无符号数据 整型转为浮点型(2)强制性
20、数据类型转换:根据用户需要用语句进行转换,形式(目标类型名)待转换表达式 例:int a=(int)3.14;/a=3(float)a/4=3.0/4结果为0.75(float)(a/4)=3/4结果为0,然后float(0),结果0.0 变量a的类型仍为int型。强制类型转换不会改变变量原类型,这也是C语言中的单目运算符,第2优先级,2023/7/1,26,内部类型转换,(3)赋值时的数据类型自动转换:赋值号右边表达式类型转换为左边变量的类型,原则:float或double型数据赋值给int型变量:直接截断小数 int或char型数据赋值给double或float型变量:补足有效位成为一个浮
21、点数 char型数据赋值给整型家族的变量:将其ASCII码值赋给最低的一个字节,高字节全补0long或int型数据赋值给short int型变量:取其低两字节赋值,高字节舍去 short int型数据赋值给int或long型变量:数据直接赋给低两字节,如果原short int值的最高位为0,则结果的高16位全部补0;否则全部补1,这叫做符号扩展。unsigned int型数据赋值给int型变量:直接传送数值。非unsigned型数据赋值给位数相同的unsigned型变量:直接传送数值。,2023/7/1,27,本章小结,本章介绍了C语言34个运算符中的28个,运算符和运算对象一起构成了表达式,对每种运算符,重点掌握以下内容:对运算对象的要求运算符的结合性运算符的优先级运算结果的特性难点:表达式中有多种类型的运算符,其计算顺序的确定和计算过程,需要多做一些习题巩固。了解数据类型的自动转换规则,并会进行强制转换进一步熟悉C语言源程序的结构,掌握一些基本语句的使用(如:变量定义、赋值语句、输出函数调用语句),可以熟练地阅读简单的程序并能得到运行结果,The end of chapter 3,