c第三章表达式和语句

上传人:痛*** 文档编号:182720805 上传时间:2023-01-27 格式:PPT 页数:46 大小:669.03KB
返回 下载 相关 举报
c第三章表达式和语句_第1页
第1页 / 共46页
c第三章表达式和语句_第2页
第2页 / 共46页
c第三章表达式和语句_第3页
第3页 / 共46页
点击查看更多>>
资源描述
第二章 表达式和语句3.1 表达式1.表达式的概述 表达式时操作符、操作数和标点符号组成的序列,其目的时用来说明一个计算过程。表达式可以嵌套,例如:2+3+(5*sizeof(int)/345。表达式根据某些约定、求值次序、结合和优先级规则来进行计算。所谓约定,即类型转换的约定。例如:float a;a=5/2;结果a得到值为2。5/2 是整数除法取整,因为5和2都是整数,不会由于a是float型而轻易改变运算的性质。所谓求值次序,是指表达式中各个操作数的求值次序视编译器不同而不同。所谓结合性,是指表达式中出现同等优先级的操作符时,该先做哪个操作的规定。例如:d=a+b c;/C+规定,加减法先左后右。先做a+b,其结果再减去c d=a=3;/C+规定,等号先右后左。先做a=3,其结果再赋给d 所谓优先级,是指不同优先级的操作符,总是先做优先级高的操作。例如:d=a+b*c;/乘法优先级比加法高。先做b*c,其结果再与a相加2.左值和右值 左值是能出现在赋值表达式左边的表达式。左值表达式具有存放数据的空间,并且存放是允许的。例如:int a=3;/a是变量,所以a是左值 const int b=4;/b是常量,所以b不是左值 显然常量不是左值,因为C+规定常量的值一旦确定是不能更改的。右值能出现在赋值表达式的右边。左值表达式也可以作为右值表达式。例如:int a,b=6;a=b;/b是变量,所以是左值,此处作为右值 a=8;/8是常量,只能作为右值,不能作为左值3.优先级和结合性 下表包含了C+所有的操作符,共有16级优先级。每一级中的操作符是同优先级的。4.语句与块 C+中所有的操作运算都能通过表达式来实现。由表达式组成的语句称为表达式语句,它由一个表达式后接一个分号“;”组成。通过计算表达式即执行了表达式语句。语句可以是空语句。空语句是只有一个分号而没有表达式的语句,其形式为:;它不产生任何操作运算,只作为形式上的语句,被填充在控制结构中。例如:if(x 9);else cout 9)cout“The number is perfect.n”;cout“It is larger than 9n”;else cout“not larger than 9n”;上面两条执行语句必须放在花括号中,因为if与else之间只能容纳一条语句,或一个语句块。而else后面的花括号则可以省略。3.2 算术运算和赋值1.操作符种类 C+提供了算术运算符+,-,*,/,%。+,-,*是通常意义的加、减、乘法。/对于整型数则为除法取整操作。例如:5/2得到结果2。/对于浮点数则为通常意义的除法。例如:5.0/2.0得到结果为2.5。由此可见,/操作符可以对不同的数据类型进行不同的操作。事实上,+,-,*,/,%对不同数据类型的操作都不同。只能对整型数进行操作。其操作意义为取余。例如 52得到结果为1。不允许对浮点数操作,如果对浮点数操作,则引起编译错误。2.赋值缩写 算术表达式的赋值表示为:int x,y,z;x=y*z;x=y/z;x=y+z;x=y z;x=y%z;当一个变量既出现在表达式的左边又出现在右边时,可以缩写。例如:x=x*y;缩写为:x*=y;x=x+y;缩写为:x+=y;x=x-y;缩写为:x-=y;x=x/y;缩写为:x/=y;x=x%y;缩写为:x%=y;3.溢出 进行算术运算时,很可能溢出结果。发生溢出是由于一个变量被赋予一个超出其数据类型表示范围的数值。数值溢出不会引起编译错误的,只要分母不为0就不会引起除0进行故障,但人使运行结果发生偏差。例如,在16位机器上进行下面的操作:int weight=42896;在16位机器中将不能得到值42896,而是-22640。因为有符号整数的表示范围是-3276832767。3.3算术类型转换 C+遇到两种不同数据类型的数值进行计算时,会将两个数作适当的类型转换,然后再进行运算。转换的方向见下图:如果一个char型数和一个int型数相加,则将char型数转换成int型数,然后进行运算。如果一个long int型数和一个float型数相加,则先将两个数据类型都转换成double型数,然后进行运算。如果一个 int 型数和一个unsigned long 型数相乘,则先将两数都转换成double 型数,然后进行运算。转换总是朝表达数据能力更强的方向,并且转换总是逐个运算进行的。例如:float f=3.5;int n=6;long k=21;double ss=f*n+k/2;ss将会得到结果31。计算ss时,首先将f(float型)和n(int型)转换成double 型数,算的21,然后计算 k/2 的整除运算结果10(long int 型),再将long int 型的数字10转换成double型数。数据运算过程中自动进行的类型转换称为隐式类型转换。上例的表达式运算过程中进行的数据类型转换就是隐式转换。有时候,我们会面临现面计算结果不正确的问题:long m=234*456/6;即发现m为-4061,而不是17784。原因式语句先进行int 型数的乘法运算,结果仍以int 型数保留起来,中间结果有一个被截断的过程,所以,最后的结果式错的。如果让第1次乘法的结果以long 型数保留下来,就能得到正确的结果。这就要求参加乘法运算的2个数中至少有一个为long 型数。例如,将其中之一标识以L或l(long),则可保证其正确 cout234*456L/6 endl;输出结果为:17784 还可以将整型数强制转换为long 型:cout(long)234*456/6endl;该语句使234成为long型数,与整数456相乘,先隐式转换,再相乘,得到一个long型数106704。再与6相除取整,从而得到正确结果。强制转换又称显示转换,其语法式在一个数值或变量前加上带括号的类型名。也可以类型名后跟带括号的数值或表达式(C不可以)。如上面的语句也可以写成:coutlong(234)*456/6endl;如果类型名是带类型修饰的,则要给类型名加括号。例如:cout(unsigned long)234*456/6endl;coutunsigned long(234)*456/6endl;/error 注意下面语句不能产生所期望的效果:coutlong(234*456)/6endl;该语句首先执行括号里的乘法,得到一个int型整数,然后强制转换为long型数,再参加除6取整运算,所以得不到正确结果。3.4增量和减量 增量和减量操作符表示为:+和-。增量操作表示加1,减量操作表示减1。例如:a+;/相当于a=a+1;+a;/相当于a=a+1;a-;/相当于a=a 1;-a;/相当于a=a 1;增量操作符有前增量与后增量之分。前增量操作+a的意义为:先修改操作数使之增1,然后将增1过的a值作为表达式的值。而后增量操作a+的意义为:先将变量a的值作为表达式的值确定下来,再将a增1。对于增量和减量操作符,它要求操作数是左值,因为操作数的值要发生变化。例如:int a=3;int b=+a;couta“”bendl;int c=a+;couta“”c)小于(=)小于等于(=,=,!=,&,|都是一个操作符的整体,所以中间不能有空格,而且前3个操作符中的字符次序不能颠倒。例如:下面的语法都是不合法的。=,=!,=,=,!=2.比较运算符 比较()和赋值()是两个不同的操作,所以用的操作符也不同。比较用于测试给定的2个操作数是否相等。例如:if(x999)cout“x is 999n”;比较操作符产生的值是比较的结果,可能是0或1,即假或真。真和假是逻辑值。在C+中,假意味着0,真意味着非0。所以,任意一个非0数都是真,表示为逻辑值就是1。例如:x=somevalue;if(x=9)cout“x is not 0n”;例中,不管x的初值是什么,总是执行cout语句。因为x=9是赋值表达式,其表达式的值是所赋的值9,而9为非0值,所以if语句的条件为真,所以总是执行cout语句。又例如:x=somevalue;if(x=0)cout“x is 0n”;例中,不管x以前是什么值,总是不会执行cout语句。因为x=0是赋值表达式,并且其值为0,为假。3.不等于运算符 当要测试一些东西不是真时,可以使用不等于操作符。例如,如果要在一些东西是真时在屏幕上显示一则消息,则可以用如下语句:if(x!=9)cout“x is not 9n”;要注意的是,如果颠倒!=,则意义完全不同:if(x=!9)cout“x is not 9n”;该if条件表达式是一个赋值语句,!9为非真,即0。所以条件表达式相当于if(x=0),于是cout语句永远也不会执行。4.嵌入赋值 有时候,需要将一个函数值赋给一个变量,然后比较该变量的值与预定值是否相等。例如:x=func();if(xsomevalue)/语句 上面的代码与下面的代码等价:if(x=func()somevalue)/语句 因为要给x赋值,然后确定x的值,所以先进行赋值。赋值表达式的值即x的值可以作为比较的操作数。这里,由于 操作比操作优先级高,所以需要额外加一个括号。这种赋值紧接着比较的表达式称为嵌入赋值。5.逻辑非运算符 !改变条件表达式的真假值,即逻辑运算的“非”。原来是0,则!0为1;原来为非0,则!操作使之变为0。例如:if(!(x9)cout=80&humi=50)cout“wow,it is hot!n”;if(temp80)cout=优先级低,所以if中的条件表达式为先求temp=80和humi=50,然后进行逻辑与&运算。7.短路表达式 如果多个表达式用&连接,则一个假表达式将使整个连接都为假。例如:int n=3,m=6;if(n4&m+10)cout“m should not changed.n”;cout“m=”m4的比较值为0,所以整个if表达式的值不用看后面就知道为0。C+利用这个特点以产生高效的代码。所以,后面的表达式不被执行。这样,m的值还是6而不是7。知道了短路表达式在C+中的处理方式,就可以在编写程序时,不但避免不比较的错误,而且还可利用它。例如:if(b!=0&a/b2)/语句 if条件表达式中的b!=0若成立,才会执行后面的关系运算,做分母是b的除法。否则,跳过整个条件语句。同理,如果多个表达式用|连接,则一个真表达式将使整个连接都为真。例如:if(temp80)cout“the room is uncomfortable.n”;例中如果temp80的关系比较,直接执行输出语句。3.6 if语句1.If语句 if语句的语法为:if(条件表达式)语句;或:if(条件表达式)语句;它的意义为:如果条件表达式进行一次测试,且测试为真,则执行后面的语句。如果if语句只控制一条语句,则包围该语句的花括号不是必需的。2.空语句 编译器必须在if条件表达式的后面找到一个作为语句结束符的分号“;”,以标志if语句的结束。这样,如果是下面的代码:if(条件表达式);语句;则不管条件表达式为真为假,总是接着执行语句。3.ifelse语句 语法为:if(条件表达式)/语句1;else /语句2;ifelse语句结构4.解决二义性 如果有下面的代码:int x=20;if(x=0)if(x50)cout“x is okn”;else cout=0)if(x50)cout“x is okn”;else cout=0)if(x50)cout“x is okn”;else cout“x is not okn”;C+规定,ifelse语句成对的规则是:else连接到上面第1个没有配对的且为可见的if上。所以上例的else应属于第二个if语句,即第一种解释。又例如:if(条件)if(条件)if(条件)语句;else 语句;上例的else连到第2个if上,因为第3个if不可见。第2个if是else最先碰到的没有配对过的if。3.7 条件运算符 条件运算符的语法为:(条件表达式)?(条件为真时的表达式):(条件为假时的表达式)例如:x=ab?a:b;条件运算符构成一个表达式。它是C+中唯一一个3目运算符,它们之间用“?”和“:”隔开。上例中,把a和b中较小的值赋给x。该例是ifelse语句的一个替代:if(ab)x=a;else x=b;条件运算符构成的表达式,它是有值的。而ifelse语句不能有值,所以ifelse语句不能替代条件运算符。例如,下面的代码不能由ifelse替代:cout(ab?a:b)endl;输出语句要打印一个值,该值是a与b的较小值。由于优先级高于条件运算符,所以输出语句中要将条件运算符构成的表达式用括号括起来。条件运算符表达式的值与测试值没有直接的关系。例如:cout(number1?”file”:”files”)y?”greater than”:xy?”equal to”:”less than”它等价于:(xy)?”greater than”:(xy)?”equal to”:”less than”)当xy时,值为“greater than”,xy时,值为“equal to”,否则,值为“less than”。条件运算符的嵌套可读性不够好。在一个条件运算符的表达式中,如果后面两个表达式的值类型相同,均为左值,则该条件运算符表达式的值为左值表达式。例如:int x=5;long a,b;(x?a:b)=1;(x?x:a)=2;(x2?1:a)=3;任何被转换的变量都不是左值。在C中,条件运算符不能作左值的。3.8 逗号表达式 逗号表达式的语法为:表达式1,表达式2,表达式n C+顺序计算表达式1,表达式2,表达式n的值。例如:int a,b,c;a=1,b=a+2,c=b+3;由于按顺序求值,所以能够保证b一定在a赋值之后,c一定在b赋值之后。该逗号表达式可以用下面3个有序的赋值语句来表示:a=1;b=a+2;c=b+3;逗号表达式是有值的,这一点是语句所不能代替的。逗号表达式的值为第n个子表达式的值,即表达式n的值。例如 int a,b,c,d;d=(a=1,b=a+2,c=b+3);coutdendl;输出结果为:6 上例中输出的结果d即为c的值。逗号表达式还可以用于函数调用中的参数。例如:func(n,(j=1,j+4),k);该函数调用有3个参数,中间的参数是一个逗号表达式。括号是必须的,否则,该函数有4个参数了。逗号表达式作为值的形式,可以用于几乎所有的地方。C+中,如果逗号表达式的最后一个表达式为左值,则该逗号表达式为左值。例如:(a=1,b,c+1,d)=5;/ok:即d=5 在C中,逗号表达式是不能作左值的。3.9 求值次序与副作用1.不同的编译器求值顺序不同 例如:int a=3,b=5,c;c=a*b+b;coutcendl;该程序段在BC中运行得到24,而在VC中运行却得到21。2.求值顺序使交换律失去作用 加法操作我们都知道a+b=b+a。也就是说,交换律成立。在C+中对简单的表达式,交换律是成立,但对复合表达式,交换律未必成立。例如:c=a*b+b;与:c=+b+a*b;在VC中,运行结果前者为21,后者为24。3.求值顺序使括号失去作用 在表达式中括号的优先级使最高的。例如,a*(b+c)中,先做加法,后做乘法。在C+中,简单的表达式括号优先可以 做到,但复合表达式未必如此。例如:int a=3,b=5,c;c=+b*(a+b);预想的操作应为先做a+b得8,然后乘上+b得6*8=48,但实际在VC中却为54。4.消除副作用 在我们举得三个例子中,原因主要是+b引起的。+b具有变量b的修改和它所提供的表达式值2个操作。表达式和语句的副作用,说明编程者对程序思路还有不够完善不够周密得地方。它导致可读性下降,破坏了可移植性。解决表达式副作用得方法是分解表达式语句,即将复合表达式语句写成几个简单的表达式语句。例 题写出程序的运行结果。1.#include void main()int a1,a2;int i=5,j=7,k=0;a1=!k;a2=i!=j;couta1=a1ta2=a2endl;2.#include void main()int x,y,z;x=1;y=1;z=1;x=x|y&z;coutx,(x&!y|z)endl;3.#include void main()int a,b,c;int s,w,t;s=w=t=0;a=-1;b=3;c=3;if(c0)s=a+b;if(a 0)if(c 0)w=a-b;else t=c;couts,w,tendl;4.#include void main()int a,b,c,d,x;a=c=0;b=1;d=20;if(a)d=d-10;else if(!b)if(!c)x=15;else x=25;coutdendl;#include void main()int grade;cout grade;if(grade100|grade0)cout=90)cout=80)cout=70)cout=60)cout D.n;else cout E.n;
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 成人自考


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!