一、分析c语言的声明
危险1:c语言的设计哲学之一是”对象的声明形式与使用形式尽可能相似“,而const volatile关键字只能出现在声明中,不能出现在使用中
危险2:人们无法用所习惯的自然方式从左至右阅读一个声明,必须牢记运算符优先级和结合性(编译器是怎么阅读代码的?)

记住一些非法的声明:
(1)foo()(); // 函数的返回值不能是函数
(2)foo()[]; // 函数的返回值不能是数组
(3)foo[](); // 数组里面不能有函数
还有一些合法声明
(1)函数的返回值可以是函数指针
(2)函数的返回值可以是指向数组的指针
(3)数组里面可以是函数指针
(4)数组里面可以是数组

联合体的一个有趣用途:把同一个数据解释成两种不同的东西

typedef声明和变量声明的形式完全一样,但是不创建变量,只是为一种类型引入一个新的名字

typedef和宏文本替换的区别
(1)typedef不可扩展                        typedef int apple; unsigned apple i; // 非法
(2)typedef在连续几个变量的声明中能保证所有变量都为同一种类型

在同一个名字空间内,任何名字必须具有唯一性,但在不同的名字空间里可以存在相同的名字。如结构体的标签名、标签、成员名属于不同的名字空间,如下代码合法 struct foo { int foo; } foo;

二、数组和指针

c语言的对象必须有且只有一个定义、但可以有多个extern声明
左值在编译时可知,表示存储结果的地方;右值在运行时可知,表示地址上的内容

五、对链接的思考

1.应用程序二进制接口(Application Binary Interface,ABI):系统向应用程序提供的接口,使其可以调用二进制函数库
2.动态链接库文件本身的大小要比静态链接库要小,除此之外,在运行时,动态链接库在内存中只有一份拷贝,而静态链接库则存在至少一份拷贝,即动态链接库既节省磁盘空间,又节省内存空间。

六、运行时数据结构

1.jump和goto
(1)goto不能跳出c语言当前的函数
(2)setjmp(env):env记录了当前的过程活动(堆栈信息),函数返回0,longjmp(env, i):还原至之前记录的过程活动,并返回i
(3)c语言的setjmp和longjmp机制  →  c++的catch和throw机制
2.MS-DOS:微软磁盘操作系统(Microsoft Disk Operating system)

七、对内存的思考

1.数据总线、地址总线、控制总线(cpu才有的)
(1)数据总线(data bus):用于处理数据,若有32根数据总线,则cpu每次可以处理32位的数据,即4字节;数据总线的根数也成为处理器的字长。
(2)地址总线(address bus):影响CPU的寻址范围(能访问的存储单元),存储单元以字节为单位存储,若有16根地址总线,则cpu的寻址范围为2的16次方,即64KB
(3)控制总线(control bus):控制其它元器件,若有16根控制总线,则cpu能控制周边的16个元器件
2.8086如何形成内存地址
(1)通过重叠两个16位的字来形成20位的地址总线,寻址范围达到1MB
(2)第一个16位称为“偏移量”
(3)第二个16位称为“段”,8086拥有4个段寄存器,分别是代码寄存器CS、数据寄存器DS、堆栈寄存器SS,用于存放代码段、数据段和堆栈段的首地址,还有一个附加寄存器ES
(4)段寄存器的值左移4位(相当于乘上16),再加上偏移量(段内地址),就能得到最终的内存地址
3.段:处理器的地址空间被分成以64KB为单位的区域,每个这样的区就被称为段
4内存媒介的速度与成本的关系
内存媒介 磁带 磁盘 内存 cache存储器 cpu寄存器
成本 1 2 3 4 5
访问速度 1 2 3 4 5
容量 5 4 3 2 1
5.内存管理由计算机硬件和操作系统协助完成(个人目前的达到的认识水平),实现物理地址和虚拟地址的转换,使得每一个进程都以为自己拥有整个地址空间的独家访问权
6.页:操作系统在磁盘和内存之间移来移去或进行保护的单位
usr/ucb/pagesize 观察系统页的大小,一般为几KB
page in (移入内存 )page out (移到磁盘)
7cache
(1)cache操作的速度与系统的周期时间相同
(2)当处理器需要从一个特殊的地址读取数据时,这个请求首先递交给Cache。如果数据已经存在于Cache中,则可以立即被提取。否则,Cache向内存传递这个请求,进行较缓慢的访问内存操作。内存读取的数据以行为单位,在读取的同时也装入到Cache中