我第一眼看到这个东西,觉得不就是让括号内的语句执行一次吗。有啥用咧?
作用解析
1. 避免goto语句
有时候,一个函数要在一开始的时候分配一些资源,假如中间发生了错误需要先释放内存,然后退出函数
于是我们有了第一个版本的测试代码
#include <iostream>
bool f1(int t) {
return t > 0;
}
bool f2(int t) {
return t == 0;
}
bool foo() {
int *p = (int *)malloc(5 * sizeof(int));
bool Tag;
Tag = f1(3);
if (!Tag) {
free(p);
p = NULL;
return false;
}
Tag = f2(3);
if (!Tag) {
free(p);
p = NULL;
return false;
}
std::cout << "f1和f2执行成功,开始释放p指向的内存空间...\n";
free(p);
p = NULL;
return true;
}
int main(int argc, char* argv[]) {
foo();
return 0;
}
这时候,你可能觉得foo函数内的有了好几次释放p指向的内存空间的过程,太过于繁琐,想用一个goto语句代替
于是,有了第二个版本的测试代码
#include <iostream>
bool f1(int t) {
return t > 0;
}
bool f2(int t) {
return t == 0;
}
bool foo() {
int *p = (int *)malloc(5 * sizeof(int));
bool Tag;
Tag = f1(3);
if (!Tag)
goto ErrorHandle;
Tag = f2(3);
if (!Tag)
goto ErrorHandle;
std::cout << "f1和f2执行成功,开始释放p指向的内存空间...\n";
free(p);
p = NULL;
return true;
ErrorHandle:
free(p);
p = NULL;
return false;
}
int main(int argc, char* argv[]) {
foo();
return 0;
}
但是,我们大家都知道,在实际的使用中,应该是要避免goto语句的,于是可以用do{…}while(0)来解决这个问题
#include <iostream>
bool f1(bool t) {
return t > 0;
}
bool f2(bool t) {
return t == 0;
}
bool foo() {
int *p = (int *)malloc(5 * sizeof(int));
bool Tag;
do {
Tag = f1(3);
if (!Tag)
break;
Tag = f2(3);
if (!Tag)
break;
} while (0);
std::cout << "f1和f2执行成功,开始释放p指向的内存空间...\n";
free(p);
p = NULL;
return Tag;
}
int main(int argc, char* argv[]) {
foo();
return 0;
}
2. 帮助定义多语句的宏
举个例子
#include <iostream>
void print_f1() {
std::cout << "this is f1...\n";
}
void print_f2() {
std::cout << "this is f2...\n";
}
#define TESTDOWHILE \
print_f1(); \
print_f2();
int main(int argc, char* argv[]) {
std::cout << "now testing : t1 = 1 ...\n";
int t1 = 1;
if (t1)
TESTDOWHILE;
std::cout << "now testing : t2 = 0 ...\n";
int t2 = 0;
if (t2)
TESTDOWHILE;
return 0;
}
运行上面的测试代码,得到下面的结果,说明,在调用TESTDOWHILE的时候,将其以不带括号的形式展开了,于是不管if语句里面的条件是否为真,宏定义中多语句后面的语句都会执行。
那么,怎么解决这个问题呢,除了可以在宏定义时使用大括号(注意在使用宏的时候末尾的分号要根据实际情况来确定),还可以在宏定义处使用do{…}while语句
#include <iostream>
void print_f1() {
std::cout << "this is f1...\n";
}
void print_f2() {
std::cout << "this is f2...\n";
}
#define TESTDOWHILE \
do{\
print_f1(); \
print_f2(); \
} while (0);
int main(int argc, char* argv[]) {
std::cout << "now testing : t1 = 1 ...\n";
int t1 = 1;
if (t1)
TESTDOWHILE;
std::cout << "now testing : t2 = 0 ...\n";
int t2 = 0;
if (t2)
TESTDOWHILE;
std::cout << "hello world ...\n";
return 0;
}
}
问题就解决了,可以看到并没有输出f2的结果