色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

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

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

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

函數(shù)宏的三種封裝方式

璟琰乀 ? 來源:大魚機器人 ? 作者:大魚機器人 ? 2020-12-22 15:49 ? 次閱讀

1. 函數(shù)宏介紹

函數(shù)宏,即包含多條語句的宏定義,其通常為某一被頻繁調(diào)用的功能的語句封裝,且不想通過函數(shù)方式封裝來降低額外的彈棧壓棧開銷。

函數(shù)宏本質上為宏,可以直接進行定義,例如:

#define INT_SWAP(a,b) \ int tmp = a; \ a = b; \ b = tmp

但上述的宏具有一個明顯的缺點:當遇到 if、while 等語句且不使用花括號僅調(diào)用宏時,實際作用范圍在宏的第一個分號后便結束。即 a = b 和 b = tmp 均不受控制語句所作用。

因此,在工程中,一般使用三種方式來對函數(shù)宏進行封裝,分別為 {}、do{。..}while(0) 和 ({})。下文將一一對三種方式進行分析,比較各自的優(yōu)劣點。

2. {} 方式

INT_SWAP 宏使用 {} 封裝后形態(tài)如下:

#define INT_SWAP(a,b)\{ \ int tmp = a; \ a = b; \ b = tmp; \}

此時,直接調(diào)用與在無花括號的控制語句(如 if、while)中調(diào)用均能正常運行,例如:

#define INT_SWAP(a,b) \{ \ int tmp = a; \ a = b; \ b = tmp; \}int main(){ int var_a = 1; int var_b = 2; INT_SWAP(var_a, var_b); printf(“var_a = %d, var_b = %d\n”, var_a, var_b); // var_a = 2, var_b = 1 if (1) INT_SWAP(var_a, var_b); printf(“var_a = %d, var_b = %d\n”, var_a, var_b); // var_a = 1, var_b = 2}

但當無花括號的 if 語句存在其他分支(else if、else 等)如:

if (1) INT_SWAP(var_a, var_b);else printf(“hello world!\n”);

會發(fā)現(xiàn)編譯出錯:

。../mnt/hgfs/share/pr_c/src/main.c: In function ‘main’:/mnt/hgfs/share/pr_c/src/main.c:18:2: error: ‘else’ without a previous ‘if’ else

這是因為 INT_SWAP(var_a, var_b); 最后的 ; 已經(jīng)把 if 的作用域終結了,后續(xù)的 else 當然沒有找到與之匹配的 if 了。

因此,解決方法有兩種,分別為不使用 ;(port.1)或規(guī)定必須使用帶花括號的 if(port.2),例如:

/* port.1 */if (1) INT_SWAP(var_a, var_b)else{ printf(“hello world!\n”);}/* port.2 */if (1){ INT_SWAP(var_a, var_b);}else{ printf(“hello world!\n”);}

可見,不使用 ; 的調(diào)用方式無論從程序閱讀還是使用方法方面都是十分別扭的;而規(guī)定必須使用帶花括號的 if 的調(diào)用方式有違常理的,因為宏函數(shù)應該適用于任何語法。

優(yōu)缺點總結:

優(yōu)點:簡單粗暴。

缺點:不能在無花括號且有分支的 if 語句中直接調(diào)用;能夠不帶 ; 直接調(diào)用。

3. do{。..}while(0) 方式INT_SWAP 宏使用 do{。..}while(0) 封裝后形態(tài)如下:

#define INT_SWAP(a,b) \do{ \ int tmp = a; \ a = b; \ b = tmp; \}while(0)

do{。..}while(0) 表示只執(zhí)行一遍 {} 內(nèi)的語句,表象來說與 {} 的功能是一致的。不同的是,do{。..}while(0) 可以提前退出函數(shù)宏、整合為一條語句與強制調(diào)用時必須使用 ;。

由于 do{。..}while(0) 實際為 while 循環(huán),因此可以使用關鍵字 break 提前結束循環(huán)。利用該特性,可以為函數(shù)宏添加參數(shù)檢測。例如:

