三章运算符和表达式.ppt

上传人:本田雅阁 文档编号:2628516 上传时间:2019-04-24 格式:PPT 页数:56 大小:731.51KB
返回 下载 相关 举报
三章运算符和表达式.ppt_第1页
第1页 / 共56页
三章运算符和表达式.ppt_第2页
第2页 / 共56页
三章运算符和表达式.ppt_第3页
第3页 / 共56页
三章运算符和表达式.ppt_第4页
第4页 / 共56页
三章运算符和表达式.ppt_第5页
第5页 / 共56页
点击查看更多>>
资源描述

《三章运算符和表达式.ppt》由会员分享,可在线阅读,更多相关《三章运算符和表达式.ppt(56页珍藏版)》请在三一文库上搜索。

1、第三章 运算符和表达式,武汉大学计算机学院,主讲:谭成予 ,教 材: C程序设计导论,本讲重点,运算符及表达式简介,表达式:由动词(运算符和函数调用)和名词(变量和常量)组成的一个完整的句子,说明了动词是如何运用到名词上产生一个结果。 运算符:完成特定运算功能的符号。 C语言运算符的类型: 算术运算符 赋值运算符 关系运算符 逻辑运算符 条件运算符 位运算符 逗号运算符 其他运算符 运算符的优先级与结合性,本讲重点,算术运算符,+ - * / %(求余) + +(自增) - -(自减),使用要点: 1)两个整型数相除,其结果为整型; 如:10/3=3 -5/3=-1 (负数采用“向零取整”)

2、2)%运算符的两个操作数必须是整型; 如:7%4=3 特别情况: 0%5=0;5%0=5; -7%4=-3;-7%-4=-3; 7%-4=3。 即: %运算的符号只取决于第一个运算数的符号。,算术运算符,双目运算符:如 +、-、*、/和%; 单目运算符:如 “+”和“-”还可分别作为取正值、负值运算符。 单目运算符“+”和“-”优先级别高于双目运算符+、-、*、/和%; 双目运算符的优先级别:先乘除(*、/或%),后加减(+或-),算术运算符,x=30 x=24 x=11 x=1 x=0 x=1 y=25.0000,/*L3-1.C:算术运算符示例*/ #include int main(vo

3、id) short int x,a=3; float y; x=20+25/5*2; printf(“x=%dn”,x); x=25/2*2; printf(“x=%dn”,x); x=-a+4*5-6; printf(“x=%dn”,x); x=a+4%5-6; printf(“x=%dn”,x); x=-3/4%-6/5; printf(“x=%dn”,x); x=(7+6)%5/2; printf(“x=%dn”,x); y=25.0/2.0*2.0; printf(“y=%.4fn”,y); return 0; ,自增、自减运算符,+ + 自增运算符,表示加1运算 - - 自减运算符,

4、表示减1运算,前缀形式:在计算时先改变变量的值,再参与其它运算. + +i - -i 例:若 i=1, 则 k=+ +i +2 运行后 i=2、k=4,后缀形式:在计算时先参与其它运算,再改变变量的值. i+ + i- - 例:若 i=1, 而 k=i+ + +2 运行后 i=2、k=3,+ +与- -运算符的使用规则: + +与- -运算只能用于有左值的表达式,而不能用于常量或一般的表达式。 如:5+ +或(a+b)+ +为不合法的。 +与-运算符的的结合性为右结合性。,自增、自减运算符,/*L3-2.C:自增、自减运算符举例*/ #include int main() short int

5、a,b,c; a=9; b=+a; printf(“(1)a=%d*b=%dn”,a,b); a=9; b=a+; printf(“(2)a=%d*b=%dn”,a,b); return 0; ,(1)a=10*b=10 (2)a=10*b=9,自增、自减运算符,正确使用自增、自减运算符,对i+ + +j 表达式的处理:采用“自左至右”的原则 即: i+ + +j 与(i+ +)+j 等价 而不是与i+(+ +j )等价,对于代码int i = 3; i = i+; 不同编译器给出不同的结果, 有的为3, 有的为4, 哪个是正确的? 为什么这样的代码: ai = i+; 不能工作?,对于代码i

