|
C語言中do{...}while(0)的秒用 今天看了些有關do{...}while(0)秒用的文章,覺得寫的很好,這里總結(jié)下分享給大家。 這里分享的有3個用法,分別是: 1.避免空的宏定義在編譯時出現(xiàn)warning。 2.多個語句一起,定義成一個宏時,增加代碼適應(特別是條件語句調(diào)用這類宏要注意) 3.避免部分goto語句的使用 1.避免空的宏定義在編譯時出現(xiàn)warning //例如: #define foo() do{}while(0) 2.多個語句一起,定義成一個宏時,增加代碼適應(特別是條件語句調(diào)用這類宏要注意),以下if(0)和if(1)在實際應用時是if(表達式),表示表達式假和真。 //例如:一個宏包含以下兩個語句, #define foo() fun1(); fun2; 編譯器預處理的時候 if(1)foo(); //此時就相當于下面的語句, if(0)fun1(); fun2();//邏輯上多執(zhí)行的代碼,會導致系統(tǒng)BUG ;//邏輯上多執(zhí)行的代碼 如果使用do{...}while(0)就可以解決上面的問題 #define foo() do{ fun1(); fun2(); }while(0) //對于下面的語句 if(0) foo(); //編譯后的執(zhí)行如下: if(0) do{ fun1(); fun2(); }while(0); 這樣就不會出現(xiàn)上面那種有邏輯上不該執(zhí)行的代碼被執(zhí)行的問題。當然這里也可以用其他方法避免這個問題,比如加大括號{} #define foo() {fun1();fun2;} 編譯器會預處理下面語句 if(0) foo(); //編譯后的執(zhí)行如下: if(0) { fun1(); fun2(); } ;//會多個;號,但是也沒有邏輯上的問題 語句塊宏定義時注意的就是這些,另外在寫if語句時,盡量后面要加大括號,避免出錯,例如上面的if(0){foo();},加上大括號{}也不會有問題。 3.避免部分goto語句的使用 //例如:如果一個函數(shù)要分配一些資源,然后中途遇到錯誤,要退出函數(shù),退出前要釋放資源,代碼結(jié)構可能如下: bool foo(){ int *p = (int*)malloc(5*sizeof(int)); bool bOk = true; //執(zhí)行并處理錯誤 bOk = fun1(); if(!bOk){ free(p); p=NULL; return false; } bOk = fun2(); if(!bOk){ free(p); p=NULL; return false; } bOk = fun3(); if(!bOk){ free(p); p=NULL; return false; } //...... //執(zhí)行成功,釋放資源并返回ture free(p); p = NULL; return true; } 這里就覺得很多代碼冗余,然而使用溝通可以很好的解決冗余的部分,代碼如下: bool foo(){ int *p = (int*)malloc(5*sizeof(int)); bool bOk = true; //執(zhí)行并處理錯誤 if(!fun1()) goto errorlable; if(!fun2()) goto errorlable; if(!fun3()) goto errorlable; //...... //執(zhí)行成功,釋放資源并返回ture free(p); p = NULL; return true; //冗余部分的,錯誤返回代碼 errorlable: free(p); p = NULL; return false; } 然后C語言中過多的使用goto語句會提高程序的靈活性,繁雜點的程序會讓程序員捉摸不定,程序跳來跳出,難以捉摸,容易邏輯上產(chǎn)生混淆從而出現(xiàn)BUG。對于上面的這種情況使用do{...}while(0)就可以很好的解決這些跳來跳出的問題,代碼結(jié)構如下: bool foo(){ //分配資源 int *p = (int*)malloc(5*sizeof(int)); bool bOk = true; //執(zhí)行并處理錯誤 do{ bOk = fun1(); if(!bOk)break; bOk = fun2(); if(!bOk)break; bOk = fun3(); if(!bOk)break; //...... }while(0); //釋放資源并返回bOk free(p); p = NULL; return bOk; } |
|
|