欢迎转载,转载请注明原文地址:http://blog.csdn.net/majianfei1023/article/details/45246865
#define TT_URI(want) do { \ char *ret = evhttp_uri_join(uri, url_tmp, sizeof(url_tmp)); \ tt_want(ret != NULL); \ tt_want(ret == url_tmp); \ if (strcmp(ret,want) != 0) \ TT_FAIL(("\"%s\" != \"%s\"",ret,want)); \ } while(0)
一.定义宏,实现局部作用域。
1.大家做c语言题目的时候,一道必考题就是 #define的算术运算。#define FUNC(x) x*3+4 ... int result = 2 * FUNC(3);
有些人可能说,这些我都知道,这跟do{...}while(0)有什么关系。
其实,我只是为了告诉你,#define使用的时候要特别小心,尤其是#define一个很复杂的逻辑的时候。
我们举个简单的#define的例子:
void print() { cout<<"print: "<<endl; } void send() { cout <<"send: "<<endl; } #define LOG print();send(); int main(){ if (false) LOG cout <<"hello world"<<endl; system("pause"); return 0; }
但是事实上:
纳闷?
注意我上面说的一句话:
也就是 #define是在预处理的时候进行直接替换!(这句话是这一节的重点)
也就是说,上面的if(false)...在这里是:
if (false) print(); send(); cout <<"hello world"<<endl;
怎么解决了,有些人马上想到,用{...}把#define 的值括住不就可以了。的确,在这里是可以的。
我们在写代码的时候都习惯在语句右面加上分号,如果在宏中使用{},我们通常会这么写:
#define LOG {print();send();};当我们的if后面有一个else呢?
就变成了:
if (false) { print(); send(); }; else { cout <<"hello"<<endl; }
那么来我们的最终版本:do{...}while(0);
#define LOG do{print();send();}while (0); int main(){ if (false) LOG else { cout <<"hello"<<endl; } cout <<"hello world"<<endl; system("pause"); return 0; }
if (false) do{ print(); send(); }while (0); else { cout <<"hello"<<endl; } cout <<"hello world"<<endl;
三.替代goto.
int dosomething() { return 0; } int clear() { } int foo() { int error = dosomething(); if(error = 1) { goto END; } if(error = 2) { goto END; } END: clear(); return 0; }
由于goto不符合软件工程的结构化,而且有可能使得代码难懂,所以很多人都不倡导使用,那这个时候就可以用do{}while(0)来进行统一的管理:
int foo() { do { int error = dosomething(); if(error = 1) { break; } if(error = 2) { break; } } while (0); clear(); return 0; }
在do{...}while(0)里面,在任何地方都可以break跳出,然后继续下面的执行逻辑。即使你不写break,也会在执行完一遍do之后,while(0)不满足,自己跳出去。