0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

do{...} while(0)的四大使用場景介紹

STM32嵌入式開發(fā) ? 來源:STM32嵌入式開發(fā) ? 2023-11-14 12:18 ? 次閱讀

這里只針對單核CPU,linux內(nèi)核和其他一些開源的代碼中,經(jīng)常會遇到這樣的代碼:


do{
 ...
}while(0)

這樣的代碼一看就不是一個循環(huán),do..while表面上在這里一點意義都沒有,那么為什么要這么用呢?

實際上,do{...}while(0)的作用遠大于美化你的代碼。查了些資料,總結(jié)起來這樣寫主要有以下幾點好處:

1、輔助定義復雜的宏,避免引用的時候出錯: 舉例來說,假設你需要定義這樣一個宏:


#define DOSOMETHING()
               foo1();
               foo2();
這個宏的本意是,當調(diào)用DOSOMETHING()時,函數(shù)foo1()和foo2()都會被調(diào)用。但是如果你在調(diào)用的時候這么寫:

if(a > 0)
    DOSOMETHING();
因為宏在預處理的時候會直接被展開,你實際上寫的代碼是這個樣子的:

if(a > 0)
    foo1();
foo2();
這就出現(xiàn)了問題,因為無論a是否大于0,foo2()都會被執(zhí)行,導致程序出錯。

那么僅僅使用{}將foo1()和foo2()包起來行么?

我們在寫代碼的時候都習慣在語句右面加上分號,如果在宏中使用{},代碼里就相當于這樣寫了:“ { ... } ; ”,展開后就是這個樣子 :

if(a > 0)
{
    foo1();
    foo2();
};
這樣甚至不會編譯通過。所以,很多人才采用了do{...}while(0);

 #define DOSOMETHING() 
         do{ 
           foo1();
           foo2();
         }while(0)
 
 ...
 
 if(a > 0)
    DOSOMETHING();


...
這樣,宏被展開后,才會保留初始的語義。GCC提供了Statement-Expressions用以替代do{...}while(0); 所以你也可以這樣定義宏:

#define DOSOMETHING() ({
        foo1(); 
        foo2(); 
})
2、避免使用goto對程序流進行統(tǒng)一的控制: 有些函數(shù)中,在函數(shù)return之前我們經(jīng)常會進行一些收尾的工作,比如free掉一塊函數(shù)開始malloc的內(nèi)存,goto一直都是一個比較簡便的方法:

 int foo()
{
     somestruct* ptr = malloc(...);
 
     dosomething...;
     if(error)
     {
         goto END;
     }


    dosomething...;
    if(error)
    {
        goto END;
    }
    dosomething...;


END:
    free(ptr);
    return 0;


}
由于goto不符合軟件工程的結(jié)構(gòu)化(bug菌PS:其實在Linux里面goto用得非常廣泛的,可以參考下(點擊藍色字體):goto關(guān)鍵字你不知道的"那些事"(C語言提升)),而且有可能使得代碼難懂,所以很多人都不倡導使用,那這個時候就可以用do{}while(0)來進行統(tǒng)一的管理:

 int foo()
{
 
     somestruct* ptr = malloc(...);
 
     do{
         dosomething...;
         if(error)
         {
            break;
        }


        dosomething...;
        if(error)
        {
            break;
        }
        dosomething...;
    }while(0);


    free(ptr);
    return 0;


}
這里將函數(shù)主體使用do()while(0)包含起來,使用break來代替goto,后續(xù)的處理工作在while之后,就能夠達到同樣的效果。

3、避免空宏引起的warning

內(nèi)核中由于不同架構(gòu)的限制,很多時候會用到空宏,在編譯的時候,空宏會給出warning,為了避免這樣的warning,就可以使用do{}while(0)來定義空宏:

#defineEMPTYMICROdo{}while(0)
4、定義一個單獨的函數(shù)塊來實現(xiàn)復雜的操作: 當你的功能很復雜,變量很多你又不愿意增加一個函數(shù)的時候,使用do{}while(0);,將你的代碼寫在里面,里面可以定義變量而不用考慮變量名會同函數(shù)之前或者之后的重復。




審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • LINUX內(nèi)核
    +關(guān)注

    關(guān)注

    1

    文章

    315

    瀏覽量

    21556
  • 預處理
    +關(guān)注

    關(guān)注

    0

    文章

    32

    瀏覽量

    10454

原文標題:do{...} while(0) 的四大使用場景

