"Побитовые и" и левая прокладка в C ++
-
01-10-2019 - |
Вопрос
У меня есть макрос, который выглядит что-то подобное:
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
Решение
В C ++ постоянна с ведущим 0
это восьмеричная постоянная, а не десятичная постоянная. Это все еще целочисленное постоянное, но 070 == 56
.
Это причина разницы в поведении.
Другие советы
Нет, дополнительно 0 означает число читается как восьмеричный (база 8). Это означает, что он не говорит 70, но 56:
0000 0000 0001 0000 '16
0000 0000 0011 1000 & '56
-------------------
0000 0000 0001 0000
Подготовка 070
с А. 0
Как будто вы делаете, говорит компилятору интерпретировать его как восьмеричное, а не десятичное. Вы, вероятно, хотите сказать 70
.
Как другие сказали, 070
восьмеричный (и 0x70
шестнадцатеричная) постоянная, где находится ваша проблема.
Я хотел бы добавить, однако, что вы должны использовать inline
Функции вместо макросов:
inline int Foo(int x) { return (x - '!' & 070); }
C ++ много сделал, чтобы позволить нам избавиться от препроцессора для многих вещей, потому что это плохое, плохое вещество и опасно. Если вы можете обойтись без этого, сделайте это.
(И если вы используете его, по крайней мере, похудеть на тех, кто должен иметь дело с вашим кодом, чтобы сделать MACROS All-opturge.)