C++小知识——浅析do{...}while(0)

我第一眼看到这个东西,觉得不就是让括号内的语句执行一次吗。有啥用咧?

作用解析

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的结果
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/CSDN_dzh/article/details/83656683
今日推荐