2010-07-01 20 views
5

Ho una macro che sembra qualcosa di simile:"Bitwise E" e Sinistra-Imbottitura in C++

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

Se chiamo il seguente codice:

Foo('1') => 16 

Tuttavia, se io chiamo la codice seguente:

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

Quindi la mia domanda è, cosa sta succedendo qui? Perché il calcolo x & 070 viene calcolato su x ma x & 70 su 0?

La mia ipotesi è che lo 0 in più a sinistra stia forzando 60 a prendere 2 byte anziché 1. In tal caso, il bit a bit & non sarebbe il seguente?

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

sapevo che la risposta a questa (0 prefix = costante ottale) ma non posso onestamente dico in più di 20 anni di programmazione in C, non l'ho mai visto usato. È solo una di quelle cose che sembra provenire da un periodo in cui sarebbe stato utile, forse qualcosa da fare con le macchine teletype o qualsiasi altra cosa. Come ragazzo incorporato, sono sempre seccato che non ci sia qualcosa come un prefisso "b" per le costanti binarie (sì, ho i miei modi per farlo in C & C++, peccato che non sia incorporato nella lingua). – Dan

risposta

12

In C++, una costante con un leader 0 è una costante ottale, non è una costante decimale. È ancora una costante intera ma 070 == 56.

Questa è la causa della differenza di comportamento.

+0

Grazie, mi aspettavo che fosse qualcosa di semplice, ma non mi ero reso conto di essere nella base sbagliata! – sohum

7

No, lo 0 in più significa che il numero viene letto come ottale (base 8). Ciò significa che non dice 70, ma 56:

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

Anteporre la 070 con una 0 come si sta facendo dice al compilatore di interpretarla come ottale, decimale non. Probabilmente vuoi dire 70.

3

Come altri hanno detto, 070 è una costante ottale (e 0x70 esadecimale), che è dove si trova il problema.

vorrei aggiungere, però, che si dovrebbe usare inline funzioni invece di macro:

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

C++ ha fatto molto per permetterci di sbarazzarsi del preprocessore per molte cose, perché è cattivo, inadatto al comportamento e pericoloso. Se puoi farne a meno, fallo.
(E se lo si utilizza, almeno la pietà di quelle che hanno a che fare con il codice più tardi per fare le macro tutto maiuscolo.)

+0

Il codice originale è stato effettivamente scritto da qualcun altro. Sto semplicemente portandolo in una lingua diversa. – sohum