//-----------------------------------------------------------
//例1
//#和##运用
#include
//#define aa bb
#define A aa
//#把宏参数变为一个字符串,
//#define STR(s) #s //需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开.修改为 :
#define _STR(s) #s
#define STR(s) _STR(s) // 转换宏
//多加这层宏的用意是把所有宏的参数在这层里全部展开, 那么在转换宏里的那一个宏(_STR)就能得到正确的宏参数.
//##把两个宏参数贴合在一起
//#define CONS(a,b) a##b //需要注意的是凡宏定义里有用'#'或'##'的地方宏参数是不会再展开.修改为:
#define _CONS(a,b) a##b
#define CONS(a,b) _CONS(a,b)
int main()
{
char * CONS(A,e)="ddddd";
//printf(STR(vck)); // 输出字符串"vck"
fprintf(stderr,"%s\n",CONS(A,e));
printf(STR(CONS(A,e\n)));
printf(STR(A\n));
return 0; //输出字符串se
}
/*
运行结果为:
ddddd
aae
aa
*/
//-------------------------------------------------------
//例2
#include
#include
#include
#define mydebug
#ifdef mydebug
#define debug_printf(argv,argv2...) printf("%s=%d\n",argv,argv2)//定参个数的宏
#else
#define debug_printf(argv...)
#endif
#define err(...) fprintf(stderr, __VA_ARGS__)//可变参数宏
#define err1(...) fprintf(stderr, ##__VA_ARGS__)
#define TEST(ARGTERM...) printf("test is "#ARGTERM" \n")
#define PASTE(a, b) a##b
#define min(X, Y) \
(__extension__ ({typeof (X) __x = (X), __y = (Y); \
(__x < __y) ? __x : __y; }))
#define max(X, Y) \
(__extension__ ({typeof (X) __x = (X), __y = (Y); \
(__x > __y) ? __x : __y; }))
#define max1(X, Y) (X>Y? X:Y)
#define min1(X, Y) (Xvoid * mem( void * buffer, int c, size_t num )
{
printf("%s\n",buffer);
}
int main(int argc, char *argv[])
{ char *pp;
int i=10,j=20;
char *PASTE(str,1) ="string";
debug_printf(__FILE__,__LINE__);
err ("i=%d\n", i);
err("hello\n");
err1("i=%d\n", i);
err1("hello\n");
TEST(123);
TEST("123",456,789);
printf("%d\n",max(i,j));
printf("%d\n",min(i,j));
printf("%d\n",max1(i,j));
printf("%d\n",min1(i,j));
printf("%s\n",PASTE(str,1));
pp=malloc(10);
strcpy(pp,"woshinide");
mem(pp,2,2);
}
'#'和'##'的一些应用特例
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__在第二层才能被解开;
2、填充结构
#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__);
4、得到一个数值类型所对应的字符串缓冲大小
#define _TYPE_BUF_SIZE(type) sizeof #type
#define TYPE_BUF_SIZE(type) _TYPE_BUF_SIZE(type)
char buf[TYPE_BUF_SIZE(INT_MAX)];
--> char buf[_TYPE_BUF_SIZE(0x7fffffff)];
--> char buf[sizeof "0x7fffffff"];
这里相当于:
char buf[11];