關於c語言中+和|的區別
當我們在coding的時候,使用兩個變數相加的情況,或者用 +,或者用 | ,都是沒有問題,比如:
0x1000 + 0x55 = 0x1055
0x1000 | 0x55 = 0x1055
介於以前這種固有的思維,因此沒有把其中不同仔細考慮,直到這幾天的bug,才恍然大悟,還是因為基礎知識的不紮實和習慣性的思維導致這個bug,不過也給我了乙個機會,徹底的搞清楚這兩個運算子在變數相加的時候的區別。
因為code是這麼定義的:
#define pci_addr(bus,device,func,reg) (uint64)(bus<<24 + device<<16 + func<<8 + reg ) & 0x00000000ffffffff
#define dram_pci pci_addr(0,0,3,0)
uint64 addr;
假如我要訪問暫存器0x55
(1) addr = dram_pci + 0x55;
(2) addr = dram_pci | 0x55;
那麼請問(1)和(2)相等嗎?
答案是: (1) addr = 0;
(2) addr = realvalue;
那麼為什麼在(1)中,addr = 0呢,問題還是出在pci_addr這個巨集定義上:
因為巨集定義最後做了乙個與運算,所以在之後的運算中就需要和 + 或者 | 進行優先順序的比較,由於+ 》 & 》 | ,因此當使用 | 的時候,就不會出現問題,能夠和我們想要的運算一致;當使用 + 的時候,由於 + 比 & 優先順序高,因此就率先計算了 0x00000000ffffffff + 0x55,導致得到了新值 0x0000000100000054,然後和之前的數值進行 &, 不就得到了 0 嘛
所以得到的經驗教訓:
1)在複雜的定義面前不能想當然的去使用自己認為沒有問題的運算子,因為檢查這個問題可不是這麼容易找到根源的。
2)在進行巨集定義的時候最好給整個巨集加上括號,那麼就可以避免很多優先順序的問題,因為呼叫這個巨集的人可能多種多樣。
3)盡可能的使用最簡單的運算子進行coding,可以避免一些問題,當然如果反覆呼叫的情況下,還是需要定義巨集,當然定義要慎重,參考2)
4)基礎很重要啊,要能快速的找到問題的根源還是需要熟悉各種運算子的優先順序,這次又好好的複習了一下。
順便附上c語言中常用運算子的優先順序:
1 () -> . :: ! ~ ++ --
2 - (unary) * (dereference) & (address of) sizeof
3 ->* .*
4 * (multiply) / %
5 + -
6 << >>
7 < <= > >=
8 == !=
9 & (bitwise and)
10 ^
11 |
12 &&
13 ||
14 ? :
15 = += -= etc.
16 ,
c語言中「 」和「 」區別
乙個豎槓 表示運算的或 二個豎槓 表示邏輯的或 c語言的位運算 取反,0取反是1,1取反是0 是左移,比如1 右移,類似左移,數值大小除以2的n次方 按位與,1與任意數等於任意數本身,0與任意數等於0,即1 x x,0 x 0 按位或,x y中只要有乙個1則結果為1 按位異或,x y相等則為0,不等...
C語言中 和 的區別
實際執行的時候沒有區別,中間的內容都是乙個字串 include include 比較兩個字串的內容,輸出相同的字元,第二個字串中 通配任意字元,直到兩字串有相同的字元 請按照要求實現下列函式 void findinstr const char pin,const char pkey,char pou...
C語言中 和「」的區別
例如你使用的是turboc include 代表編譯時直接在turboc軟體設定指定的路徑 預設是turboc所在資料夾下的include資料夾 中尋找裡面是否有stdlib.h的庫檔案。如果有,直接載入 如果沒有,報錯 無法找到庫檔案 include stdlib.h 代表編譯時先尋找你正在編輯的...