6、nt i = 3; i = i+; 不同编译器给出不同的结果, 有的为3, 有的为4, 哪个是正确的? 答: 没有正确答案; 这个表达式无定义。注意, i+ 和+i 都不同于i+1。如果你要使i 自增1, 使用i=i+1, i+=1, i+ 或+i, 而不是任何组合.,正确使用自增、自减运算符,如: 若i=3,则表达式(i+ +)+(i+ +)+(i+ +)的结果应为多少? 有的系统从左到右顺序完成括号中的运算,即表达式经过为3+4+5=12。 另外一些系统(如Turbo C、MS C)则先计算表达式的值,再自加3次i,即表达式结果为3+3+3=9。,正确使用自增、自减运算符,对printf(

7、“%d,%d”, i,i+ +);的理解 若 i=3 ,则在Turbo C中对输出函数参数的求值顺序采用“自右至左” 结果为:4,3(而不是3,3),不要滥用增量运算符; 增量运算符有副作用,会改变运算分量的值 但是如果使用不当,会带来意想不到的结果.,正确使用自增、自减运算符,对于代码int i = 3; i = i+; 不同编译器给出不同的结果, 有的为3, 有的为4, 哪个是正确的? 为什么这样的代码: ai = i+; 不能工作?,为什么这样的代码: ai = i+; 不能工作? 答: 子表达式i+ 有一个副作用 它会改变i 的值 由于i 在同一表达式的其它地方被引用, 这会导致无定义

8、的结果, 无从判断该引用(左边的ai 中)是旧值还是新值。,正确使用自增、自减运算符,本讲重点,赋值运算符,变量=表达式,含义:将“=”右边的运算对象之值赋给左边的运算对象。 如:x=1; x=x+1;,使用要点: (1)赋值运算符左边的量(称为左值)一般是变量。 (2)当“=”两边数据类型不同时,将进行数据类型的自动转换,原则是:以“=”左边运算对象的数据类型为准。 如: int x; float y=3.5; x=y; 则运行结果为int型,赋值表达式,求解过程: 赋值运算符按照“右结合性”顺序运算,将“=”右边表达式的值赋值给左边的变量。,表达式值为3,a,b,c值均为3 表达式值为7,

9、a值为7,c为2 表达式值为10,a=10,b=4,c=6 表达式值为5,a=5,b=10,c=2 若a=12,(1)则a-=a*a 后,a=-132,(2)a+=-132后,a=-264,使用举例: a=b=c=3 a=5+(c=2) a=(b=4)+(c=6) a=(b=10)/(c=2) a+=a-=a*a,赋值表达式,注意: (1)区分赋值语句和赋值表达式; (2)赋值表达式不仅可以出现在赋值语句中,也可以出现在其它语句中。 (3)赋值运算符的优先级别今比逗号运算符级别高,低于其他运算符。 (4)赋值表达式的值等于右边表达式的值。,赋值运算时不同类型数据间的自动转换,1、实型数据赋值给

10、整型数据时,舍弃小数部分; 即:int=float的结果为int型。 如:float a; int s; a=12.34; s=a; 这时s的值为12。 2、将整型数据赋值给实型变量时,数值不变,但数据是浮点形式的; 即float=int的结果为float型。 如:int s; float a; s=12; a=s; 这时a的值为12.00000。,赋值运算时不同类型数据间的自动转换,3、当字符数据赋值给整型变量时,则将字符数据放到整型变量的低8位中,高8位数根据的存放数据有两种情况: 即: int=char 当char为无符号或unsigned char时,高8位应补0; 如:unsigne

11、d char c; int x; c=376; (八进制数376) x=c; 则x的值为254。 当char为有符号数据时,高8位需进行“符号位扩展”,即高8位将依据符号位的值来决定是补0或补1; 如:char c; int x; c=376; (八进制数376) x=c; 则x的值为-2。,1 1 1 1 1 1 1 0,1 1 1 1 1 1 1 0,0 0 0 0 0 0 0 0,1 1 1 1 1 1 1 1,1 1 1 1 1 1 1 0,1 1 1 1 1 1 1 0,赋值运算时不同类型数据间的自动转换,4、将带符号的整型数据赋值给长整型数据时,要进行符号扩展。如果int型数据为正

