C语言课件第3章_第1页
C语言课件第3章_第2页
C语言课件第3章_第3页
C语言课件第3章_第4页
C语言课件第3章_第5页
已阅读5页,还剩147页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第3章表达式3.1表达式基础3.2算术表达式3.3赋值表达式3.4逻辑表达式3.5位运算表达式3.6其它表达式习题三第3章表达式3.1表达式基础13.1表达式基础3.1.1表达式的组成1.运算符运算符又称操作符,是一个符号,它指示在一个或多个操作数上完成某种运算操作或动作。C语言中,将除了输入、输出及程序流程控制操作以外的所有基本操作都作为运算处理,如赋值运算“=”、逗号运算“,”、括号运算“( )”。C语言的运算符按完成的运算操作可分为算术运算符、关系运算符、逻辑运算符、赋值运算符与其它运算符等,按参与运算符的操作数个数可分为单目运算符、双目运算符与三目运算符。3.1表达式基础3.1.1表达式的组成12

(1)算术运算符:+、−、*、/、%、++、−−

(2)关系运算符:<、<=、==、!=、>、>=。

(3)逻辑运算符:!、&&、||。

(4)位运算符:<<、>>、~、|、^、&。

(5)赋值运算符:=、+=、−=、*=、/=、%=。

(6)条件运算符:?:。

(7)逗号运算符:,。(8)指针运算符:*、&。

(9)求字节数运算符:sizeof。

