C++Primer第5版学习笔记(三)
第四/五章的重难点内容
 
 
      你可以点击这里回顾第三章内容
      因为第五章的内容比较少,因此和第四章的笔记内容合并。
      第四章是和表达式有关的知识,表达式是C++的基础设施,本章由三部分组成:
 
      1.表达式概念基础,包括表达式的基本概念,左值和右值的概念,优先级结合律,求值顺序。
      2.各种运算符,主要包括算数\关系\逻辑\赋值\递增递减\成员访问\条件\位运算\sizeof\逗号运算符 这10种运算符。
      3.类型转换,包括隐式和显式两种转换的规则。
 
      下面是这一章的知识点:
 
      知识点1:P120,4.1.1,表达式的基本概念
      表达式由一个或者多个运算对象组成,多个对象组成表达式时,对象之间用运算符连接形成复杂表达式。
      运算符中,需要两个对象和运算符连接形成表达式的这种运算符叫做二元(双目,二目)运算符。
      分析一个表达式,必须先了解运算对象的含义、运算符的优先级结合律和运算符的求值顺序。
      1.对于含有子表达式的复杂表达式,应该按照求值顺序,看看应该先求哪一个子表达式的值。
      2.对于不那么复杂的子表达式,应该按照优先级,查看表达式中的每个操作数(对象)应该先跟那一个运算符在一起运算。
      3.如果有优先级相同的运算符同时在同一个运算对象左右,应该按照结合律选定结合顺序是从右向左还是从左向右计算表达式的值。
 
      知识点2:P121,4.1.1,左值和右值
      起源:左值和右值原来是C语言中的概念,特指赋值运算符左右两段的表达式。C语言中,能放在赋值运算符左侧被赋值的对象就是左值,反过来在赋值运算符右侧的对象就是右值。C++中的这两个概念的词义发生了改变。
      概述:可以暂时概述一下C++中左值和右值的概念。从性质上来看,当一个对象做右值时,我们使用的是这个对象的内容;当一个对象做左值时,我们使用的是它在内存中的位置。
      应用:表达式中有的位置需要的是左值,有的位置需要的是右值。表达式的值本身也有左右的分别。
      赋值运算符中左侧操作数和表达式结果都是左值。
      取地址符的操作对象是左值,得到的是右值。
      解引用、下标运算符的求值结果是左值。
      decltype作用于表达式时,如果表达式的结果是一个左值,decltype会返回一个引用类型。
 
      知识点3:P122,4.1.2,优先级和结合律
      1.优先级 复杂表达式中一个运算对象连接多个不同运算符时,哪个运算符优先级高,就先计算哪个运算符和对象作用后的值。
      2.结合律 复杂表达式中一个运算对象连接多个优先级相同的运算符时,根据这一优先级对应的结合律,按从右至左或者从左至右的顺序计算表达式的值。
      如3+2*4-7;这个表达式是一个复杂表达式,因为表达式里*号优先级比较高,所以先计算2*4,得到3+8-7;得到的新表达式更简洁了,只剩下+-两个符号,这两个符号优先级相同,因此查看这个优先级对应的结合律可知这一级别的符号满足左结合性。因此从左向右计算,得到11-7;进一步得到结果4。
 
      知识点4:P123,4.1.3,求值顺序
      一个表达式里如果运算对象都是函数返回的,都需要计算求值才知道对象的状态,函数调用符号优先级右一致,中间隔着几个优先级低的其他符号连接操作对象,比如int a=f()+g();这时候是函数f()先被调用还是g()先被调用呢?答案是未定义。C++语法没有规定这种情况应该谁先谁后。就像下面的表达式++i+i++这个表达式中,优先级最高的表达式++i和i++中间隔着优先级低的运算符+,这是,关于++i先计算还是i++先计算,这是未定义的,而因为这个表达式先计算++i或先计算i++的结果不同,所以这条表达式是错误的。一个变量如果在同一个表达式里被多次改变,这个表达式的求值顺序又不一定,就会出现二义性。应该避免这样的写法。
       目前只有四种运算符明确规定了求值顺序。
       1.逻辑运算符&&和||:这两个运算符先计算左边操作数的值。
       2.条件运算符?: :条件运算符先计算?前的表达式,并求值,之后对视情况对:左右侧的表达式求值。
       3.逗号运算符, :这个运算符的求值顺序是从左至右。
 
      知识点5:关于运算符,左值和右值的归纳
      本章各种运算符形成的表达式所返回的值的属性和运算符需要的操作数的属性如下:
      算数/逻辑/位运算符:  操作对象和结果都是右值    赋值运算符:左侧的操作对象必须是可以修改的左值,                                                                                                                                               ·                                                                                       右侧的操作对象是右值,返回一个左值。
      递增/递减运算符:  前置版本的++/--返回左值,后置版本的++/--返回右值。操作对象都必须是左值。
      箭头成员访问运算符: 作用于指针,表达式结果左值。
      点成员访问运算符:这个成员所属的对象是左值,结果就是左值;这个成员所属的对象是右值,结果就是右值。                                                                                                                                                                   
      条件运算符:  条件运算符的三个表达式都是左值或者都能转化成左值类型时,结果为左值;否则是右值。
 
      知识点6:P125,4.3,除法和取模的结果
      两个非浮点型变量/字面值相除,结果还是原来的类型,不会有原来操作数是整数,运算之后结果是小数的情况。
      C++11中, 对于除运算符,结果向零取整(直接切掉小数部分,得到的数就是结果)。对于取模运算符,结果的符号和被除数的符号一致。
 
      知识点7:P136,4.8,位运算符
      左移运算符移动二进制数后会在右侧插入零,右移运算符在处理有符号类型的操作数(尤其是带负号的)时具体行为由环境决定。
 
      知识点8:P157,4.9,sizeof运算符
      sizeof运算符有两种用法,第一种是sizeof后面直接加一条表达式语句;第二种形如sizeof (类型名);第二种形式后会得到该类对象所占空间的大小。第一种形式中,如果表达式是指针类型,sizeof运算符会返回指针本身的大小。当有一个类名叫data,类中有一个成员叫做student时,可以使用作用域标识符和sizeof联动,使用sizeof(data::student);就可以计算出student占字节数。
 
        知识点9:P141,4.11,隐式类型转换
      概述:在C++中,一些类型可以按照一定规则互相转换,很多时候语境中需要使用两个或多个相同的类型才能继续运算。因此这时一种类型的值会被自动转换成另一个类型的值。这个过程就是隐式转换,其中算术隐式转换较为常见。
      主要的隐式转换发生的情况:
      1、大多数表达式中,比int小的类型会被提升为int型。
      2、在条件中,非布尔值要转化成布尔值。
      3、在初始化和赋值语句中,赋值符号的右侧对象的类型转换成左侧对象的类型进行运算。
      4、算术/关系运算中对象有有多种类型的,转化成同一类型。
      5、形参转化为实参的类型(第六章)。
      6、数组名会被转换为指针。
      7、0,nullptr会转为任何类型的指针。任何类型的指针都可以转化为(const)void *类型。
 
     对第四条算数转换时发生隐式转换的补充:
     再算术运算符的作用下,不同的操作数要转换成同一个类型才能够进行计算。以i+a;这个表达式举例,了解算术转换的方式。
      1、首先,当i和a的类型占字节比int小,如char、short,把他们转换为int型。如果他们原来类型的最大值在当前系统里大于int型最大值,则转化成unsigned int型。
      2、之后,如果i和a的类型相同,结束算数隐式转换,若i和a的类型不同,把占字节少的类型的对象转成占字节多的类型的对象。
      3、如果占字节多的带符号类型的最大值小于占字节少的带转换对象的最大值,带符号类型将被转换为无符号类型。
 
      知识点10:P144,4.11.3,显示转换
      一个命名的强制类型转换具有以下形式:cast-name<要转换成的类型> (被转换的值);其中,cast-name是四种强制类型转换:static_cast、dynamic_cast、const_cast和reinterpret_cast之中的一种。
      static_cast用于常见的强制类型转换。只要两个类型有关联,比如浮点数类型和整数类型,整数类型和布尔值类型,布尔值类型和指针类型,就可以使用static_cast。只是不能转换常量const到变量。
      const_cast用于去掉(或者加上)对象的底层const,要转换的类型和转换的类型都必须是指针或者引用类型。常用于将在第六章介绍的函数重载。
      reinterpret_cast依赖机器,是强行改变一个类型到另外一个不相干的类型。
      dynamic_cast支持运行时类型识别,在19章将会提到。
 
      第五章是和语句有关的知识,语句也是C++的重要组分,本章由三部分组成:
 
      1.语句的概念,包括简单语句和语句作用域的概念。
      2.条件/循环/跳转语句,条件语句主要包括if/else语句、switc语句和:?表达式条件语句;循环语句则是for语句和while语句;跳转语句包括continue、break和goto语句。
      3.try/throw和异常处理,包括异常处理的使用方法。
 
 下面是这一章的知识点:
 
      知识点1:P155,5.2,语句作用域
      用花括号括起来的块就是作用域的标志。在作用域中定义的对象只在作用域中起作用。块之外是没法访问和控制块内部的变量的。
      尤其是在switch语句中,switch的执行过程可能跨过一些标签,当标签里声明并定义了一个对象,这个对象的作用域就延伸到了所有case标签里,如果case 1定义了int a;switch执行了case2,这时这个我们不想执行的语句却产生了自己的作用域,这显然是不行的。因此可以在case标签后使用大括号形成块,这样就不会出现作用域的问题。
      goto也一样不能向前(代码的下几行)跳过对象的定义。不允许跨过变量的定义到达变量的作用域内。但是goto语句可以向后(代码的前几行)跳过定义。
 
      知识点2:P172,5.6,try语句块和异常处理
      可以用try\throw和catch联动进行异常处理,形式如下:
      try
      {待检测块}    //待检测块里面包括throw语句来抛出异常
      catch (异常类型   异常对象的对象名)
      {异常处理语句 }
      catch (同上,可以写很多catch)
      {另一组异常处理语句}
     
      throw抛出异常和catch处理异常的头文件都在stdexcept里定义。抛出异常的语句形如:throw 异常类型("异常文本");
      异常类型一般只支持赋值,初始化,调用成员函数.what之类的几种操作。
 
     你可以点击这里查看下一章节的内容

