预处理器是编译过程中一个单独的步骤
预处理在编译之前进行,预处理之后的文件将会被输出给编译器
-
仿对象宏:
#define 标识符 替换列表
将之后每一个出现的标识符替换成替换列表(替换列表可以为空),示例:#include <stdio.h> #define NUM 100 int main(void){ printf("%d", NUM); }
程序将会输出100
-
仿函数宏:
-
#define 标识符(形参列表) 替换列表
示例:
#define max(a,b) (((a)>(b))?(a):(b)) int main(void){ printf("%d",max(1,2)); }
max(1,2)
会被替换成(((1)>(2))?(1):(2))
-
#define 标识符(形参列表, ...) 替换列表
在替换列表中,额外实参会替换__VA_ARGS__
标识符 替换列表中可以包含标记序列__VA_OPT__(内容)
:当没有额外实参的时候,标记序列被替换为空,否则被替换为内容
示例:
#define DEFINE_ARRAY(type, name, size, ...) type name[size] __VA_OPT__(= { __VA_ARGS__ }) int main(void){ DEFINE_ARRAY(int, arr, 4, 1, 2, 3, 4); }
DEFINE_ARRAY(int, arr, 4, 1, 2, 3, 4)
会被替换成int arr[4] = {1, 2, 3, 4}
-
# 运算符:把实参包含在引号中,变成一个字符串字面量:
示例:
#define STR(a) #a int main(void){ printf("%s is %s", STR(mdr), STR("cute")); }
STR(mdr)
会被替换成"mdr"
STR("cute")
会被替换成"\"cute\""
-
## 运算符:连接两个记号
示例:
#define FUN(x) int fun_##x(){return x;} FUN(2) int main(void){ printf("%d", fun_2()); }
FUN(2)
会被展开成int fun_2(){return 2;}
-
#define
的替换列表包含多行内容时,在每一行(除了最后一行末尾加\
示例:
#define FUN(x) int fun_##x(){return x;} #define OUTPUT(str, ...) printf(#str __VA_OPT__(,) __VA_ARGS__) #include<stdio.h> FUN(2) int main(void){ OUTPUT(%d, fun_2()); }
展开后的结果:
#include<stdio.h> int fun_2(){return 2;} int main(void){ printf("%d", fun_2()); }
程序会输出
2
-
-
#undef 标识符
:解除之前对标识符
的定义
include "文件名"
include <文件名>
(1)先搜索当前目录,搜索不到再搜索标准包含目录 (2)直接搜索标准包含目录
-
defined
运算符defined 标识符
:如果定义了标识符
,求值为1,否则为0 -
#if
,#elif
,#else
,#endif
-
#elifdef
,#elifndef
本章内容对应 cppref 链接如下: