class03运算符和表达式.ppt_第1页
class03运算符和表达式.ppt_第2页
class03运算符和表达式.ppt_第3页
class03运算符和表达式.ppt_第4页
class03运算符和表达式.ppt_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

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

文档简介

面向对象程序设计与实践 第3课 运算符和表达式 主讲人:杨峰 Page 2 本课主要内容 n运算符 n运算符的优先级 n表达式 n表达式的求值顺序 Page 3 1表达式的概念 n1.1 表达式的概念 什么是表达式(expression)? l表达式是程序的最基本构造块 表达式由运算符和操作数组成,通过运算符对 操作数的运算得到一个值 最简单的表达式是字面量和变量名 length = 20; l字面量20是一个表达式,它的值就是20 llength也是表达式 l赋值运算符=和2个操作数length,20组成一个赋值表达式,该表达式的值是20 l赋值表达式加一个;号,就是一条赋值语句 Page 4 1表达式的概念 n1.1 表达式的概念 l简单表达式通过运算符组合构成更复杂的表达式 int perimeter = ( length + width ) * 2; 算术表达式 算术表达式 赋值表达式 赋值表达式末尾加分号,构成一个赋值语句。 Page 5 1表达式的概念 n1.2 左值的概念 l一个对象在内存中占据一片连续的区域,左值 就是指向某个对象的表达式。 左值的概念比变量更广泛 变量是有名的对象 而左值则可以表示有名和无名的对象 int *rs = new int(20); cout (expr); C用第1种。C+建议用第3种,如: volumn = static_cast(side * side * side); Page 22 4运算符的优先级与结合性 n4.1运算符优先级 l运算符的优先级基本可以归结为: 单目高于双目 双目高于三目 三目高于赋值 从低到高:赋值三目双目单目 Page 23 4运算符的优先级与结合性 l已经学过的运算符中 sizeof运算符优先级高; 自增、自减运算符优先级较高; 四则运算符与数学规定相同,先乘除(求余),后加减 然后是赋值运算符和复合赋值运算符。 从低到高:赋值运算符和复合赋值运算符四则运 算符自增、自减运算符sizeof运算符 l括号可以改变运算优先级 Page 24 4运算符的优先级与结合性 n4.2运算符的结合性 l大部分的运算符都是从左往右计算的,这种方向称为结 合性(这是一个小小的定义(o)哦) 算术运算符具有左结合性,比如 int result = m*n*u*v*w; 从左向右计算 赋值运算符是右结合的。((o)这是个特例)比如 Thirdvalue = SecondValue = FirstValue = expr; 就是先执行 FirstValue = expr , 然后执行SecondValue = FirstValue, 再执行 Thirdvalue = SecondValue 大部分单目运算符是右结合的,因为通常是单目 运算符在前面, 变量跟后面。比如 -value, +value;后置的+和-是左结 合,因为写出来是这个样子 value+。即单目运算符总是和紧 挨着它的那个变量结合到一块 通常不用关心结合性的问题,运算符的结合性是完全符合习惯的 Page 25 4运算符的优先级与结合性 n4.2运算符的结合性 a+b 是表示(a+)+b还是a+(+b)? 因为编译器总是从左向右读入token,所以解释为前者。 a-b则表示a-(-b) Page 26 5表达式的求值顺序 n5.1 基本原则 l相同优先级的运算符2侧的表达式求值顺序是没 有定义的。不能假设表达式是从左到右求值 lvalue = expr1 + expr2 + expr3; expr1、expr2、expr3这3个子表达式那个先求值是不确定的。 不同的编译器可能会有不同的处理。 所以不要编制依赖求值顺序的代码。 int i = 1; vi = i+;/不同编译器可能得到不同的结果。可能是v1=1 也可能是v2=1 什么样的代码是依赖求值顺序的?如果一个表达式里针对同一变量既有赋值又有算术 运算,这种表达式的值就是依赖求值顺序的。 int a = 1; int b = 2; int lvalue; lvalue = (a + b) + (a=5); Page 27 5表达式的求值顺序 n5.2运算符优先级 l一个复杂的表达式 按照 括号和优先级划分子表 达式 lvalue = expr1 * expr2 * expr3 + expr4 / expr5; 因为乘除运算的优先级高于加运算,所以赋值右侧的数学表达式解释为 expr1 * expr2 * expr3 是一个子表达式SUB1, expr4 / expr5是另一个子表达式SUB2; expr1 * expr2 * expr3 和 expr4 / expr5这2个子表达式的值求出以后才会 计算 SUB1+SUB2。 但是, SUB1 和 SUB2这2个子表达式谁先求值就是不确定的了。 如果加括号: lvalue = expr1 * expr2 * (expr3 + expr4) / expr5; 赋值右侧的数学表达式就解释为 expr1、 expr2、 expr3 + expr4、 expr5 4个子表达式。 Page 28 5表达式的求值顺序 n5.3副作用何时发生? int lvalue = (i+)+(i+)+(i+); 假设 i=3 +运算符有副作用,这一个运算符做了2件事,作为表达式,它返回了一个值,然 后又把i的值加了1,加1的动作就是一个副作用。 现在的问题是,这个副作用是何时发生的?(C和C+的语言规范对此没有定义, 只要求在语句结束的时候要执行完成) 把上面的表达式写成 expr1 + expr2 + expr3。 显然这是一个算术表达式,由3个子表达式组成。因为3个子表达式都是i+, 所以 无论3个子表达式谁先求值,结果都是相同的。影响计算结果的因素实际上是副作用何 时执行。 如果一个编译器在子表达式求值完成后就执行副作用,那么结果应该是12。 现在VC和gcc结果是9,说明副作用是在语句完成的时候才执行的(3+3+3,然后i累 加3次值为6)。 (如果确实是在子表达式求值完成后就执行副作用,象(i+)*3+(i+)*4+(i+)*5这 样的代码才能体现出求值顺序不确定对计算结果产生的不确定性) 类似的,对于(+i)+(+i)+(+i),表达式要求返回i增加以后的值,所以VC和 gcc是在先执行副作用以后,再对子表达式求值(先执行i累加3次值为6,然后执行 6+6+6),所以结果是18 Page 29 5表达式的求值顺序 n5.4 示例分析 a=b+=c+-d+-e/-f; 首先把运算符拆开 a = b += c+ - d + -e / -f; 再分析优先级 a = (b += ( (c+) - d + (-e) / (-f) ) ); 最后的执行结果是 c不变,e减1,f求负;然后e除以f; 然后 c减d再加e/f;计算结果加到b上;最后把b赋给a。 都算完以后c加1(副作用) Page 30 5表达式的求值顺序 n5.5复杂表达式求值中的数据类型转换 l一个复杂的表达式 按照 括号和优先级划分为子表达 式 l每个子表达式求值的时候,如果运算符2侧类型不一 致,就会产生类型转换 单目运算符当然没有类型转换的问题。 双目运算符执行向上提升。 三目运算符则是对 : 两侧的2个操作数执行向上提升 赋值运算符则是根据目标类型进行提升或截断。 Page 31 5表达式的求值顺序 n5.5复杂表达式求值中的数据类型转换 double a; long b = 400; int c = 20; double d = 2.0; long e = 200; int f = 50; a = b += c+ - d + -e / -f; e/f 执行一个提升,结果为long; c-d执行一个提升,结果为d

温馨提示

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

评论

0/150

提交评论