一、一般用法
我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起.
用法:
#include
using namespace std;
#define STR(s)#s
#define CONS(a,b)int(a##e##b)
int main()
{
cout<
cout<
return 0;
}
二、当宏参数是另一个宏的时候
需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开.
1, 非'#'和'##'的情况
#include
using namespace std;
#define TOW(2)
#define MUL(a,b)(a*b)
int main()
{
cout << TOW << "*" << TOW << "=" << MUL(TOW, TOW);//这行的宏会被展开为:2 * 2 = (2*2); MUL里的参数TOW会被展开为(2).
}
2, 当有'#'或'##'的时候
#include
using namespace std;
#define A(2)
#define STR(s)#s
#define CONS(a,b)int(a##e##b)
int main()
{
cout << "int max: " << STR(INT_MAX) << endl;//"int max: INT_MAX"
cout << CONS(A, A) << endl;//int(AeA) // compile error
}
INT_MAX和A都不会再被展开, 然而解决这个问题的方法很简单. 加多一层中间转换宏.
加这层宏的用意是把所有宏的参数在这层里全部展开, 那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数.
#include
using namespace std;
#define A(2)
#define _STR(s)#s
#define STR(s)_STR(s)// 转换宏
#define _CONS(a,b)int(a##e##b)
#define CONS(a,b)_CONS(a,b)// 转换宏
int main()
{
cout << "int max: " << STR(INT_MAX) << endl;//INT_MAX,int型的最大值,为一个变量 输出为: int max : 0x7fffffff
cout << CONS(A, A) << endl;//输出为:200 CONS(A, A)--> _CONS((2), (2))--> int((2)e(2))
}
三、'#'和'##'的一些应用特例
1、合并匿名变量名
#include
using namespace std;
#define___ANONYMOUS1(type, var, line) typevar##line
#define__ANONYMOUS0(type, line) ___ANONYMOUS1(type, _anonymous, line)
#defineANONYMOUS(type) __ANONYMOUS0(type, __LINE__)
int main()
{
ANONYMOUS(static int);//即: static int _anonymous70; 70表示该行行号;
}
//第一层:ANONYMOUS(static int); --> __ANONYMOUS0(static int, __LINE__);
//第二层: --> ___ANONYMOUS1(static int, _anonymous, 70);
//第三层: --> static int _anonymous70;
//即每次只能解开当前层的宏,所以__LINE__在第二层才能被解开;
2、填充结构
#include
using namespace std;
#defineFILL(a) {a, #a}
enum IDD { OPEN, CLOSE };
typedef struct MSG {
IDD id;
const char * msg;
}MSG;
int main()
{
MSG _msg[] = { FILL(OPEN), FILL(CLOSE) };//相当于: MSG _msg[] = { { OPEN, "OPEN" },{ CLOSE, "CLOSE" } };
}
3、记录文件名
#include
using namespace std;
#define_GET_FILE_NAME(f)#f
#defineGET_FILE_NAME(f)_GET_FILE_NAME(f)
static charFILE_NAME[] = GET_FILE_NAME(__FILE__);
4、得到一个数值类型所对应的字符串缓冲大小
#include
using namespace std;
#define_TYPE_BUF_SIZE(type)sizeof #type
#defineTYPE_BUF_SIZE(type)_TYPE_BUF_SIZE(type)
charbuf[TYPE_BUF_SIZE(INT_MAX)];
//--> char buf[_TYPE_BUF_SIZE(0x7fffffff)];
//--> char buf[sizeof "0x7fffffff"];
//这里相当于: char buf[11];
【alps_008】:
基本看了一遍,楼主的情况属于一般用法:
“#把宏参数变为一个字符串,用##把两个宏参数贴合在一起”
#include
#include
#defineSTRCPY(a,b)strcpy(a##_p,#b)//把第一个参数后边加上字符_p,把第二个参数变成字符串
int main()
{
char var1_p[20];
char var2_p[30];
strcpy(var1_p, "aaaa");
strcpy(var2_p, "bbbb");
STRCPY(var1, var2);//等于strcpy(var1_p,"var2");
STRCPY(var2, var1);//等于strcpy(var2_p,"var1");
printf("%s\n", var1_p);
printf("%s\n", var2_p);
return 0;
}
【jeffer007】:
Token-Pasting Operator (##)
// preprocessor_token_pasting.cpp
#include
#include
#definepaster(n)printf_s("token"#n"=%d", token##n)
int token9 = 9;
int main()
{
paster(9);//Outputtoken9 = 9
}
Stringizing Operator (#)
// stringizer.cpp
#include
#definestringer(x)printf(#x"\n")
int main()
{
stringer(In quotes in the printf function call);//In quotes in the printf function call
stringer("In quotes when printed to the screen");//"In quotes when printed to the screen"
stringer("This: \" prints an escaped double quote");//"This: \" prints an escaped double quote"
}
出处:http://blog..net/firetaker/article/details/7381345