„Logisches Und“ und Links Padding in C ++
-
01-10-2019 - |
Frage
Ich habe ein Makro, das in etwa so aussieht:
Foo(x) ((x - '!') & 070)
Wenn ich den folgenden Code aufrufen:
Foo('1') => 16
Allerdings, wenn ich den folgenden Code aufrufen:
(('1' - '!') & 70) => 0
Also meine Frage ist, was ist denn hier los? Warum funktioniert x & 070
berechnen zu x
aber x & 70
berechnet auf 0?
Meine Vermutung ist, dass die zusätzlichen 0 auf der linken Seite 60 zwingen 2 Bytes zu nehmen statt 1. In diesem Fall würde das bitweise nicht & sein folgt wie?
0000 0000 0001 0000 '16
0000 0000 0100 0110 & '70
-------------------
0000 0000 0000 0000
Lösung
In C ++, eine Konstante mit einem führenden 0
ist eine oktale Konstante, kein Dezimalkonstante. Es ist noch eine ganze Zahl konstant, sondern 070 == 56
.
Dies ist die Ursache für den Unterschied im Verhalten.
Andere Tipps
Nein, die zusätzliche 0 bedeutet die Zahl als Oktal gelesen (Basis 8). Das heißt nicht sagen, dass es nicht 70, sondern 56:
0000 0000 0001 0000 '16
0000 0000 0011 1000 & '56
-------------------
0000 0000 0001 0000
vorangestellter 070
mit einem 0
wie Sie tun, teilt den Compiler als Oktal zu interpretieren, nicht dezimal. Sie wollen wahrscheinlich 70
sagen.
Wie bereits gesagt, 070
ein oktaler (und 0x70
einen hexadezimalen) konstant, was wo ist dein Problem liegt.
Ich möchte aber hinzufügen, dass Sie inline
Funktionen anstelle von Makros verwenden sollte:
inline int Foo(int x) { return (x - '!' & 070); }
C ++ hat viel dafür getan, damit wir loswerden der Präprozessor für viele Dinge bekommen, denn es ist schlecht, schlecht benehmen, und gefährlich. Wenn Sie ohne es tun können, tun dies.
(Und wenn Sie es verwenden, zumindest die Gnade auf solche mit mit Ihrem Code behandeln später Makros zu machen alle Großbuchstaben).