chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

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

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

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

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

璟琰乀 ? 來源:大魚機器人 ? 作者:大魚機器人 ? 2020-12-22 15:49 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1. 函數(shù)宏介紹

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

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

#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)系本站處理。 舉報投訴
  • 編程
    +關注

    關注

    90

    文章

    3723

    瀏覽量

    97424
  • 函數(shù)
    +關注

    關注

    3

    文章

    4421

    瀏覽量

    67815
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    ATE系統(tǒng)中這三種測量卡的架構和功能

    測試儀行業(yè)面臨的一個挑戰(zhàn)是,如何在不顯著增加測試儀時間、尺寸或成本的情況下,滿足對大量測試通道的需求。盡管半導體測試儀(也稱為自動測試器件(ATE))種類繁多,但在大多數(shù)測試儀都包含三種主要卡:電壓
    的頭像 發(fā)表于 04-09 15:12 ?110次閱讀
    ATE系統(tǒng)中這<b class='flag-5'>三種</b>測量卡的架構和功能

    AI技術時代三種全新工作模式如何實現(xiàn)

    AI技術正在重塑我們的工作。前沿企業(yè)以“人類主導、智能體運營”為核心,形成三種AI技術的融合模式:人類+AI技術助手、人機混合、人類主導智能體運營,這些模式不僅提升效率,更在重構協(xié)作方式,幫助組織以更低的阻力邁向成功。
    的頭像 發(fā)表于 01-29 15:08 ?716次閱讀

    C語言中實現(xiàn)函數(shù)三種方式

    的第一個分號后便結束。即 a = b 和 b = tmp 均不受控制語句所作用。 因此,在工程中,一般使用三種方式來對函數(shù)進行
    發(fā)表于 12-29 07:34

    請問CW32芯片的三種工作模式是什么?

    CW32芯片的三種工作模式是什么?
    發(fā)表于 12-26 06:48

    星海FR系列三種封裝快恢復二極管DO-15、DO-201AD、R-6的全面對比與應用解析

    星海FR系列快恢復二極管憑借其卓越的性能和多樣化的封裝形式,深受工程師和電子愛好者的青睞。這里,星海授權代理商南山電子將對對星海FR系列三種封裝快恢復二極管:DO-15、DO-201AD、R-6
    的頭像 發(fā)表于 12-18 16:25 ?727次閱讀
    星海FR系列<b class='flag-5'>三種</b><b class='flag-5'>封裝</b>快恢復二極管DO-15、DO-201AD、R-6的全面對比與應用解析

    星海SK系列肖特基二極管SMBG、SMBX、SMC三種封裝選型建議

    本文將帶來星海SK系列肖特基二極管SMBG、SMBX、SMC三種封裝選型建議,幫助您為項目選擇最合適的器件。SMBG封裝尺寸適中:體積相對較小,適合在空間有限的P
    的頭像 發(fā)表于 10-16 16:08 ?2625次閱讀
    星海SK系列肖特基二極管SMBG、SMBX、SMC<b class='flag-5'>三種</b><b class='flag-5'>封裝</b>選型建議

    伺服電機的三種制動方式有什么區(qū)別?

    伺服電機作為自動化控制系統(tǒng)中執(zhí)行元件的核心部件,其制動性能直接影響設備的定位精度和安全可靠性。目前主流的伺服電機制動方式包括動態(tài)制動、再生制動和電磁機械制動三種,它們在制動原理、應用場景及技術特點上
    的頭像 發(fā)表于 09-19 18:26 ?2135次閱讀
    伺服電機的<b class='flag-5'>三種</b>制動<b class='flag-5'>方式</b>有什么區(qū)別?

    TC377配置SMU FSP時,如何配置頻率參數(shù);三種模式有何區(qū)別,配置上有何區(qū)別?

    TC377配置SMU FSP時,如何配置頻率參數(shù);三種模式有何區(qū)別,配置上有何區(qū)別?
    發(fā)表于 08-08 07:48

    三種SPWM波形生成算法的分析與實現(xiàn)

    摘要:變頻技術作為現(xiàn)代電力電子的核心技術,集現(xiàn)代電子、信息和智能技術于一體。而SPW(正弦波脈寬調(diào)制)波的產(chǎn)生和控制則是變頻技術的核心之一。本文對SPI波形生成的三種算法-對稱規(guī)則采樣法、不對稱規(guī)則
    發(fā)表于 07-31 13:34

    C語言中的內(nèi)聯(lián)函數(shù)

    在C編程中,內(nèi)聯(lián)函數(shù)都用于避免函數(shù)調(diào)用的開銷并編寫可復用的邏輯部分,但它們在工作方式和安全性方面存在顯著差異。
    的頭像 發(fā)表于 07-25 15:10 ?2043次閱讀
    C語言中的內(nèi)聯(lián)<b class='flag-5'>函數(shù)</b>與<b class='flag-5'>宏</b>

    MEMS中的三種測溫方式

    在集成MEMS芯片的環(huán)境溫度測量領域,熱阻、熱電堆和PN結原理是三種主流技術。熱阻是利用熱敏電阻,如金屬鉑或注入硅的溫度電阻系數(shù)恒定,即電阻隨溫度線性變化的特性測溫,電阻變化直接對應絕對溫度,需恒流源供電。
    的頭像 發(fā)表于 07-16 13:58 ?1866次閱讀
    MEMS中的<b class='flag-5'>三種</b>測溫<b class='flag-5'>方式</b>

    1553B總線常見三種組網(wǎng)方式

    1553B總線作為航空電子系統(tǒng)中的關鍵通信協(xié)議,其組網(wǎng)方式直接影響系統(tǒng)的可靠性和實時性。本文將深入解析1553B總線的三種典型組網(wǎng)結構:單總線結構、雙冗余總線和多總線分層架構,并結合實際應用場景分析
    的頭像 發(fā)表于 06-21 17:39 ?2387次閱讀
    1553B總線常見<b class='flag-5'>三種</b>組網(wǎng)<b class='flag-5'>方式</b>

    開關電源三種控制模式:PWM/PFM/PSM

    摘要 本文詳細介紹了開關電源的三種主要調(diào)制方式:PWM(脈沖寬度調(diào)制)、PFM(脈沖頻率調(diào)制)和PSM(脈沖跨周期調(diào)制)。PWM通過調(diào)整脈沖寬度保持恒定頻率,適用于重負載,但輕負載效率低。PFM則在
    發(fā)表于 06-09 16:11

    HarmonyOS基礎組件:Button三種類型的使用

    中的Button相較于Android原生來說,功能比較豐富,擴展性高,減少了開發(fā)者的代碼數(shù)量,簡化了使用方式。不僅可以自定義圓角還支持三種樣式。 常用屬性 名稱 參數(shù)類型 描述 type
    的頭像 發(fā)表于 06-09 15:48 ?2694次閱讀
    HarmonyOS基礎組件:Button<b class='flag-5'>三種</b>類型的使用

    介紹三種常見的MySQL高可用方案

    在生產(chǎn)環(huán)境中,為了確保數(shù)據(jù)庫系統(tǒng)的連續(xù)可用性、降低故障恢復時間以及實現(xiàn)業(yè)務的無縫切換,高可用(High Availability, HA)方案至關重要。本文將詳細介紹三種常見的 MySQL 高可用
    的頭像 發(fā)表于 05-28 17:16 ?1418次閱讀