日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

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

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

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

宏的高級用法

工程師 ? 來源:嵌入式軟件實戰(zhàn)派 ? 作者:嵌入式軟件實戰(zhàn)派 ? 2020-09-15 15:59 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

對于條件/分支處理的程序設計,我們慣性地會選擇switch-case或者if-else,這也是C語言老師當初教的。以下,我們用一個播放器的例子來說明,要實現(xiàn)的功能如下:

收到用戶操作播放器命令請求,如“播放”、“暫?!钡?,程序要對命令作區(qū)分;

針對不同的命令請求,作相應的處理;

輸出必要的輔助信息。

首先,將命令定義成enum類型:

enum { CMD_PLAY, CMD_PAUSE, CMD_STOP, CMD_PLAY_NEXT, CMD_PLAY_PREV, };

然后,用switch-case的分支處理:

switch(cmd) { case CMD_PLAY: // handle play command break; case CMD_PAUSE: // handle pause command break; case CMD_STOP: // handle stop command break; case CMD_PLAY_NEXT: // handle play next command break; case CMD_PLAY_PREV: // handle play previous command break; default: break; }

實際上,這也沒什么毛病。但是,時間長了,需求不斷變更,程序不斷迭代,這個switch-case會變得非常冗長而很難維護。你不相信?我曾經(jīng)見到過》1000行的類似這樣的代碼。如果讓你接手維護這樣的代碼,你內(nèi)心會不會狂奔著萬千***?

但是,我不敢更改這個祖?zhèn)鞯膕witch-case啊,那么小心翼翼地將這些命令處理封裝成函數(shù)。像這樣:

#define FUNC_IN() printf(“enter %s \r\n”, __FUNCTION__) void func_cmd_play(void* p) { FUNC_IN(); } void func_cmd_pause(void* p) { FUNC_IN(); } void func_cmd_stop(void* p) { FUNC_IN(); } void func_cmd_play_next(void* p) { FUNC_IN(); } void func_cmd_play_prev(void* p) { FUNC_IN(); } void player_cmd_handle(int cmd, void* p) { switch(cmd) { case CMD_PLAY: func_cmd_play(p); break; case CMD_PAUSE: func_cmd_pause(p); break; case CMD_STOP: func_cmd_stop(p); break; case CMD_PLAY_NEXT: func_cmd_play_next(p); break; case CMD_PLAY_PREV: func_cmd_play_prev(p); break; default: break; } }

后來,甲方還是不斷地更改需求,導致播放器的命令越來越多,幾十個上百個了……痛定思痛,我——要——改——革!!

解放switch-case/if-else

腦子里想來想去,度娘上翻來翻去,于是定義了個結(jié)構(gòu)體:

typedef void(*pFunc)(void* p); typedef struct { tCmd cmd; pFunc func; }tPlayerStruct; tPlayerStruct player_cmd_func[] = { {CMD_PLAY, func_cmd_play) }, {CMD_PAUSE, func_cmd_pause) }, {CMD_STOP, func_cmd_stop) }, {CMD_PLAY_NEXT, func_cmd_play_next) }, {CMD_PLAY_PREV, func_cmd_play_prev) }, }; #define ARR_LEN(arr)sizeof(arr)/sizeof(arr[0]) void player_cmd_handle(int cmd, void* p) { for(int i = 0; i 《 ARR_LEN(player_cmd_func); i++) { if(player_cmd_func[i].cmd == cmd && NULL != player_cmd_func[i].func) { player_cmd_func[i].func(p); break; } } }

咦?好像代碼簡潔了不少哦,改完之后好有成就感。

身為追求卓越的程序員,我還是有點不滿意,可不可以不用for循環(huán),直接使用player_cmd_func[cmd].func(p);,這樣還可以免去查詢的步驟,提高效率?

想法是好的,如果上面的程序不用for循環(huán),有可能數(shù)組越界,還有如果有命令增加,順序下標不對應的問題。

之前,我在《C語言的奇技淫巧之五》中的第50條提到過這個方法,還立了個flag,我要用MACRO寫個更高效更好的代碼!

使用X-MACRO

你聽說過X-MACRO么?聽過沒聽過都沒關(guān)系,來,我們一起耍起來!

MACRO或者說宏定義(書上或者規(guī)范上一般講預處理)基本原因都很簡單,看看就很容易學會??雌饋砗孟褚彩瞧降瓱o奇,似乎沒什么大作用。但是,你可別小看它,我們將其安上個“X”就很牛逼(不知道這個是啥傳統(tǒng),對于某些函數(shù)的擴展,喜歡在其前面或后面加個“X”,然后這個函數(shù)比之前的函數(shù)功能強大很多,Windows里面的Api就有這案例)。

