C语言宏定义相关
C语言宏定义在代码编写中很常见,它常会带来一些很高的性能和很方便的写法,在看Linux源码中sockaddr_in的时候遇到宏定义中##。特地在此记录.
宏定义中##用法
问题背景
Linux中sockaddr_in的定义在文件/netinet/in.h文件中。具体如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| struct sockaddr_in { __SOCKADDR_COMMON (sin_); in_port_t sin_port; struct in_addr sin_addr; unsigned char sin_zero[sizeof (struct sockaddr) - __SOCKADDR_COMMON_SIZE - sizeof (in_port_t) - sizeof (struct in_addr)]; }; #define __SOCKADDR_COMMON(sa_prefix)\ sa_family_t sa_prefix##family
|
从上面可以看出,__SOCKADDR_COMMON的宏定义中出现了##的使用方法。那它在宏定义中的意思是什么呢?
##详解
##是一种分隔连接方式。它的作用是先分隔,然后进行强制连接。
在普通的宏定义中,预处理器一般吧空格解释为分段标志,然后进行相应的替换工作。但是这样做的结果是被替换的段之间会出现空格。如果我们不希望这些空格出现,可以使用##来代替空格。
如:
1 2
| #define type1(type,name) type name_##type##_type #define type2(type,name) type name##_##type##_type
|
上述type1(int,c)将被替换为:int name_int_type
上述type2(int,c)将被替换为:int c_int_type
故我们再回去看SOCKADDR_COMMON的宏定义.
SOCKADDRCOMMON (sin);将被解释为sa_family_t sin_family;
注意在函数参数中使用##可以将空字符串过滤掉,否则会出现问题。如:
1 2 3 4 5 6 7 8 9 10 11 12 13
| #define comac_get_args_cnt( ... ) comac_arg_n( __VA_ARGS__ ) #define comac_arg_n( _0,_1,_2,_3,_4,_5,_6,_7,N,...) N #define comac_args_seqs() 7,6,5,4,3,2,1,0 #define comac_join_1( x,y ) x##y #define comac_argc( ... ) comac_get_args_cnt( 0,##__VA_ARGS__,comac_args_seqs() ) int main() { comac_argc(); }
|
#详解
在宏定义中,#符号的作用是将宏定义参数用””括起来,
1 2
| #define example(test) printf("%s", #test); example(123 456);
|
宏定义中占位符理解
在宏定义中我们可以使用字母或者单词作为占位符,初次之外,我们也可以使用_1,_2作为占位符,不要被它蒙骗了,其作用与单词作为占位符相同。如:
1 2
| #define sum(a,b) (a+b) #define sum(_1,_2) (_1+_2)
|