C++Primer笔记.pdf
《C++Primer笔记.pdf》由会员分享,可在线阅读,更多相关《C++Primer笔记.pdf(52页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、C+P ri m e r 笔记新一篇:VC笔记第 1 章 开 始1 C+程序程序源文件的名字,一般包括两部分:文件名以及文件后缀。文件后缀一般用来标识文件的内容头文件:一般以.h 后缀结尾程序文本文件:C+一般以.c p p 后缀结尾C+标准库中的名字都是在一个称作s t d 的名字空间中声明的,这些名字在我们的程序文本文件中是不可见的。除非我们显式地使它们可见u si n g 指示符告诉编译器要使用在名字空间s t d 中声明的名字2、预处理器指示符预 处 理 器 指 示 符 用 号 标 识,这个符号将放在程序中该行的最起始一列上。处理这些指示符的程序被称做预处理器,通常捆绑在编译器中#i
2、n c l u d e#i n c l u d e 指示符读入指定文件的内容,它有两种格式#i n c l u d e#i n c l u d e h 如果文件名用类括号 和括起来表明这个文件是一个工程或标准头文件,查找过程会检查预定义的目录。我们可以通过设置搜索路径环境变量或命令行选项来修改这些目录如果文件名用一对引号括起来,则表明该文件是用户提供的头文件,查找该文件时将从当前文件目录开始Si f n d e f由于嵌套包含文件的原因,一个头文件可能会被多次包含在一个源文件中.条件指示符可防止这种头文件的重复处理#i f n d e f B O O K STO RE _ HSd e f i
3、n e B O O K STO RE _ H/*B o o k st o re,h 的内容*/#e n d i f条件指示符#i f n d e f 检查B O O K STO RE !在前面是否已经被定义,这里B O O K STO RE _ H 是一个预编译器常量,习惯上预编译器常量往往被写成大写字母。如果B O O K STO RE!在前面没有被定义,则条件指示符的值为真。于是从#i f n d e f到#e n d i f 之间而所有语句都被包含进来进行处理,相反如果#i f n d e f 指示符的值为假则它与#e n d i f 指示符之间的行将被忽略为了保证头文件只被处理一次,把
4、如下#d e f i n e 指示符#d e f i n e B O O K STO RE _ H放在#i f n d e f 后面,这样在头文件的内容第一次被处理时一,B O O K STO RE _ H 将被定义,从而防止了在程序文本文件中以后#i f n d e f 指示符的值为真Si f d e f#if d e f 指示符常被用来判断一个预处理器常量是否已被定义,以便有条件地包含程序代码我们在编译程序时可以使用-D 选项,并且在后面写上预处理器常量的名字,这样就能在命令行中定义预处理器常量$CC-DDEBUG main.C也可以在程序中用#d e fin e 指示符定义预处理器常量3
5、、注释注释是用来帮助程序员读程序的语言结构,它是一种程序礼仪,可以用来概括程序的算法、标识变量的意义、或者阐明一段比较难懂的程序代码。注释不会增加程序的可执行代码的长度。在代码生成以前,编译器会将注释从程序中剔除掉C+中有两种注释符号:一种是注释对/*/,与 C 语言中的一样。注释的开始用/*标记,编译器会把/*与*/之间的代码当作注释。第二种注释符是双斜线,它可用来注释一个单行,程序行中注释符右边的内容都将被当作注释而被编译器忽略第 2 章 C+浏览1、内置数组数据类型C+为基本算术数据类型提供了内置的支持另外,标准库还支持基本类抽象的组合在内置数据类型与标准类库之间是复合类型,特别是指针和
6、数组。数组a r r a y 是一种顺序容器它包含单一类型的元素2、动态内存分配和指针在 C+中对象可以静态分配即编译器在处理程序源代码时分配,也可以动态分配一一即程序执行时一,调用运行时刻库函数来分配。这两种内存分配方法的主要区别是效率与灵活性之间的平衡准则不同。出于静态内存分配是在程序执行之前进行的,因而效率比较高。但是它缺少灵活性,它要求在程序执行之前就知道所需内存的类型和数量。一般来说,存储未知数目的元素需要动态内存分配的灵活性C+支持用指针类型来存放对象的内存地址值。C+预定义了 一个专门的取地址操作符&,当我们把它应用在一个对象上时,返回的是对象的地址值。为了访问指针所指向的实际对
7、象,我们必须先用解引用操作符*来解除指针的引用在 C+中指针的主要用处是管理和操纵动态分配的内存静态与动态内存分配的两个主要区别是:1.静态对象是有名字的变量,我们直接对其进行操作。而动态对象是没有名字的变量,我们通过指针间接地对它进行操作2.静态对象的分配与释放由编译器自动处理,程序员需要理解这一点,但不需要做任何事情。相反动态对象的分配与释放,必须由程序员显式地管理,相对来说比较容易出错,它通 过 new 和 d e le te 两个表达式来完成d e le te 表达式的两个版本:删除单个对象d e le te 指针;删除对象数组d e l e t e d 指针;如果忘了删除动态分配的内
8、存,程序就会在结束时出现内存泄露问题。内存泄露是指一块动态分配的内存,我们不再拥有指向这块内存的指针,因此我们没有办法将它返还给程序供以后重新使用3、基于对象的设计支持基于对象设计的类的一般形式如下c l a s s c l a s s n a m e pu b l i c:/公有操作集合pr i v a t e:/私有实现代码);类定义包括两个部分:类头,由关键字c l a s s与相关联的类名构成。类体由花括号括起来,以分号结束。类头本身也用作类的声明。通过使用两个成员访问操作符中的一个,我们可以调用一个有名字的成员函数。这两个操作符为用于类对象的点操作符.以及用于类对象指针的箭头操作符-
9、在类定义中被定义的成员函数会被自动当作是内联函数,此外我们也可以用i n l i n e关键字显式地要求一个函数被视为内联函数。构造函数程序设计中的一个常见错误是使用事先并没向被正确初始化的对象。实际上,这是一个极为常见的错误。所 以C+为用户定义的类提供了一种自动初始化机制:类构造函数,构造函数是一种特殊的类成员函数,专门用于初始化对象。如果构造函数被定义了,那么在类的每个对象第一次被使用之前,这构造函数就被自动应用在对象上函数重载C+支持被称为函数重载的机制,函数重载允许两个或更多个函数使用同一个名字。限制条件是它们的参数表必须不同:参数类型不同或参数的数目不同。根据不同的参数表编译器就能
10、够判断出对某个特定的调用应该选择哪一个版本的重载函数重载函数在运行时刻的行为与非重载函数完全一样,主要的负担是在编译时刻用来决定中该调用哪个实例所需要的时间在类体的外面定义类的成员函数,惟一的语法区别是要指出成员函数属于哪个类,这可以通过类域操作符来实现,类名:析构函数每个类对象在被程序最后一次使用之后,它的析构函数就会被自动调用。我们通过在类的名字前面加一个波浪线】来标识析构函数。一般地,析构函数会释放在类对象使用和构造过程中所获得的资源类定义以及相关的常数值或t y pe d e f名通常存储在头文件中,并且头文件以类名来命名。不在类定义内部定义的类成员函数都存储在与类名同名的程序文本文件
11、中。这些函数不用随每个使用相关类的程序而重新编译,这些成员函数通过预编译之后被保存在类库中4、面向对象程序设计子类型与基类共享公共的接口公有操作的公共集。由于共享公共接口,允许了子类和基类在程序内部可互换使用,而无需考虑对象的实际类型。从某种意义上来说公共接口封装了单个子类型中与类型相关的细节,类之间的类型/子类型关系形成了继承或派生层次关系虚拟函数为了把一个类设计成基类,设计考虑是找出类型相关的成员函数,并把这些成员函数标记为v i rtua l。对于类型相关的成员函数,它的算法由特定的基类或派生类的行为或实现来决定对于一个非虚拟函数的调用,编译器在编译时刻选择被调用的函数,而非虚拟函数的决
12、定则要等到运行时刻。在执行程序内部的每一个调用点上,系统根据被调用对象的实际基类或派生类的类型来决定选择哪一个虚拟函数实例派生类对象的初始化过程派生类对象实际上由几部分构成:每个基类是一个类的子对象,它在新定义的派生类中有独立的一部分。派生类对象的初始化过程是这样的,首先自动调用每个基类的构造函数来初始化相关的基类子对象,然后再执行派生类的构造函数。从设计的角度来看,派生类的构造函数应该只初始化那些在派生类中被定义的数据成员,而不是基类中的数据成员因为基类的构造函数并没有被派生类继承(析构函数和拷贝赋值操作符同样也没有),我们需要派生类的构造函数作为向基类构造函数传递参数的接口C+支持另外两种
13、形式的继承:多继承,也译多重继承,也就是一个类可以从两个或多个基类派生而来。以及虚拟继承,在这种继承方式下,基类的单个实例在多个派生类之间共享5、泛 型 设 计(函数模板和类模板)C+的模板设施提供了一种机制,它能够将类或函数定义内部的类型和值参数化,这些参数在其他方面不变的代码中用作占位符,以后,这些参数会被绑定到实际类型上,可能是内置的类型,也可能是用户定义的类型关键字te m pl a te引入模板,模板参数由一对尖括号 括起来,类型标识符由关键字c l a ss标明,类型标识符作为实际类型的占位符当我们为类模板定义对象时一,编译器必须为相关的对象分配内存。为了做到这一点,形式模板参数被
14、绑定到指定的实际参数类型上。不是所有类模板的成员函数都能自动地随类模板的实例化而被实例化,只有真正被程序使用到的成员函数才会被实例化。模板机制也支持面向对象的程序设计,类模板可以作为基类或派生类6、基于异常的设计异常是指在运行时刻程序出现的反常情形,例如数组下标越界、打开文件失败以及动态可用内存耗尽异常处理为“响应运行时刻的程序异常”提供了一个标准的语言级设施,它支持统一的语法和风格,也允许每个程序员进行微调异常处理机制的主要构成:1.程序中异常出现的点。一旦识别出程序异常,就会导致抛出(rai s e或t hro w)异常。异常被抛出时,正常的程序就被刮起,直到异常被处理完毕2.程序中异常被
15、处理的点。程序异常的抛出与处理位于独立的函数或成员函数调用中。找到处理代码通常要涉及到展开程序调用栈。一旦异常被处理完毕,就恢复正常的程序执行。但不是在发生异常的地方恢复执行过程,而是在处理异常的地方恢复执行过程如果异常机制按照函数被调用的顺序回查每个函数直道m ai n。函数,仍然没有找到处理代码,那么它将调用标准库函数t erm i n at e。缺省情况下,t erm i n at e0函数结束程序一种特殊的、能够处理全部异常的cat ch子句如下:cat ch(.)(处理所有异常;虽然它无法访问异常对象)7、名字空间名字空间机制允许我们封装名字,否则这些名字就有可能会污染全局名字空间。
16、一般来说,只有当我们希望自己的代码被外部软件开发部门使用时.,才使用名字空间关键字n am es p ace后面的名字标识了一个名字空间,它独立于全局名字空间,我们可以在里面放一些希望声明在函数或类体之外的实体为了提供有意义的名字空间,同时程序员又能很方便地访问在名字空间内定义的实体,C+提供了别名设施。名字空间别名允许用一个可替代的、短的或更一般的名字与一个现有的名字空间关联起来/提供一个更一般化的别名n am as p ace L I B =I B M _C an ad a_L abo rat o ry;u s i n g指示符使名字空间内的云有声明都可见,这样这些声明能够不加限定地使用u
17、si ng na me spa c e I B M _C a na d a _Li b ora tory;usi ng声明提供了选择更为精如的名字可视性机制,它允许使名字空间中的单个声明可见usi ng I B M _C a na d a _Li b ora tory:M a tri x;为了防止标准C+用的组件污染用户程序的全局名字空间,所有标准C+库的组件都被声明在一个被称为std的名字空间内8、标准数组向量在标准C+中,数组类是C+标准库的一部分,现在它不叫数组,而叫向量了向量是一个类模板#i nc lud e v e c tor v e c O;空的 v e c torv e c to
18、r v e c l(10);标 准v e c tor类模板支持使用下标操作符,另一种遍历方法是使用迭代器对来标记向量的开始处和结束处。迭代器是一个支持指针类型对象的类对象。V e c tor类模板提供了一对操作b e g i n。和e nd(),它们分别返回指向“向量开始处”和“结束处后一个”的迭代器,这一对迭代器合起来可以标记出待遍历元素的范围v e c tor:i te ra tor i te r=v e c.b e g i n();i te r+;*i te r=3;i te ra tor是v e c tor类模板中用ty pe d e f定义的类型能够应用到向量上的操作惊人地多,但是它
19、们并不是作为v e v tor类模板的成员函数提供的。它们是以一个独立的泛型算法集的形式,由标准库提供。泛型算法接受一对迭代器,它们标记了要遍历的元素的范围,泛型算法还能接受指向内置数组的指针对标准库还提供了对ma p关联数组的支持,即数组元素可以被整数之外的其他东西索引第3章C+数据类型我们编写的程序以及所保存的程序数据在计算机的内存中是以二进制位序列的方式存放的。位是含有0或1值的一个单元,在物理上它的值是个负或正电荷通过对内存进行组织,我们可以引用特定的位集合,用地址引用内存类型抽象使我们能够对一个定长的位序列进行有意义的解释1、文字常量C+预定义了一组数值数据类型(内置数据类型),可以
20、用来表示整数、浮点数和单个字符。此外,还定义了用来表示字符串的字符数组当一个数值,出现在程序中时,它被称为文字常量:称 之 为“文字”是因为我们只能以它的值的形式指代它,称 之 为“常量”是因为它的值不能被改变。每个文字都有相应的类型。文字常量是不可寻址的,尽管它的值也存储在机器内存的某个地方,但是我们没有办法访问它的地址整数文字常量可以被写成十进制、八进制或者十六进制的形式(这不会改变该整数值得位序列)在缺省情况下,整形文字常量被当作是一个i n t型的有符号值。我们可以在文字常量后面加一个“L”将其指定为l o n g类型。类似地,我们可以在整数文字常量的后面加上“U”,将其指定为一个无符
21、号数。此外,我们还可以指定无符号l o n g型的文字常量浮点型文字常量可以被写成科学计数法或普通的十进制形式。浮点型文字常量在缺省情况下被认为是do ub l e型,单精度文字常量由值后面的“F”来标示。类似地,扩展精度中值后面跟的“L”表示单 词t ur e和f a l s e是b o o l型的文字常量可打印的文字字符常量可以写成用单引号括起来的形式,一部分不可打印的字符、单引号、双引号以及反斜杠用转义序列来表示字符串文字常量由零个或多个用双引号括起来的字符组成。不可打印字符可以由相应的转义序列来表示。字符串文字常量的类型是常量字符数组。它由字符串文字本身以及编译器加上的表示结束的空字符
22、构成。空字符是C和C+用来标记字符串结束的符号2、变量变量为我们提供了一个有名字的内存存储区,可以通过程序对其进行读、写和处理。C+中的每个符号变量都与一个特定的数据类型相关联,这个类型决定了相关内存的大小、布局、能够存储在该内存区的值的范围以及可以应用其上的操作集变量和文字常量都有存储区,并且有相关的类型。区别在于变量是可寻址的,对于每一个变量,都有两个值与其相关联:1 .它的数据值,存储在某个内存地址中2 .它的地址值一一即,存储数据值的那块内存的地址变量的定义会引起相关内存的分配,因为一个对象只能有一个位置,所以程序中的每个对象只能被定义一次在C+中,程序在使用对象之前必须先知道该对象,
23、这 对“编译器保证对象在使用时的类型正确性”是必须的。引用一个未知对象将会引起编译错误对象声明的作用是使程序知道该对象的类型和名字。它由关键字ext er n以及跟在后面的对象类型以及对象的名字构成。声明不是定义,不会引起内存的分配。实际上,它只是说明了在程序之外的某处有这个变量的定义变量的定义一个简单的对象定义由一个类型指示符后面跟一个名字构成,以分号结束一个简单的定义指定了变量的类型和标识符,它并不提供初始值。如果一个变量是在全局域内定义的,那么系统会保证给它提供初始值0。如果变量是在局部域内定义的,或是通过n ew表达式动态分配的,则系统不会向它提供初始值0。这些对象被称为是未初始化的。
24、未初始化的对象不是没有值,而是它的值是未定义的初始的第一个值可以在对象的定义中指定,一个被声明了初始值的对象也被称为已经初始化的。C+支持两种形式的初始化,第一种形式是使用赋值操作符的显示语法形式,在隐式形式中,初始值被放在括号中3、指针类型指针持有另一个对象的地址,是我们能够间接地操作这个对象每个指针都有一个相关的类型,不同数据类型的指针之间的区别不是在指针的表示上,也不是在指针所持有的值上一一对所有类型的指针这两方面都是相同的。不同之处在于指针所指向的对象的类型上。指针的类型可以指示编译器怎样解释特定地址上内存的内容,以及该内存区域应该跨越多少内存单元我们通过在标识符前加一个解引用操作符(
25、*)来定义指针。在逗号分割的标识符列表中,每个将被用作指针的标识符前都必须加上解引用操作符不允许不同指针类型之间相互赋值,因为不同类型的指针对内存的存储布局和内容的解释完全不同。C+提供了一种特殊的指针类型:(v o i d *)类型指针,它可以被任何数据指针类型的地址值赋值。v o i d *v表示相关的值是个地址,但该地址的对象类型不知道。我们不能够操作空类型指针所指的对象,只能传送该地址值或将它与其他地址值进行比较C+提供了解引用操作符(*)来间接地读和写指针所指向的对象指针可以让它的地址值增加或减少一个整数值,这类指针操作,被称为指针的算术运算4、字符串类型C+提供了两种字符串的表示:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Primer 笔记
限制150内