今天在閱讀linux代碼的時候,看到linux很多代碼都用了:剛開始以為這是多此一舉,既然是while(0),那麼寫和沒寫都是一個樣。但是在好奇心的驅動下,查閱了許多資料後,發現,這句代碼真的是“神”一般的操作,那麼它到底有什麼作用呢?
一,避免使用goto控制流程:我們在一些函數中,如果在退出前,需要一些清理工作,正常情況下,我們可以使用goto來實現,比如:
int foo()
{
somestruct *ptr = malloc(...);
dosomething...;
if(error)
goto END;
dosomething...;
END:
free(ptr);
return 0;
}
但是由于goto
但是由于goto不符合結構化設計,很多人都不倡導使用,這時候就可以使用do while了:
int foo()
{
somestruct *ptr = malloc(...);
do
{
dosomething...;
if(error)
break;
dosomething...;
} while(0);
free(ptr);
return 0;
}
這裡将函數主體部分使用do{...}while(0)包含起來,使用break來代替goto,後續的清理工作在while之後,現在既能達到同樣的效果,而且代碼的可讀性、可維護性都要比上面的goto代碼好的多了。
二.避免宏定義的一些編譯或者錯誤:我們假設定義一個宏:
#define DELETE_IT(p) delete p; p = NULL;
那麼在下面的代碼中:
If(NULL!=p)
DELETE_IT(p)
else
.......
宏會被展開成:
If(NULL!=p)
delete p; p=NULL;
else
........
那麼就存在兩個問題:
1,編譯錯誤:因為if分支後面有兩個語句,導緻else分支沒有對應的if
2,邏輯錯誤:假設沒有else分支,則SAFE_FREE中的第二個語句無論if測試是否通過,都會執行,這個就很嚴重
那麼有什麼辦法解決這個問題嗎?答案是有,do while就是用來解決這個問題的:
#define DELETE_IT(p) do { delete p; p=NULL; } while(0);
這樣定義,展開後,就變成:
If(NULL!=p)
do { free(p); p=NULL; } while(0);
else
.......
這樣就可以避免上面的問題了
即學即用的技巧,可以在代碼秀一下了
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!