读书笔记之:C++Primer 第3版

C++ Primer v3

前两天看完了《C++ primer》的第4版,今天刚看完第3版。第3版看得比较粗略。总的感觉是第4版显得比较条理,第3版的细节比较分散。第4版中将很多应该注意的知识点都重点强调了一下,从第3版不好区分哪些比较重点。

第一章 C++概述
1. 编译C++程序时,编译器自动定义了一个预处理器名字__cplusplus.
在编译标准C时,编译器自动定义宏__STDC__。当然,__cplusplus和__STDC__不能被同时定义
第二章 C++浏览
1. C++中的数组
在内置数据类型与标准库类的类型之间是复合类型(compound type)特别是指针和数组,引用类型。
虽然C++对数组提供了内置支持,但是这种支持仅限于“用来读写单个元素”的机制,C++不支持数组的抽象(abstraction),也不支持对整个数组的操作。
数组类型本身没有自我意识,它不知道自己的长度,我们必须另外记录数组本身的这些信息。在C++中,数组不同于整数类型和浮点数类型,它不是C++语言的一等(first-class)公民。数组是从C语言继承过来的,它反映了数据与其进行操作的算法的分离,而这正是过程化程序设计的特征。
2. 静态与动态内存分配
(1)静态对象是有名字的变量,可以直接对其进行操作。而动态对象是没有名字的变量,我们只能通过指针对其进行间接操作。
(2)静态对象的分配与释放是由编译器自动处理的。相反动态对象的分配与释放必须由程序员显式地管理。
内存泄露(memory leak)是指一块动态分配的内存,我们不再拥有指向这块内存 的指针,因此我们没有办法将它返还给程序供以后重新使用。

第3章 C++数据类型
1. 常用的转义字符

backspace(退格键) \b

carriage return (回车键) \r

alert (beel) (响铃符) \a

single quote (单引号) \'

horizontal tab(水平制表键) \t

newline(换行符) \n

backslash (反斜杠键) \\

double quote (双引号) \"

vertical tab(垂直制表键) \v

formfeed (进纸键) \f

question mark (问号) \?

 


 

 

 

 

 

 2. 变量

什么是变量?变量是程序的静态存储区域中的一块内存区域的名字。
变量和文字常量都有存储区域,并且也有相关的类型。区别在于变量是可寻址的。
对于每一个变量,都有两个值与其关联:
(1)它的数值(右值,只能读取)(2)它的地址(左值,可以被赋值)
3. 关键字
c89中有32个关键字,C99添加5个

auto 1

else enum extern 3

register return 2

void volatile 2

break 1

float for 2

short signed sizeof static struct switch 6

while 1

case char const continue 4

goto 1

typedef 1

inline restrict _Bool _Complex _Imaginary 5

default do double 3

if int long 3

union unsigned 2

 

C++中的关键字(63)

asm auto 2

false float for friend 4

namespace new 2

template this throw ture try typedef typeid typename 8

bool break 2

goto 1

operator 1

union unsigned using 3

case catch char class const const_cast continue 7

if inline int 3

private protected public 3

virtual void volatile 3

default delete do double dynamice_cast 5

long 1

register reinterpret_cast return 3

wchar_t while 2

else enum explicit export extern 5

mutable 1

short signed sizeof static static_cast struct switch 7

操作符替代名(11)
and and_eq, bitand bitor, compl, not not_eq, or or_eq, xor xor_eq

 4. const限定符

一般编译器不能跟踪指针在程序中任意一点指向的对象。(这种内部工作需要根据数据流分析(data flow analysis),通常由单独的优化器(optimizer)组件来完成)
5. 枚举类型
enum MODE{IN,OUT,APPEND}
我们不能使用枚举成员进行迭代:
//wrong
for ( open_modes iter = input; iter != append; ++iter )
// ...
C++不支持在枚举成员之间前后移动
我们可以定义枚举类型的对象,并且我们只能够使用相同枚举类型的对象或枚举成员来进行初始化。
但是,在必要时,枚举类型会自动被提升为算术类型。
如:
const int array_size = 1024;
// ok: pt2w 被提升成 int 类型
int chunk_size = array_size * pt2w;

