«Побитовое И» и Левый отступ в C ++ - PullRequest
5 голосов
/ 01 июля 2010

У меня есть макрос, который выглядит примерно так:

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

Ответы [ 4 ]

12 голосов
/ 01 июля 2010

В C ++ константа с ведущим 0 является восьмеричной константой, а не десятичной константой. Это все еще целочисленная константа, но 070 == 56.

Это причина различий в поведении.

7 голосов
/ 01 июля 2010

Нет, дополнительный 0 означает, что число читается как восьмеричное (основание 8). Это означает, что это не говорит 70, но 56:

0000 0000 0001 0000     '16 
0000 0000 0011 1000 &   '56
------------------- 
0000 0000 0001 0000 
3 голосов
/ 01 июля 2010

Как говорили другие, 070 - это восьмеричная (и 0x70 шестнадцатеричная) константа, в которой и заключается ваша проблема.

Я хотел бы добавить, что вы должны использовать inline функции вместо макросов:

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

C ++ многое сделал для того, чтобы мы могли избавиться от препроцессора для многих вещей, потому что это плохо, плохо себя ведет и опасно. Если вы можете обойтись без этого, сделайте это.
(И если вы используете его, по крайней мере, помилуйте тех, кто будет иметь дело с вашим кодом позже, чтобы сделать макросы полностью прописными.)

3 голосов
/ 01 июля 2010

Добавление 070 к 0, как вы делаете, говорит компилятору интерпретировать его как восьмеричное, а не десятичное число.Вы, вероятно, хотите сказать 70.

...