C预处理器:在程序执行之前查看程序。根据程序中的预处理器指令,预处理器把符号缩写替换成其表示的内容。
预处理指令示例:
#define、#include、#ifdef、#else、#endif、#ifndef、#if、#elif、#line、#error、#pragma
目录
#undef
#undef 用于“取消”已定义的 #define 指令。
如果想使用一个名称,又不确定是否之前使用过,可用 #undef 取消之前的定义。
//宏定义
#define LIMIT 400
//"取消"宏定义
#undef LIMIT
#ifdef、#else、#endif
#define MAVIS //定义了空宏
#ifdef MAVIS //执行
#include "horse.h"
#define STABLES 5
#else //不执行
#include "cow.h"
#define STABLES 15
#endif //结束 #ifdef 必须要!
#ifdef、#else、#endif 可以用在函数中,以便选择适合的代码段。
但是: #ifdef 和 #endif 必须成对出现!
#ifndef
#ifndef 指令与 #ifdef 指令的方法类型,也可以和 #else、#endif 一起使用,但他们的逻辑相反。
#ifndef 指令判断后面的标识符是否是未定义的,常用与定义之前未定义的常量。
#ifndef SIZE
#define SIZE 100
#endif
也可以防止引用头文件多时,被重复定义,或者定义为不同的数,导致问题。
开发写 .h 文件时不都是:
防止多次引用多次声明什么的。
#ifndef __GIPO_H__
#define __GIPO_H__
/* .h文件中的内容主体 */
#endif
#if、#elif
示例:
#if SYS == 1
#include "ibmpc.h"
#elif SYS == 2
#include "vax.h"
#elif SYS == 3
#include "mac.h"
#else
#include "general.h"
#endif
较新的编译器提供另一种方法测试名称是否已定义,即用 #if defined (VAX) 代替 #ifdef VAX 。
这里,defined 是一个预处理运算符,如果它的参数是用 #define 定义过,则返回 1,否则返回 0。这种方法的优点就是:可以和 #elif 一起使用。
#if defined (IBMPC)
#include "ibmpc.h"
#elif defined (VAX)
#include "vax.h"
#elif defined (MAC)
#include "mac.h"
#else
#include "general.h"
#endif
条件编译可以让程序更容易移植。
#line、#error
#line 指令重置 __LINE__ 和 __FILE__ 宏报告的行号和文件名。
#line 1000 //把当前行号设置为1000
#line 10 "cool.c" //把行号重置为10,把文件名重置为 cool.c
#error 指令让预处理器发出一条错误消息,该消息包含指令中的文本。如果可能的话,编译过程应该中断。
使用 #error 的例子:
#if __STDC_VERSION__ != 201112L
#error Not C11
#endif
会输出:
文件名: 行号: error: #error Not C11
#pragma
C Primer Plus 解释不清楚,后续用到再更新。
编译指示(pragma)
例如:在开发C99时,标准被称为 C9X,让编译器支持 C9X
#pragma c9x on
C99还提供了 _Pragma 预处理运算符,该运算符把字符串转换成普通的编译指示
_Pragma ("nonstandardtreatmenttypeB on")
等价:
#pragma nonstandardtreatmenttypeB on