#define INT_SWAP(a,b) \do{ \ if (a 《 0 || b 《 0) \ break; \ int tmp = a; \ a = b; \ b = tmp; \}while(0)

由于 do{。..}while(0); 實際為一種語法,編譯器會把 do{。..}while(0); 認為為一條語句。

因此,do{。..}while(0) 方式的函數(shù)宏可以在無花括號且有分支的 if 語句中直接調(diào)用。例如:

#define INT_SWAP(a,b) \do{ \ if (a 《 0 || b 《 0) \ break; \ int tmp = a; \ a = b; \ b = tmp; \}while(0)int main(){ int var_a = 1; int var_b = 2; if (1) INT_SWAP(var_a, var_b); else printf(“hello world!\n”); printf(“var_a = %d, var_b = %d\n”, var_a, var_b); // var_a = 2, var_b = 1 return 0;}

C 語言規(guī)定,do{。..}while(0) 語法必須使用 ; 作為語句結尾。因此不可能存在以下語句的程序出現(xiàn):

if (1) INT_SWAP(var_a, var_b)else{ printf(“hello world!\n”); }

優(yōu)缺點總結:

優(yōu)點:支持在無花括號且有分支的 if 語句中直接調(diào)用;支持提前退出函數(shù)宏;強制調(diào)用時必須使用 ;。

缺點:無返回值,不能作為表達式的右值使用。

4. ({}) 方式({}) 為 GNU C 擴展的語法,非 C 語言的原生語法。

INT_SWAP 宏使用 ({}) 封裝后形態(tài)如下:

#define INT_SWAP(a,b) \({ \ int tmp = a; \ a = b; \ b = tmp; \})

與 do{。..}while(0) 相同,({}) 支持在無花括號且有分支的 if 語句中直接調(diào)用。例如:

#define INT_SWAP(a,b) \({ \ int tmp = a; \ a = b; \ b = tmp; \})int main(){ int var_a = 1; int var_b = 2; if (1) INT_SWAP(var_a, var_b); else printf(“hello world!\n”); printf(“var_a = %d, var_b = %d\n”, var_a, var_b); // var_a = 2, var_b = 1 return 0;}

與 do{。..}while(0) 不同的是,({}) 不能提前退出函數(shù)宏與支持返回值。({}) 畢竟不是 while 循環(huán),不能直接使用 break退出函數(shù)宏是比較容易理解。那支持返回值是什么意思呢?

答案是 C 語言規(guī)定 ({}) 中的最后一條語句的結果為該雙括號體的返回值。例如:

