C/C++预处理指令之——替换文本宏

C/C++预处理指令之——替换文本宏

  • 语法
  • 解释
    • #define 指令
    • 仿对象宏
      • 示例
    • 仿函数宏
      • 示例
    • # 与 ## 运算符
      • 示例
      • 示例
    • #undef 指令
  • 常用的预定义宏
  • 写在最后

语法

#define 标识符 [替换列表]
#define 标识符(形参) 替换列表
#define 标识符(形参,…) 替换列表 (C99 起)
#define 标识符(…) 替换列表 (C99 起)
#undef 标识符

解释

#define 指令

#define 指令定义 标识符 为宏,即它们指示编译器将所有 标识符 的后继出现替换为 替换列表 ,可以可选地附加地处理。若已定义该标识符为任何类型的宏,则程序为病式,除非定义相同。

仿对象宏

仿对象宏将所定义的 标识符 的每次出现替换为 替换列表

示例

#define PI 3.14
int main() {
	int a = PI;
	return 0;
}

这段代码在预编译后将会被替换成

int main() {
	int a = 3.14;
	return 0;
}

仿函数宏

类函数宏将所定义的 标识符 的每次出现替换为 替换列表 ,额外地接受数个参数,它们会替换 替换列表 中任何 形参 的对应出现。
与函数用法类似,但请注意这并不是函数

示例

#define MUL(a, b) a * b
int main() {
	int a = MUL(2, 5);
	//为了让大家理解替换文本宏只是替换所以写了这一句代码
	MUL(int, p) = &a;
	return 0;
}

这段代码在预编译后将会被替换成

int main() {
	int a = 2 * 5;
	int * p = &a;
	return 0;
}

# 与 ## 运算符

在仿函数宏中, 替换列表 中标识符前的 # 运算符对标识符做形参替换,并将结果环绕在引号中,等效地创建一个字符串字面量。而且,预处理器会添加反斜杠,以转义环绕内嵌字符串字面量的引号,若存在,并按需在字符串中双写反斜杠。它移除所有前导和尾随空白符,且将任何文本中部的空白符序列(但非内嵌字符串字面量中的)缩减成单个空格。此运算被称作“字符串化”。若字符串化的结果不是合法字符串字面量,则行为未定义。

示例

#出现在 VA_ARGS 前时,将整个展开的 VA_ARGS 放入引号:

#define showlist(...) puts(#__VA_ARGS__)
showlist();            // 展开成 puts("")
showlist(1, "x", int); // 展开成 puts("1, \"x\", int")

替换列表 中任意二个相继标识符间的 ## 运算符对二个标识符进行参数替换,然后连接结果。此运算被称作“连接”或“记号粘贴”。只可以粘贴有一同组成合法记号的记号:组成较长标识符的标识符、组成数字的数位或组成 += 的运算符 + 与 = 。不能通过粘贴 / 与 * 创建注释,因为注释被认为在宏替换前移除。若连接的结果不是合法记号,则行为未定义。
注意:一些编译器提供允许 ## 出现在逗号后和 VA_ARGS 前的扩展,在此情况下 ## 在 VA_ARGS 非空时无效,但在 VA_ARGS 为空时移除逗号:这使得可以定义如 fprintf (stderr, format, ##VA_ARGS) 的宏。

示例

#define print(fmt, args...) printf(fmt, ##args)

#undef 指令

#undef 指令解除定义 标识符 ,即它取消先前 #define 对 标识符 的定义。若标识符无与之关联的宏,则忽略此指令。

常用的预定义宏

宏命令 作用
__FILE__ 展开成当前文件名,为字符串字面量,可用 #line 指令更改
__LINE__ 展开成源文件行号,为整数常量,可用 #line 指令更改
__DATE__ 展开成翻译的日期,格式为 “Mmm dd yyyy” 的字符串字面量。月份名如同以 asctime 生成,而若月之日期小于 10 则 “dd” 的首字符为空格
__TIME__ 展开成翻译的时间,格式为 “hh:mm:ss” 的字符串字面量,如同asctime()所生成

当然预定义的宏远远不止这些,还有很多我也没有列举出来,当大家有需要的时候可以查阅手册。上面的代码大家也可以自行运行测试,预编译指令为:

gcc -E filename.c >> output.c

g++用法相同

写在最后

这次的分享就到这里,如果有什么错误欢迎各位大佬指正,感谢各位看到这里!

你可能感兴趣的:(C/C++学习,c++,c语言)