C宏定义中## 和# 的含义
2014-04-06 22:59
316 查看
1. #的作用是将宏参数字符串化,
例如下面的宏定义
#define STR( s ) #s
那么在程序中
printf("The string is %s/n", STR(OPEN) );
会被展开成
printf("The string is %s/n", "OPEN" );
也就是说,会对#后跟的参数加引号,使其变成一个字符串。
2. ##的作用是对文本进行连接
例如下面的宏定义
#define CONS( a, b ) a##e##b
那程序中
printf("the number is %d/n", CONS(2,3) );
会被展开成
printf("the number is %d/n", 2e3 );
需要注意的是,在有#和##的宏中,如果参数本身是宏,则这个参数宏不会展开。
加一层中间转换宏可以解决这个问题。
#define _STR(s) #s
#define STR(s) _STR(s) // 转换宏
#define _CONS(a,b) int(a##e##b)
#define CONS(a,b) _CONS(a,b) // 转换宏
3.综合理解
至于为什么加##进行分隔,举个例子容易理解,比如#define F(x) T##x##_,如果前面的##不加,则Tx##_,其中的Tx,编译器就无法识别里面的x是参数里给的x,而是Tx当成一起得了,后面的也类似,总之,加##就是为了把参数识别出来,如果在开头,只加后面的就可以了,如x##_
简单的说,##就是把参数当成不带引号的字符串进行替换,#把参数当成带引号的字符串进行替换
## 连接符号由两个井号组成,其功能是在带参数的宏定义中将两个子串(token)联接起来,从而形成一个新的子串。但它不可以是第一个或者最后一个子串。所谓的子串(token)就是指编译器能够识别的最小语法单元。具体的定义在编译原理里有详尽的解释,但不知道也无所谓。同时值得注意的是#连接符是把传递过来的参数当成字符串进行替代。下面来看看它们是怎样工作的。这是MSDN上的一个例子。
假设程序中已经定义了这样一个带参数的宏:
#define paster( n ) printf( "token" #n " = %d", token##n )
同时又定义了一个整形变量:
int token9 = 9;
现在在主程序中以下面的方式调用这个宏:
paster( 9 );
那么在编译时,上面的这句话被扩展为:
printf( "token" "9" " = %d", token9 );
详细解说:#n 相当于 “n”, token##n 相当于token9,须注意##不能当成两个#,他们意义是不同的。
注意到在这个例子中,paster(9);中的这个”9”被原封不动的当成了一个字符串,与”token”连接在了一起,从而成为了token9。而#n也被”9”所替代。
可想而知,上面程序运行的结果就是在屏幕上打印出token9=9
注意##和#的使用场合,不能乱用。
例如下面的宏定义
#define STR( s ) #s
那么在程序中
printf("The string is %s/n", STR(OPEN) );
会被展开成
printf("The string is %s/n", "OPEN" );
也就是说,会对#后跟的参数加引号,使其变成一个字符串。
2. ##的作用是对文本进行连接
例如下面的宏定义
#define CONS( a, b ) a##e##b
那程序中
printf("the number is %d/n", CONS(2,3) );
会被展开成
printf("the number is %d/n", 2e3 );
需要注意的是,在有#和##的宏中,如果参数本身是宏,则这个参数宏不会展开。
加一层中间转换宏可以解决这个问题。
#define _STR(s) #s
#define STR(s) _STR(s) // 转换宏
#define _CONS(a,b) int(a##e##b)
#define CONS(a,b) _CONS(a,b) // 转换宏
3.综合理解
至于为什么加##进行分隔,举个例子容易理解,比如#define F(x) T##x##_,如果前面的##不加,则Tx##_,其中的Tx,编译器就无法识别里面的x是参数里给的x,而是Tx当成一起得了,后面的也类似,总之,加##就是为了把参数识别出来,如果在开头,只加后面的就可以了,如x##_
简单的说,##就是把参数当成不带引号的字符串进行替换,#把参数当成带引号的字符串进行替换
## 连接符号由两个井号组成,其功能是在带参数的宏定义中将两个子串(token)联接起来,从而形成一个新的子串。但它不可以是第一个或者最后一个子串。所谓的子串(token)就是指编译器能够识别的最小语法单元。具体的定义在编译原理里有详尽的解释,但不知道也无所谓。同时值得注意的是#连接符是把传递过来的参数当成字符串进行替代。下面来看看它们是怎样工作的。这是MSDN上的一个例子。
假设程序中已经定义了这样一个带参数的宏:
#define paster( n ) printf( "token" #n " = %d", token##n )
同时又定义了一个整形变量:
int token9 = 9;
现在在主程序中以下面的方式调用这个宏:
paster( 9 );
那么在编译时,上面的这句话被扩展为:
printf( "token" "9" " = %d", token9 );
详细解说:#n 相当于 “n”, token##n 相当于token9,须注意##不能当成两个#,他们意义是不同的。
注意到在这个例子中,paster(9);中的这个”9”被原封不动的当成了一个字符串,与”token”连接在了一起,从而成为了token9。而#n也被”9”所替代。
可想而知,上面程序运行的结果就是在屏幕上打印出token9=9
注意##和#的使用场合,不能乱用。
相关文章推荐
- 使用宏定义让参数含义更清晰
- C++/C 宏定义(define)中# ## 的含义
- C++/C宏定义中## 连接符与# 符的含义
- min()的宏定义中的(void) (&_x == &_y)的含义
- c语言中用宏定义一个常量,数字后面带个U, L, F的含义
- C++/C宏定义中## 连接符与# 符的含义
- C++/C宏定义中## 连接符与# 符的含义
- C++/C宏定义中## 连接符与# 符的含义
- C++/C宏定义中## 连接符与# 符的含义
- C++/C 宏定义(define)中# ## 的含义 宏拼接
- C++/C 宏定义(define)中# ## 的含义(转)
- C++/C宏定义中## 连接符与# 符的含义
- c语言中用宏定义一个常量,数字后面带个U, L, F的含义
- C++/C宏定义中## 连接符与# 符的含义
- C++/C宏定义中## 连接符与# 符的含义(转自http://blog.163.com/wshyao@126/blog/static/1070451420081018103237836/)
- C++/C宏定义中## 连接符与# 符的含义
- C++/C宏定义中##与#的含义
- C++/C宏定义中## 连接符与# 符的含义
- C++/C 宏定义(define)中# ## 的含义(转)
- C++/C宏定义中## 连接符与# 符的含义