12、值,则long int 型数据的高16位补0;如果int型数据为负值,则long int 型数据的高16位补1,以保持其原有数据不变。 5、将 long int 型数据赋值给int型数据时,只将long int 型数据的低16位原封不动的送到int 型变量中去(截断)。 6、将unsigned int型数据赋值给long int型数据时,不存在符号扩展问题,只需将高位补0;将unsigned int型数据赋值给 int型数据时,有可能出现错误数据。 如: int a; unsigned b=65535; a=b; printf(“%dn”,a); 此时a的值为-1。,复合赋值运算符,在赋值运算

13、符“=”之前加上其它运算符构成的运算符。,表达式1 运算符=表达式2 等价于:表达式1=表达式1 运算符 (表达式2),a+=3 等价于 a=a+3 x*=3 等价于 x=x*3 x%=3 等价于 x=x%3 x/=y+3 等价于 x=x/(y+3),使用要点 凡是二元(二目)运算符,都可以与“=”组合成复合赋值符 如:+=,-=,*=,/=,%=,=,&=,=,|=等。 使用复合赋值符的目的:简化程序;提高编译效率。,本讲重点,关系运算符,关系运算符用于判断各个运算对象之间的相互关系 符号类型:、=、=、!= 优先级: 、=的优先级相同,而= =、!=优先级相同,且前者高于后者; 关系运算符

14、的优先级低于算术运算符,高于赋值运算符。 例: ca+b 等价于 c(a+b) 算术运算符 高 ab!=c 等价于 (ab)!=c a= =bc 等价于 a=(bc) 关系运算符 低,关系表达式,用关系运算符将两个表达式连接起来的式子(连接的表达式可以是算术表达式也可以是关系表达式、逻辑表达式、赋值表达式、字符表达式) 例如:ab、 a+bc-d、(a=3)(b=5)、ab)(bc)等,关系表达式,关系表达式的值为一个逻辑值,即只有“真”和“假”两种状态. C语言中没有逻辑型数据,借用数值表示。C语言规定,对于关系表达式的结果分别用1、0表示“真”、“假”。 关系表达式条件成立(值为真),则表

15、达式的值为真(1),否则为假(0)。 例如:(1)已知a=12,b=20;则表达式ab的值为“0”; 而ac的值为“1”; 表达式c=ab的值为“0”; 表达式a!=b+c的值为“1”。 C语言识别表达式是否成立的方法是:所有值为“0”的表达式表示“假”,所有值为“非零” 的表达式都表示“真”。 请区别:x=1 与 x= =1 的不同。,关系表达式,/*L3-3.C:*/ #include int main(void) int a,b,c; a=b=c=10; a=b= c; printf(“a=%d,b=%d,c=%dn”,a,b,c); a=(b=c+*2); printf(“a=%d,b

16、=%d,c=%dn”,a,b,c); a=bc=100; printf(“a=%d,b=%d,c=%dn”,a,b,c); return 0; ,a=1,b=10,c=10 a=1,b=20,c=11 a=0,b=20,c=11,本讲重点,逻辑运算符,1、含义:逻辑运算符用于完成逻辑(布尔)运算。 2、符号类型:&(逻辑与)、|(逻辑或)、!(逻辑非) 3、优先级:!优先级别高于&和|,而&又高于|。 4、使用要点 在C语言中,没有逻辑型的数据,以“1”代表“真”,以“0”代表“假”。 逻辑运算规则: & 参与运算的表达式同时为真, 则&运算的结果为真; | 参与运算的表达式其中之一 为真,则

17、|运算的结果为真; ! 为单目运算符,取运算对象的相反值。,逻辑运算真值表,逻辑运算短路原则,a & b 当a为0时,可提前计算表达式结果为0,因此不在计算b。 例如,设变量int m,n,a,b的值均为0,则执行表达式(m=a=b)|(n=a=b)后,m, n 的值分别为( )和( )。,a | b 当a为1时,可提前计算表达式结果为0,因此不在计算b。,逻辑运算符,/*L3-4.C: 判断一年是否是闰年*/ /*分析:如果年号能被4整除而不能被100整除,或者能被400整除就是闰年;否则就是平年。*/ #include int main(void) int year,leap; print