X-MACRO是一種可靠維護代碼或數(shù)據(jù)的并行列表的技術(shù),其相應項必須以相同的順序出現(xiàn)。它們在至少某些列表無法通過索引組成的地方(例如編譯時)最有用。此類列表的示例尤其包括數(shù)組的初始化,枚舉常量和函數(shù)原型的聲明,語句序列和切換臂的生成等。X-MACRO的使用可以追溯到1960年代。它在現(xiàn)代C和C ++編程語言中仍然有用。

X-MACRO應用程序包括兩部分:

列表元素的定義。

擴展列表以生成聲明或語句的片段。

該列表由一個宏或頭文件(名為LIST)定義,該文件本身不生成任何代碼,而僅由一系列調(diào)用宏(通常稱為“ X”)與元素的數(shù)據(jù)組成。LIST的每個擴展都在X定義之前加上一個list元素的語法。LIST的調(diào)用會為列表中的每個元素擴展X。

好了,少扯淡,我們是實戰(zhàn)派,搞點有用的東西。

對于MACRO有幾個明顯的特征:

MACRO實際上就是做替換工作;

宏定義的替換工作是在編譯前進行的,即預編譯;

宏定義可以用undef取消,然后再重新反復定義。

我們就用這幾個特征把MACRO耍到牛X起來!

#define X(a,b)a int x = DEF_X(1,2); #undef DEF_X #define DEF_X(a,b)b int y = DEF_X(1,2);

從上面可以看到,這個x和y的值是不一樣的。

于是可以定義一個這樣的宏:

#define CMD_FUNC \ DEF_X(CMD_PLAY, func_cmd_play) \ DEF_X(CMD_PAUSE, func_cmd_pause) \ DEF_X(CMD_STOP, func_cmd_stop) \ DEF_X(CMD_PLAY_NEXT, func_cmd_play_next) \ DEF_X(CMD_PLAY_PREV, func_cmd_play_prev) \

CMD的enum可以這樣定義:

