原谅我的懒 !!!

  1. 宏定义在 #define 那一行结束。如果你要书写多行,需要使用 \ 换行

  2. 只有在定义宏之后,宏才能生效

  3. 类函数宏 #define lang_init() c_init()

  4. 宏参数 #define min(A, B) ((A) < (B) ? (A) : (B))

  5. 如果宏的内容中有字符串,那么不会被宏参数替换:#define foo(x) x, “x” ===> foo(bar) → bar, “x”

  6. 一定要为宏参数添加括号

  7. 若宏的结果为值,则为整个宏添加括号

  8. 若宏替换的是代码块,则要为这段代码添加 do{…}while(0)

  9. 可以在宏参数前添加 #,将参数转换为字符串,字符串化会将参数中的所有字符(包括引号)都字符串化,如果中间有很多空格,字符串化后将只有一个空格。如果想通过 # 来实现参数值的字符串化,就需要需要使用两层的宏:

    #define IDL_NS_STR(x) IDL_INNER_NS_STR(x)
    #define IDL_INNER_NS_STR(x) @#x
    #define FOO 4

    IDL_INNER_NS_STR(FOO)
    "FOO"
    IDL_NS_STR(FOO)
    "4"

    在使用 IDL_INNER_NS_STR 的时候,x 会立即被字符串化,而没有被宏展开。但是如果我们使用另外一个宏 IDL_NS_STR 嵌套着,那就会先展开,将值带入后,然后再字符串化。

  10. 使用”##”操作符可以实现宏中标记的连接。预处理器会将所有注释转为空格,## 会将左右的空格都忽略。

  11. 如果不确定有多少个宏参数,可以使用 … 代替,这在很多语言中都有类似的做法。相应的,使用 VA_ARGS 在具体的宏中,代替 …

    #define IDL_PRINTF(…) fprintf (stderr, ##__VA_ARGS__)

    在加上 ## 之后,预处理器就会在传入空的时候,删掉前面的 , 了

  12. C语言中预定义宏:

__FILE__ :当前源代码的文件名(字符串)
__LINE__:当前源代码中的行号(整型)
__DATE__:进行预处理的日期(”Mmm dd yyyy”形式的字符串)
__TIME__:源文件编译时间(格式“hh:mm:ss”)
__FUNCTION__:同__func__(但IDE不支持),当前源代码的函数名
__PRETTY_FUNCTION__:同__FUNCITON__,但在g++下会输类名、函数名及其他函数信息
Contents