/ 编程语言 · 2023年 10月 18日 0

60 次浏览

大部分从Java之后的编程语言都不支持宏,因为它们离C语言偏远。一个例外是C#, 它总是如此调皮。

什么是宏?

  • 宏,是一种批量处理的称谓。计算机科学中,代表根据一系列预定义的规则替换一定的文本模式。宏起源于汇编语言macro替换。
  • 宏用于预处理,在编译之前,sizeof是编译期计算,它是在预处理之后,所以不能将sizeof放到预处理指令中判断。

编程语言不同标准

  • C/C++经常利用宏来指明编译器对应标准的版本。比如
    #define __STDC_VERSION__ 201112L代表C11. 此宏可让程序员根据不同语言标准写不同的代码,在底层代码中尤为有效。MSVC可用_MSC_VER和_MSC_FULL_VER等宏来代表不同编译器版本。

宏排错

  • 避免在整形变量小于32位的机器上使用:
    #if INT_MAX <= 32767
    #error “Int should be over 2 bytes”
    #endif
  • 有一段代码,为了确定在哪句发生问题,可封装包含__FILE__和__LINE__、__func__宏的语句二分查找出错的位置。
  • 每次release一个新版本,为了记录版本,避免用错版本,利用__DATE__和__TIME__记录版本编译时间。

编译选项

  • C语言支持-D或-U定义或取消定义一个宏变量。

宏和注释

  • 宏定义后面紧跟着注释,注释并不会被当做宏扩展的一部分,原因在于预处理会先去除注释。
    • #define YOUR_MACRO do_something() // This will do something

宏和字符串

  • #可将符号转换成”字符串”格式。
  • 宏扩展不能扩展到字符串里面的"标识符",因为字符串内部的字符都被看做字符串一部分,而非标识符。

作用范围

  • 宏作用范围是当前出现处到文件结尾,哪怕当前出现在函数内部。
    • 如遇到此宏的 #undef 则作用域结束。

宏嵌套

因为宏的原始性,不像函数,编译器很轻松了解程序员的意图。宏替换嵌套可能导致完全不同的理解方式,为此,形成了一套最基本的宏替换原则。

  1. 宏替换总是从最外层开始解析。
  2. 如果包含#或者##或者是最内层,直接做当前层替换;否则,进入内一层重复此过程继续处理。
  3. 当第2步执行完替换,检查表达式是否还有宏,如有继续上面第1步,如没有即结束。