Chapter 15

  • (本章介绍I/O,涉及内容多为各种函数的细节,因此不一一整理)
  • 各不相同但容易混淆的三个概念:

    • 文件:物理存储介质上所保存的内容
    • 流:函数库为I/O所提供的接口
    • 缓冲:程序对流进行读写时所使用的一块空间(可以手动指定不要缓冲)
  • 文件和流之间的转换由操作系统完成,而程序只是通过FILE数据结构来管理储存流和缓冲区的I/O状态

Chapter 16

  • 断言<assert.h>

    • 通过断言某个值为真来进行测试

      void assert(int expression); // 断言expression的值为真
      • 断言指针非空:

        assert(ptr != NULL);

        若条件不为真,则终止程序并打印表达式及断言位置:

        > Assertion failed: value != NULL, file.c line 274
    • 可以通过#define NDEBUG在编译时忽略所有断言而不用修改源码,当然命令行参数-DNDEBUG也有同样效果

Chapter 17

  • (本章介绍各种数据结构,不一一整理)

Chapter 18

  • (本章介绍C编译为汇编的细节,不过已经用ARM学过啦,所以没有细读,以下为简单的笔记)
  • 静态变量和它的初始化:编译器在程序的数据区(.data)为静态变量创建空间并初始化
  • 堆栈帧(stack frame)

    • 堆栈中的一个区域
    • 每一次函数调用都产生一个堆栈帧,用于保存局部变量和其他值
    • 帧指针指向堆栈帧的起始位置(因此每次函数调用中的帧指针都不同,使用link / unlink来切换帧指针)
    • 堆栈帧中的所有值都通过使用帧指针(frame pointer(不是 stack pointer))加上一个offset来访问
    • 参数:逆序入栈(这样可以通过对帧指针加上一个递增的常数offset来顺序访问参数)
  • 函数(.text区)

    • 函数序(prologue):准备工作

      • 为函数的局部变量保留堆栈中的内存(创建堆栈帧)
    • 函数体(body):

      • 对变量和函数的单纯声明不会产生指令,但初始化产生对应的赋值命令
    • 函数跋(epilogue):负责在返回前清理堆栈(事实上并不完全清理,因为只有调用者才知道参数个数)
  • 同一个编译器产生的程序才能被互相链接

小明的贤鱼
2 声望0 粉丝

while(true) -1s;