《The C++ Programming Language》 学习笔记

0

1.把时间花在“经典”上,或许生命的分量将从此不同。—— 出版社的话

2.带着一种健康的怀疑的态度去阅读,有些过于细节的东西不要钻牛角尖。

3.本书不适合初学者,因为作者经验过于丰富,他认为的不言自明的东西对初学者而言是一种学 习障碍。

4.知识分为两类:我们自己知道的那些事物,或者我们知道从何处找到有关它的信息。(Samuel Johnson)

致读者

  1. 学习C++最重要的事情是集中关注概念,不要迷失在语言的 技术细节中。对程序设计和设计技术的理解远比对细节的理 解更重要,而这种理解的根本是时间和是实践。

  2. C++所支持的不同的程序设计风格的基础是强类型检查,大 部分的目标都是要获得一种喔咕高层次的抽象以直接表达程 序员的思想。每种风格都可以在有效管理时间和空间的情况 下,达到它的目的。

  3. 你可以用Fortran/C/Smalltalk等风格写程序,可以在任何语 言这样做,但是在一个有着不同设计哲学的语言里,这样做 不经济也不愉快。去颠覆一个语言的基本类型系统,可能得 到的至多是伊皮鲁斯式的胜利(指付出极大的代价获得的胜 利)。

  4. C++设计准则: 简单性:很多时候我们都是去简化语言的定义而不是简化编 译器 与C的高度兼容性:这样可以免于清理C语法

  5. C++没有内部高级数据类型和高级的基本操作,如果用户需 要一个类型,那么可以在语言本身之中去定义它。事实上, 定义新的通用或者专用类型就是在C++里最基本的程序设计 活动。

  6. C和C++之间的差异,从根本上说,在于强调类型和结构的 级别不同。在兼容C的基础上,为了使C++能够成为一个编 写库,使用库的更好的语言,C++增加了一些推广和若干主 要的扩充,包括:多重继承,static成员函数,const成员函 数,protected成员,模版,异常处理,运行时类型识别和 名字空间。

  7. C++的设计就是为了使较大的的程序能够以一种合理的方式 构造出来,并能使一个人也能对付相当大的一批代码,进一 步的目的是使一个平均行的C++代码能够表述出远比平均行 的C或Pascal代码更多的东西。

  8. 一个程序设计语言要服务于两个相互关联的目的:它一要为 程序员提供一种描述所需执行的动作的载体,二要为程序员 提供一组概念,使他们能够利用这个概念去思考什么东西是 能够做的。

  9. C++的发展历史:C++保留C作为其一个子集,并保留了C在 功能上的强项,即能在足够低的层次上处理最苛刻的系统程 序设计工作。C++引进了C前驱BCPL的//注释约定。从 Simula67搬过来了类的概念(包括派生类和虚函数)。而关 于重载运算符和自由地将声明放置在可以出现语句的任何位 置是借鉴了Algo168。模版功能的设计,部分地受到Ada中 类属的启发和部分地受到Clus语言参数化模块的影响。异常 处理机制,受到了Ada,Clu,ML的影响。而其他方面例如多重 继承,纯虚函数,名字空间这些却是由C++使用经验推动下 推广而来而不是其他语言引进。

  10. 要用好这个语言,你需要一种观点,以便给这组特征和技术 带来一种秩序。

  11. 怎样在C++里写出好程序:“了解你想说什么”,以及“实践, 模仿最好的作品”。

  12. “忠告”只是一个粗略的使用规则,而不是万古不变的定律, 他们只适用于“合适的地方”,从来没有任何东西能够代替智 慧,经验,常识和好的鉴赏力。

