用某种编程语言编写的程序称为源代码,将源代码保存成一个文件就称为源文件。C语言的源文件扩展名约定为“.C”。代码清单的源代码是不能直接运行的,因为CPU能直接解释和执行的只有本机代码。CPU是计算机的大脑,他只能理解本机代码形式的程序。不同编程语言所编写的源代码翻译成本机代码之后就变成了同一种语言。转储是指将文件内容按1字节2位十六进制数的形式显示出来,本机代码的内容就是数值序列。这就是本机代码的本质。负责将用C语言等高级语言编写的源代码翻译成本机代码的程序称为编译器。编译器会读取源代码的内容并将其翻译成本机代码。编译器需要对读取的源代码进行司法分析、语法分析、语义分析等处理,这样才能够生成本机代码。CPU的类型不同,其对应的本机代码也不同。因此,不仅不同的编程语言所使用的编程编译器不同,不同类型的CPU所使用的编辑器也不同。编译器本身也是一种程序,因此也有其对应的运行环境。
作为元代码的翻译结果,编译器生成的是包含本机代码的文件,但这个文件不能直接运行。要得到可执行的EXE文件,在编译之后还需要进行链接操作。将多个目标文件拼接在一起生成一个EXE文件的过程称为链接,用于完成这一操作的程序为链接器。一些通用代码需要链接在所有程序的开头,这些代码被称为启动代码。因此,即便一个程序没有调用位于其他目标文件中的函数,也必须连接启动代码。库文件是由多个目标文件打包而成的。在连接时指定库文件,连接器就可以从中提取所出的所需的目标文件,并将其与其他目标文件一起连接生成EXE文件。不包含在源代码中,而是以库文件的形式随编译器一起被分发的。这样的函数称为标准函数。
windows API的目标文件通常不是以库文件的形式存在的,而是以一种称为DLL的特殊库文件的形式存在的。与之相对,包含目标文件本身,可以直接链接到EXE文件的库文件称为静态链接库。EXE文件作为一个独立的文件存储在硬盘中,当我们在资源管理器中双击EXE文件时,EXE文件中的内容会被加载到内存并运行。在EXE文件中,变量和函数被分配的内存地址都是虚拟的,在程序运行时,这些虚拟的内存地址会转换成实际的内存地址。链接器会在EXE文件的开头记录需要进行内存地址转换的各个位置,这些信息被称为重定位信息。重定位信息中记录的是变量和函数的相对地址,所谓相对地址,就是某个地址与基地址之间的相对距离,也就是偏移量。
栈是用来存放函数内部临时使用的变量以及调用函数时传递的参数等数据的内存空间。堆是在程序运行时用来存放任意数据的内存空间。EXE文件中并不包含栈和堆的区别EXE文件加载到内存并运行的那一刻,栈和堆所需的内存空间才得到分配。无论是C语言还是C++,如果不是在程序中显式地释放堆空间,那在程序运行结束后,这些空间就依然处于占用状态,这一现象称为内存泄露,如果内存泄露一直存在,就有可能造成内存不足,从而导致宕机。