18、f(“Input your year:n”); scanf(“%d”, ,Input your year: 1944 1944 is a leap year.,本讲重点,条件运算符,表达式1?表达式2:表达式3,条件运算符的执行顺序 先求表达式1,若为真则求解表达式2,整个表达式的值为表达式2的值;若表达式1的值为假则求解表达式3,整个表达式的值为表达式3的值.,条件运算符的优先级别高于赋值运算符,但低于其他运算符。,条件表达式中表达式1的类型可以与表达式2和表达式3的类型不一致.表达式2与表达式3的类型也可以不一致.,条件运算符,/*L3-5.c: 条件运算符范例*/ #include in

19、t main(void) float x=1.0; int a=2,b=3; x=(ab)?a:b; printf(“%.4f”,x); return 0; ,3.0000,条件表达式(ab)?a:b的值为整型数据,但x为实型数据,所以输出为实型数据.,条件运算符,/*L3-6.C:*/ #include int main(void) int a,b,c; a=b=c=1; a+=b; b+=c; c+=a; printf(“(1)%dn”,ab?a:b); printf(“(2)%dn”,ac?a-:c+); (a=b=c)?printf(“AA”):printf(“CC”); printf

20、(“na=%d,b=%d,c=%dn”,a,b,c); return 0; ,(1)2 (2)3 CC a=2,b=2,c=4,条件运算符,例3.7:计算下面的函数 1 x0 sign(x)= 0 x=0 1 x0,#include int main(void) float x; scanf(“%f”, ,本讲重点,位运算符-位逻辑运算符,1 组成:&(按位与) |(按位或) (按位反) (按位异或) 2 运算规则:位逻辑运算是按二进制一位一位进行运算,相邻位之间没有进位和借位等问题。 &、|和运算符的运算规则与逻辑运算符的规则类似。 (按位异或)可看作按位加,不产生进位。 3 优先级别:优先

21、级别最高,其余3个优先级别依次为 & 高于 高于 | 但3个都高于逻辑运算符,低于关系运算符。,例:如果m为0x137f,n为0xf731,则m和n在16位计算机内的二进制表示形式如下: m 0 0 0 1 0 0 1 1 0 1 1 1 1 1 1 1 n 1 1 1 1 0 1 1 1 0 0 1 1 0 0 0 1 _ m&n= 0 0 0 1 0 0 1 1 0 0 1 1 0 0 0 1=0x1331 m|n= 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1=0xf77f mn= 1 1 1 0 0 1 0 0 0 1 0 0 1 1 1 0=0xe44e m= 1

22、1 1 0 1 1 0 0 1 0 0 0 0 0 0 0=0xec80 如果是32位机,m的结果是不同的,请同学们考虑应当是多少?,位运算符-位逻辑运算符,4 与逻辑运算符区别: 位逻辑运算符是针对二进制位,而逻辑运算符是针对整个表达式。 位逻辑表达式计算出来的结果有具体数值,而逻辑表达式结果只有“真”和“假”两个取值。 位逻辑运算符&、|和的两个运算分量是可以交换的,但逻辑运算符&和|的运算分量是不能交换的。 例: 4&6 结果为 4 4&6 结果为 1 4|6 结果为 6 4|6 结果为 1 4&8 结果为 0 4&8 结果为 1 4|8 结果为 12 4|8 结果为 1, 使特定位翻转

23、 例如, 假设变量a的取值为0x7a,则表达式a017的结果的低4位和变量a的低4位正好相反。 017 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 a 0 0 0 0 0 0 0 0 0 1 1 1 1 0 1 0 _ a017= 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0 1 与0异或,结果保持原值不变 使用下面3个语句可交换两个变量取值 a=ab; b=ba; a=ab;,ab=aba=aab=b,位运算符-位逻辑运算符,位运算符-位逻辑运算符,5、 位逻辑运算符特殊用法: & 取某个数的指定位(保留指定位) 例如, 0377表示成二进制为 0 000

24、000 011 111 111 那么表达式a&0377 结果为变量a的低8位。(也可看成a的高8位清0)。 指定位清0 | 将某个数指定位置1 例如,017表示成二进制为 0 000 000 000 001 111 那么表达式a|017结果为变量a的低4位置1,其余为不变。,例,将int型变量a的最低位清0 在16位机器中,可用表达式 a&0177776 在32位机器中,要用表达式 a&037777777776 可见采用以上做法可移植性差,采用运算符进行改进,可采用以下表达式 a&1 理由: 1在16位机中结果为1111 1111 1111 1110=0177776 1在32位机中结果为111

25、1 1111 1111 1111 1111 1111 1111 1110= 037777777776 类似表达式如 a&077 结果为将变量a的低6位清0,位运算符-位逻辑运算符,位运算符-移位运算符,1 组成: 左移 右移 要求参与运算的两个运算分量是整型数据 2 使用形式: 表达式1表达式2 3 运算规则: 将“表达式1”的值(二进制形式)向左移动“表达式2”取值所表示的位数。移出去的高位被舍弃,而右边低位补0。 例如,a=10,表示成二进制数为00001010,那么 a 0 0 0 0 1 0 1 0 a2的结果为 0 0 1 0 1 0 0 0 = 40 如果移位后的数据没有产生数据溢

26、出,则左移n位相当与被移对象乘以2n。,运算规则: 将“表达式1”的值(二进制形式)向右移动“表达式2”取值所表示的位数。移出去的低位被舍弃。 例如,a=10,表示成二进制数为00001010,那么 a 0 0 0 0 1 0 1 0 a2的结果为 0 0 0 0 0 0 1 0 = 2 右移一位表示除以2,右移n位相当于被移对象除以2n. 在右移时,要注意的是对于无符号数,右移后左边高位补0。这种移位方式称为“逻辑移位”。 对于有符号数,如果移位对象是正数,左边高位补0;如果移位对象是负数,则左边高位补1(即与补符号位相同的数),这种移位方式称为“算术移位”。 注意,有些系统采用逻辑移位方式

27、,而另外一些系统采用算术移位方式。Turbo C采用算术移位。,位运算符-移位运算符,3 运算规则: 例如,a=0113755,则 a 1 0 0 1 0 1 1 1 1 1 1 0 1 1 0 1 如果系统采用逻辑移位,则 a1的结果为 0 1 0 0 1 0 1 1 1 1 1 1 0 1 1 0 如果系统采用算术移位,则 a1的结果为 1 1 0 0 1 0 1 1 1 1 1 1 0 1 1 0 请同学们在使用右移运算符时注意留意你所使用的系统处理的方法。 优先级别: 移位运算符的优先级别低于算术运算符,高于关系运算符。,位运算符-移位运算符,本讲重点,逗号运算符,表达式1,表达式2

28、表达式1,表达式2,表达式3,表达式n,含义:用于分隔各个表达式,最后一个表达式的值代表整个表达式的值 如:a=1,a+2 a=3,a+3,a+10,a=a+20,a+1,从左至右依次计算各个表达式的的值,最后一个表达式的值即为整个表达式的值。 例:1)a=3*5,a*4 结果为60 2)(a=3*5,a*4),a+5 结果为20 “顺序求值运算符”,逗号运算符,使用要点 优先级在所有运算符中为最低。 如: x=(a=3,6*a) 结果为 x=18 x=a=3,6*a 结果为 18 (x=3) 并非任何地方出现的“,”都是作为运算符使用的。 如: printf(“%d,%d,%d”,a,b,c

29、); 即函数参数间的“,”只作为分隔符。,本讲重点,其他运算符, 强制类型运算符 使用形式 (类型名)表达式 例如,假设变量a为int类型,表达式(double)a 的结果为double 类型的。(注意并没有改变变量a的类型),其他运算符,3 sizeof() 用于计算变量或者某种类型的数据在计算机内部表示所占用的字节数。例如, sizeof(int) 在字长16位的机器中,该表达式结果为2。在字长为32位的机器中,该表达式的结果为4。 基本运算符 ( ) 括号 下标运算符 - 指向运算符 . 成员运算符 以上4个运算符优先级别是所有运算符中最高的。,本讲重点,各种运算符的结合性,单目运算符、条件运算符、赋值运算符的结合性是从右到左。其余运算符的结合性均为从左到右。,各种运算符的优先级,基本运算符 高 单目运算符 算术运算符(先乘除,后加减) 移位运算符 关系运算符 逻辑运算符(!除外) 条件运算符 赋值运算符 低 逗号运算符,THE END,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1