C++Primer第5版学习笔记(三)的更多相关文章

  1. C++Primer第5版学习笔记(四)

    C++Primer第5版学习笔记(四) 第六章的重难点内容         你可以点击这里回顾第四/五章的内容       第六章是和函数有关的知识,函数就是命名了的代码块,可以处理不同的情况,本章内 ...

  2. C++Primer第5版学习笔记(二)

    C++Primer第5版学习笔记(二) 第三章的重难点内容         这篇笔记记录了我在学习C++常用基本语法的学习过程,基本只记录一些重难点,对概念的描述不是一开始就详尽和准确的,而是层层深入 ...

  3. C++Primer第5版学习笔记(一)

    C++Primer第5版学习笔记(一) 第一.二章的重难点内容        这个笔记本主要记录了我在学习C++Primer(第5版,中文版)的过程中遇到的重难点及其分析.因为第一.二章都比较简单,因 ...

  4. 【原】Learning Spark (Python版) 学习笔记(三)----工作原理、调优与Spark SQL

    周末的任务是更新Learning Spark系列第三篇,以为自己写不完了,但为了改正拖延症,还是得完成给自己定的任务啊 = =.这三章主要讲Spark的运行过程(本地+集群),性能调优以及Spark ...

  5. C++Primer第五版学习笔记

    <C++ Primer>Learning Note 程序实例下载地址:http://www.informit.com/title/0321714113 第一章            开始 ...

  6. C++ Primer(第4版)-学习笔记-第5部分:高级主题

    第17章  用于大型程序的工具 异常处理 不存在数组或函数类型的异常.相反,如果抛出一个数组,被抛出的对象转换为指向数组首元素的指针,类似地,如果抛出一个函数,函数被转换为指向该函数的指针. 不要抛出 ...

  7. C++ Primer(第4版)-学习笔记-第4部分:面向对象编程与泛型编程

    第15章 面向对象编程OOP(Object-oriented programming)           面向对象编程基于三个基本概念:数据抽象.继承和动态绑定.      在 C++ 中,用类进行 ...

  8. C++ Primer(第4版)-学习笔记-第3部分:类和数据抽象

    第12章 类       每个类可以没有成员,也可以定义多个成员,成员可以是数据.函数或类型别名. 成员函数必须在类内部声明,可以在类内部定义,也可以在类外部定义.如果在类内部定义,就默认是内联函数. ...

  9. C++ Primer(第4版)-学习笔记-第2部分:容器和算法

    第9章 顺序容器 顺序容器和关联容器 顺序容器内的元素按其位置存储和访问. 关联容器,其元素按键(key)排序. 顺序容器(sequential container). 顺序容器的元素排列次序与元素值 ...

