C语言宏中#的功能是将其后面的宏参数进行字符串化操作(Stringizing operator),简单说就是在它引用的宏变量的左右各加上一个双引号。
如定义好#define STRING(x) #x之后,下面二条语句就等价。
char *pChar = "hello";
char *pChar = STRING(hello);
##它可以拼接符号(Token-pasting operator),如:
#define paster( n ) printf( "token"#n" = %d\n", token##n )
int token9 = 100;
再调用 paster(9);宏展开后token##n直接合并变成了token9。
整个语句变成了
printf( "token""9"" = %d", token9 );
在C语言中字符串中的二个相连的双引号会被自动忽略,于是上句等同于
printf("token9 = %d", token9);。
即输出token9 = 100
下面是我的具体测试代码,
#include <stdio.h>
#define test(a) printf("tt"#a"=%d\n",n1##a)
#define DEBUG_LOG(fmt,level,args...) printf("DEBUG_"#level":"#fmt"\n",##args)
int log_level = 0;
// #fmt 为将输入的参数 fmt改为 字符串输出
// fmt 是传入什么参数打印什么参数
// ## 是为了拼接1个参数 实际我感觉在此处用处不大,如果有知道的可以提示下,谢谢。
#define debug_log_printf(fmt,level,args...) \
do\
{\
if(level == log_level)\
printf("DEBUG_"#level"[%s]"fmt"\n",__FUNCTION__,args) ;\
}while(0)
//__VA_ARGS__ 是一个可变参数的宏 ,意思是后面加几个参数都行
#define debug_log_printf1(fmt,level,...) \
do\
{\
if(level == log_level)\
printf("DEBUG_"#level"[%s]"fmt"\n",__FUNCTION__,##__VA_ARGS__) ;\
}while(0)
void printf_test_fun(int n1ccb,int ccb)
{
int num = 199;
char str_test[] = "test_printf";
test(ccb);
DEBUG_LOG("n1ccb is %d",5,n1ccb);
debug_log_printf("cc1b is %d",0,ccb);
debug_log_printf1("n1ccb = %d num = %d %s",0,n1ccb,num,str_test);
}
int main(void)
{
int n1ccb = 100;
int ccb =88;
printf("Hello World\n");
printf_test_fun(n1ccb,ccb);
return 0;
}
如果有朋友有更好的见解或者我的代码中有问题,欢迎讨论和指出,谢谢。
重定义打印的例子:
#define DEBUG_YL_MSG_BUFF(buff,length) \
{ \
Printf("[%s][%d] ---%s:", __FUNCTION__, __LINE__,#buff);\ //打印函数名 行数 以及传入的buff字符串名称
for(uint32_t count = 0;count<length;count++)\
{\
Printf(" 0x%x",buff[count]);\
}\
Printf("\n");\
}
#define DEBUG_YL_MSG(fmt, ...) \
{ \
{ \
Printf("[yl][%s][%d]"fmt"\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__);\//打印函数,行数以及更多的参数
} \
}