(10)强制类型转换运算符:(类型)。(11)其它运算符;· 、→、( )、[]等。(1)算术运算符:+、−、*、/、%、++、−−32.操作数操作数是运算符的操作对象,可以是常量、变量、函数与表达式。常量、变量、函数本身就是简单表达式,从一般意义上讲,C语言中所有操作数都是表达式。复杂表达式由运算符连接简单表达式形成。2.操作数43.1.2表达式的书写C语言的表达式虽然来源于数学表达式,是数学表达式在计算机中的表示,但在书写时应该注意遵循C语言表达式书写的原则:(1)C语言的表达式只能采用线性的形式书写。例如:①应写成1/3+i+j*j*j。②应写成(a+b)/(c+d)*e+f。3.1.2表达式的书写5(2)C语言的表达式只能使用C语言中合法的运算符和操作数,对有些操作必须调用库函数完成,而且运算符不能省略。例如:①πr2应写成3.14159*r*r。②应写成0.5*a*b*sin(alph)。③|x-y|应写成fabs(x-y)。④y+2X应写成y+pow(2,x)。(2)C语言的表达式只能使用C语言中合法的运63.1.3表达式的分类C语言表达式种类很多,有多种分类方法。我们一般依据运算的特征将表达式分为:①算术表达式,如a+b*2.0-3.0/5.0。②关系表达式,如x>=y,关系表达式可以认为是逻辑表达式的特殊情况。③逻辑表达式,如(x>=2)&&(x<=8)。④赋值表达式,如a=b=c=1。⑤条件表达式,如(a>b)?a:b。⑥逗号表达式,如a=2,b=a*a,c=sqrt(b)。3.1.3表达式的分类71.运算的优先级运算的优先级是指运算执行的先后顺序。C语言将运算的优先级划分为15级,第1级优先级最高,第15级优先级最低。初等运算( )、[ ]、→、·的优先级最高;单目运算!、~、++、−−、−、(类型)、*、&、sizeof的优先级次高;算术运算+、−、*、/、%再次之;然后是关系运算<、<=、==、!=、>、>=;再然后是逻辑运算&&、||,条件运算式?:,赋值运算=、+=、−=、*=、/=、%=;1.运算的优先级8逗号运算优先级最低;位运算优先级比较分散。可将优先级顺序简单记忆为算术、关系和逻辑,移位、位逻辑在中间。请参阅附录B。表达式求值时按运算的优先级别从高到低顺序进行,优先级相同的运算顺序由运算的结合性规定。通过圆括号运算可以改变运算的优先顺序,先圆括号内,后圆括号外。逗号运算优先级最低;92.运算符的结合性运算符的结合性是指,优先级相同的运算从左到右进行(左结合性)还是从右至左进行(右结合性),左结合性是人们习惯的计算顺序。C语言中,只有单目运算(!、~、++、--、-、*、&)、条件运算(?:)、赋值运算(=、+=、-=、*=、/=、%=)的结合性是右结合,其余运算为左结合。2.运算符的结合性103.类型转换一般地,相应的运算只有相应类型的数据才能进行,不同类型数据进行运算时,要进行类型转换。类型转换有自动转换与强制转换两种方式。1)自动转换自动转换(又称隐含转换)由系统自动完成,转换的规则如图3-1所示。3.类型转换11图3-1中,横向箭头方向表示必定要进行的转换,即short型、char型数据必定先转换成int型,float型数据必定先转换为double型,再进行运算。纵向箭头方向表示类型自动转换的方向,请注意转换的方向是由低向高转换的,int型最低,double型最高。int型与unsigned型数据进行运算,int型转换成unsigned型;int型与long型数据进行运算,int型转换成long型;int型与double型数据进行运算,int型转换成double型。其它类推。这种转换是一种保值映射,在转换中数据的精度不受损失。图3-1中,横向箭头方向表示必定要进行的转换,即12图3-1类型自动转换规则图3-1类型自动转换规则132)强制转换强制类型转换通过类型转换运算完成。格式:(类型名)(表达式)强制转换将表达式的类型强制转换成类型名指定的类型。例如x、y为float,则(int)(x+y)将实型表达式x+y强制转换成整型。值得注意的是,强制类型转换在将高类型转换为低类型时,数据精度会有损失,是一种不安全的转换。同时强制类型转换是一次性的、暂时性的,并不能永久改变所转换表达式的类型。例如a为int,则(double) a为双精度型,a依然为整型。2)强制转换14例3–1表达式计算。(1)floatx=2.5,y=4.7;inta=7;计算x+a%3*(int)(x+y)%2/4⑦①④③②⑤⑥①a%3等于1。②x+y等于7.2。③(int)(x+y)等于7。④a%3*(int)(x+y)等于7。⑤a%3*(int)(x+y)%2等于1。⑥a%3*(int)(x+y)%2/4等于0。⑦x+a%3*(int)(x+y)%2/4等于2.5+0,结果为2.5。例3–1表达式计算。15(2)inta=2,b=3;floatx=3.5,y=2.5;计算(float)(a+b)/2+(int)x%(int)y②①③⑦④⑥⑤①a+b等于5。②(float)(a+b)等于5.0,强制转换成float型。③(float)(a+b)/2等于5.0/2.0,结果为2.5。④(int)x等于3,强制转换成int型。⑤(int)y等于2,强制转换成int型。⑥(int)x%(int)y等于1。⑦(float)(a+b)/2+(int)x%(int)y等于2.5+1.0,结果为3.5(双精度型)。(2)inta=2,b=3;floatx=3.16(3)inti=3;floatf=1.0;doubled=2.3;计算10+′a′+i*f-d①③②④①′a′转换成97,10+′a′等于107。②i,f转换成双精度型,i*f等于3.0。③107转换成双精度型,10+′a′+i*f等于110.0。④10+′a′+i*f-d等于107.7。(3)inti=3;floatf=1.0;do173.2算术表达式1.自增运算自增运算符:++。自增运算是单目运算,操作数只能是整型变量,有前置、后置两种方式:++i,在使用i之前,先使i的值增加1,俗称先增后用。i++,先使用i的值,然后使i的值增加1,俗称先用后增。3.2算术表达式1.自增运算18例如:i=1999;j=++i;/*先将i的值增1,变为2000后赋给j,j的值也为2000*/j=i++;/*先将i的值赋给j,j的值为1999。然后将i的值增1,变为2000*/自增运算的优先级处于第2级,具右结合性。例如:192.自减运算自减运算符:--自减运算与自增运算一样也是单目运算,操作数也只能是整型变量。同样有前置、后置两种方式:--i,在使用i之前,先使i的值减1,俗称先减后用。i--,先使用i的值,然后使i的值减1,俗称先用后减。2.自减运算20如:i=2000;j=--i;/*先减,将i的值减1,变为1999。后使用,j的值也为1999*/j=i--;/*先使用,j的值为2000。后减,将i的值减1,i的值变为1999*/自减运算的优先级、结合性同自增运算。如:i=2000;21请特别注意:(1)自增、自减运算只能用于变量,不能用于常量或表达式。(2)自增、自减运算比等价的赋值语句生成的目标代码更高效。(3)自增、自减运算常用于循环语句中,使循环控制变量自动加或减1;还可用于指针变量,使指针指向下一个或上一个地址。请特别注意:22(4)表达式中包含有自增、自减运算时,特别容易出错,务请小心。例如,i=1,(++i)+(++i)+(++i)的值为多少呢?可能计算出是9(=2+3+4),其实这是错误的。实际上计算时先对整个表达式扫描,i先自增3次,由1→2→3→4,因此计算结果应为12(=4+4+4)。(i++)+(i++)+(i++)的值又是多少呢?分析同上,应为3,当然表达式计算完成后i的值同样改变为4。(4)表达式中包含有自增、自减运算时,特别容易出错233.运算符的组合问题C语言的运算符一般为一个字符,有的由两个字符组成。在表达式中出现多个字符时如何组合呢?C编译系统在处理时,原则上尽可能自左至右将若干字符组合成一个运算符。如将i+++j解释为(i++)+j,而不是i+(++j)。如要表示i+(++j),必须加括号。标识符、关键字也按同样的原则进行处理。3.运算符的组合问题24例3–2自增自减运算。/*程序3-2,自增自减运算*/#include″stdio.h″main(){inti,j;i=j=5;printf(″i++=%d,j--=%d\n″,i++,j--);printf(″++i=%d,--j=%d\n″,++i,--j);printf(″i++=%d,j--=%d\n″,i++,j--);printf(″++i=%d,--j=%d\n″,++i,--j);printf(″i=%d,j=%d\n″,i,j);}例3–2自增自减运算。25运行结果: i++=5,j−−=5 ++i=7,−−j=3 i++=7,j−−=3 ++i=9,−−j=1 i=9,j=1运行结果:263.3赋值表达式3.3.1赋值运算赋值运算符:=。赋值运算是双目运算,一个操作数为变量,另一个操作数为表达式。赋值运算符左边的操作数只能是变量,右边可以是表达式。进行赋值运算时先计算右边表达式的值,然后将右边表达式的值赋给左边变量,即送给左边变量对应的存储单元,并以此作为整个赋值表达式的值。例如i为int,i=3+5%2,则先计算右边表达式3+5%2的值,得到4,然后将4赋给左边变量i。3.3赋值表达式3.3.1赋值运算赋值27说明:(1)赋值运算的优先级为第14级,具有右结合性。(2)赋值运算中的表达式最简单的形式是一个常量,这时变量得到一个初值。例如: inti;floatx;charch; i=100;x=12.345;ch='A';说明:28(3)赋值运算中的表达式又可以是赋值表达式,如此可辗转赋值。例如: intx,y,z;x=y=z=0.0,相当于x=(y=(z=0.0)),即x、y、z都得到值0.0。 ③② ①(4)赋值运算符“=”不同于数学中的等号。例如,i=i+1在数学中绝对不成立,但在C语言中肯定成立,其含义是将i的当前值加上1再赋给i。(3)赋值运算中的表达式又可以是赋值表达式,如此可293.3.2赋值类型转换在进行赋值运算时,一般要求赋值运算符两侧操作数的类型相同或相容。如果赋值运算符两侧操作数的类型不一致,要进行类型转换。赋值运算时的类型转换以赋值运算左边操作数的类型为主体进行。(1)将实型数据赋给整型变量时,舍弃实数的小数部分。例如i为int,若有i=1.23,则i的值为1。(2)将整型数据赋给单、双精度型变量时,数值大小不变,但以浮点形式存储到变量中。3.3.2赋值类型转换30(3)字符型数据赋给整型变量时,由于字符数据只占一个字节,而整型变量为2个字节,因此将字符型数据放在整型变量的低8位中,而对整型变量的高8位要进行扩充。(4)将基本整型数据赋给长整型变量时,基本整型数据放在长整型变量的低16位,高16位用符号位扩充。反之,将长整型数据赋给基本整型变量时,只将长整型数据的低16位送给基本整型变量。(3)字符型数据赋给整型变量时,由于字符数据只占31①inti=-1;longintj;j=i;i的二进制形式:0000000000000001j的二进制形式:00000000000000000000000000000001②inti=−1; longintj; j=i;i的二进制形式:1111111111111111j的二进制形式:11111111111111111111111111111111①inti=-1;32③longinti=−1; intj; j=i;i的二进制形式:11111111111111111111111111111111j的二进制形式:1111111111111111③longinti=−1;33(5)将无符号整型数据赋给长整型变量时,不存在符号位扩展的问题,只需将高位补0即可。将无符号整型数据赋给一个占字节数相同的整型变量时,将无符号整型数据原样送整型变量中,并将最高位当作符号位,如果数据超出相应的整型范围,将产生数据错误。如果将整型数据赋给占字节数相同的无符号整型变量时,也是原样照赋,最高位作数值处理。(5)将无符号整型数据赋给长整型变量时,不34例如:①unsignedinti=65535; intj; j=i;/*j的值为−1*/②inti=−1; unsignedintj;  j=i;/*j的值为65535*/例如:353.3.3复合赋值运算在基本赋值运算符“=”之前加上任一双目算术运算符及位运算符可构成复合赋值运算符,又称带运算的赋值运算符。算术复合赋值运算符:+=、-=、*=、/=、%=位复合赋值运算符:&=、|=、^=、>>=、<<=一般形式:变量☆=表达式等价于:变量=变量☆表达式☆代表任一双目算术运算符或位运算符。复合赋值运算先进行所带运算,再进行赋值运算。复合赋值运算的优先级同赋值运算。3.3.3复合赋值运算在基本赋值运算符36例如:①inta=3;a+=2等价于a=a+2,结果为5。②floatx=1.2,y=2.1;y*=x+3.4等价于y=y*(x+3.4),结果为9.66。③inta=3,b=2;b/=a+=1等价于b=b/(a=a+1),结果为0。例如:37例3-3赋值运算。 /*程序3-3,赋值运算*/ #include"stdio.h" main( ) {inti,j;floatx,y; i=j=1; x=y=1.1;printf("i=%d,j=%d\n",i,j);例3-3赋值运算。38x=i+j;y+=1;printf("x=%4.2f,y=%4.2f\n",x,y);i=i+++j;x=2*x+y;printf("i=%d,x=%4.2f\n",i,x);}运行结果: i=1,j=1 x=2.00,y=2.10i=3,x=6.10x=i+j;39printf(″x=%4.2f,y=%4.2f\n″,x,y);i=i+++j;x=2*x+y;printf(″i=%d,x=%4.2f\n″,i,x);}运行结果:i=1,j=1x=2.00,y=2.10i=2,x=6.10printf(″x=%4.2f,y=%4.2f\n″,x403.4逻辑表达式3.4.1关系表达式关系表达式是逻辑表达式中的一种特殊情况,关系表达式由关系运算符和操作数组成,关系运算用于完成数的比较运算。关系运算有<、<=、==、!=、>、>=,<、<=、>、>=的优先级相同,==、!=的优先级相同,前者的优先级高于后者。关系运算符的优先级低于算术运算,高于逻辑运算&&、||,也高于赋值运算。3.4逻辑表达式3.4.1关系表达式413.4.2逻辑表达式逻辑表达式由逻辑运算符和操作数组成,逻辑表达式用于程序设计中的条件描述。逻辑表达式中操作数可以是逻辑量和关系表达式。C语言有!、&&、‖三种逻辑运算,运算规则在上章已作介绍。!运算的优先级高于算术运算,&&运算的优先级高于‖运算,&&、‖运算的优先级低于关系运算,高于赋值运算。3.4.2逻辑表达式42在计算逻辑表达式时务请注意:&&和‖是一种短路运算。所谓短路运算,是指在计算的过程中,只要表达式的值能确定,便不再计算下去。逻辑与运算时,计算到某个操作数为假,可以确定整个表达式的值为假时,剩余的表达式部分便不再计算。逻辑或运算时,计算到某个操作数为真,可以确定整个表达式的值为真时,剩余的表达式部分便不再计算。在计算逻辑表达式时务请注意:43例如:①e1&&e2&&e3,若e1为0,可确定表达式的值为0,则不再计算e2、e3。②e1‖e2‖e3,若e1为真,则可确定表达式的值为真,也不再计算e2、e3。例如:44例3—4用逻辑表达式描述下列条件:(1)x是3的倍数。x%3==0(2)x是偶数。x%2==0(3)x是3的倍数且x是偶数。(x%3==0)&&(x%2==0)(4)100<x<200。(x>100)&&(x<200)例3—4用逻辑表达式描述下列条件:45(5)x等于2或8。(x==2)||(x==8)(6)三位数x是回文数:x/100==x%10(7)a、b、c为三边,它们构成等边三角形的条件:(a==b)&&(b==c)(8)某年是闰年:((year%4==0)&&(year%100!=0))‖(year%400==0)(5)x等于2或8。463.5位运算表达式3.5.1位逻辑运算1.按位取反运算运算符:~。按位取反运算用来对一个二进制数按位取反,即0位变1,1位变0。例如,计算~25。25的二进制表示为:0000000000011001。按位取反的结果为:1111111111100110,即−26。3.5位运算表达式3.5.1位逻辑运算47~运算常用于产生一些特殊的数。如高8位全1、低8位全0的数0xFF00,按位取反后变为0x00FF。~1,在16位与32位的系统中,都代表只有最低位为0的整数。~运算是位运算中惟一的单目运算,也是惟一具有右结合性的位运算。~运算常用于产生一些特殊的数。如高8位全1、低8位全482.按位与运算运算符:&。按位与运算的规则是操作数的对应位为1,则该位的运算结果为1,否则为0。例如,计算0x29&0x37。0x29与0x37的二进制表示为:0000000000101001与0000000000110111。按位与的结果为:00000000000100001,即0x21。按位与运算的主要用途是清零及取数的某些位或保留数的某些位。2.按位与运算49例如:①a&0,将a清0。②a&0xFF00,取数a的高8位,低8位清0。③a&0x00FF,取数a的低8位,高8位清0。例如:503.按位或运算运算符:|按位或运算的规则是操作数的对应位都为0,则该位的运算结果为0,否则为1。例如:0x29|0x37,0x29与0x37的二进制表示为:0000000000101001与0000000000110111按位或结果为:0000000000111111,即等于0x3f。利用|运算可将数的部分位或所有位置1。3.按位或运算51例如:a|0x000F,a的低4位全置1,其它位保留。a|0xFFFF,a的每一位全置1。例如:524.按位异或运算运算符:^按位异或运算的规则是操作数的对应位相同,则该位的运算结果为0,否则为1。例如:0x29^0x37,0x29与0x37的二进制表示为:0000000000101001与0000000000110111按位异或结果为:0000000000011110,即等于0x1e。利用^运算将数的特定位翻转,保留原值,不用临时变量交换两个变量的值。4.按位异或运算53例如:(1)a^0x00FF,将数a的低8位翻转,高8位不变。(2)a^0,保留数a的原值。(3)a=a^b,b=b^a,a=a^b,不用临时变量交换a,b的值。位逻辑运算自身的优先级由高到低依次是~、&、|、^,在整个运算体系中~运算的优先级位于第二级,&、|、^运算低于关系运算,高于逻辑运算。位逻辑运算意义与逻辑运算一样,但位逻辑运算对二进制位而言,且必须对数的所有二进制位进行,而且操作数只能为整数。如果参与运算的数据长度不同,将对短的数据先进行高位符号扩展后再进行位运算。例如:543.5.2移位运算1.左移位运算运算符:<<左移位运算的左操作数是要进行移位的整数,右操作数是要移的位数。左移位运算规则是高位左移后溢出,舍弃,空出的低位补0。例如,计算15<<2。15的二进制表示为:0000000000001111。左移2位结果为:0000000000111100,等于60。左移一位相当于该数乘以2,左移两位相当于该数乘以4(22)。使用左移位运算可以快速实现乘2运算。3.5.2移位运算1.左移位运算552.右移位运算运算符:>>。右移位运算规则是低位右移后被舍弃,空出的左边高位对无符号数移入0,对有符号数,如果是正数,则空出的左边高位移入0,如果是负数,则左边移入0还是1,要取决于所用的编译系统,有的移入0(逻辑右移),有的移入1(算术右移)。例如,15>>2,右移2位,等于0000000000000011,即3。2.右移位运算56右移一位相当于将该数除以2,右移两位相当于将该数除以4(22)。使用右移位运算可以快速实现除2运算。移位运算的优先级低于算术运算,高于关系运算。所有位运算也可与赋值运算组合成复合赋值运算:&=、|=、^=、<<=、>>=,请参阅赋值运算。右移一位相当于将该数除以2,右移两位相当于将该数除57例3—5取一个整数a的从右端开始的4~7位。/*程序3—5,取一个整数a的从右端开始的4~7位*/#include″stdio.h″main(){unsigneda,b,c,d;scanf(″%o″,&a);/*八进制形式输入*/b=a>>4;/*a右移4位*/c=~(~0<<4);/*得到一低4位全为1,其余位为0的数*/d=b&c;/*取b的0~3位,即得到a的4~7位*/printf(″a=%o,a(4~7)=%o″,a,d);}输入数据:331运行结果:a=331,a(4~7)=15例3—5取一个整数a的从右端开始的4~7位。583.6其它表达式3.6.1条件表达式条件表达式由条件运算符和操作数组成,用以将条件语句以表达式的形式出现,完成选择判断处理。条件运算符由“?”和“:”组成。条件运算是三目运算,有三个操作数,一般形式如下:表达式1?表达式2:表达式33.6其它表达式3.6.1条件表达式59表达式1必须为逻辑表达式,是条件运算的条件。如表达式1为真,则计算表达式2,并以此作为整个表达式的值;如表达式1为假,则计算表达式3,并以此作为整个表达式的值。例如:①a>b?a:b表示若a大于b,则表达式的值为a;若a小于b,则表达式的值为b。实际上是求a、b的最大值。②a>0?a:−a表示若a大于0,则表达式的值为a;若a小于等于0,则表达式的值为−a。实际上是求a的绝对值。条件运算的优先级为倒数第三级,高于赋值运算和逗号运算,低于逻辑运算,具有右结合性。如a>b?a:c>d?c:d,相当于a>b?a:(c>d?c:d)。表达式1必须为逻辑表达式,是条件运算的条件。如60例3—6判断整数的正负。/*程序3—6,判断整数的正负*/#include″stdio.h″main(){intx;scanf(″%d″,″&x″);x>0?printf(″%s″,″正数″):printf(″%c″,″负数″);}例3—6判断整数的正负。613.6.2逗号表达式逗号表达式由逗号运算符和操作数组成,用以将多个表达式连接成一个表达式。逗号运算符:,。逗号运算是双目运算。其简单形式为:表达式1,表达式2逗号运算的规则为先计算表达式1,再计算表达式2,并以此作为整个表达式的值。例如,计算a=2,a*6的值。先计算表达式a=2,再计算表达式a*6,并以此作为整个表达式的值,因此该表达式的值为12。3.6.2逗号表达式62逗号运算的优先级最低,具有左结合性。逗号表达式的更一般使用形式为:表达式1,表达式2,表达式3,…,表达式n这时的运算规则是先计算表达式1,再计算表达式2,再计算表达式3,…,再计算表达式n的值,并以此作为整个表达式的值。所以逗号运算又称为顺序求值运算。例如:x=a=3,6*x,6*a,a+x的值为6。逗号运算的优先级最低,具有左结合性。633.6.3其它运算

