关于C语言的宏
之前C语言没有好好学习,最近想看看Bash的源代码,碰到了宏,所以做点笔记。
#和##
'#'则是表示在替换宏的时候,在宏左右都加上双引号,比如
#define CONVERT_TO_STR(x) #x
那么CONVERT_TO_STR(abc) 则会被替换为“abc”
'##'则是表示连接的意思,是把两个宏参数连接到一起,比如
#define CANCAT(a,b) a##b
那么CANCAT(abc,def) 则会被替换为 abcdef
值得注意的是,如果宏定义中有'#'或者'##'的地方,左右的若是宏则也不会被展开:比如
CANCAT(A,B)
若#define A 1
#define B 2
那么结果将会是AB,而不是12。
解决的方法则是加入#define NEW_CANCAT(a,b) CANCAT(a,b),这样,当使用NEW_CANCAT的时候,会先展开其中的参数,后面再展开CANCAT。
变参宏
变参数宏可以被用来输出日志,比如:
#define LOG( format, ... ) printf( format, __VA_ARGS__ )
或者
#define LOG( format, args …) printf(format, args)
第二个指定了参数args,而第一个则是默认的__VA_ARGS__
其实这个LOG不怎么好,因为如果我们调用LOG(“abc”)的时候,会产生错误。常常使用#define LOG( format, args …) printf(format, ##args),这里的##args则表示如果args为空,则去除前面的’,’。
#ifdef和#if defined
这两个宏基本类似,比如#ifdef ABC = #if defined ABC,但是,第二个宏可以同时检查多个预变量。
比如
#if (!defined(ABC) && defined(EFG))
#endif
而之前的宏只能
#ifndef ABC
#ifdef EFG
#endif
#endif