文章出處:【微信號:c-stm32,微信公眾號:STM32嵌入式開發(fā)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    C語言中whiledo-while循環(huán)的用法

    循環(huán)是一種重要的控制結(jié)構(gòu),可以使程序重復執(zhí)行一段代碼,直到滿足特定條件為止。在C語言中,whiledo-while是兩種常用的循環(huán)結(jié)構(gòu),本文將詳細介紹這兩種循環(huán)的用法。
    發(fā)表于 08-18 16:35 ?1450次閱讀
    C語言中<b class='flag-5'>while</b>和<b class='flag-5'>do-while</b>循環(huán)的用法

    幾種LED調(diào)光協(xié)議分析及具體應用場景介紹

    市面上主流幾種LED調(diào)光協(xié)議分析及具體應用場景介紹目前國內(nèi)外的LED驅(qū)動已經(jīng)不僅僅滿足照明需求,更多是去追求各種不同場景的應用,搭配各種數(shù)字協(xié)議,實現(xiàn)某種特定的功能,比如在汽車大燈的應用中,未為兼容
    發(fā)表于 12-31 08:04

    C語言宏定義使用do{}while(0)的好處是什么

    C語言宏定義使用do{}while(0)的好處1. 概述經(jīng)常寫項目代碼,有時需要用到宏定義,而宏定義的用法是否標準,則是會影響到是否能快速查錯以及代碼拓展性的問題。在宏定義的用法上大家為什么都推薦用
    發(fā)表于 02-25 06:28

    C++語言基礎講解視頻do while循環(huán)語句

    C++語言基礎講解視頻do while循環(huán)語句
    發(fā)表于 01-14 15:32 ?5次下載

    Proteus之do-while語句的應用

    Proteus之do-while語句的應用,很好的Proteus資料,快來學習吧。
    發(fā)表于 04-18 14:49 ?0次下載

    Java教程之如何進行Java中的do-while循環(huán)

    我們知道當一開始循環(huán)條件就不滿足的時候,while循環(huán)一次也不會 執(zhí)行。有的時候。我們有這樣的需要:無論如何循環(huán)都先執(zhí)行一次,再判斷循環(huán)條件。 決定是否繼續(xù)執(zhí)行.do-while循環(huán)就幫助我們滿足這樣的需要。
    發(fā)表于 01-23 11:05 ?7次下載
    Java教程之如何進行Java中的<b class='flag-5'>do-while</b>循環(huán)

    RFID標簽的四大主流應用場景

    一文帶你了解RFID標簽的四大主流應用場景
    的頭像 發(fā)表于 08-20 10:53 ?1.2w次閱讀

    HAL庫中do{...} while(0U) 宏定義的作用和意義

    HAL庫中do{...} while(0U)宏定義的作用和意義
    的頭像 發(fā)表于 03-03 14:07 ?3240次閱讀

    基于智慧城市的應用場景創(chuàng)新需求,組成全光自動駕駛網(wǎng)絡四大部分

    全光城市2.0是基于智慧城市的應用場景創(chuàng)新需求,匹配城市通信基礎設施規(guī)劃,所提出的城市目標網(wǎng)絡架構(gòu),包括全光接入、全光錨點、全光交換、全光自動駕駛網(wǎng)絡四大組成部分。
    發(fā)表于 09-10 09:56 ?895次閱讀

    do{...} while(0U) 這種代碼的作用和意義

    在一些項目中,我們可能看到過很多,在學習的時候沒有見過的代碼,比如 do{...} while(0U) 這種代碼,在我們學習的時候可能很少見,但實際項目中卻存在很多類似代碼。 今天就來講講關(guān)于
    的頭像 發(fā)表于 06-04 14:00 ?2537次閱讀
    <b class='flag-5'>do</b>{...} <b class='flag-5'>while</b>(<b class='flag-5'>0</b>U) 這種代碼的作用和意義

    C語言基礎:宏定義使用do{}while(0)的好處

    C語言宏定義使用do{}while(0)的好處1. 概述 經(jīng)常寫項目代碼,有時需要用到宏定義,而宏定義的用法是否標準,則是會影響到是否能快速查錯以及代碼拓展性的問題。在宏定義的用法上大家為什么都
    發(fā)表于 01-13 13:06 ?2次下載
    C語言基礎:宏定義使用<b class='flag-5'>do</b>{}<b class='flag-5'>while</b>(<b class='flag-5'>0</b>)的好處

    C程序中do{}while(0)宏定義的作用

    在嵌入式開發(fā)中,宏定義非常強大也非常便捷,如果正確使用可以讓你的工作事半功倍。然而,在很多的C程序中,你可能會看到不是那么直接的比較特殊一點的宏定義,比如do{}while(0)。
    的頭像 發(fā)表于 05-23 12:44 ?2593次閱讀

    如何去區(qū)分whiledo while 的用法

    如何去區(qū)分whiledo while 的用法。 2 方法 Do while
    的頭像 發(fā)表于 02-24 10:40 ?845次閱讀

    C語言-宏定義中使用do{...} while(0)到底圖個啥

    在 Linux 內(nèi)核中,經(jīng)常會看到do{} while(0)這樣的語句,許多人開始都會疑惑,認為do{} while(
    的頭像 發(fā)表于 06-11 10:59 ?654次閱讀

    do{}while(0)只執(zhí)行一次有意義嗎?

    在嵌入式開發(fā)中,宏定義非常強大也非常便捷,如果正確使用可以讓你的工作事半功倍。然而,在很多的C程序中,你可能會看到不是那么直接的比較特殊一點的宏定義,比如do{}while(0)。
    的頭像 發(fā)表于 10-09 14:20 ?521次閱讀
    <b class='flag-5'>do</b>{}<b class='flag-5'>while</b>(<b class='flag-5'>0</b>)只執(zhí)行一次有意義嗎?