1.取地址运算运算符:&取地址运算是单目运算,操作数只能是变量,得到变量的地址。C语言程序设计中许多场合要使用到地址数据。如输入函数scanf(),输入参数就要求是地址表,将读入的数据送变量对应的存储单元中。取地址运算的优先级次高。C语言还提供一个指针运算“*”,用于取存储单元的内容.3.6.3其它运算1.取地址运算642.求字节数运算运算符:sizeof求字节数运算是单目运算,操作数可以是类型名,也可以是变量、表达式,用以求得相应类型或数据所占的字节数。此运算的优先级与取地址运算优先级相同。2.求字节数运算65例3-7计算各种类型数据的存储字节数。/*程序3-7,计算各种类型数据的存储字节数*/#include"stdio.h"main( ){clrscr( );printf("sizeof(int)=%dbyte\n",sizeof(int));printf("sizeof(longint)=%dbyte\n",sizeof(longint));printf("sizeof(shortint)=%dbyte\n",sizeof(shortint));printf("sizeof(unsignedint)=%dbyte\n",sizeof(unsignedint));printf("sizeof(unsignedlongint)=%dbyte\n",sizeof(unsignedlongint));printf("sizeof(float)=%dbyte\n",sizeof(float));printf("sizeof(double)=%dbyte\n",sizeof(double));printf("sizeof(char)=%dbyte\n",sizeof(char));}例3-7计算各种类型数据的存储字节数。663.括号运算在其它语言中括号是某些语法成分的描述方式,C语言将括号亦作为运算处理。(1)圆括号运算():用于改变运算的优先级,还用于将函数的参数与函数名相分离。(2)中括号运算[]:又称下标运算,用来得到数组的分量下标变量。括号运算的优先级处于最高一级。3.括号运算67习题三1.简述C语言表达式的书写原则。2.简述C语言运算的优先级与结合性。3.简述表达式计算时数据类型的自动转换规则。4.简述表达式计算时数据类型的强制转换方法。

