@[TOC]
前言
程序的环境
在ANSI C 的任何一种实现中:都有2种环境:编译环境: 编译器将源代码(后缀.c文件中的代码)转换为包含机器语言(二进制代码)的目标代码文件,同时通过链接器 将 目标文件与 库文件,启动代码文件进行链接 生成 可执行的代码文件。这一过程又可细分为 预处理,编译,汇编,链接。
执行环境:执行可执行代码文件 。
编译环境
预处理
预处理进行的是
文本操作
,不进行任何相关计算。
- 库文件的包含
- (.h)文件中是一些声明或者是自定义类型的声明等。一旦程序调用某些未声明函数,程序会creash。
- 宏的文本替换和预处理指令的操作等
- 去除程序注释内容
- 。。。
编译
分为2步:
- 分别将每个文件中的全局变量名和函数名进行汇总。
- 这也是,为什么在使用函数或者变量时,要进行 提前声明,或者定义式声明,或者引用式声明(extern)
- 通过 词法分析,语法分析,语义分析,分析代码的意思,将源代码转换为汇编语言。
汇编
- 将编译完成的汇编代码 转换为 机器可以识别的二进制代码,生成目标代码文件.
- 对每个符号和其地址 汇总到一个表中---符号表。
- 这样在程序遇到符号名,就可以通过地址,访问符号。
链接
- 对所有符号表进行合并和重定位。
因为不同的文件中的符号可能有重名的,这样就需要确定唯一的有效符号。
- 合并断表。
- 将启动代码,库代码(更多的是将程序用到库函数代码进行链接),目标代码文件,链接,生成可执行文件 (,exe)。
- 这也是为什么,在使用库函数 printf等,我们只需要在文件中 include <stdio.h>等库文件。
执行环境
- 程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
- 程序的执行便开始。接着便调用main函数。
- 开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。
- 终止程序。正常终止main函数;也有可能是意外终止 .