1、辅助定义复杂的宏,避免引用的时候出错
举例来说,假设你需要定义这样一个宏:
#define COMFUNC()\
api1();\
api2();
这个宏的本意是,当调用COMFUNC()时,函数api1()和api2()都会被调用。但是如果你在调用的时候这么写:
if (a>0)
COMFUNC();
代码实际是这个样子的:
if (a>0)
api1();
api2();
这样调用和使用者本身想法完全不一样,这样调用使得api2(),不管a>0是否成立都执行。
通常人们会用“{};”把api1(),api2()括在里面,代码实际如下:
if (a>0)
{
api1();
api2();
};
如果是使用if 和else就会出错。所以选用下面的方式比较好
#define COMFUNC() \
do{ \
api1();\
api2();\
}while(0)\
if(a>0)
COMFUNC();
2、避免使用goto对程序流进行统一的控制:
如下普通写法的代码,冗余过大。
bool Execute()
{
// 分配资源
int *p = new int;
bool bOk(true);
// 执行并进行错误处理
bOk = func1();
if(!bOk)
{
delete p;
p = NULL;
return false;
}
bOk = func2();
if(!bOk)
{
delete p;
p = NULL;
return false;
}
bOk = func3();
if(!bOk)
{
delete p;
p = NULL;
return false;
}
// ..........
// 执行成功,释放资源并返回
delete p;
p = NULL;
return true;
}
使用goto语句可以简化代码如下,但是goto语句太灵活,容易出问题。
bool Execute()
{
// 分配资源
int *p = new int;
bool bOk(true);
// 执行并进行错误处理
bOk = func1();
if(!bOk) goto errorhandle;
bOk = func2();
if(!bOk) goto errorhandle;
bOk = func3();
if(!bOk) goto errorhandle;
// ..........
// 执行成功,释放资源并返回
delete p;
p = NULL;
return true;
errorhandle:
delete p;
p = NULL;
return false;
}
使用do while(0)完成上诉功能最安全保险而且代码简洁。
bool Execute()
{
// 分配资源
int *p = new int;
bool bOk(true);
do
{
// 执行并进行错误处理
bOk = func1();
if(!bOk) break;
bOk = func2();
if(!bOk) break;
bOk = func3();
if(!bOk) break;
// ..........
}while(0);
// 释放资源
delete p;
p = NULL;
return bOk;
}