目录
前言:编译与链接
源文件在成为可执行程序之前往往要经过“翻译环境”和“执行环境”,其中翻译环境可细分为“编译”和“链接”,“编译”又可细分为“预编译(处理)”、“编译”和“汇编”,本章讲的是预处理阶段的知识,包括预定义符、宏、条件编译、文件包含等……(主要为宏)
预定义符号:
c语言为我们提供了一些预定义符号,让我们可以快速的实现某种功能,如输出文件当前被编译的时间、日期等。
常见的几个预定义符号:
__FILE__ __FUNCTION__ |
//进行编译的源文件 %s //当前执行的函数 %s |
这些预定义符号存储了一些信息,我们可以用相应格式输出出来。
例:
命令行定义:
许多C 的编译器提供了一种能力,允许在命令行中定义符号。用于启动编译过程。
例如:当我们根据同一个源文件要编译出一个程序的不同版本的时候,这个特性有点用处。(假定某个程序中声明了一个某个长度的数组,如果机器内存有限,我们需要一个很小的数组,但是另外一个机器内存大些,我们需要一个数组能够大些。)
#define定义标识符:
#define 定义的标识符在预处理阶段会被替换成指定内容,我们可以通过它压缩代码的长度,以及增加代码的可读性。
具体操作如下:
用#define 定义标识符MAX,在源文件预处理阶段,该语句后的代码如果出现MAX则会自动替换为10,这一操作为文本操作。(注:由于#difine定义标识符内容不可更改,因此具有常属性,MAX也称之为标识符常量)
那么除了定义标识符常量,我们还可以用#define做什么?
①关键字等进行缩写,如register,不过会降低代码可读性
#define reg register
②创建一个死循环
#define sss for( ; ; );
③选择语句中简写case语句
#define CASE break;case
case 1:
{
……
}
break;
CASE 2:
{
}
CASE 3:
{
}
④实现某一固定功能,如上文中打印当前编译状态的操作
#define STATUS printf("当前正在编译的文件:%s\n文件被编译的日期:%s\n文件被编译的时间:%s\n文件当前的行号:%d\n", __FILE__,__DATE__,__TIME__,__LINE__)
以上例子都说明了#define定义标识符本质上完成的是文本替换的工作,另外要注意的还有#define这行语句是不需要加“;”的,如果加上的话也被视为替换内容,这点在标识符常量使用时可能会产生错误,所以不建议加“;”。
#define 定义宏:
#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义
宏(define macro)。
#define定义标识符和#define定义宏都与#define相关,按理该划为一个模块,但我觉得#define定义宏完全可以单独拿出来细讲,所以单独划出一个模块来。
1.定义宏的格式
宏区别于标识符,而又类似于函数的一点在于,它是有参数的,并且参数用括号围起来的,格式如下:
#define name( parament-list ) stuff
其中的 parament-list 是一个由逗号隔开的符号表,它们可能出现在stuff中,其中括号要和name紧紧相连不能有空格,否则就变成定义标识符了。
对于宏名还有一个约定俗成的规则:采用纯大写字符来命名以区分函数。
2.宏的作用
宏也会在预处理阶段被替换到代码之中,但宏体内的参数也会被替换。</