《C专家编程》阅读笔记
每次读完书都没什么感觉,哪怕在书上做了笔记读完一段时间后仍旧感觉很空无所得,所以这次决定在读《C专家编程》这本书时,对一些我之前不是很了解或者我认为很重要的点进行简单的记录。
Chapter 1
- 表达式的运算要在CPU内执行,CPU内整型运算器的操作数的字节长度一般是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执行时也要先转换为CPU内整型操作数的标准长度。通用CPU是难以直接实现两个8比特字节直接相加运算所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。
- 当执行算数运算时,操作数的类型如果不同,就会发生转换。数据类型一般朝着浮点精度更高,长度更长的方向转换,整型数如果转换为signed不会丢失信息,就转换为signed,否则转换为unsigned。
Chapter 2
-
sizeof是操作符,不是函数,当sizeof的操作数是个类型名时,两边必须加上括号,但当操作数如果是变量则不必加括号,最好都加上括号。
-
相邻的字符串常量将自动合并成一个新的字符串
-
lint软件很重要,要早用lint程序,勤用lint程序。
Chapter 3
- C语言声明的优先级规则
A. 声明从它的名字开始读取,然后按照优先级顺序依次读取。
B. 优先级从高到低依次是:
B.1 声明中被括号括起来的那部分;
B.2 后缀操作符:括号()表示这是一个函数,而方括号[]表示这是一个数组;
B.3 前缀操作符:星号表示“指向...的指针”;
C. 如果const和(或)volatile关键字的后面紧跟类型说明符(如int,long等),那么它作用于类型说明符。在其他情况下,const和(或)volatile关键字作用于它左边紧邻的指针星号
。
char * const *(*next)();
// A 变量名为next
// B.1 next是指向一个...的指针
// B.2 右边接的是()表示函数,所以next是一个函数指针
// B.3 往左分析,第一个*表示返回值是一个指向(char * const)的指针
// C 分析char * const,const后不是类型说明符则修饰的是左侧的*,表示指向char的常量指针
Chapter 4
- 数组名和指针的不同点
指针 | 数组 |
---|---|
保存数据的地址 | 保存数据 |
间接访问数据,首先取得指针的内容,把它作为地址,然后从这个地址提取数据。 | 直接访问数据,a[i]只是简单地以a+i为地址取得数据 |
通常用于动态数据结构 | 通常用于存储固定数目且数据类型相同的元素。 |
相关的函数为malloc(),free() | 隐式分配和删除 |
通常指向匿名数据 | 自身即为数据名 |
Chapter 5
- 警惕Interpositioning,就是通过编写与库函数同名的函数来取代该库函数的行为,自己修改的新函数不仅在自己的代码中生效,在项目其它调用该函数的库中也是生效的,你能保证自己正确使用但无法保证库如何使用你编写的函数。
Chapter6
- 数据段:初始化后的全局和静态变量,BBS(Better Save Space)段:未被初始化的全局和静态变量(记录大小),文本段:存储指令代码等,大小易受优化措施影响。
Chapter7
- 虚拟内存,内存地址统一管理,使得每个进程都以为自己拥有整个地址空间的使用权。当物理内存中的数据有一段时间未被使用它们就有可能被转移到硬盘中,等到实际需要使用时再载入到物理内存中。
- Cache存储器,位于CPU和内存之间,是一种极快的存储缓冲区,所有对内存的读取和写入操作都要经过Cache。当处理器需要从一个特定的地址提取数据时,这个请求首先递交给Cache。如果数据已存在于Cache中,它就可以立即被提取,否则,Cache向内存传递这个请求。Cache写入数据两种类型:
- 全写法(write-through)Cache---每次写入Cache时总是同时写入到内存中,使内存和Cache始终保持一致。
- 写回法(write-back)Cache---当第一次写入时,只对Cache进行写入。如果已经写入过的Cache行再次需要写入时,此时第一次写入的结果尚未保存,所以要先把它写入到内存中。当内核切换进程时,Cache中的所有数据也都要先写入到内存中。
Chapter9
- 数组和指针相同的情况:
表达式
中的数组名被编译器当作一个指向该数组第一个元素的指针(特例:sizeof 数组名、&取数组地址、数组是一个字符串常量初始值)。- 下标总是与指针的偏移量相同。
- 在函数的参数声明中,数组名被编译器当作指向该数组第一个元素的指针。
Chapter10
- 二维数组和指针数组的区别:①二维数组内存是连续的,指针数组可以是离散的。②二维数组声明时就分配了空间,而指针数组须为每一个指针分配空间。③取值的底层逻辑不一样,类似指针跟数组的区别。
Chapter11
- C++特性:
1.抽象:把一些事物的共性抽象总结出来
2.封装:把数据和方法都放到类中,并添加访问控制(public、protected、private、friend、virtual)
3.类中的函数实现可以放在类定义中,也可放在类的外部(更常见,代码组织更清晰)
4.构造和析构函数:构造函数,当类的一个对象被创建时使用,负责对象内部变量的初始化,构造函数可以重载。析构函数,当对象被销毁时调用,负责释放一些内部资源。
5.继承:从一个类派生另一个类,使前者所有的特征在后者中自动可用
6.多态:声明一个基类对象,运行时确定该对象的具体子类,基类中需要多态使用的函数得加virtual修饰。