关于#/##在宏定义中的用法
2011-04-03 17:12
435 查看
关于#/##在宏定义中的用法 (2011-04-01 11:58)
http://blog.chinaunix.net/space.php?uid=20792262&do=blog&id=201691
分类: 算法与数据结构
第1篇
在C/C++的宏定义中,#/##存在特殊的作用1. #运算符将一个宏的参数转换为字符串字面量。它仅允许出现在带参数的宏的替换列表中。
view plaincopy to clipboardprint?
#include <cstdio>
#define PRINT_STR(s) printf(#s" = %s/n", s)
int main()
{
char *s1 = "aaa";
PRINT_STR(s1);
return 0;
}
输出:s1 = aaa注:printf(#s" = %s/n", s) -> printf(s1" = %s/n", s1) -> printf("s1 = %s/n", s1)->printf("s1 = %s/n", "aaa")#s只是做宏参数字面替换s则仍然是一个变量名2.##运算符可以将两个记号(例如标识符)“粘”在一起,成为一个记号。(无需惊讶,##运算符被称为“记号粘合”。)如果其中一个操作数是宏参数,“粘合”会在当形式参数被相应的实际参数替换后发生。
view plaincopy to clipboardprint?
#include <cstdio>
#define PRINT_STR(i) printf("str = %s/n", s##i)
int main()
{
char *s1 = "s1";
char *s2 = "s2";
char *s3 = "s3";
PRINT_STR(1);
PRINT_STR(2);
PRINT_STR(3);
return 0;
}
输出:str = s1
str = s2
str = s33.C99的复杂宏:可变参数
view plaincopy to clipboardprint?
#include <cstdio>
#define PRINT_STR(format, ...) do{printf(format, __VA_ARGS__);}while(0)
int main()
{
char *str1 = "s1";
char *str2 = "s2";
PRINT_STR("str1 is %s /nstr2 is %s/n",str1, str2);
return 0;
}
输出:str1 is s1
str2 is s2but attention!
view plaincopy to clipboardprint?
#include <cstdio>
#define PRINT_STR(format, ...) do{printf(format, __VA_ARGS__);}while(0)
int main()
{
char *str1 = "s1";
char *str2 = "s2";
PRINT_STR("str1 is over/n");
return 0;
}
编译:macro1.cpp: In function ‘int main()’:
macro1.cpp:8: error: expected primary-expression before ‘)’ token
这里提示错误,原因是少了变参列表,只有format参数,这里在format参数后就多了一个','。so,GNU CPP想出了一个特殊的##操作,没错,##操作又来了,但是不是上面的拼接行为了。如果可变参数被忽略或为空,“##”操作将使预处理器去除掉它前面的那个逗号。如果在宏调用时,确实提供了一些可变参数,GNU CPP也会工作正常,它会把这些可变参数放到逗号的后面。
view plaincopy to clipboardprint?
#include <cstdio>
#define PRINT_STR(format, ...) do{printf(format, ##__VA_ARGS__);}while(0)
int main()
{
char *str1 = "s1";
char *str2 = "s2";
PRINT_STR("str1 is over/n");
return 0;
}
输出:str1 is over
第2篇
在C/C++中,宏定义是由define完成的,define中有三个特殊的符号值得我们注意:
1. #:在宏展开的时候会将#后面的参数替换成字符串,如:
#define p(exp) printf(#exp);
调用p(asdfsadf)的时候会将#exp换成"asdfsadf"
2. ##:将前后两个的单词拼接在一起。例如《The C Programming Language》中的例子:
#define cat(x,y) x##y
调用cat(var, 123)展开后成为var123.
3. #@:将值序列变为一个字符
#define ch(c) #@c
调用ch(a)展开后成为'a'.
自己写了一小段测试程序:
#define A(a,b) a##b
#define B(a) #a
#define C(a) #@a
#include <iostream>
using namespace std;
void main()
{
int v = 0,v1 = 1,v12 = 2;//v stands for var
cout << A(v1,2) << endl;
cout << B(v1) << endl;
cout << C(v) << endl;
}
结果为:
1
v1
v
版权声明: 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。
http://blog.chinaunix.net/space.php?uid=20792262&do=blog&id=201691
分类: 算法与数据结构
第1篇
在C/C++的宏定义中,#/##存在特殊的作用1. #运算符将一个宏的参数转换为字符串字面量。它仅允许出现在带参数的宏的替换列表中。
view plaincopy to clipboardprint?
#include <cstdio>
#define PRINT_STR(s) printf(#s" = %s/n", s)
int main()
{
char *s1 = "aaa";
PRINT_STR(s1);
return 0;
}
输出:s1 = aaa注:printf(#s" = %s/n", s) -> printf(s1" = %s/n", s1) -> printf("s1 = %s/n", s1)->printf("s1 = %s/n", "aaa")#s只是做宏参数字面替换s则仍然是一个变量名2.##运算符可以将两个记号(例如标识符)“粘”在一起,成为一个记号。(无需惊讶,##运算符被称为“记号粘合”。)如果其中一个操作数是宏参数,“粘合”会在当形式参数被相应的实际参数替换后发生。
view plaincopy to clipboardprint?
#include <cstdio>
#define PRINT_STR(i) printf("str = %s/n", s##i)
int main()
{
char *s1 = "s1";
char *s2 = "s2";
char *s3 = "s3";
PRINT_STR(1);
PRINT_STR(2);
PRINT_STR(3);
return 0;
}
输出:str = s1
str = s2
str = s33.C99的复杂宏:可变参数
view plaincopy to clipboardprint?
#include <cstdio>
#define PRINT_STR(format, ...) do{printf(format, __VA_ARGS__);}while(0)
int main()
{
char *str1 = "s1";
char *str2 = "s2";
PRINT_STR("str1 is %s /nstr2 is %s/n",str1, str2);
return 0;
}
输出:str1 is s1
str2 is s2but attention!
view plaincopy to clipboardprint?
#include <cstdio>
#define PRINT_STR(format, ...) do{printf(format, __VA_ARGS__);}while(0)
int main()
{
char *str1 = "s1";
char *str2 = "s2";
PRINT_STR("str1 is over/n");
return 0;
}
编译:macro1.cpp: In function ‘int main()’:
macro1.cpp:8: error: expected primary-expression before ‘)’ token
这里提示错误,原因是少了变参列表,只有format参数,这里在format参数后就多了一个','。so,GNU CPP想出了一个特殊的##操作,没错,##操作又来了,但是不是上面的拼接行为了。如果可变参数被忽略或为空,“##”操作将使预处理器去除掉它前面的那个逗号。如果在宏调用时,确实提供了一些可变参数,GNU CPP也会工作正常,它会把这些可变参数放到逗号的后面。
view plaincopy to clipboardprint?
#include <cstdio>
#define PRINT_STR(format, ...) do{printf(format, ##__VA_ARGS__);}while(0)
int main()
{
char *str1 = "s1";
char *str2 = "s2";
PRINT_STR("str1 is over/n");
return 0;
}
输出:str1 is over
第2篇
在C/C++中,宏定义是由define完成的,define中有三个特殊的符号值得我们注意:
1. #:在宏展开的时候会将#后面的参数替换成字符串,如:
#define p(exp) printf(#exp);
调用p(asdfsadf)的时候会将#exp换成"asdfsadf"
2. ##:将前后两个的单词拼接在一起。例如《The C Programming Language》中的例子:
#define cat(x,y) x##y
调用cat(var, 123)展开后成为var123.
3. #@:将值序列变为一个字符
#define ch(c) #@c
调用ch(a)展开后成为'a'.
自己写了一小段测试程序:
#define A(a,b) a##b
#define B(a) #a
#define C(a) #@a
#include <iostream>
using namespace std;
void main()
{
int v = 0,v1 = 1,v12 = 2;//v stands for var
cout << A(v1,2) << endl;
cout << B(v1) << endl;
cout << C(v) << endl;
}
结果为:
1
v1
v
版权声明: 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。
相关文章推荐
- 关于#/##在宏定义中的用法
- 关于函数式宏定义的典型用法及易错点
- C/C++ 关于#/##在宏定义中的用法
- 关于宏定义的用法
- 关于#/##在宏定义中的用法
- 关于宏定义的一些用法
- 关于宏定义中#与##的用法
- C/C++ 关于#/##在宏定义中的用法
- 关于cookie的部分用法(页面中新消息声音提醒开关)
- 关于indy 10.5.7在delphi 7下的数据发送接收的用法分享
- c语言基础:关于switch的用法
- 关于vim的用法手册
- 关于typedef的用法总结
- 关于#pragma warning 用法的研究
- 关于Python的super用法研究
- SQL Server 中关于EXCEPT和INTERSECT的用法
- 关于子类和父类中的this的用法
- 一些关于speechlib tts 的用法
- 关于全排列 next_permutation() 函数的用法
- C语言宏定义时#(井号)和##(双井号)的用法