typedef enum { #define DEF_X(a,b) a, CMD_FUNC #undef DEF_X CMD_MAX }tCmd;

預編譯后,這實際上就是這樣的:

typedef enum { CMD_PLAY, CMD_PAUSE, CMD_STOP, CMD_PLAY_NEXT, CMD_PLAY_PREV, CMD_MAX }tCmd;

接著,我們按這種套路定義一個函數(shù)指針數(shù)組:

const pFunc player_funcs[] = { #define DEF_X(a,b) b, CMD_FUNC #undef DEF_X };

甚至,我們可以定義一個命令的字符串,以作打印信息用:

const char* str_cmd[] = { #define DEF_X(a,b) #a, CMD_FUNC #undef DEF_X };

只要這個DEF_X(a,b)里面的a和b是對應關(guān)系正確的,CMD_FUNC后面的元素順序是所謂了,這個比前面的結(jié)構(gòu)體有天然優(yōu)勢。這樣,我們就可以直接用下標開始操作了:

void player_cmd_handle(tCmd cmd, void* p) { if(cmd 《 CMD_MAX) { player_funcs[cmd](p); } else { printf(“Command(%d) invalid!\n”, cmd); } }

這不僅提高了效率,還不用擔心命令的順序問題。

這種X-MACRO的用法對分支結(jié)構(gòu),特別是消息命令的處理特別的方便高效。

以下附上該案例的完整測試源碼:

#include 《stdio.h》 #define FUNC_IN() printf(“enter %s \r\n”, __FUNCTION__) #define CMD_FUNC \ DEF_X(CMD_PLAY, func_cmd_play) \ DEF_X(CMD_PAUSE, func_cmd_pause) \ DEF_X(CMD_STOP, func_cmd_stop) \ DEF_X(CMD_PLAY_NEXT, func_cmd_play_next) \ DEF_X(CMD_PLAY_PREV, func_cmd_play_prev) \ typedef enum { #define DEF_X(a,b) a, CMD_FUNC #undef DEF_X CMD_MAX }tCmd; const char* str_cmd[] = { #define DEF_X(a,b) #a, CMD_FUNC #undef DEF_X }; typedef void(*pFunc)(void* p); void func_cmd_play(void* p) { FUNC_IN(); } void func_cmd_pause(void* p) { FUNC_IN(); } void func_cmd_stop(void* p) { FUNC_IN(); } void func_cmd_play_next(void* p) { FUNC_IN(); } void func_cmd_play_prev(void* p) { FUNC_IN(); } const pFunc player_funcs[] = { #define DEF_X(a,b) b, CMD_FUNC #undef DEF_X }; void player_cmd_handle(tCmd cmd, void* p) { if(cmd 《 CMD_MAX) { player_funcs[cmd](p); } else { printf(“Command(%d) invalid!\n”, cmd); } } int main(void) { player_cmd_handle(CMD_PAUSE, (void*)0); player_cmd_handle(100, (void*)0); return 0; }

留個作業(yè)題:

如何靈活地將一個結(jié)構(gòu)體的內(nèi)容系列化到一個數(shù)組中,以及如何將一個數(shù)組的內(nèi)容解系列化到結(jié)構(gòu)體中?

例如,將以下結(jié)構(gòu)體s的內(nèi)容copy到data中(別老想著memcopy哦):

typedef struct STRUCT_DATA { int a; char b; short c; }tStruct;tStruct s; unsigned char data[100];

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

    關(guān)注

    5210

    文章

    20680

    瀏覽量

    337386
  • 宏匯編器
    +關(guān)注

    關(guān)注

    0

    文章

    7

    瀏覽量

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

掃碼添加小助手

加入工程師交流群

    評論

    相關(guān)推薦
    熱點推薦

    低成本鍵盤旋鈕開源項目介紹

    辦公切軟件、調(diào)參數(shù)太繁瑣?創(chuàng)作時控筆刷 / 縮放總找快捷鍵?商用鍵盤價格高,還難適配個性化操作需求?想自制鍵盤,卻遇設計復雜、組裝難度高的問題?
    的頭像 發(fā)表于 03-25 11:09 ?570次閱讀

    微科技首家歐洲全資子公司正式成立

    在國家積極鼓勵企業(yè)“走出去”及共建“一帶一路”倡議的宏大背景下,國內(nèi)功率半導體領域的領先企業(yè)——江蘇微科技股份有限公司(以下簡稱“微科技”)今日宣布,其首家歐洲全資子公司 MacMic
    的頭像 發(fā)表于 03-04 11:06 ?675次閱讀

    變頻器的特殊用法

    變頻器作為電力電子技術(shù)的重要應用設備,其核心功能是通過改變電源頻率實現(xiàn)對電機轉(zhuǎn)速的精確控制。然而在實際工業(yè)場景和創(chuàng)意應用中,工程師們早已突破傳統(tǒng)認知,開發(fā)出一系列令人驚嘆的特殊用法。這些創(chuàng)新實踐不僅拓展了變頻器的應用邊界,更展現(xiàn)了電力電子技術(shù)的無限可能。
    的頭像 發(fā)表于 03-03 17:08 ?624次閱讀

    龍芯中科與杉科技完成產(chǎn)品適配互認證

    近日,龍芯中科技術(shù)股份有限公司與杭州杉科技股份有限公司完成基于龍芯3C6000處理器平臺對杉分布式存儲系統(tǒng)的適配與性能驗證。測試結(jié)果表明,杉分布式存儲產(chǎn)品在龍芯3C6000平臺上運行穩(wěn)定、性能優(yōu)異,標志著雙方在國產(chǎn)自主計算
    的頭像 發(fā)表于 01-23 17:08 ?999次閱讀
    龍芯中科與<b class='flag-5'>宏</b>杉科技完成產(chǎn)品適配互認證

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

    1. 函數(shù)介紹 函數(shù),即包含多條語句的定義,其通常為某一被頻繁調(diào)用的功能的語句封裝,且不想通過函數(shù)方式封裝來降低額外的彈棧壓棧開銷。 函數(shù)本質(zhì)上為
    發(fā)表于 12-29 07:34

    微科技一舉斬獲兩項重磅行業(yè)大獎

    聚力創(chuàng)新動能,破局產(chǎn)業(yè)難題,領航技術(shù)前沿!近期深圳半導體與電源技術(shù)領域盛會密集,微科技攜旗下子公司上海微愛賽半導體有限公司(以下簡稱“微愛賽”)強勢亮相。憑借突出的技術(shù)實力與產(chǎn)品性能,
    的頭像 發(fā)表于 12-19 17:22 ?1040次閱讀
    <b class='flag-5'>宏</b>微科技一舉斬獲兩項重磅行業(yè)大獎

    泰科技與ADI正式簽署合作備忘錄

    近日,南京泰半導體科技股份有限公司(以下簡稱“泰科技”)與全球領先的高性能半導體公司ADI正式簽署合作備忘錄,雙方將在半導體測試與精密信號測量領域展開持續(xù)深度合作,共同推動高性能測試系統(tǒng)的技術(shù)創(chuàng)新與市場應用落地。
    的頭像 發(fā)表于 12-02 09:09 ?1727次閱讀

    C語言的printf基本用法介紹

    大家只需要掌握最基本的用法,以后隨著編程知識的學習,我們會逐步介紹更加高級用法,最終讓大家完全掌握 printf。
    發(fā)表于 11-12 07:04

    齊光多種不同封裝貼片發(fā)光管點亮多元應用新視界

    在當今快速發(fā)展的科技時代,貼片發(fā)光管憑借其體積小、功耗低、亮度高、色彩豐富等優(yōu)點,廣泛應用于各個領域。齊光多種不同封裝貼片發(fā)光管點亮多元應用新視界,為現(xiàn)代生活和工業(yè)生產(chǎn)帶來了諸多便利與創(chuàng)新。那么
    的頭像 發(fā)表于 10-17 16:51 ?1594次閱讀
    <b class='flag-5'>宏</b>齊光多種不同封裝貼片發(fā)光管點亮多元應用新視界

    SConscript結(jié)果與rtconfig.h中定義相反,是什么原因呢?

    當我在rtconfig.h中把定義注釋時,添加了構(gòu)建 當我取消定義注釋時,反而排除了構(gòu)建 SConscript結(jié)果與rtconfig.h中定義相反,是什么原因呢
    發(fā)表于 09-23 06:01

    干貨放送!集物流運輸沖擊記錄儀直播精選問答集錦,你想知道的都在這

    集技術(shù)主題直播于8月20日圓滿結(jié)束,感謝各位熱情參與!直播中,集科技高級技術(shù)工程師針畢工對不同物流運輸?shù)膶嶋H應用場景,為大家分析如何高效監(jiān)測運輸環(huán)境,保障貨物安全交付和厘清貨損責任。直播中,我們
    的頭像 發(fā)表于 09-02 17:03 ?996次閱讀
    干貨放送!<b class='flag-5'>宏</b>集物流運輸沖擊記錄儀直播精選問答集錦,你想知道的都在這

    干貨放送!集科技物聯(lián)網(wǎng)技術(shù)直播精選問答集錦,建議收藏!

    集直播圓滿結(jié)束,感謝各位熱情參與!直播上,集科技多位高級技術(shù)工程師針對不同產(chǎn)線的實際應用場景,為大家分析如何突破瓶頸,提高生產(chǎn)效率。直播中,我們收到了眾多提問,展現(xiàn)了大家對集物聯(lián)
    的頭像 發(fā)表于 08-08 18:24 ?685次閱讀
    干貨放送!<b class='flag-5'>宏</b>集科技物聯(lián)網(wǎng)技術(shù)直播精選問答集錦,建議收藏!

    景智駕再獲老股東追加投資

    近日,景智駕再次獲得老股東博將資本與衢州智遠的追加投資。在競爭激烈、技術(shù)迭代加速的市場環(huán)境下,此次支持彰顯了投資方對景智駕核心能力與長期發(fā)展?jié)摿Φ母叨日J可。
    的頭像 發(fā)表于 06-09 11:06 ?1001次閱讀

    Vicor助力發(fā)打造主動懸架電源系統(tǒng)

    廈門發(fā)電聲股份有限公司(發(fā))打造業(yè)內(nèi)性能卓越的主動懸架電源系統(tǒng),旨在將長期以來僅見于豪華車型的功能引入中端車型。發(fā)成功突破困擾知名汽車技術(shù)供應商幾十年的技術(shù)瓶頸,在滿足主動懸架系統(tǒng)對尺寸、重量及瞬態(tài)性能的嚴苛需求的同時,兼
    的頭像 發(fā)表于 06-04 15:24 ?1368次閱讀

    微科技2025供應商大會成功舉辦

    近日,以“協(xié)同·精進·共贏”為主題的微科技2025供應商大會在常州隆重召開。來自全國各地的專家和供應商伙伴們齊聚一堂,與微科技共同回顧合作成果,展望未來藍圖。
    的頭像 發(fā)表于 05-30 15:33 ?1107次閱讀
    临江市| 阳泉市| 军事| 林甸县| 班玛县| 施甸县| 襄汾县| 克什克腾旗| 铁岭县| 武夷山市| 永吉县| 木里| 延庆县| 新和县| 宁陵县| 芦山县| 白河县| 额敏县| 闽清县| 虹口区| 马鞍山市| 临泽县| 左权县| 九江县| 芦溪县| 萍乡市| 开封县| 乡城县| 廊坊市| 余姚市| 中西区| 延津县| 曲松县| 青州市| 芜湖县| 石门县| 洛阳市| 常德市| 黔东| 昌乐县| 忻城县|