第4章 表达式
1. 算术异常
算术异常主要归咎于算术的自然本质(比如除以0)或归咎于计算机的自然本质(比如溢出)

第7章
1. 缺省实参
函数调用的实参按位置解析,缺省实参只能用来替换函数调用缺少的尾部实参。
函数声明可以为全部或部分参数指定缺省实参。在左边参数的任何缺省实参被提供之前,最右边未初始化参数必须被提供缺省实参。这是由于函数调用的实参是按照位置解析的。

一个参数只能在一个文件中被指定一次缺省实参。
习惯上,缺省实参在公共头文件包含的函数声明中指定,而不是在函数定义中。如果缺省实参在函数定义的参数表中提供,则缺省实参只能用在包含该函数定义的文本文件的函数调用中。
函数后继的声明中可以指定其他缺省实参——一种对特定应用定制通用函数的有用方法。
【1】


2. 返回值
C++中,如果函数返回一个左值,那么对返回值的任何修改都将改变被返回的实际对象。
为了防止对返回值的无意修改,返回值应该被声明为const:
const int &get_val(...)
3. 函数指针
当一个函数名没有被调用操作符修饰时,会被解释成指向该类型函数的指针。
将取地址操作符作用在函数名上也能产生指向该函数类型的指针。
利用函数指针调用函数时,不需要解引用操作符。无论是用函数名直接调用函数,还是用指针间接调用函数,两者的写法都是一致的。
4. 指向extern “C“函数的指针
指向C函数的指针与指向C++函数的指针类型不同。所以如果用指向C++函数指针去为指向C函数的指针来进行赋值或初始化的话会产生编译错误。
如:
extern "C" void (*pf1)(int);
void(*pf2)(int);
pf1=pf2;//error
当链接指示符应用在一个声明上的时候,所有被它声明的函数都将受到链接指示符的影响。
如:
// pfParm 是一个指向 C 函数的指针
extern "C" void f1( void(*pfParm)(int) );

第8章 域和生命期
1.类型安全机制( type-safe-linkage)
在c++中,有一种机制,通过它可以把函数参数的类型和数目编码在函数名中,叫做类型安全链接(type-safe linkage)。类型安全链接可以用来帮助捕捉不同文件中函数声明不匹配的情况。
不同文件中出现的同一对象或函数声明的其他类型不匹配情况,在编译或链接时可能不会被捕捉到.因为编译器一次只能处理一个文件,它不能很容易地检查到文件之间的类型违
例.这些类型违例可能是程序严重错误的根源.例如, 文件之间错误的对象声明或函数返问类型就不能被检测出来.这样的错误只能在运行时刻异常或程序的错误输出中才能被揭示出
来.
2. 常量折叠(constant folding)
常量折叠(Constant folding)是其中一种被很多现代编译器使用的编译器最优化技术。常量折叠是在编译时间简单化常量表达的一个过程。简单来说就是将常量表达式计算求值,并用求得的值来替换表达式,放入常量表。可以算作一种编译优化。
例如
const int i=100;
const int j=i+10;

在编译时并没有给i和j 分配存储空间,也就是说遇到i就用100代替,编译同时也进行了简单的常量计算,所以遇见j就用110代替,这样i和j就不占用内存了。若是要做取地址操作,比如:long address =(long)&j; 这就需要为常量j分配内存空间了,但其值是不可改变的。
编译器会为常量分配了地址 ,但是在使用常量的时 ,常量会被一立即数替换(保护常量,防止被破坏性修改)
3. 动态内存分配
【2】

4. 定位new表达式
【3】

5. 显示调用析构函数
1。显式调用的时候,析构函数相当于的一个普通的成员函数
2。编译器隐式调用析构函数,如分配了对内存,显式调用析构的话引起重复释放堆内存的异常
3。把一个对象看作占用了部分栈内存,占用了部分堆内存(如果申请了的话),这样便于理解这个问题
系统隐式调用析构函数的时候,会加入释放栈内存的动作(而堆内存则由用户手工的释放)
用户显式调用析构函数的时候,只是单纯执行析构函数内的语句,不会释放栈内存,摧毁对象

第9章 函数重载
1. extern "C" 与函数重载
【4】

你可能感兴趣的:(读书笔记)