C/C++中宏定义的经典运用
connect(ui-> /*定义enum*/ /*声明各个函数*/ /*初始化表*/ 以上实现方法能够较好的避免#define和#undef的限定作用域问题,这实际上采用ENTRY作为参数传递给STATE_TABLE,然后ENTRY可用来实现不同的指令,这些指令的定义也是一系列的宏定义,这种实现架构能够比较好的避免缺少声明等问题。同时也较少了错误的产生可能。 这种实现模型只是简化的版本,STATE_TABLE(ENRTY)中的ENTRY可以定义多个参数如下所示: /*COMMANDS*/ #define TABLE(ENTRY) 比如将上面的初始化实现修改为下面的形式,也就是多个参数的形式,实现如下: 点击(此处)折叠或打开 typedef void(*p_func_t)(void); #define EXPAND_AS_ENUM(a,b,c) a, #define EXPAND_AS_JUMPTABLE(a,b,c) b, #define EXPAND_AS_FUNCDEC(a,b,c) void c(void); #define STATE_TABLE(ENTRY) enum{ STATE_TABLE(EXPAND_AS_FUNCDEC) p_func_t init_table[NUM_STATES] = 上面的实现并不是非常的恰当,因为第二个、第三个参数实质上是一致的,没有必要定义为三个参数。本文只是说明三个参数的实现情况。其他多个参数的实现情况类似。为了说明这种模型的可行性,我写了简单的测试代码,由于各个模块的初始化代码需要程序员手动的实现,因此可以定义在其他的位置,同时在宏定义中也已经实现了各个函数的声明问题,因为不会出现未定义的问题。具体的实现如下所示: #include typedef void(*p_func_t)(void); #define EXPAND_AS_ENUM(a,b) a, #define EXPAND_AS_INITTABLE(a,b) b, #define EXPAND_AS_FUNCDEC(a,b) void b(void); #define STATE_TABLE(ENTRY) enum{ STATE_TABLE(EXPAND_AS_FUNCDEC) p_func_t init_table[NUM_STATES] = /*测试代码*/ for(i = 0; i < NUM_STATES; ++ i) return 0; /*各个模块的初始化函数实现*/ void func_1(void) void func_2(void) void func_3(void) void func_4(void) 关于多变量的情况,在Linux内核源码中的物理内存与虚拟内存之间可以采用这种方式实现,在很多情况下都知道寄存器的物理内存,一般一组相关的寄存器的映射方式都是相同的,采用这种宏定义的实现方式就能较好完成定义问题,当然只是可行的方法而已。 #define ADDRESS_OFFSET (0x8000) #define REGISTER_MAP(ENTRY) /*物理地址*/ 宏定义的这种实现方式在一些嵌入式系统中是非常有效的,掌握这种实现方法能够较好的管理各个模块、各种状态下对应的处理函数。这是一种经典的用法。这实际上给出可一种解决问题的模型架构,掌握好这种方式能够较好的实现模块的管理问题。这种实现方法不仅代码量少,而且能够避免很多错误的产生,能够快速的进行修改,但是难点在于代码对于初学者有一定的难度,而且宏定义实现的函数还能够采用其他的方法实现,只是宏定义能够较好的简化代码,使得代码优美且易维护。
enum{
STATE_TABLE(EXPAND_AS_ENUM)
NUM_STATES
};
STATE_TABLE(EXPAND_AS_FUNCDEC)
p_func_t inital_table[NUM_STATES] =
{
STATE_TABLE(EXPAND_AS_INITTABLE)
};
#define COMD1(a0,a1,a2,...,am) /*具体实现*/
#define COMD2(a0,a1,a2,...,am) /*具体实现*/
...
ENTRY(a0,a1,a2,...,am)
ENTRY(a0,a1,a2,...,am)
...
ENTRY(a0,a1,a2,...,am)
ENTRY(STATE_0,func_0,func_0)
ENTRY(STATE_1,func_1,func_1)
ENTRY(STATE_2,func_2,func_2)
ENTRY(STATE_3,func_3,func_3)
ENTRY(STATE_4,func_4,func_4)
STATE_TABLE(EXPAND_AS_ENUM)
NUM_STATES
};
{
STATE_TABLE(EXPAND_AS_INITTABLE)
};
ENTRY(STATE_0,func_0)
ENTRY(STATE_1,func_1)
ENTRY(STATE_2,func_2)
ENTRY(STATE_3,func_3)
ENTRY(STATE_4,func_4)
STATE_TABLE(EXPAND_AS_ENUM)
NUM_STATES
};
{
STATE_TABLE(EXPAND_AS_JUMPTABLE)
};
int main()
{
int i = 0;
(jumptable[i])();
}
void func_0(void)
{
printf("In func_0");
}
{
printf("In func_1");
}
{
printf("In func_2");
}
{
printf("In func_3");
}
{
printf("In func_4");
}
#define PHYS_ADDRESS(a,b,c) a=c;
#define VIRU_ADDRESS(a,b,c) a = b + c;
ENTRY(reg0,ADDRESS_OFFSET,0x10)
ENTRY(reg1,ADDRESS_OFFSET,0x14)
ENTRY(reg2,ADDRESS_OFFSET,0x18)
...
ENTRY(regm,ADDRESS_OFFSET,0x2c)
REGISTER_MAP(PHYS_ADDRESS)
/*虚拟地址*/
REGISTER_MAP(VIRU_ADDRESS)
CC++宏定义经典运 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)