C-预处理器
预处理器
C 预处理器只是一个文本替换工具, 它们会指示编译器在实际编译之前完成所需的预处理. C 预处理器(C Preprocessor)简写为 CPP.
所有的预处理器命令都是以井号 (#) 开头. 它必须是第一个非空字符, 为了增强可读性, 预处理器指令应从第一列开始.
指令 | 描述 |
---|---|
#define | 定义宏 |
#include | 包含一个源代码文件 |
#undef | 取消已定义的宏 |
#ifdef | 如果宏已经定义, 则返回真 |
#ifndef | 如果宏没有定义, 则返回真 |
#if | 如果给定条件为真, 则编译下面代码 |
#else | #if 的替代方案 |
#elif | 如果前面的 #if 给定条件不为真, 当前条件为真, 则编译下面代码 |
#endif | 结束一个 #if……#else 条件编译块 |
#error | 当遇到标准错误时, 输出错误消息 |
#pragma | 使用标准化方法, 向编译器发布特殊的命令到编译器中 |
定义宏
宏是一种抽象 (Abstraction), 它根据一系列预定义的规则替换一定的文本模式.
解释器或编译器在遇到宏时会自动进行这一模式替换. 对于编译语言, 宏展开在编译时发生, 进行宏展开的工具常被称为宏展开器.
#define 宏名(记号) 内容
#define MaxSize 50
char a[MaxSize];
printf("%llu", sizeof (a));
纯文本替换
#define pint int*
pint a, b; // a是int类型指针变量, b是int类型变量
// 等价于 int *a, b;
含参数的宏
#define Mul(x) x*x
int a = Mul(3); // a = 9
又比如:
#define string(i) "param: "#i""
char b[20] = string(Hello);
puts(b); // "param: Hello"
#define show_string(s) printf("I can print: "#s".")
show_string(123); // "I can print: 123."
#define Test(n) x##n
int Test(1) = 10;
x1 = 20;
printf("%d", x1); // 20
取消定义
#undef
#define string(i) "param: "#i""
char b[20] = string(Hello);
#undef string
// 取消已有定义 string
标准预定义宏
宏 | 描 述 |
---|---|
__DATE__ | 当前源文件的编译日期, 用 "mmm dd yyyy" 形式的字符串常量表示 |
__FILE__ | 当前源文件的名称, 用字符串常量表示 |
__LINE__ | 当前源文件中的行号, 用十进制整数常量表示, 它可以随#line指令改变 |
__TIME__ | 当前源文件的最新编译吋间,用 "hh:mm:ss" 形式的字符串常量表示 |
__STDC__ | 如果今前编泽器符合ISO标准, 那么该宏的值为1, 否则未定义 |
__STDC_VERSION__ | 如果当前编译器符合C89, 那么它被定义为199409L; 如果符合C99, 那么它被定义为199901L; 在其他情况下, 该宏为宋定义 |
__STDC_HOSTED__ | (C99)如果当前是宿主系统, 则该宏的值为1; 如果当前是独立系统, 则该宏的值为0 |
__cplusplus | 当编写C++程序时该标识符被定义 |
条件编译
根据一定条件进行 if 判断
#ifdef
与#ifndef
#ifdef PI // 判断是否定义了PI
#define M 0
#else // 如果没有, 则
#define M 1
#include <math.h>
#endif // 结束
#if
#define M 1
#if M == 1
#define N 1
#elif M == 2
#define N 0
#else
#define N (-1)
#endif