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

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

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

3天內不再提示

帶參數宏定義易出現的隱藏bug和定義方式歸納

嵌入式那些事 ? 來源:嵌入式那些事 ? 2023-10-20 15:26 ? 次閱讀

宏定義尤其是帶參數的宏定義,特別容易出現一些隱藏問題,因為宏定義在預處理階段是按照定義原封不動的進行展開,此時如果展開之后涉及到運算符優先級的問題,那么隱藏bug就此出現。

這里我先列舉一個簡單的例子,然后歸納下帶參數宏定義對于括號使用的一些說明。

1.構造帶有隱藏bug的宏定義

下面定義兩個帶參數宏,MUL_TWO是將兩個數進行相乘,MUL_THREE是將三個數進行相乘。

#defineMUL_TWO(val1,val2)(val1*val2)
#defineMUL_THREE(x,y,z)(MUL_TWO(x,y)*z)

比如我這里計算2 * 3 * 4的運算結果,那么只需調用宏MUL_THREE(2, 3, 4)就可得到計算結果為:24,計算結果是正確的。但是如果將MUL_THREE(2, 3, 4)修改為MUL_THREE(1+1, 1+2, 1+3),此時的運算結果又是多少呢,很簡單,我們將這個宏進行展開,展開的過程如下所示:

MUL_THREE(1+1,1+2,1+3)=>(MUL_TWO(1+1,1+2)*1+3)
(MUL_TWO(1+1,1+2)*1+3)=>((1+1*1+2)*1+3)

然后我們計算下,得出結果是7,是不是計算錯誤了。

2.改造上述宏定義

這里的宏定義還是比較簡單的,并且大多數的小伙伴應該都知道在定義帶參數的宏時,參數需要使用括號括起來,那么我們改造下上述的宏,改造結果如下所示:

#defineMUL_TWO(val1,val2)((val1)*(val2))
#defineMUL_THREE(x,y,z)(MUL_TWO(x,y)*z)

此時再來對MUL_THREE(1+1, 1+2, 1+3)進行展開,展開的過程如下所示:

MUL_THREE(1+1,1+2,1+3)=>(MUL_TWO(1+1,1+2)*1+3)
(MUL_TWO(1+1,1+2)*1+3)=>(((1+1)*(1+2))*1+3)

然后我們計算下,得出結果是9,計算結果還是有問題。仔細檢查下宏定義,原來是對MUL_THREE宏的z沒有用括號括起來,這個問題也是比較容易犯的,修改好之后的宏如下所示:

#defineMUL_TWO(val1,val2)((val1)*(val2))
#defineMUL_THREE(x,y,z)(MUL_TWO(x,y)*(z))

此時再來對MUL_THREE(1+1, 1+2, 1+3)進行展開,展開的過程如下所示:

MUL_THREE(1+1,1+2,1+3)=>(MUL_TWO(1+1,1+2)*(1+3))
(MUL_TWO(1+1,1+2)*(1+3))=>(((1+1)*(1+2))*(1+3))

此時的計算結果就是沒問題的了。

這里我再提個問題,為什么你在MUL_THREE宏中,只使用括號括起了z,為啥x和y你不同等對待,確實哈,如果對于不是很熟悉的小伙伴,可能看到我說的情況,會毫不猶豫的也對x和y進行同樣的保護;也有的小伙伴看到我說的這個情況可能腦子里面就暈了。

3.帶參數宏定義對于括號使用的一些說明

其實不對x和y做保護是有一個前提的,那就是你所定義的每一個宏定義都要確保對在當前宏中使用到的參數用括號進行保護。不知道各位明白我的意思不,不明白的話,看看我下面的總結吧。

帶參數宏定義,對于括號何時使用的總結:

(1).帶參數宏定義,如果參數在當前的宏中有進行運算,那么必須對該參數使用括號括起來(類似例子中MUL_THREE里面的z,MUL_TWO里面的val1和val2);

(2).帶參數宏定義,如果參數沒有在當前的宏中有進行運算,而是直接當成參數傳遞給其他的宏,那么該參數是不用使用括號進行保護的(類似例子中MUL_THREE里面的x和y)。

對于上面的總結第(2)點,能夠對傳遞給其他宏的參數不進行括號保護是因為總結的第(1)點已經對宏做了一個規定,只要所有的宏定義都按照第(1)點進行書寫,那么第(2)點自然也就不會出什么問題。







審核編輯:劉清

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

    關注

    180

    文章

    7605

    瀏覽量

    136905
  • Mul
    Mul
    +關注

    關注

    0

    文章

    5

    瀏覽量

    7959
  • 宏定義
    +關注

    關注

    0

    文章

    50

    瀏覽量

    9023

原文標題:C語言-帶參數宏定義易出現的隱藏bug和定義方式歸納

