博客專欄

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

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

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

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

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

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

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

剛學習 C語言的時候,你應該經(jīng)常看到過 1 個感嘆號的情況,比如:

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

但兩個感嘆號估計就很難見到了。

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

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

仔細想過后才驚嘆其中的巧妙。

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

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

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

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

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

但不管哪一個,都不如第一個簡單高效。

簡單可以很容易看出來,高效何在?

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

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

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

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

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

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

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

比如 GPIO 有個引腳號需要判斷是 0 或 1,一般這樣:

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

或者

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

上一種確實也是不錯的選擇,但是這里需要修改兩個地方,修改時很容易遺忘,所以不如下面這種簡單:

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

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

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

微信圖片_20220109183759.jpg

效率不輸移位方式!

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



關鍵詞: 單片機

相關推薦

技術專區(qū)

關閉