资源描述
单击此处编辑母版标题样式,*,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,第4,章,C+,表达式,与基本程序控制结构,运算符是指用来表示在数据上执行某些特定操作的符号。,参与运算的数据称为操作数。,根据参与运算的操作数的个数是一个、两个或三个,运算符分为一元运算符、二元运算符和三元运算符。,41,运算符与表达式,表达式,是指,用运算符和圆括号把常量、变量和函数等运算成分连接起来的有意义的式子,。,单个常量、变量和函数也都可以看成是一个表达式。,表达式经过计算后都会得到一个确定的,值,这个值就是表达式的值。,每个表达式都具有唯一确定的值和唯一确定的类型。,例如:,98.56 , (98.56) ,x , 876-78 ,3*(2.5+5) ,sqrt(9),都是合法的表达式。,它们的值分别为,98.56、98.56、,x,的值、,794、22.5、3,。其中,sqrt,(),是一个计算平方根的标准函数,包含在库,math.h,中。,C+,中有一种表达式称为逗号表达式,指的是用逗号分隔开的表达式序列。,比如:,x = 3 , y = 8 , x + y,逗号表达式的求值次序是从左到右依次计算各表达式的值,以最后一个表达式的值和类型作为整个逗号表达式的值和类型。比如上面这个逗号表达式的值为,11,。,4.1.1,算术表达式,用算术运算符(,+、-,、*、,/,)连接起来的表达式就称为算术表达式。,用除法运算符进行整数除法与进行浮点数除法是不同的。用于整数时,表示整除,如果有余数,余数部分就被省略了。如:,5 / 2,得到的结果为,2(,int,型),8 / 5,得到的结果为,1(,int,型),而用于浮点数时:,5.0 / 2.0,得到的结果为,2.5(,float,型),8.0 / 5.0,得到的结果为,1.6(,float,型),取余运算符用于取整数除法的余数,是对除法运算符的一个必要的补充。 如:,5,2,得到的结果为,1,8,5,得到的结果为,3,在/和%,运算中,注意除数不能为零,否则将产生溢出错误。,在做,+,和*运算特别是*运算时,很容易出现运算结果产生溢出的情况,要注意将数据定义为足够长度的类型。,当赋值运算符的两边出现相同的变量时,,C+,还提供了一个简洁的表达方式:,x=。,其中的,x,可为,+、-,、*、,/,、等。,假定,e1,和,e2,是表达式,那么,e1 = (e1) x (e2),就等价于,e1 x = e2,例如,表达式,a=a+9,可以用,+=,写成如下形式:,a+=9,注意围绕,e2,的括号。例如,表达式,y-=x+1,实际上是,y=y-(x+1),+ +,和,- -,运算符,增,1,运算符和减,1,运算符分别对其操作数进行加,1,和减,1,操作,它们既可以用在变量前,作为前缀运算符,例如:,int,m, n;,+m;,-n;,又可用在变量后,作为后缀运算符。例如,:,m+;,n-;,前缀增(减),1,运算符在使用变量的值之前就使变量值加,1,或减,1,,,后缀增(减),1,运算符在使用变量的值之后才使变量值加,1,或减,1,。,例如,若,n,的值为,5,,那么,x = n +;,先将,n,的值,5,赋给,x,,即,x,的值为,5,,再将,n,的值加,1,,则,n,为6,。而,x = + n;,先将,n,的值加,1,得到,6,,再将,n,的值赋给,x,,则,x,和,n,的值都为,6,。,4.1.2,关系运算,C+,的关系运算符都是二元的,有,、=、= 4,的值为,1,,,而表达式,67 != 67,的值为,0,。,例,4.1,关于关系运算的一个例子,#,include ,void main(),double x=45.3, y;,cout,y;,cout,(xy)10) & (x2),的值为,0,,因为,(32),的值为,1,。,C+,在计算逻辑表达式的值时,若从左到右计算到某处就已经能够确定表达式的值,则不再继续后面部分的求值。,例如,形如,e1 & e2,的表达式,,在已求得表达式,e1,的值为,0,的情况下,已经能够确定整个逻辑表达式的值为,0,,C+,就不再对,e2,求值。,同样,形如,e1 | e2,的表达式,,如果已经求得,e1,的值为,1,,则整个表达式的值一定为,1,,C+,就不再对,e2,求值。,4.1.4,条件运算符,条件运算符,?:是,C+,中唯一的一个三元运算符。,条件运算符的表达式具有如下形式,:,e1 ? e2 : e3,其中,e1、e2、e3,皆为表达式。,条件运算执行的操作是:先计算表达式,e1,的值,如果为非,0,,则计算表达式,e2,的值并把它作为整个表达式的值,;,而如果,e1,的值为,0,,则计算表达式,e3,的值,并用它作为整个表达式的值。,例如,表达式,(,x y ) ? 10 : 20,如果,x,的值大于,y,的值,则表达式的值为,10,,否则表达式的值为,20,。,又如,在语句,max = (ab) ? a : b;,中,,max,将赋值为,a、b,中较大的数。,4.1.5,位运算,在计算机存储器中,所有的数据都是以二进制形式存放的。位运算是对二进制机器数进行的操作。,C+,中的位运算符有,6种:,按优先级顺序为,,(),&,|,。,位运算符的运算对象只能是整型(,int,),或字符型(,char),,位运算不改变运算对象本身。,例4.2,下面的小程序将输出,:,fedcba98,#include,void main(),int,a=0x01234567;,/0000 0001 0010 0011 0100 0101 0110 0111,cout,hexa,endl,;,/1111 1110 1101 1100 1011 1010 1001 1000,(1),(按位求反):,一元运算,将运算对象各位求反。,(2),(右移),:,二元运算,左操作数为移位对象,右操作数为移动位数,n。,返回移位对象整体向右移动,n,位,高位用,n,个0,填补以后的值。(当移位对象为负数的补码时,高位用,n,个1,填补。),例4.3,左移和右移,#,include,void main(),int,a=0x0089abcd;,/0000 0000 1000 1001 1010 1011 1100 1101,int,b=-100;,/1111 1111 1111 1111 1111 1111 1001 1100,cout,hex(a5)5),endl,;,/0000 0000 0000 0100 0100 1101 0101 1110,cout,hex(b5)5),endl,;,/1111 1111 1111 1111 1111 1111 1111 1100,程序输出:,113579,a0,44d5e,fffff380,fffffffc,(4)&,(按位与):,二元运算,将两个运算对象按位相与。,(,5),(按位异或):,二元运算,将两个运算对象按位异或。,(,6)|,(按位或):,二元运算,将两个运算对象按位相或。,例4.4,按位逻辑运算,#,include,void main(),int,a=0x01234567;,/0000 0001 0010 0011 0100 0101 0110 0111,int,b=0x89abcdef;,/1000 1001 1010 1011 1100 1101 1110 1111,cout,hex(a&b),endl,;,/0000 0001 0010 0011 0100 0101 0110 0111,cout,hex(ab),endl,;,/1000 1000 1000 1000 1000 1000 1000 1000,cout,hex(a|b),endl,;,/1000 1001 1010 1011 1100 1101 1110 1111,程序输出:,1234567,88888888,89,abcdef,4.1.6,求字节数运算,求字节数运算为一元运算,用,sizeof,(),运算符。其功能是求变量或表达式的数据类型在内存中占据的字节数。待求字节数的表达式放在括号中,返回值为整型。,例4.5,求字节数运算,#,include,#include,void main(),short a=-32768;,float b=9.0;,double c=5.7;,char d=k;,cout,sizeof,(a) ;,cout,sizeof,(b) ;,cout,sizeof,(c) ;,cout,sizeof,(d) ;,cout,sizeof,(,sqrt,(b) ;,cout,sizeof,(a+b+c) .,(类成员访问), ,(数组下标),: :,(作用域访问),左,2,*(,取内容,) &(,取地址,) ! + - + (,一元,) - (,一元,),sizeof,右,3,*(乘) / %,左,4,+ -,左,5,左,6, =,左,7,= !=,左,8,&,左,9,|,左,10,? :,(条件运算),右,11,= += -= *= /= %= = &= |= =,右,12,左,C+,各运算符的优先级总的来说有如下规律(按优先级从高到低):,一元,二元,(,除了赋值,),三元,赋值,逗号,;,二元运算符又有如下规律:,算术,关系,逻辑,;,逻辑运算符有如下规律:,! & |,。,例4.7,根据表达式的求值次序,求下列表达式的值,假定有,int x = 5 , y = 4 , z = 6 ;,char a = s , b = t ;,int w = 2 ;,表达式 表达式的值,z / y, z / 4.0, z / y % z / x, a b | y z, a != b & z 6, a = b & ! ( y z ), a = b & ! y z, x + 1 +z, x + 1 z+, -x -y | x + y z & z % 3 = 0, ( x+ , x += y , x + y ),1,1.5,0,1,0,0,1,1,0,1,14,按照结构化程序设计的思想,程序由三种单入口、单出口的基本结构组成:,顺序结构、选择结构、循环结构。,C+,的控制流就是由这三种基本结构组成的。,42,基本程序控制结构,4.2.1,顺序结构,顺序结构的程序是指程序中的所有语句都是按书写顺序逐一执行的,只有顺序结构的程序功能有限。,例,4.8,计算球的体积,。,已知球的体积公式为:,4,R,3,V= ,3,# include ,void main(), float radius , bulk;,cout radius ; /,输入半径,bulk = (4*3.1416* radius* radius* radius)/3;,cout bulk = bulk ,endl,; /,输出体积,选择结构也称为分支结构,用于处理在程序中出现了两条或更多执行路径可供选择的情况。选择结构可以用选择语句来实现。选择语句包括,if,语句和,switch,语句。,4.2.2,选择结构,1,If,语句,if,语句有两种格式。,格式,1:,if (,条件表达式,),语句,功能:对条件表达式求值,若值为真(非,0,)则执行它后面的语句,;,否则什么也不做。,若需要执行的语句用单条语句写不下,就应该用复合语句。,例4.9,将两个数排序输出,#,include ,void main( ),float a , b ,ls,;,cout ab;,if (ab),ls = a;,a = b;,b =,ls,;,cout,a b,endl,;,格式,2,:,if (,条件表达式,),语句,1,else,语句,2,功能:对条件表达式求值,若值为真(非,0,)执行其后的语句,1;,否则执行,else,后面的语句,2,。即根据条件表达式是否为真分别作不同的处理。,4.10 用,if else,对例,4.9,的改写,#,include ,void main(),loat,a , b ,ls,;,cout,ab;,if (ab),cout,a b,endl,;,else,cout, b a ,endl,;,上一节介绍的条件运算符也可以用,if,语句来改写。例如:,y = (ab)? a:b;,可以用下面这个,if-else,语句来代替:,if (ab) y=a;,else y=b;,if,语句中也可以包含,if,语句,这就构成了,if,语句的嵌套。,例,4.11,某单位向职工按月发放医疗补贴的具体方案如下:职工工龄在,10,年以下的,医疗补贴为其基本工资的,10% ;,工龄在,10,年以上,20,年以下的,医疗补贴为其基本工资的,15% ;,工龄在,20,年以上,30,年以下的,医疗补贴为其基本工资的,20% ;,工龄在,30,年以上的,医疗补贴为其基本工资的,30%,。输入某职工的工龄及基本工资,计算他每月应得的医疗补贴。,#,include ,void main(),int,seniority;,double wages, allowance;,cout,seniority; /,输入工龄,cout,wages; /,输入基本工资,if (seniority10 ) /,工龄在,10,年以下,allowance=wages*0.1;,else if( seniority 20 ) /,工龄在,10,年,19,年,allowance=wages*0.15;,else if ( seniority 30 ) /,工龄在,20,年,29,年,allowance=wages*0.2;,else allowance=wages*0.3; /,工龄在,30,年以上,cout,The allowance is : allowance,endl,;,#,include,void main(),int,seniority ;,double wages , allowance ;,cout, seniority ;,cout, wages ;,if ( seniority= 10 & seniority= 20 & seniority = 30 ),allowance = wages * 0.3 ;,cout, The allowance is : allowance 2 ) if ( x 4 ) x = 35 ; else x = 78 ;,cout, x 2 ) if ( x 2 ) if ( x 4 ) x = 35 ;,else x = 78 ; ,当,x2,或者,x4,时,这两种理解会导致两个不同的答案。这就叫产生了二义性。,在绝大多数的语言中,包括,C+,,都采用最近匹配原则来解决这个问题。所谓最近匹配原则就是每个,else,必须与离它最近的那个没有匹配的,if,相匹配。按照这个原则,上面的第二种理解是正确的。,2,switch,语句,switch,语句又称为开关语句,其格式如下:,switch (,表达式,),case,常量表达式,1 :,语句序列,1,break ;,case,常量表达式,2 :,语句序列,2,break ;,case,常量表达式,n :,语句序列,n,break ;,default :,语句序列,n+1,break ;,其中,,switch,后面的表达式的类型必须与,case,后面的常量表达式的类型一致,而且只能是字符型、整型或枚举型。,case,后面的表达式必须是常量表达式,不能含有变量,;,同一个,switch,中不能有重复的常量表达式。,switch,语句执行的过程如下:,先计算,switch,后面的表达式的值,然后拿它与各,case,后面的常量表达式比较。当遇到某个,case,中的常量表达式的值与它相等时,就执行那个,case,后的语句序列,直到遇到,break,语句或,switch,语句结束时的右花括号“,”,时,才退出,switch,语句,去执行,switch,后面的语句。如果没有一个常量表达式与,switch,后面的表达式值相等,就执行,default,后的语句序列。,例4.13,根据一个代表星期的,0到6,之间的整数,在屏幕上打印出它代表的是星期几,#,include ,void main( ),int,w ; /,代表星期的整数,cout, w ;,switch ( w ),case 0 :,cout, Its Sunday . ,endl,;,break ;,case 1 :,cout, Its Monday . ,endl,;,break ;,case 2 :,cout, Its Tuesday . ,endl,;,break ;,case 3 :,cout, Its Wednesday . ,endl,;,break ;,case 4 :,cout, Its Thursday . ,endl,;,break ;,case 5 :,cout, Its Friday . ,endl,;,break ;,case 6 :,cout, Its Saturday . ,endl,;,break ;,default :,cout, Invalid data ! ,endl,;,default,语句是可以缺省的。如果没有,default,,则当所有匹配都失败时,将不执行任何操作。建议使用,default,语句,除非,case,语句已覆盖了所有的可能,以避免由于没有考虑到某种情况而给程序带来的不利影响。,break,语句在,switch,中的作用是跳出整个,switch,语句。,在例,4.13,中,每个,case,的语句序列后都有一个,break,语句(最后一个,case,或,default,语句的,break,可以省略)。在这种情况下,各个,case,的排列次序可以是任意,不会影响程序的结果。如果没有,break,,则执行完该,case,语句的语句序列后,还将接下去执行后面的,case,的语句序列。在这种情况下,各个,case,排列的次序不同,就可能产生不同的结果。,例如,把例,4.7,中的,break,都删去(假定输入的,w,的值为,4,),会出现什么情况呢?,如果是在有,break,的情况下,,w,应与第五个,case,中的常量,4,匹配,从而在屏幕上打印出:,Its Thursday .,之后就该跳出,switch,,到达程序末尾并结束。然而,没有了,break,的,switch,语句得到的结果与原来大不一样。在打印了上面的字符串后,并不会跳出,switch,,而是依次进入后面的,case,及,default,语句去执行打印语句,于是得到的输出为:,Its Thursday .,Its Friday .,Its Saturday .,Invalid data !,如果多个,case,后的语句序列是相同的,即要做的操作是一样的,可采用下面的格式以避免重复书写:,switch (,表达式,),case,常量表达式,1 :,case,常量表达式,2 :,case,常量表达式,i :,语句序列,break ;,case,常量表达式,n :,语句序列,n,break ;,default :,语句序列,n+1,例4.14 用,switch,语句来实现例,4.11,include ,void main( ),int,seniority , s ;,double wages , allowance ;,cout, seniority ;,cout, wages ;,s = seniority / 10 ; /,得到工龄的十位数字,switch ( s ),case 0 : /,工龄在,10,年以下,allowance = wages * 0.1 ;,break ;,case 1 : /,工龄在,10,年,19,年,allowance = wages * 0.15 ;,break ;,case 2 : /,工龄在,20,年,29,年,allowance = wages * 0.2 ;,break ;,case 3 : /,工龄在,30,年,49,年,case 4 :,allowance = wages * 0.3 ;,break ;,default :,allowance = 0 ;,cout, The allowance is : allowance ,endl,;,C+,中有三种循环语句可用来实现循环结构:,while,语句、,do_while,语句和,for,语句,。这些语句各有各的特点,而且常常可以互相替代。在编程时应根据题意选择最适合的循环语句。,4.2.3,循环结构,1,while,语句,while,语句的格式为:,while(,条件表达式),语句,/,循环体,while,语句的执行过程:,(,1,)对条件表达式求值,如果值为真(非,0,)则执行步骤(,2,),否则转步骤(,4);,(2,)执行循环体中的语句,;,(3,)返回(,1);,(4,)终止循环,去执行,while,语句的下一语句。,例,4.15,计算,100,之内的奇数之和,#,include,void main(),int,n=1;,int,sum=0;,while ( n 100 ),sum +=n; /,累加,n +=2; /,修改为下一个奇数,cout, The sum is : sum ,endl,;,#,include ,void main(),int,seniority ;,double wages , allowance ;,cout, seniority ; /,输入第一个人的工龄,while ( seniority != 0 ) /,若工龄不为,0,则进入循环,cout,wages ;,if(seniority=10 & seniority=20 & seniority=30),allowance = wages * 0.3 ;,cout, The allowance is : allowance ,endl,;,cout, seniority ; /,输入下一人的工龄, ,例4.16,将例,4.12,改进为可以重复计算不同的人的医疗补贴(以输入的工龄为,0,作为结束条件),break,语句不仅可用于跳出,switch,语句,还可用于跳出循环(包括三种循环语句)。但它只能跳出它所在的循环语句或,switch,语句,不能跳出外层的循环语句或,switch,语句(如果有的话)。若想跳出外层语句,还要在外层中使用,break。,例,4.17,从键盘接收,10,个整数,求它们的平方根。若遇到负数就终止程序,#,include ,# include ,void main(),int,i=1, num;,double root ;,while ( i = 10 ),cout, num ;,if ( num 0 ) /,若,num,是负数则退出循环,break ;,root =,sqrt,(num) ;,cout, root ,endl,;,i+ ;,例4.18,对例,4.17,的改进:遇到负数则忽略并重新输入下一个数据,#,include,# include,void main(),int,i = 1, num;,double root;,while ( i = 10 ),cout,num;,if (num0), /,若,num,是负数则回到循环开始处,cout, valid number!;,continue;,root =,sqrt,(num);,cout, root ,endl,;,i+;, ,continue,语句用在循环体中,它的作用是忽略循环体中位于它之后的语句,重新回到条件表达式的判断。,2,do_while,循环语句,while,语句的特点是先判断条件,再确定是否执行循环体,也即“先判断,后执行”,;,如果第一次对条件表达式求值时它就为假,则循环体就一次也不被执行。,do_while,语句是先执行一次循环体之后,再根据条件表达式的值确定是否还要继续执行循环体,也即“先执行,后判断”,循环体至少会被执行一次。,do_while,语句的格式为:,do,语句,/,循环体,while (,条件表达式,) ;,其中的条件表达式及语句的规定同,while,语句一样。注意条件表达式后面的分号不能少,因为整个,do_while,语句实际上相当于一条语句。,do_while,语句的执行过程如下:,(,1,)执行一遍循环体,;,(2,) 对条件表达式求值,若为真(非,0,)则转步骤(,1,),否则转步骤(,3);,(3,)终止循环,去执行,do_while,语句的下一语句。,do_while,和,while,语句在大多数情况下都可以相互替代(除非是有可能循环体一次也不被执行的情况)。例如,例,4.9,中是利用,while,语句来计算,100,之内的奇数之和的,可以将它改写为用,do_while,语句来求和。,例,4.19,用,do_while,语句来改写例,4.15,#,include ,void main(),int,n=1;,int,sum=0;,do,sum+=n; /,累加,n +=2; /,修改为下一个奇数,while(n100 );,cout, The sum is : sum ,endl,;,例,4.20,根据下面的公式求,的值。计算到最后一项的绝对值小于,10,-6,时停止:,/4 = 1 1/3 + 1/5 1/7 + ,# include ,void main( ),double pi=0, x=1;,int,s=1 ;,do ,pi = pi + s / x ;,x += 2 ;,s = - s ;,while(1/x =1e-6);,pi=pi*4;,cout,pi= pi,endl,;,3,for,语句,当循环次数确定的时候,用,for,语句更为直观。,for,语句的格式如下:,for (,表达式,1;,表达式,2;,表达式,3 ),语句,/,循环体,其中的表达式,1,通常用于对循环控制变量进行初始化,;,表达式,2,用于表示循环是否结束的条件,;,表达式,3,用于对循环控制变量作修改。,for,语句执行的过程如下:,(,1,)对表达式,1,求值,;,(2,) 对表达式,2,求值,若其值为真则执行步骤(,3,),否则转步骤(,6);,(3,) 执行循环体,;,(4,)对表达式,3,求值,;,(5,)转步骤(,2);,(6,)结束循环,去执行,for,语句的下一语句。,例如:,int,i ;,for ( i = 1 ; i = 10 ; i+ ),cout, $ ;,程序的运行结果是:,$,for,语句也属于“先判断,后执行”的循环语句,可以用,while,语句替代。,例如,上面这个程序段可以改写为:,int,i = 1 ;,while (i = 10 ) ,cout, $ ;,i + ;,C+,中,for,语句的形式很灵活,,for,后面的三个表达式均可以缺省(但中间的分号不能缺省)。例如上面的程序段也可写成下面的形式:,int,i=1;,for( ; i = 10 ; i+ ),cout, $;,或者,int,i=1;,for( ; i = 10 ; ),cout,10) break;,cout, $;,例,4.21,用,for,语句改写例,4.19,#,include,void main(),int,sum = 0 ;,for (,int,n = 1 ; n 100 ; n = n + 2 ),sum += n ; /,累加,cout, The sum is : sum ,endl,;,在此例中,将变量,n,的声明及初始化作为,for,语句的第一个表达式,这是完全可以的。,C+,的变量可以随时定义,随时使用。只是定义在不同地方的变量的作用域可能会有所不同。比如上例中,如果将变量,n,定义在,for,语句的前面,它的作用域就会发生改变。,4,多重循环,一个循环的循环体中如果又包含另外的循环,就构成了循环的嵌套。前者称为外循环,后者称为内循环。根据循环嵌套的重数,可以有双重循环、三重循环,,统称多重循环。,例,4.22,分析下面程序的运行结果,#,include,void main(),for(,int,i=1; i=4; i+ ),for(,int,j=1; j= 5; j+ ),cout,i + j ;,cout,=,73,),(,x != y ) | ( c B ),z & y | x y,z | y & x y,200 * x / y,double(x) / y +23,x / y + 23,c + y % x,x *=,int,(b/a) + y,c,c = 2 | y % - x 0,+x = y ? x+ : y+,* p * y,+x - y,0,1,0,0,120,23.6,23,67,87,1,4,15,-1,#,include,void main(),int,x = 3 , y = 5 , z = 0 ;,int,*p = ,char c = A ;,float a = 3 , b = 72 ;,cout,= 73 ) ),endl,;,cout, B ),endl,;,cout, y),endl,;,cout, y ),endl,;,cout,(200 * x / y) ,endl,;,cout,(double(x) / y +23),endl,;,cout,( x / y + 23 ),endl,;,cout,( c + y % x),endl,;,cout,(x *=,int,(b/a) + y),endl,;,cout, 0),endl,;,cout,( +x = y ? x+ : y+),endl,;,cout,(* p * y),endl,;,cout,(+x - y- ),endl,;,0,1,0,0,120,23.6,23,67,87,1,5,528,83,#,
展开阅读全文