糯米文學吧

位置:首頁 > 計算機 > C語言

C語言中do...while(0)技巧

C語言9.34K

在linux內核代碼中,經常看到e(0)的宏,e(0)有很多作用,具體技巧有哪些呢?以下僅供參考!

C語言中do...while(0)技巧

1、避免goto語句:

通常,如果一個函數開始要分配一些資源,然後如果在中途遇到錯誤則要退出函數,當然,退出前要釋放資源,我們的代碼可能如下:

#defien N 10

bool Execute()

{

// 分配資源

int *p = (int *)malloc(N * sizeof(int));

bool bOk = true;

// 執行並進行錯誤處理

bOk = func1();

if(!bOk)

{

free(p);

p = NULL;

return false;

}

bOk = func2();

if(!bOk)

{

free(p);

p = NULL;

return false;

}

bOk = func3();

if(!bOk)

{

free(p);

p = NULL;

return false;

}

// ..........

// 執行成功,釋放資源並返回

free(p);

p = NULL;

return true;

}

這裏最大的問題是代碼宂餘,每增加一個操作,就要做相應的錯誤處理,非常不靈活,於是想到了一下的goto:

#defien N 10

bool Execute()

{

// 分配資源

int *p = (int *)malloc(N * sizeof(int));

bool bOk = true;

// 執行並進行錯誤處理

bOk = func1();

if(!bOk) goto errorhandle;

bOk = func2();

if(!bOk) goto errorhandle;

bOk = func3();

if(!bOk) goto errorhandle;

// ..........

// 執行成功,釋放資源並返回

free(p);

p = NULL;

return true;

errorhandle:

free(p);

p = NULL;

return false;

}

代碼宂餘是解決了,但是引入了C語言中比較微妙的goto語句,雖然正確的使用goto語句可以大大提高程序的靈活性與簡潔性,但是會使我們的程序捉摸不定,為了既避免使用goto語句,又能消除代碼宂餘,可以考慮使用下面的` e(0):

#defien N 10

bool Execute()

{

//分配資源

int *p = (int *)malloc(N * sizeof(int));

bool bOK = true;

do {

//執行並進行錯誤處理

bOK = fun1();

if(!bOK) break;

bOK = fun2();

if(!bOK) break;

bOK = fun3();

if(!bOK) break;

//.........

} while(0);

//釋放資源

free(p);

p = NULL;

return bOK;

}

2、避免空聲明在編譯時出現警告:

在linux內核源代碼中,經常看到如下宏以避免在編譯時出現警告:

#define FOO do { } while(0)

3、編寫符合習慣的代碼塊:

你可能經常會使用如下的宏:

#define exch(x,y) { int tmp; tmp=x; x=y; y=tmp; }

然而在某些情況下將會失效,下面的代碼使用...

if (x > y)

exch(x,y); // 分支 1

else

do_something(); // 分支 2

但是將被解釋為一個分支的if語句:

if (x > y) {

int tmp;

tmp = x;

x = y;

y = tmp;

}

; // 空語句

else // ERROR!!!

do_something();

錯誤出在“;”直接位於代碼塊的後面,解決的辦法是將代碼嵌入e(0),於是得到下面的代碼:

if (x > y)

do {

int tmp;

tmp = x;

x = y;

y = tmp;

} while(0);

else

do_something();

於是上面的宏可以修改為:

#define exch(x,y) do {

int tmp;

tmp = x;

x = y;

y = tmp;

} while(0)

4、在條件語句中使用複雜的宏:

假如一個宏包含類似如下幾行代碼:

#define FOO(x)

printf("arg is %s", x);

do_something_useful(x);

現在想像一下下面的代碼:

if (blah == 2)

FOO(blah);

這將解釋為:

if (blah == 2)

printf("arg is %s", blah);

do_something_useful(blah);;

我們就會發現,if語句只作用於printf(), do_something_useful() 沒按照願意一起執行,即沒有像你預期的那樣被包含在if代碼中,於是可以使用如下的代碼塊:

if (blah == 2)

do {

printf("arg is %s", blah);

do_something_useful(blah);

} while (0);

這樣上面的宏就可以改為:

#define FOO(x) do {

printf("arg is %s", blah);

do_something_useful(blah);

} while (0)

標籤:dowhile0 語言