int main(){ int a = ({ 10; 1000; }); printf(“a = %d\n”, a); // a = 1000}

因此,({}) 可以為函數(shù)宏提供返回值。例如:

#define INT_SWAP(a,b) \({ \ int ret = 0; \ if (a 《 0 || b 《 0) \ { \ ret = -1; \ } \ else \ { \ int tmp = a; \ a = b; \ b = tmp; \ } \ ret; \})int main(){ int var_a = 1; int var_b = 2; if (INT_SWAP(var_a, var_b) != -1) printf(“swap success !!\n”); // swap success !! else printf(“swap fail !!\n”); printf(“var_a = %d, var_b = %d\n”, var_a, var_b); // var_a = 2, var_b = 1 return 0;}

可見,此時的 INT_SWAP 宏已與函數(shù)十分接近。

優(yōu)缺點總結:

優(yōu)點:支持在無花括號且有分支的 if 語句中直接調(diào)用;有返回值,支持作為表達式的右值。

缺點:不支持提前退出函數(shù)宏;非 C 的原生語法,編譯器可能不支持。

5. 總結綜上,在 {}、do{。..}while(0) 和 ({}) 這三種函數(shù)宏的封裝方式之中,應盡可能不使用 {},考慮兼容性一般選擇使用 do{。..}while(0),當需要函數(shù)宏返回時可以考慮使用 ({}) 或直接定義函數(shù)。

責任編輯:haq

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

    關注

    88

    文章

    3614

    瀏覽量

    93686
  • 函數(shù)
    +關注

    關注

    3

    文章

    4327

    瀏覽量

    62573
收藏 人收藏

    評論

    相關推薦

    三種封裝形式下的400G光模塊概述

    本文主要就三種封裝形式(QSFP-DD、OSFP、QSFP112)的400G光模塊做了簡單的梳理,從為什么會有400G光模塊問世?400G光模塊在三種封裝形式下的各個具體型號(以短距離
    的頭像 發(fā)表于 11-11 11:35 ?362次閱讀
    <b class='flag-5'>三種</b><b class='flag-5'>封裝</b>形式下的400G光模塊概述

    systemd journal收集日志的三種方式

    隨著 systemd 成了主流的 init 系統(tǒng),systemd 的功能也在不斷的增加,比如對系統(tǒng)日志的管理。Systemd 設計的日志系統(tǒng)好處多多,這里筆者就不再贅述了,本文筆者主要介紹 systemd journal 收集日志的三種方式
    的頭像 發(fā)表于 10-23 11:50 ?235次閱讀
    systemd journal收集日志的<b class='flag-5'>三種</b><b class='flag-5'>方式</b>

    Windows管理內(nèi)存的三種主要方式

    Windows操作系統(tǒng)提供了多種方式來管理內(nèi)存,以確保系統(tǒng)資源的有效利用和性能的優(yōu)化。以下是關于Windows管理內(nèi)存的三種主要方式的詳細闡述,包括堆內(nèi)存管理、虛擬內(nèi)存管理以及共享內(nèi)存管理,每種
    的頭像 發(fā)表于 10-12 17:09 ?707次閱讀

    常用的pwm跟蹤控制方式是哪三種

    PWM(脈寬調(diào)制)跟蹤控制是一廣泛應用于電機控制、電源管理、通信等領域的技術。它通過調(diào)整脈沖的寬度來控制輸出信號的占空比,從而實現(xiàn)對系統(tǒng)的精確控制。常用的PWM跟蹤控制方式主要有三種:增量式PWM
    的頭像 發(fā)表于 08-14 10:34 ?1132次閱讀

    計算機網(wǎng)絡中的三種通信方式

    計算機網(wǎng)絡中的三種通信方式,即單工通信、半雙工通信和全雙工通信,是理解和設計高效網(wǎng)絡架構的基礎。每種通信方式都有其獨特的特性、應用場景及優(yōu)缺點。以下是對這三種通信
    的頭像 發(fā)表于 08-07 15:00 ?2485次閱讀

    簡述斬波電路的三種控制方式

    斬波電路是一常見的電力電子器件,廣泛應用于直流電壓調(diào)節(jié)、電壓變換、電流變換等領域。它可以實現(xiàn)對電流和電壓的控制,以滿足不同的電氣設備的需求。斬波電路的控制方式主要有三種:脈寬調(diào)制控制、頻率調(diào)制控制
    的頭像 發(fā)表于 03-11 15:22 ?3880次閱讀

    熱傳遞的三種方式是什么

    熱傳遞有三種基本形式:導熱(Thermal Conduction)、對流(Thermal Convection)和輻射(Thermal Radiation)。每種形式都有其獨特的物理過程和應用領域
    的頭像 發(fā)表于 02-06 14:02 ?2224次閱讀
    熱傳遞的<b class='flag-5'>三種</b><b class='flag-5'>方式</b>是什么

    光耦隔離 電容隔離 磁隔離這三種隔離方式各有什么優(yōu)缺點?

    光耦隔離、電容隔離和磁隔離是三種常見的隔離方式,它們各有優(yōu)缺點,適用于不同的應用場景。
    的頭像 發(fā)表于 01-30 15:38 ?5830次閱讀

    介紹三種建模方式

    據(jù)量大,而是指樣本的完備性。還有就是大數(shù)據(jù)或者AI被專業(yè)學者或者行業(yè)工程師所詬病的就是,純粹的數(shù)據(jù)驅動搞不出所以然出來,需要領域知識(即Domain Knowledge)的協(xié)助。此外,還有第三種建模方式就是混合驅動,即基礎物理模型加上數(shù)據(jù)驅動的
    的頭像 發(fā)表于 01-23 10:48 ?1812次閱讀

    運動控制的三種控制方式

    非標項目中有非常多的運動控制,根據(jù)系統(tǒng)配置、電機類型以及精度需求的不同主要有三種控制方式:開環(huán)控制、半閉環(huán)控制、全閉環(huán)控制。
    的頭像 發(fā)表于 01-23 09:48 ?1469次閱讀
    運動控制的<b class='flag-5'>三種</b>控制<b class='flag-5'>方式</b>

    嵌入式Linux開發(fā)的三種方式

    嵌入式Linux開發(fā)主要有三種方式:裸機開發(fā)、SDK開發(fā)和驅動開發(fā)。
    的頭像 發(fā)表于 01-22 14:22 ?961次閱讀

    通過TestStand三種主要運行方式探究TestStand開放式架構

    在這張圖中,我們可以看到三種主要運行方式分別是”Test UUTs”、”Single Pass”、”Run MainSequence”。大家不妨先嘗試一下看看同一個序列文件用三種運行方式
    的頭像 發(fā)表于 01-19 17:34 ?4677次閱讀
    通過TestStand<b class='flag-5'>三種</b>主要運行<b class='flag-5'>方式</b>探究TestStand開放式架構

    自動控制的基本方式三種是什么

    自動控制是指利用特定的設備和技術手段,通過對被控制系統(tǒng)的輸入信號進行監(jiān)測和調(diào)整,以實現(xiàn)期望的輸出狀態(tài)或目標。自動控制的基本方式三種:開環(huán)控制、閉環(huán)控制和神經(jīng)網(wǎng)絡控制。 第一基本方式
    的頭像 發(fā)表于 01-17 09:38 ?3551次閱讀

    分布式鎖的三種實現(xiàn)方式

    分布式鎖的三種實現(xiàn)方式? 分布式鎖是在分布式系統(tǒng)中用于實現(xiàn)對共享資源進行訪問控制的一機制。分布式鎖的實現(xiàn)需要考慮高可用性、高性能和正確性等方面的問題。在實際應用中,有多種不同的方式
    的頭像 發(fā)表于 12-28 10:01 ?895次閱讀

    伺服電機的三種控制方式 如何確定選擇伺服電機控制方式

    伺服電機的三種控制方式 如何確定選擇伺服電機控制方式? 伺服電機是一能夠根據(jù)輸入信號實時調(diào)整轉速和位置的電動機。它通常用于需要高精度、高效率、高可靠性的工業(yè)領域,如機床、機器人、印刷
    的頭像 發(fā)表于 12-26 14:02 ?1600次閱讀
    主站蜘蛛池模板: 迈开腿让我看下你的小草莓声音| 男女XX00上下抽搐动态图| 麻豆AV久久AV盛宴AV| 秋霞电影网伦大理电影在线观看| 亚洲 欧美 中文 日韩 另类| 中文字幕精品AV内射夜夜夜| 成人特级毛片| 后入到高潮免费观看| 欧美精品一区二区三区四区 | 色欲色香天天天综合| 亚洲精品无码国产爽快A片百度| 2020国产成人精品视频人| 俄罗斯aaaaa一级毛片| 九九热在线视频| 日本高清免费一本视频在线观看| 亚洲欧美日韩国产另类电影 | 99视频免费看| 国产精品一区二区三区四区五区 | 在线亚洲色拍偷拍在线视频| 嘟嘟嘟WWW免费高清在线中文| 近亲乱中文字幕| 秋霞在线观看视频一区二区三区| 亚洲日本天堂在线| 豆奶视频在线高清观看| 菊地凛子av| 亚洲 日韩 在线 国产 视频| chinese黑人第一次| 交换年轻夫妇HD中文字幕| 日韩高清在线亚洲专区| 中文人妻熟妇精品乱又伧| 国产特级毛片AAAAAAA高清| 欧美s00老人| 一个人免费完整观看日本| 国产成人在线小视频| 蜜柚影院在线观看免费高清中文 | 伊人久久大香线蕉综合亚洲| 国产成人在线观看免费网站| 欧美激情精品久久久久| 在线观看成年人免费视频| 国产午夜AV无码无片久久96| 日本VA在线视频播放|