博客專欄

        EEPW首頁 > 博客 > 7 年了,沒見過代碼中出現(xiàn)過兩個(gè)感嘆號(hào)

        7 年了,沒見過代碼中出現(xiàn)過兩個(gè)感嘆號(hào)

        發(fā)布人:魚鷹談單片機(jī) 時(shí)間:2022-01-09 來源:工程師 發(fā)布文章

        有半個(gè)多月沒更新筆記了,廣告少,動(dòng)力也明顯不足了,挺安逸的,畢竟最近魚鷹也有其它事情要忙,主業(yè)要緊。在此感謝大家的繼續(xù)關(guān)注!

        今天繼續(xù)更新一篇小短文,希望對(duì)你有幫助。

        int func(int temp)
        {
          return !!temp;
        }

        不知道你是否看過上面類似的代碼,兩個(gè)感嘆號(hào)出現(xiàn)在代碼中,難道代碼也有思想,也需要表達(dá)情感嗎?

        剛學(xué)習(xí) C語言的時(shí)候,你應(yīng)該經(jīng)??吹竭^ 1 個(gè)感嘆號(hào)的情況,比如:

        if(one != two)
        {
          .......
        }
        -----------------------------------------
        if(!temp)
        {
        ......
        }
        -----------------------------------
        typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
        -----------------------------------------
        one = !temp;

        但兩個(gè)感嘆號(hào)估計(jì)就很難見到了。

        魚鷹大學(xué)四年、工作三年都沒見過這種寫法,直到前段時(shí)間看 Linux 源碼,才接觸到,第一次看到時(shí)非常驚訝,怎么還有這種寫法?

        為什么要用兩個(gè)感嘆號(hào),作用是什么,只是為了表現(xiàn) C 語言的奇技淫巧嗎?

        仔細(xì)想過后才驚嘆其中的巧妙。

        假設(shè)一個(gè)字節(jié)變量 byte,可代表范圍 0~255,0 代表其中一種含義,1 ~255 代表另一種含義(你可能會(huì)問,怎么不直接用 0 和 1 表示,因?yàn)檫@個(gè)變量本身不只有 0 和 1,只是在另一個(gè)使用的地方才會(huì)只使用二值含義,總之會(huì)有這種情況)。

        如果我要用另一個(gè)變量 bit 來表示這兩種含義,一般情況我們會(huì)這么做:

        int func(unsigned char byte)
        {
          unsigned char bit;
          if(byte == 0)  {
            bit = 0;
          }
          else{
            bit = 1;
          }
          return bit;
        }

        更優(yōu)雅簡(jiǎn)單一點(diǎn)是這樣寫:

        int func(unsigned char byte)
        {
          bit = byte ? 1 : 0;
          return bit;
        }

        但不管哪一個(gè),都不如第一個(gè)簡(jiǎn)單高效。

        簡(jiǎn)單可以很容易看出來,高效何在?

        它不需要判斷語句(判斷語句在單片機(jī)中可能影響不是很大,但在有多級(jí)緩存的情況下,影響可能很大,這就是為什么 linux 中用 likely() 之類的進(jìn)行優(yōu)化)。

        這樣,不管原先的 byte 是什么值,都將變成 0 或 1。

        這樣一來,如果調(diào)用者使用如下方式:

        if(func() == 1)
        {
        }
        或者 
        if(func())
        {
        }

         都不會(huì)出現(xiàn)問題。

        對(duì)于負(fù)數(shù)也是如此,只要是為了把 0 單獨(dú)分開,都可以采用這種方式。

        這在底層開發(fā)中也非常實(shí)用。

        比如 GPIO 有個(gè)引腳號(hào)需要判斷是 0 或 1,一般這樣:

        bit =  (GPIOB->IDR & GPIO_Pin_4) >> 4;

        或者

        bit = (GPIOB->IDR & GPIO_Pin_4) ? 1 : 0;

        上一種確實(shí)也是不錯(cuò)的選擇,但是這里需要修改兩個(gè)地方,修改時(shí)很容易遺忘,所以不如下面這種簡(jiǎn)單:

        bit =  !!(GPIOB->IDR & GPIO_Pin_4);

        如果換個(gè) IO ,需要修改代碼時(shí),只要修改一次就搞定,相當(dāng)方便,所以建議大家使用上面那種方式獲取位的值。

        而從匯編的角度來看,兩次 ! 也只需要一條指令搞定:

        微信圖片_20220109183759.jpg

        效率不輸移位方式!

        *博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。



        關(guān)鍵詞: 單片機(jī)

        相關(guān)推薦

        技術(shù)專區(qū)

        關(guān)閉
        主站蜘蛛池模板: 彭州市| 彩票| 彭阳县| 沾化县| 普定县| 新泰市| 镇宁| 亚东县| 平泉县| 松江区| 长岛县| 遂宁市| 屏边| 定州市| 乌拉特前旗| 邮箱| 巩留县| 五台县| 屏边| 绿春县| 夏邑县| 平度市| 蓬溪县| 庆安县| 武威市| 瓮安县| 榆树市| 平利县| 阿尔山市| 清涧县| 六安市| 香格里拉县| 定襄县| 旌德县| 武鸣县| 观塘区| 镇沅| 曲阳县| 门源| 交口县| 平度市|