2010-07-01 52 views
5

我有一個宏,看起來是這樣的:「按位與」和左填充在C++

Foo(x) ((x - '!') & 070) 

如果我把下面的代碼:

Foo('1') => 16 

但是,如果我叫以下代碼:

(('1' - '!') & 70) => 0 

所以我的問題是,這是怎麼回事?爲什麼x & 070計算爲x,但x & 70計算爲0?

我的猜測是,左邊的額外0迫使60取2個字節而不是1.在這種情況下,不會按位進行如下操作&?

0000 0000 0001 0000  '16 
0000 0000 0100 0110 & '70 
------------------- 
0000 0000 0000 0000 
+0

我知道這個答案(0前綴=八進制常量),但我可以誠實地說,在20多年的C編程中,我從來沒有見過它被使用過。這只是其中一件似乎源於它有用的時間,可能與電傳打字機或其他類似的東西有關。作爲一個嵌入式的人,我總是嘲笑,沒有像二進制常量的'b'前綴(是的,我有我自己的方式在C和C++中這樣做,太糟糕了,它不是內置於該語言中)。 – Dan 2010-07-04 16:30:55

回答

12

在C++中,前導0的常量是八進制常數,而不是十進制常量。它仍然是一個整數常量,但是070 == 56

這是造成行爲差異的原因。

+0

謝謝,我希望它是直截了當的,但沒有意識到我是在錯誤的基地! – sohum 2010-07-01 18:25:42

7

不,額外0表示數字被讀爲八進制(基數8)。這意味着它不說70,但56:

0000 0000 0001 0000  '16 
0000 0000 0011 1000 & '56 
------------------- 
0000 0000 0001 0000 
3

前面加上0700像你正在做的是告訴編譯器將其解釋爲八進制,不是小數。你可能想說70

3

正如別人所說,070是一個八進制(和0x70十六進制)常量,這是你的問題所在。

我想補充,雖然,你應該使用inline函數而不是宏:

inline int Foo(int x) { return (x - '!' & 070); } 

C++已經做了很多讓我們擺脫了預處理對很多事情的,因爲它是不好,行爲不端,危險。如果沒有它,你可以這樣做。 (如果你使用它,至少要對那些稍後處理你的代碼的人施加憐憫,以使宏全部爲大寫。)

+0

原始代碼實際上是由其他人編寫的。我只是將它移植到另一種語言。 – sohum 2010-07-01 18:26:23