C++概览

  1. 一门语言的好坏不在于它拥有多少特征而在于它所拥有的特 征是否足以在所希望应用领域中支持某种所希望的程序设计 风格。

  2. 从程序组织的观点看,函数被人们用于在许多算法的迷宫里 建立起一种秩序,算法本身通过函数调用和其他语言功能写 出。

  3. C++允许把任何声明放到名字空间。

  4. 分别编译是任何程序都要考虑的问题。

  5. 异常处理:处理错误的标准方式。

  6. 模块化是一切成功的大型程序的最基本共同特征。

  7. 名字和类名相同的成员函数为构造函数。每个构造函数定义 了一种初始化这个类的方式。如果一个类的对象出了其作用 域,需要作些清理工作,这时就需要构造函数对应物:析构 函数。构造函数初始化类的时候就是用new运算符从自由空 间(也称堆或者动态分配)分配一些存储。而析构函数进行 清理的时候就是释放这些内存。

  8. 抽象类型的界面能更完全地将用户与实现细节分离开来。

  9. virtual在simula和C++中的意思就是:可以在今后由这个类 派生的类中重新定义。

  10. 编译器将virtual函数的名字转化为指向这些函数的指针表的 下表。这个表叫做虚函数表(vtbl)。虚函数的调用机制基 本上可以做到和正常调用函数一样的效率,其空间开销是带 有虚函数的类的对象里包含着一个指针,而每个这样的类需 要一个vtbl。

  11. 没有一种方式来区分类的共同特点和特有特点。表达这种区 分并由此获益就定义了面相对象程序设计。具有能表达和利 用这种区分的结构的语言将支持面向对象的程序设计,其他 语言就不行。

  12. 派生类由其基类继承来了成员,对基类和派生类的使用称为 继承。

  13. 在类型之间,能够使用继承和虚函数挖掘出共性的数量,可 以看作是面向对12象程序设计对于该问题适用性的一个石蕊 检验。

  14. 将表,向量,映射(也称关联数组)等都定义为模版。一个 能保存一集=元素的类,称容器类(或简称容器)。

  15. 对一项工作来说完美的东西对另外的工作来说常常可能就存 在严重的缺陷,因为在一个领域中完美的事物往往意味着专 有化。

  16. 考察C++的各项细节的真正目的在于能够应用它们,在有效 设计的环境里,去支持良好的程序设计风格。你并不需要了 解所有C++的细枝末节才能写出一个好的C++程序。

标准库概览

  1. 没有任何一种重要程序只用某种裸裸的程序设计语言赤设计,首先需 要开发出一组支撑库(C++标准库)作为进一步工作的基础。

  2. 由main()函数返回的int值,如果有,就是这个程序返回给“系统”的 值,如果没有值被返回,系统将收到一个反应程序成功完成的值。返 回值非0表示出错。
  3. #include <iostream>: 表示编译器去包含位于iostream中的标准 流I/O功能的声明。如果没有这些声明,语句std::cout«“Hello World!\n”;将没有任何意义。运算符«(送出)将它的第二个参 数”Hello World!\n”(字符串文字量)写到第一个参 数std::cout(标准输出流)中去。

  4. 标准库名字空间:标准库定义在一个称为std的名字空间 内,std::cout这样子写的原因就是,说明了使用的是标准(std)cout 而不是其他的cout。

  5. 标准库的每个功能都是通过程序包含的头文件提供的,为了能编译和 运行某些程序片段,必须去#include合适的头文件,此外,还必须使 用std::前缀来调用某些功能,或者将出自std的每个名字做成全局的 (using namespace std;)后就不用每次都写std::前缀。

  6. 默认情况下,送到cout的值都是字符(数值或字符常量至少其一)的 序列。要输出字符常量,必须将要输出的字符单括号括住:cout « ‘a’;

  7. 一个输出表达式的结果本身还可以用作进一步的输出: cout « “The value of i is:” « 10;

  8. 字符串之间的加法就是串接。string可以相互比较也可以和字符串文 字量相比较。

  9. 子字符串的操作函数:substr();指代函数参数指明的子串副 本。replace();用一个值替换掉指定的子串。代码如下:
string name = "lam c j";
string s = name.substr(4, 7); name.replace(4, 7, "chuanjiang"); cout << s << "\n" << name;
  1. C风格的字符串:以\0结束的字符串,C中字符串都是当作数组来处 理的。

  2. cin和getline()的区别:cin以一个空白字符结束一次输入,gerline可 以截取完整输入。

  3. 容器:一个以保存一批对象为主要目的的类称为容器。

  4. Vector:解决内部数组规模太大浪费内存规模太小溢出的问题。定 义:vectorname_2(size);vector是一种能简单赋值的简 单对象。但是,标准库的vector不提供范围检查,修订版的Vec自带 有范围检查。

  5. map:关联数组或者字典。

  6. 容器界面的一致性能够使我们能够描述各种不依赖任何特定容器类型 的算法。

  7. 迭代器是一种处理容器中元素排列的非常一般而又极其有用的概念。 此外,它也用于I/O上。

  8. 谓词:用于控制算法的函数。

  9. 标准库算法:在C++标准库中的环境中,一个算法就是指在一组在元 素序列上操作的模板。

  10. valarray,比vector更适合与数值计算。

  11. size_t是实践中用于表示数组下标的无符号整数类型。

  12. STL:C++标准库中提供的最常见的数据结构以及在其身上的通用算法 (对任何容器都适用而不需要任何转化),这个框架称为STL,可拓 展,用户可以很容易地提供各种容器和算法。

  13. 忠告:不要像重新发明车轮一样企图做每件事,去使用库。不要相信 奇迹,要理解你的库能干什么,他们如何做以及做的时候需要多大的 代价。需要用到的功能一定要#include进去。标准库的功能定义在名 字空间std之中。

