一,这是个什么玩意
有时候在宏定义或打印语句中经常见到#井号或者##双井号,看着很牛逼的用法
二,有毛用啊
#:表示字符串化;##:表示concatenate(连接)
具体就是,#号的功能是将其后面的参数进行字符串化操作,即无论后面的宏变量是字符串还是常量,都当成字符来处理。
## 被称为连接符,用来将##两边的内容连接成一个。注意这里连接的对象是变量就行,也不一定是宏的变量。
三,怎么用啊
其实知道了上面的内容就基本知道怎么用了,直接上例子
[c] view plaincopy
- #include <iostream>
- void test_command(){
- printf("I am test command\n");
- }
- void test2_command(){
- printf("I am test2 command\n");
- }
- struct testcommand
- {
- char * commandName;
- void (*function) (void);
- };
- #define COMMAND(NAME) {#NAME,NAME##_command}
- #define PRINT(NAME) printf("test"#NAME"=%d\n", test##NAME)
- main(){
- int test9=9;
- PRINT(9);
- struct testcommand commands[] = {
- COMMAND(test1),
- COMMAND(test2),
- };
- commands[0].function();
- commands[1].function();
- }
得到的结果是:
test9=9
I am test1 command
I am test2 command
1、优化代码编程,根据实际项目定义。
*2、一般情况下,if else分支较多的时候用switch case结构,如果case分支又很多的时候,这时候建议用数组结构的方式,具体里面有重复定义的东西也可以结合使用#或##,其实主要是为了优化编程结构,提高代码的编写效率和阅读效率,例如
typedef struct _test_struct_
{
u16 caseId;//各个case id
u16 (*functioinProcess)(u8 tag,u16 len,u8 *data);//处理各个case 的函数
}test_struct;
static test_struct caseIdList[]=
{
{caseId1,caseId1_process_function},
{caseId2,caseId2_process_function},
{caseId3,caseId3_process_function},
{caseId4,caseId4_process_function},
};
然后之前处理各个case分支的函数直接循环查询调用caseIdList数据即可。如下
void caseprocessfuncton(u8 tag,u16 len,u8 *data)
{
for(i=0;i<sizeof(caseIdList)/sizeof(caseIdList[0]);i++)
{
if(caseIdList[i].caseId == tag)
{
caseIdList[i].functionProcess(tag,len,data);
}
}
}
还有一种写法用#或##
#define CASEID_PROCESS(NAME) {NAME,NAME##_process_function}
static test_struct caseIdList[]=
{
CASEID_PROCESS(caseId1),
CASEID_PROCESS(caseId2),
CASEID_PROCESS(caseId3),
CASEID_PROCESS(caseId4),
};
#define DRV_I2CX_REGISTER(a) fst_i2c##a##_handle.Instance = I2C##a//主要起连接作用的
四、成为大神的用法
1、记住上面的2的用法
2、能单独作为一部分提出出来的可以提取出来,结合是否可以用##来连接从而用了区分