习题三1.简述C语言表达式的书写原则。685.将下列数学表达式书写成C语言表达式。(1)ax2+bx+c (2)(3) (4)(5) ln(x++sin2x+cos3x) (6)πr2h1+πr2h25.将下列数学表达式书写成C语言表达式。696.将下列条件用C语言逻辑表达式描述。(1)i是j的倍数。(2) k是奇数且是3的倍数。(3)点(x+y)在以原点为圆心,r为半径的圆上。(4)C语言考试成绩cj高于60分,低于70分。(5)三个数x、y、z互不相等。(6)以a、b、c为三边构成三角形的条件。(7)方程ax2+bx+c=0有实根。(8)四位的整数x是回文数。

6.将下列条件用C语言逻辑表达式描述。707.已知变量有如下的定义: floatx=20.5; inty=12,z=8;计算下列表达式的值。(1) (int)x+y+z (2) x+y%3%2(3) y%=z%=5 (4) x*(y+=z)(5) y+=y-=y*=y (6) x+y+z,x+y,x(7) x*=y,x/=y,y (8) z=++y+(++y)+(++y)

7.已知变量有如下的定义:718.已知变量有如下的定义:inta=3,b=4,c=5;计算下列表达式的值。(1)a+b>c&&b==c (2) a‖b+c&&b−c(3)!(a>b)&&!c‖4 (4) !(x=a)&&(y=b)(5)!(a+b)+c−1&&b+c/2 (6) a+b&&b+c‖c+a

