我们使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起.
用法:
点击(此处)折叠或打开
-
- #include <stdio.h>
-
-
#define STR(s) #s
-
#define CONS_1(a,b) (a##e##b)
-
-
-
void other_test()
-
{
-
//printf("%d\n", 4e3); //error,输出0,格式不匹配
-
printf("%g\n", 4e3); //4000
-
printf("%d\n", (int)4e3); //4000
-
}
-
- /*
-
** "#","##" test
- */
-
void macro_parameter_test_1(void)
-
{
-
printf("%s\n", STR(test)); //printf("%s\n", "test");
-
printf("%d\n",(int)CONS_1(2,3)); //2000
-
}
-
-
-
int main()
-
{
-
//other_test();
-
macro_parameter_test_1();
-
-
return 0;
- }
二、当宏参数是另一个宏的时候
需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开,但宏定义中没有使用“#”和“##”的地方宏可以嵌套
1, 非'#'和'##'的情况(不含#,##符号的嵌套)
点击(此处)折叠或打开
- #include <stdio.h>
-
-
#define TOW (2)
-
#define MUL(a,b) (a*b)
-
-
int main()
-
{
- printf("%d*%d=%d\n", TOW, TOW, MUL(TOW,TOW));
- /*
- ** 宏展开:printf("%d*%d=%d\n", (2), (2), ((2)*(2)));
-
** MUL里的参数TOW也会被展开为(2).
- */
-
return 0
- }
2, 当有'#'或'##'的时候(含有#,##符号的宏嵌套)
点击(此处)折叠或打开
-
-
#include <stdio.h>
-
#include <limits.h>
-
-
#define A 2
-
#define STR(s) #s
-
#define CONS(a,b) (a##e##b)
-
-
int main(void)
-
{
-
printf("%x\n", INT_MAX); //0x7fffffff
-
//printf("%x\n", INT_MIN); //0x80000000
-
-
printf("%s\n", STR(INT_MAX)); //printf("%s\n", "INT_MAX"); INI_MAX没有被替换
-
printf("%s\n", STR(A)); //printf("%s\n","A"); A没有被替换
-
-
printf("%g\n", CONS(A,A)); //error, A没有被替换
-
return 0;
- }
INT_MAX和A都不会再被展开, 然而解决这个问题的方法很简单. 加多一层中间转换宏.
加这层宏的用意是把所有宏的参数在这层里全部展开, 那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数.
点击(此处)折叠或打开
-
#include <stdio.h>
-
#include <limits.h>
-
-
#define A 2
-
#define STR(s) #s
-
#define CONS(a,b) (a##e##b)
-
-
#define _STR(s) STR(s) //转换宏
-
#define _CONS(a,b) CONS(a,b) //转换宏
-
-
int main(void)
-
{
-
printf("%x\n", INT_MAX); //0x7fffffff
-
//printf("%x\n", INT_MIN); //0x80000000
-
-
printf("%s\n", _STR(INT_MAX)); //printf("%s\n", "2147483647"); INI_MAX被替换,但是是以10进制格式输出
-
printf("%s\n", _STR(A)); //printf("%s\n", "2");
-
-
printf("%g\n", _CONS(A,A)); //200
-
return 0;
- }
-
- /*
- ** _STR(INT_MAX) --> STR(2147483647) -->转换为字符串
- ** _STR(A) --> STR(2) --> "2"
- ** _CONS(A,A) --> CONS(2,2) --> 2e2
- */
-
点击(此处)折叠或打开
-
#include <stdio.h>
-
-
#define X e
-
#define CONS(a,b) (a##X##b)
-
-
int main()
-
{
-
printf("%f\n", CONSS(2,3)); //error, X不被替换
- }
三、'#'和'##'的一些应用特例
1、合并匿名变量名
点击(此处)折叠或打开
-
-
#define ___ANONYMOUS1(type, var, line) type var##line
-
#define __ANONYMOUS0(type, line) ___ANONYMOUS1(type, _anonymous, line)
-
#define ANONYMOUS(type) __ANONYMOUS0(type, __LINE__)
-
-
/*
-
** 例:ANONYMOUS(static int); 即: static int _anonymous70; 70表示该行行号;
-
** 第一层:ANONYMOUS(static int); --> __ANONYMOUS0(static int, __LINE__);
-
** 第二层: --> ___ANONYMOUS1(static int, _anonymous, 70);
-
** 第三层: --> static int _anonymous70;
-
** 即每次只能解开当前层的宏,所以__LINE__在第二层才能被解开;
- */
点击(此处)折叠或打开
-
#define FILL(a) {a, #a}
-
-
enum IDD{OPEN, CLOSE};
-
typedef struct MSG{
-
IDD id;
-
const char * msg;
-
}MSG;
-
-
MSG _msg[] = {FILL(OPEN), FILL(CLOSE)};
-
/*
-
** MSG _msg[] = {{OPEN, "OPEN"},
-
** {CLOSE, "CLOSE"}};
- */
3、记录文件名
点击(此处)折叠或打开
-
#define _GET_FILE_NAME(f) #f
-
#define GET_FILE_NAME(f) _GET_FILE_NAME(f)
-
- static char FILE_NAME[] = GET_FILE_NAME(__FILE__);
小例子:
点击(此处)折叠或打开
-
#include<stdio.h>
-
#include<string.h>
-
-
#define STRCPY(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;
- }
转自:http://www.cnblogs.com/hnrainll/archive/2012/08/15/2640558.html