随机推荐

  1. SVN库迁移过程总结

    一.背景:老SVN是安装在32位服务器上:现在64位服务器上安装了新版本SVN服务,所以需要将SVN从老服务器上迁移到新服务器上. 1.SVN Server下载:https://www.visuals ...

  2. List集合的去除重复性练习

    package com.java.b.listdmeo.www; import java.util.ArrayList;import java.util.Iterator; import com.ja ...

  3. jQuery慢慢啃之事件对象(十一)

    1.event.currentTarget//在事件冒泡阶段中的当前DOM元素 $("p").click(function(event) { alert( event.curren ...

  4. ubuntu14.04.1 LTS 64bits较快的更新源

    网上关于ubuntu更新源的帖子一大堆,但是我使用网易源的时候,执行sudo apt-get update命令的时候,总是在最后几步出现hash校验的问题,虽然没什么大的影响,但是对于患有强迫症晚期综 ...

  5. php邮箱找回密码功能

    原理很简单: 用户找回密码的时候,填写用户名,程序得到用户名便可以去数据库取出用户对应的密码以及当时填写的邮箱, 根据用户名和密码生成一个key=md5(username+password),然后$s ...

  6. iOS: 学习笔记, Swift与Objective-C混用总结

    Swift与Objective-C交互总结 在Swift中使用Objective-C(简单) 在创建OjbC文件时, XCode会提示创建XXX-Bridging-Header.h文件, 创建之 在创 ...

  7. Xcode 插件开发

    我最近一年来都在开发ios应用,不过感觉公司的app维护起来非常麻烦. 因为公司要为很多个企业订做app,每个app的功能基本相同,只是界面上的一些图片和文字要换掉,功能也有一些小改动.考虑到代码维护 ...

  8. mysql update from 子查询

    mssql 子查询更新 update log set uin= b.uinfrom log a,logs bwhere a.accountuin = b.accountuin mysql 不支持 up ...

  9. deep learning framework(不同的深度学习框架)

    常用的deep learning frameworks 基本转自:http://www.codeceo.com/article/10-open-source-framework.html 1. Caf ...

  10. Uva_11021 Tribles

    题目链接 题意: 现在有k只麻球, 每只麻球只能存活一天, 第二天就会死去, 死去之前可能生下x只小麻球(x = 0,1,2,...,n  1), 概率分别为P[0], P[1], ... , P[n ...