类型和声明

速览:本章只提供最基本的元素,C++程序将从这些东西中构造 起来。你必须知道这些东西,再加上伴随他们的术语和简单的语 法,便能完成和阅读项目代码。但要理解后面的内容并不需要彻底 理解本章的所有细节。可以根据需要再转回来进一步理解细节。

  1. 每个名字都有一个与之相关的类型,这个类型决定了可以对 这个名字进行什么样的操作。

  2. 整数和指针都可以隐式地转化为bool类型。非零为true,零 为false。

  3. ASCII码是ISO-646的变形之一,这个字符集只是部分的标准 化了因此会引起很多问题。任何字符都是整型,对他们可以 进行算术运算和使用逻辑运算符。

  4. signed char(-128~127),unsigned char(0~255)。将超过上 述范围的值存入普通的char都会导致微妙的移植性问题。如 果真的需要使用不止一种char类型,或者将整数存入char 中,阅读C.3.4(page 752)。

  5. 类型wchar_t用于保存更大字符集里的字符(如Unicode字 符)。它的大小由实现决定,且保证足够存放具体实现所用 现场所支持的最大字符集。它来自C,在C中,wchar_t是一 个typedef而不是一个内部类型。加上后缀_t就是为了区 分typedef和标准类型。

  6. 字符文字量即为字符常量。用字符文字量代替十进制表示可 使程序更具有移植性。

  7. 整数文字量的四种形式:十进制(decimal),八进制 (octal,以0开头),十六进制(hexadecimal,以0x(X)开 头)和字符文字量。8位和16位更适合表示表示二进制位的模 式。这些记法表示的真正数值常常因机器位数而异。后缀U和 L分别显式地表示unsigned和long文字量。没有后缀时编译 器就会根据文字量的大小和实现中文字量的大小自动为整数 文字量确定一个适当的类型。

  8. 如果你的程序是成功的,那么它很可能就需要移植性。在写 程序时,理解程序对实现的依赖性的影响并加以限制,比以 后在去才去踩这个泥潭要容易的多。 在许多机器上,不同种 类的基础类型之间,在对存储的时间,存储访问时间和计算 速度方面存在明显的差异。C++对象的大小使用char大小的 倍数表示的,所以按照定义char的大小为1(至少8位),一 个char能保存的机器的字符集中的一个字符。

  9. 字节和现实长度换算:一个字节 = 0.2in. 1英寸(in) = 0.0254m. 1mile = 1609.344m.

  10. 保值:如果一个值v可以在一个类型T的变量中确切地表示, 那么从v到T的转换就是保值的。那些转化不能够保值的地方 尽量避免相关转化。

  11. 在声明函数的时候,必须刻画返回值的类型,为了避免削弱 语法的规范性,以及与C的使用方式相冲突,函数不返回值 必须使用void说明。

  12. 枚举是保存一组用户自己刻画的值的类型。 里面的元素未说 明则从0开始先后顺序递增。枚举的取值范围(能保存所有枚

举符值的常规2补码表示的最小位段2^k)如下:如果枚举符 中的值都是非负的为[0:2^k-1],如果有负的枚举符值为 [-2^k,2^k-1]。在同一个机器上,枚举的大小不大于整型。

本文最后修改时间: 2015-03-28 17:02:44 +0000 (完) CC BY-NC-ND 3.0

若您发现文章中的错误,并愿告知于我,或想与我交流,我的联系方式在: Contacts


上一篇 DIV+CSS 笔记

All The Best

下一篇 《Beginning C》 学习笔记