初学C语言时,经常会看见文件起始一句#define PI 3.1415之类的预处理语句,大部分国内教材没有再进一步介绍C其他的预处理语句。下面进行一些总结:

define

常规用法

#define macro-name replacement-text 又被称为宏替换,出现这一语句后,该语句之后所有宏均会被替换为replacement-text,包括在此文件后处理的文件。

在C程序生成流程中(C源程序->编译预处理->编译->优化程序->汇编程序->链接程序->可执行文件),宏替换发生在编译之前,可通过gcc -E选项验证。

注意,marco-name作为简单的被替换字段,无法求sizeof(),不占用运行时内存,在替换时由于编译器并不检查其所处位置,可能出现替换后运算顺序不符合预期的情况。这是一种十分隐蔽的错误。#define x a+b
建议在运算中使用const修饰符初始化需要的变量。

define带参数

例如#define MIN(a,b) (a<b ? a : b),使用MIN(x,y)表达式时将得到x,y中的最小值。

又例如#define PR(EX) cout << #EX <<": "<< EX <<endl;,这是一个在调试中常用的宏,可以在打印表达式的同时打印它的值。

这其中,“#EX”中的井号称为字符串化运算符,在预处理器中使用这个符号将把参数转换为一个字符数组。

ifdef #else #endif

用于对程序的某个部分进行有条件地编译,在调试一段代码时常用。用法:

#define DEBUG // 注意不能使用NDEBUG,这是C中的关键字。
//...
#ifdef DEBUG
//调试代码,当DEBUG被define时进行编译
#else
//DEBUG没有被define时编译,可省略此部分
//...
#endif
//调试代码段结束

通过#undef DEBUG可以方便地取消标记的define。

Last modification:May 2nd, 2019 at 11:15 pm
If you think my article is useful to you, please feel free to appreciate