二元空间分割树
平截头体剔除算法
源文件、头文件及翻译单元(细微但重要的区别)
编辑器每次只翻译一个C++ 源文件至机器码。所以源文件也叫翻译单元
头文件通常用于在多个翻译单元之间分享信息,例如类型声明及函数原型,C++ 编辑器并不知道头文件,所以实际情况是,C++预处理器预先把每个#include语句替代为相对应的头文件内容,然后再把翻译单元给编辑器。所以头文件是独立的文件,但多亏有预处理器把头文件展开,编辑器收到的才是翻译单元
程序库、可执行文件及动态链接库
编译翻译单元后,输出的机器码会存储在对象文件中,对象文件的机器码是:
1.可重定位的:未决定代码的内存位置
2.未链接的:未解决的外部函数参考,以及翻译单元外定义的全局数据
对象文件可以集合成程序库,程序库只是一个简单的存档,包含了多个对象文件
链接器把对象文件和程序库链接成可执行文件。可执行文件包含完全解析的程序吗,操作系统可载入及执行这些机器码。
链接器的工作包括:
- 计算全部机器码的最终相对地址,即当程序执行时机器码在内存中的分布
- 确保正确的解析每个翻译单元(对象文件)的所有外部函数参考和全局数据
可执行文件里的机器码是浮动的,文件中的所有指令和数据地址是相对于一个任意的基址并非绝对地址,直到程序载入内存,在执行之前,最终绝对基址才会决定下来
动态链接库是一种特殊的库,其行为像正常的静态的链接库和可执行文件的混合体,DLL的行为像库,因为它包含函数,供其他多个不同的可执行文件调用,然而,DLL的行为也像可执行文件,因为操作系统能独立的载入DLL,而且DLL可包含启动及终止代码,其执行方式和C++可执行文件的main函数相似
预处理器设置
C++ 预处理器处理#include文件的展开,以及处理#define宏的定义和替换,所有现代的C++预处理器皆有一个极强大的功能,就是可以通过命令行定义预处理宏(因而也能通过生成配置定义)。用这种方式定义宏,和在代码中编写#define指令等效。
void f()
{
#ifdef _DEBUG
printf("")
#endid
}
内联函数
内联函数展开是称为优化的泛代码转换例子之一,可以使用编译器选项去控制编译器尝试优化代码的进取性以及使用哪些优化方法。
断言?
内存泄漏和损坏检测
如果内存在分配后永不释放,就会产生内存泄露,泄露会浪费内存,最终造成致命性的内存不足。
内存损坏是指,程序不慎把数据写进内存的错误位置,覆盖了该位置原来的重要数据,也同时未能吧数据写道应该写的位置。
指针
指针指向已释放的内存,或者指针被意外地复制为非零整数或浮点数,那么这些指针就化为内存损坏的危险工具,因为数据最终会写