8.已知变量有如下的定义:729.已知变量有如下的定义:inta=12;计算下列表达式的值。(1) ~a (2) a&0xF0F0(3) a|0xF0F0 (4) a^0xFF00

9.已知变量有如下的定义:7310.阅读下面的程序,给出程序的运行结果。#include"stdio.h"main( ){intx,y,z;x=2;y=x+2;printf("x=%d,y=%d\n",x,y);x*=y=z=4;printf("x=%d,y=%d,z=%d\n",x,y);x=y==z;printf("x=%d,y=%d\n",x,y);}

10.阅读下面的程序,给出程序的运行结果。7411.编写程序,求三个数的和、积以及平均值。12.a=5,b=10,编写程序计算(a+b)/(a-b)的值。13.a=b=1,编写程序计算a==b、++a<++b和a&&b的值。14.x=3,y=4,z=5,编写程序计算以下表达式的值:11.编写程序,求三个数的和、积以及平均值。7515.a=1,b=2,c=1,编写程序计算以下表达式的值:(1)(-b+)/2a。(2)(-b-)/2a。16.i=12,编写程序验证:(1)i*4与i<<2结果相同。(2)i/4与i>>2结果相同。

15.a=1,b=2,c=1,编写程序计算以下表达式的值:76第3章表达式3.1表达式基础3.2算术表达式3.3赋值表达式3.4逻辑表达式3.5位运算表达式3.6其它表达式习题三第3章表达式3.1表达式基础773.1表达式基础3.1.1表达式的组成1.运算符运算符又称操作符,是一个符号,它指示在一个或多个操作数上完成某种运算操作或动作。C语言中,将除了输入、输出及程序流程控制操作以外的所有基本操作都作为运算处理,如赋值运算“=”、逗号运算“,”、括号运算“( )”。C语言的运算符按完成的运算操作可分为算术运算符、关系运算符、逻辑运算符、赋值运算符与其它运算符等,按参与运算符的操作数个数可分为单目运算符、双目运算符与三目运算符。3.1表达式基础3.1.1表达式的组成178

(1)算术运算符:+、−、*、/、%、++、−−

(2)关系运算符:<、<=、==、!=、>、>=。

(3)逻辑运算符:!、&&、||。