文章出處:【微信號:嵌入式那些事,微信公眾號:嵌入式那些事】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    C語言定義使用技巧

    寫好C語言,漂亮的定義很重要,使用定義可以防止出錯,提高可移植性,可讀性,方便性等等。下面列舉一些成熟軟件中常用的
    發表于 07-29 09:35 ?1117次閱讀

    C語言定義與枚舉類型知識

    定義的標識符不占內存,只是一個臨時的符號,預編譯后這個符號就不存在了。在簡單的程序使用參數定義可完成函數調用的功能,又能減少系統開銷,
    發表于 10-11 17:34 ?1608次閱讀

    C語言中常用的定義

    寫好C語言,漂亮的定義很重要,使用定義可以防止出錯,提高可移植性,可讀性,方便性等等。下面列舉一些成熟軟件中常用的
    發表于 10-18 10:05 ?1683次閱讀

    請問FLASH 的定義是如何定義的?為什么?

    ,"ramfuncs");#pragma CODE_SECTION(OffsetISR,"ramfuncs");#endif但是這個FLASH 的定義不知在哪里進行
    發表于 06-11 07:42

    C語言定義使用技巧

    寫好C語言,漂亮的定義很重要,使用定義可以防止出錯,提高可移植性,可讀性,方便性 等等。下面列舉一些成熟軟件中常用得
    發表于 11-13 12:04 ?36次下載

    內聯函數和定義的區別介紹

    定義是C語言提供的三種預處理功能的其中一種,這三種預處理包括:定義、文件包含、條件編譯。定義
    發表于 12-15 15:33 ?2339次閱讀
    內聯函數和<b class='flag-5'>宏</b><b class='flag-5'>定義</b>的區別介紹

    不帶參數定義是什么?不帶參數定義的資料介紹詳細過程概述

    c語言中有一個定義,其中有一類就是不帶參數定義
    發表于 09-04 15:38 ?5次下載

    當使用參數調用時,會將參數替換為主體

    在大多數定義示例中,每次出現參數名稱都帶有括號,并且另一對括號通常會包圍整個
    的頭像 發表于 11-16 16:41 ?2334次閱讀

    對于定義與重復定義的問題

    對于定義與重復定義的問題
    發表于 11-29 18:21 ?1次下載
    對于<b class='flag-5'>宏</b><b class='flag-5'>定義</b>與重復<b class='flag-5'>定義</b>的問題

    C語言定義--單片機中斷

    在單片機中斷中可以使用定義代替函數,減小系統運行時間。1.參數定義的優點:用
    發表于 01-13 12:52 ?6次下載
    C語言<b class='flag-5'>宏</b><b class='flag-5'>定義</b>--單片機中斷

    C語言中的定義

    #define命令是C語言中的一個定義命令,它用來將一個標識符定義為一個字符串,該標識符被稱為名,被定義的字符串稱為替換文本。命令有兩種
    的頭像 發表于 09-28 16:05 ?3464次閱讀
    C語言中的<b class='flag-5'>宏</b><b class='flag-5'>定義</b>

    C語言定義的使用原理

    使用STM32開發的朋友不知道是否有發現過這樣的一些定義
    的頭像 發表于 02-01 14:36 ?1610次閱讀

    c語言定義可以嵌套嗎?

    某些代碼或表達式替換為指定的字符串,從而使程序更加靈活和可讀性更高。定義的語法形式為: #define 名(參數列表) 體 其中,
    的頭像 發表于 09-04 17:38 ?3193次閱讀

    c語言參數定義

    c語言參數定義? C語言定義是一種替換機制
    的頭像 發表于 09-04 17:45 ?2429次閱讀

    define定義

    define定義 以#號開頭的都是編譯預處理指令,它們不是C語言的成分,但是C程序離不開它們,#define用來定義一個,程序在預處理階段將用define
    的頭像 發表于 11-24 15:35 ?887次閱讀
    主站蜘蛛池模板: 国产伦精品一区二区三区免费观看| 最近中文字幕完整版高清| 亚洲 欧美 国产 综合不卡| YELLOW视频直播在线观看高清| 伦理片在线3348| 中文字幕一区二区三区在线播放| 江苏电台在线收听| 亚洲 欧美 视频 手机在线 | 小夫妻天天恶战| 国产福利视频在线观看福利| 日日色在线影院| 古代荡女丫鬟高H辣文纯肉| 色呦呦人人视频| 国产精品ⅴ视频免费观看| 无套内射CHINESEHD熟女| 国产精品人妻无码久久久蜜桃| 泰国淫乐园实录| 国产伦精品一区二区三区精品| 亚洲精品高清AV在线播放| 精品午夜视频| 真实国产熟睡乱子伦对白无套| 免费精品国产人妻国语| rio 快播| 四虎永久精品视频在线| 国产精品自在在线午夜精品| 亚洲粉嫩美白在线| 久久久无码精品一区二区三区| 做a爱片的全过程| 琪琪热热色原日韩在线| 国产成人v视频在线观看| 亚洲 日韩 国产 制服 在线| 久久99AV无色码人妻蜜| 97伦理97伦理2018最新| 日韩精品 中文字幕 有码| 国产三级在线观看免费| 伊人AV一区二区三区夜色撩人| 男宿舍里的呻吟h| 国产电影尺度| 稚嫩挤奶h调教h| 日韩精品无码免费专区| 国产综合视频在线观看一区|