【预处理】
C语言提供了其他高级语言没有的预处理工具。在源代码通过编译器之前,预处理器先对源代码进行处理,他是在称之为预处理器命令行或指令的控制下操作。
预处理指令大致分为三类:宏替换指令、文件包含指令、编译器控制指令
1.宏替换指令
宏替换是程序中的标识符被预定义的字符串取代的过程。在#define语句指令下工作。一般形式是
#define identifier string
宏替换包括:简单宏替换、参数化宏替换、嵌套宏替换。
简单宏替换:略。
参数化宏替换:
例:#define CUBE(x) (x*x*x)
则在程序中CUBE(a)=a*a*a;类似于函数的调用,当调用宏时,预处理器将替换该字符串。此种替换预处理器只是盲目的将x替换成a。如果CUBE(a+b)则替换成了(a+b*a+b*a+b)显然不和常理,可以修改为
#define CUBE(x) ((x)*(x)*(x))
宏的参数替换可以是任意的字符串系列。
宏嵌套:
我们在定义宏时,可以让下面的宏嵌套上面已经定义的宏,如:
#define M 5 #define N M+1 .......
2.文件包含
#include"filename" #include<filename>
3.编译器控制命令
(1)已包含的一个文件中含有某些宏定义,但是不知道某个宏是否已经定义了。想确认一下TEST宏是否被定义,如:
#include"define.h" #ifndef TEST #define TEST 1 #endif
假设在define.h里没有定义TEST那么下面的语句#define TEST 1就被执行。如果没有#ifndef的判断,重复定义是会出错的。当然也可以取消定义
#include"define.h" #ifndef TEST #undef TEST #endif
(2)假设在两个不同类型的计算机中,要求编写一个可以在两个计算机上运行的程序。因为机器不同,所以可能代码也有所不同,但是也不能写两个程序啊。可以采用
main() { ...... #ifdef IBM_PC { ......... } #else { ............. } #endif }
如果运行在IBM机上,只需在开始,宏定义下#define IBM_PC即可
(3)在测试系统时,希望在某些位置加入特定的语句来测试系统。例如插入printf语句来显示中间结果和消息,成为调试语句。你可以把这些语句称为程序的一部分,但是只在需要是起作用。
main() { ....... #ifdef TEST { printf(.....); } #endif ...... }
在测试阶段可以定义宏TEST如果测试结束就可以删去宏TEST这样测试代码也就不再起作用了。
**C预处理器还支持一个更通用的测试条件形式 #if指令
#if constant_expression { ..... } #endif
4.ANSI C的其他预处理指令
(1)#elif 指令,相当于if...else...if语句系列。
例:
#if expression1 ...... #elif expression2 ...... #endif
(2)#pragma 基于实现的指令,可以用来制定提交给编译器的不同指令。
#pragma message("文本消息") 遇到这个指令就输出文本信息
#pragma code_seg(["section-name"[,"section-class"]])设置程序中函数代码存放的代码段,开发驱动程序是用到
#pragma once 保证头文件编译一次
#pragma hdrstop 表示预编译头文件到此为止,后面的不再编译。
#pragma startup 指定编译优先级,
#pragma package(smart_int)根据优先级大小来编译
#pragma resource"*.dfm" 把文件*.dfm添加到工程中
#pragma comment(...) 把一个注释放入对象文件或可执行文件,常用的lib关键字可以连入一个库文件
#pragma loop_opt(on)/loop_opt(off)用来激活或终止该编译程序支持的一些编译功能。
#pragma warning(...)处理警告信息
(3)#error 用来在调试时产生诊断消息
(4)字符串化运算
ANSI C支持一种成为字符串化的运算符#,用在宏函数的定义中。该运算符允许在宏定义中使用一个形参,它将被转化为一个字符串。
类似与参数化宏替换,可以讲替换内容直接转化成字符串,例如:
#define sum(x) printf(#x"=%f\n",x) main() { ..... sum(a+b); ...... }
预处理器把此语句替换为
printf("a+b""=%f\n",a+b);
等价于
printf("a+b=%f\n",a+b);
(5)标记符粘贴运算符##
ANSI标准定义的标记符粘贴运算符##可以把宏定义中的两个标记符组合成一个标记符。
如
#define combine(s1,s2) s1##s2 main() { printf("%f",combine(a,5)); }
则替换结果为
printf("%f",a5);