(4)位运算符:<<、>>、~、|、^、&。

(5)赋值运算符:=、+=、−=、*=、/=、%=。

(6)条件运算符:?:。

(7)逗号运算符:,。(8)指针运算符:*、&。

(9)求字节数运算符:sizeof。

(10)强制类型转换运算符:(类型)。(11)其它运算符;· 、→、( )、[]等。(1)算术运算符:+、−、*、/、%、++、−−792.操作数操作数是运算符的操作对象,可以是常量、变量、函数与表达式。常量、变量、函数本身就是简单表达式,从一般意义上讲,C语言中所有操作数都是表达式。复杂表达式由运算符连接简单表达式形成。2.操作数803.1.2表达式的书写C语言的表达式虽然来源于数学表达式,是数学表达式在计算机中的表示,但在书写时应该注意遵循C语言表达式书写的原则:(1)C语言的表达式只能采用线性的形式书写。例如:①应写成1/3+i+j*j*j。②应写成(a+b)/(c+d)*e+f。3.1.2表达式的书写81(2)C语言的表达式只能使用C语言中合法的运算符和操作数,对有些操作必须调用库函数完成,而且运算符不能省略。例如:①πr2应写成3.14159*r*r。②应写成0.5*a*b*sin(alph)。③|x-y|应写成fabs(x-y)。④y+2X应写成y+pow(2,x)。(2)C语言的表达式只能使用C语言中合法的运823.1.3表达式的分类C语言表达式种类很多,有多种分类方法。我们一般依据运算的特征将表达式分为:①算术表达式,如a+b*2.0-3.0/5.0。②关系表达式,如x>=y,关系表达式可以认为是逻辑表达式的特殊情况。③逻辑表达式,如(x>=2)&&(x<=8)。④赋值表达式,如a=b=c=1。⑤条件表达式,如(a>b)?a:b。⑥逗号表达式,如a=2,b=a*a,c=sqrt(b)。3.1.3表达式的分类831.运算的优先级运算的优先级是指运算执行的先后顺序。C语言将运算的优先级划分为15级,第1级优先级最高,第15级优先级最低。初等运算( )、[ ]、→、·的优先级最高;单目运算!、~、++、−−、−、(类型)、*、&、sizeof的优先级次高;算术运算+、−、*、/、%再次之;然后是关系运算<、<=、==、!=、>、>=;再然后是逻辑运算&&、||,条件运算式?:,赋值运算=、+=、−=、*=、/=、%=;1.运算的优先级84逗号运算优先级最低;位运算优先级比较分散。可将优先级顺序简单记忆为算术、关系和逻辑,移位、位逻辑在中间。请参阅附录B。表达式求值时按运算的优先级别从高到低顺序进行,优先级相同的运算顺序由运算的结合性规定。通过圆括号运算可以改变运算的优先顺序,先圆括号内,后圆括号外。逗号运算优先级最低;852.运算符的结合性运算符的结合性是指,优先级相同的运算从左到右进行(左结合性)还是从右至左进行(右结合性),左结合性是人们习惯的计算顺序。C语言中,只有单目运算(!、~、++、--、-、*、&)、条件运算(?:)、赋值运算(=、+=、-=、*=、/=、%=)的结合性是右结合,其余运算为左结合。2.运算符的结合性863.类型转换一般地,相应的运算只有相应类型的数据才能进行,不同类型数据进行运算时,要进行类型转换。类型转换有自动转换与强制转换两种方式。1)自动转换自动转换(又称隐含转换)由系统自动完成,转换的规则如图3-1所示。3.类型转换87图3-1中,横向箭头方向表示必定要进行的转换,即short型、char型数据必定先转换成int型,float型数据必定先转换为double型,再进行运算。纵向箭头方向表示类型自动转换的方向,请注意转换的方向是由低向高转换的,int型最低,double型最高。int型与unsigned型数据进行运算,int型转换成unsigned型;int型与long型数据进行运算,int型转换成long型;int型与double型数据进行运算,int型转换成double型。其它类推。这种转换是一种保值映射,在转换中数据的精度不受损失。图3-1中,横向箭头方向表示必定要进行的转换,即88图3-1类型自动转换规则图3-1类型自动转换规则892)强制转换强制类型转换通过类型转换运算完成。格式:(类型名)(表达式)强制转换将表达式的类型强制转换成类型名指定的类型。例如x、y为float,则(int)(x+y)将实型表达式x+y强制转换成整型。值得注意的是,强制类型转换在将高类型转换为低类型时,数据精度会有损失,是一种不安全的转换。同时强制类型转换是一次性的、暂时性的,并不能永久改变所转换表达式的类型。例如a为int,则(double) a为双精度型,a依然为整型。2)强制转换90例3–1表达式计算。(1)floatx=2.5,y=4.7;inta=7;计算x+a%3*(int)(x+y)%2/4⑦①④③②⑤⑥①a%3等于1。②x+y等于7.2。③(int)(x+y)等于7。④a%3*(int)(x+y)等于7。⑤a%3*(int)(x+y)%2等于1。⑥a%3*(int)(x+y)%2/4等于0。⑦x+a%3*(int)(x+y)%2/4等于2.5+0,结果为2.5。例3–1表达式计算。91(2)inta=2,b=3;floatx=3.5,y=2.5;计算(float)(a+b)/2+(int)x%(int)y②①③⑦④⑥⑤①a+b等于5。②(float)(a+b)等于5.0,强制转换成float型。③(float)(a+b)/2等于5.0/2.0,结果为2.5。④(int)x等于3,强制转换成int型。⑤(int)y等于2,强制转换成int型。⑥(int)x%(int)y等于1。⑦(float)(a+b)/2+(int)x%(int)y等于2.5+1.0,结果为3.5(双精度型)。(2)inta=2,b=3;floatx=3.92(3)inti=3;floatf=1.0;doubled=2.3;计算10+′a′+i*f-d①③②④①′a′转换成97,10+′a′等于107。②i,f转换成双精度型,i*f等于3.0。③107转换成双精度型,10+′a′+i*f等于110.0。④10+′a′+i*f-d等于107.7。(3)inti=3;floatf=1.0;do933.2算术表达式1.自增运算自增运算符:++。自增运算是单目运算,操作数只能是整型变量,有前置、后置两种方式:++i,在使用i之前,先使i的值增加1,俗称先增后用。i++,先使用i的值,然后使i的值增加1,俗称先用后增。3.2算术表达式1.自增运算94例如:i=1999;j=++i;/*先将i的值增1,变为2000后赋给j,j的值也为2000*/j=i++;/*先将i的值赋给j,j的值为1999。然后将i的值增1,变为2000*/自增运算的优先级处于第2级,具右结合性。例如:952.自减运算自减运算符:--自减运算与自增运算一样也是单目运算,操作数也只能是整型变量。同样有前置、后置两种方式:--i,在使用i之前,先使i的值减1,俗称先减后用。i--,先使用i的值,然后使i的值减1,俗称先用后减。2.自减运算96如:i=2000;j=--i;/*先减,将i的值减1,变为1999。后使用,j的值也为1999*/j=i--;/*先使用,j的值为2000。后减,将i的值减1,i的值变为1999*/自减运算的优先级、结合性同自增运算。如:i=2000;97请特别注意:(1)自增、自减运算只能用于变量,不能用于常量或表达式。(2)自增、自减运算比等价的赋值语句生成的目标代码更高效。(3)自增、自减运算常用于循环语句中,使循环控制变量自动加或减1;还可用于指针变量,使指针指向下一个或上一个地址。请特别注意:98(4)表达式中包含有自增、自减运算时,特别容易出错,务请小心。例如,i=1,(++i)+(++i)+(++i)的值为多少呢?可能计算出是9(=2+3+4),其实这是错误的。实际上计算时先对整个表达式扫描,i先自增3次,由1→2→3→4,因此计算结果应为12(=4+4+4)。(i++)+(i++)+(i++)的值又是多少呢?分析同上,应为3,当然表达式计算完成后i的值同样改变为4。(4)表达式中包含有自增、自减运算时,特别容易出错993.运算符的组合问题C语言的运算符一般为一个字符,有的由两个字符组成。在表达式中出现多个字符时如何组合呢?C编译系统在处理时,原则上尽可能自左至右将若干字符组合成一个运算符。如将i+++j解释为(i++)+j,而不是i+(++j)。如要表示i+(++j),必须加括号。标识符、关键字也按同样的原则进行处理。3.运算符的组合问题100例3–2自增自减运算。/*程序3-2,自增自减运算*/#include″stdio.h″main(){inti,j;i=j=5;printf(″i++=%d,j--=%d\n″,i++,j--);printf(″++i=%d,--j=%d\n″,++i,--j);printf(″i++=%d,j--=%d\n″,i++,j--);printf(″++i=%d,--j=%d\n″,++i,--j);printf(″i=%d,j=%d\n″,i,j);}例3–2自增自减运算。101运行结果: i++=5,j−−=5 ++i=7,−−j=3 i++=7,j−−=3 ++i=9,−−j=1 i=9,j=1运行结果:1023.3赋值表达式3.3.1赋值运算赋值运算符:=。赋值运算是双目运算,一个操作数为变量,另一个操作数为表达式。赋值运算符左边的操作数只能是变量,右边可以是表达式。进行赋值运算时先计算右边表达式的值,然后将右边表达式的值赋给左边变量,即送给左边变量对应的存储单元,并以此作为整个赋值表达式的值。例如i为int,i=3+5%2,则先计算右边表达式3+5%2的值,得到4,然后将4赋给左边变量i。3.3赋值表达式3.3.1赋值运算赋值103说明:(1)赋值运算的优先级为第14级,具有右结合性。(2)赋值运算中的表达式最简单的形式是一个常量,这时变量得到一个初值。例如: inti;floatx;charch; i=100;x=12.345;ch='A';说明:104(3)赋值运算中的表达式又可以是赋值表达式,如此可辗转赋值。例如: intx,y,z;x=y=z=0.0,相当于x=(y=(z=0.0)),即x、y、z都得到值0.0。 ③② ①(4)赋值运算符“=”不同于数学中的等号。例如,i=i+1在数学中绝对不成立,但在C语言中肯定成立,其含义是将i的当前值加上1再赋给i。(3)赋值运算中的表达式又可以是赋值表达式,如此可1053.3.2赋值类型转换在进行赋值运算时,一般要求赋值运算符两侧操作数的类型相同或相容。如果赋值运算符两侧操作数的类型不一致,要进行类型转换。赋值运算时的类型转换以赋值运算左边操作数的类型为主体进行。(1)将实型数据赋给整型变量时,舍弃实数的小数部分。例如i为int,若有i=1.23,则i的值为1。(2)将整型数据赋给单、双精度型变量时,数值大小不变,但以浮点形式存储到变量中。3.3.2赋值类型转换106(3)字符型数据赋给整型变量时,由于字符数据只占一个字节,而整型变量为2个字节,因此将字符型数据放在整型变量的低8位中,而对整型变量的高8位要进行扩充。(4)将基本整型数据赋给长整型变量时,基本整型数据放在长整型变量的低16位,高16位用符号位扩充。反之,将长整型数据赋给基本整型变量时,只将长整型数据的低16位送给基本整型变量。(3)字符型数据赋给整型变量时,由于字符数据只占107①inti=-1;longintj;j=i;i的二进制形式:0000000000000001j的二进制形式:00000000000000000000000000000001②inti=−1; longintj; j=i;i的二进制形式:1111111111111111j的二进制形式:11111111111111111111111111111111①inti=-1;108③longinti=−1; intj; j=i;i的二进制形式:11111111111111111111111111111111j的二进制形式:1111111111111111③longinti=−1;109(5)将无符号整型数据赋给长整型变量时,不存在符号位扩展的问题,只需将高位补0即可。将无符号整型数据赋给一个占字节数相同的整型变量时,将无符号整型数据原样送整型变量中,并将最高位当作符号位,如果数据超出相应的整型范围,将产生数据错误。如果将整型数据赋给占字节数相同的无符号整型变量时,也是原样照赋,最高位作数值处理。(5)将无符号整型数据赋给长整型变量时,不110例如:①unsignedinti=65535; intj; j=i;/*j的值为−1*/②inti=−1; unsignedintj;  j=i;/*j的值为65535*/例如:1113.3.3复合赋值运算在基本赋值运算符“=”之前加上任一双目算术运算符及位运算符可构成复合赋值运算符,又称带运算的赋值运算符。算术复合赋值运算符:+=、-=、*=、/=、%=位复合赋值运算符:&=、|=、^=、>>=、<<=一般形式:变量☆=表达式等价于:变量=变量☆表达式☆代表任一双目算术运算符或位运算符。复合赋值运算先进行所带运算,再进行赋值运算。复合赋值运算的优先级同赋值运算。3.3.3复合赋值运算在基本赋值运算符112例如:①inta=3;a+=2等价于a=a+2,结果为5。②floatx=1.2,y=2.1;y*=x+3.4等价于y=y*(x+3.4),结果为9.66。③inta=3,b=2;b/=a+=1等价于b=b/(a=a+1),结果为0。例如:113例3-3赋值运算。 /*程序3-3,赋值运算*/ #include"stdio.h" main( ) {inti,j;floatx,y; i=j=1; x=y=1.1;printf("i=%d,j=%d\n",i,j);例3-3赋值运算。114x=i+j;y+=1;printf("x=%4.2f,y=%4.2f\n",x,y);i=i+++j;x=2*x+y;printf("i=%d,x=%4.2f\n",i,x);}运行结果: i=1,j=1 x=2.00,y=2.10i=3,x=6.10x=i+j;115printf(″x=%4.2f,y=%4.2f\n″,x,y);i=i+++j;x=2*x+y;printf(″i=%d,x=%4.2f\n″,i,x);}运行结果:i=1,j=1x=2.00,y=2.10i=2,x=6.10printf(″x=%4.2f,y=%4.2f\n″,x1163.4逻辑表达式3.4.1关系表达式关系表达式是逻辑表达式中的一种特殊情况,关系表达式由关系运算符和操作数组成,关系运算用于完成数的比较运算。关系运算有<、<=、==、!=、>、>=,<、<=、>、>=的优先级相同,==、!=的优先级相同,前者的优先级高于后者。关系运算符的优先级低于算术运算,高于逻辑运算&&、||,也高于赋值运算。3.4逻辑表达式3.4.1关系表达式1173.4.2逻辑表达式逻辑表达式由逻辑运算符和操作数组成,逻辑表达式用于程序设计中的条件描述。逻辑表达式中操作数可以是逻辑量和关系表达式。C语言有!、&&、‖三种逻辑运算,运算规则在上章已作介绍。!运算的优先级高于算术运算,&&运算的优先级高于‖运算,&&、‖运算的优先级低于关系运算,高于赋值运算。3.4.2逻辑表达式118在计算逻辑表达式时务请注意:&&和‖是一种短路运算。所谓短路运算,是指在计算的过程中,只要表达式的值能确定,便不再计算下去。逻辑与运算时,计算到某个操作数为假,可以确定整个表达式的值为假时,剩余的表达式部分便不再计算。逻辑或运算时,计算到某个操作数为真,可以确定整个表达式的值为真时,剩余的表达式部分便不再计算。在计算逻辑表达式时务请注意:119例如:①e1&&e2&&e3,若e1为0,可确定表达式的值为0,则不再计算e2、e3。②e1‖e2‖e3,若e1为真,则可确定表达式的值为真,也不再计算e2、e3。例如:120例3—4用逻辑表达式描述下列条件:(1)x是3的倍数。x%3==0(2)x是偶数。x%2==0(3)x是3的倍数且x是偶数。(x%3==0)&&(x%2==0)(4)100<x<200。(x>100)&&(x<200)例3—4用逻辑表达式描述下列条件:121(5)x等于2或8。(x==2)||(x==8)(6)三位数x是回文数:x/100==x%10(7)a、b、c为三边,它们构成等边三角形的条件:(a==b)&&(b==c)(8)某年是闰年:((year%4==0)&&(year%100!=0))‖(year%400==0)(5)x等于2或8。1223.5位运算表达式3.5.1位逻辑运算1.按位取反运算运算符:~。按位取反运算用来对一个二进制数按位取反,即0位变1,1位变0。例如,计算~25。25的二进制表示为:0000000000011001。按位取反的结果为:1111111111100110,即−26。3.5位运算表达式3.5.1位逻辑运算123~运算常用于产生一些特殊的数。如高8位全1、低8位全0的数0xFF00,按位取反后变为0x00FF。~1,在16位与32位的系统中,都代表只有最低位为0的整数。~运算是位运算中惟一的单目运算,也是惟一具有右结合性的位运算。~运算常用于产生一些特殊的数。如高8位全1、低8位全1242.按位与运算运算符:&。按位与运算的规则是操作数的对应位为1,则该位的运算结果为1,否则为0。例如,计算0x29&0x37。0x29与0x37的二进制表示为:0000000000101001与0000000000110111。按位与的结果为:00000000000100001,即0x21。按位与运算的主要用途是清零及取数的某些位或保留数的某些位。2.按位与运算125例如:①a&0,将a清0。②a&0xFF00,取数a的高8位,低8位清0。③a&0x00FF,取数a的低8位,高8位清0。例如:1263.按位或运算运算符:|按位或运算的规则是操作数的对应位都为0,则该位的运算结果为0,否则为1。例如:0x29|0x37,0x29与0x37的二进制表示为:0000000000101001与0000000000110111按位或结果为:0000000000111111,即等于0x3f。利用|运算可将数的部分位或所有位置1。3.按位或运算127例如:a|0x000F,a的低4位全置1,其它位保留。a|0xFFF

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论