2014-01-28 2 views
3

Я читал другие вопросы об этом, но они не отвечают на мой вопрос.Как это работает «флажок проверки бита»

В следующем коде я понимаю, что он проверяет, установлен ли этот бит, но почему мой вопрос?

bool test(uint8_t& flag) 
{ 
    return flag & (1 << 4); 
} 

Я не понимаю, почему она возвращает bool и она работает, флаг uint8_t и 1 << 4 должно быть что-то вроде этого 00010000 (я думаю). Почему этот код возвращает значение желаемого единственного бита, а не самого правого или что-то в этом роде?

+0

Вы можете выбрать язык, используя C или C++? Похоже, C++, но я хочу убедиться. –

+1

@KarolyHorvath: увидев использование ключевого слова bool, я бы предположил, что C здесь не имеет значения. – PlasmaHH

+1

@PlasmaHH: '#include '. подсказка C++ - это пропуск по ссылке (что, кстати, здесь не имеет смысла), но кроме того, ответ идентичен на обоих языках. –

ответ

6

C++ draft standard раздел 4.12булевых преобразования говорит (курсив моего):

prvalue арифметики, незаданное перечисление, указатель, или указатель на тип члена может быть преобразован в prvalue типа bool. Значение нуля, значение нулевого указателя или значение указателя нулевого элемента преобразуется в значение false; любое другое значение преобразуется в значение true. Для прямой инициализации (8.5) prvalue типа std :: nullptr_t может быть преобразовано в prvalue типа bool; результирующее значение ложно.

Таким образом, любое ненулевое значение будет преобразовано в true.

Вы выразили некоторые сомнения в результате 1 << 4 у нас есть быстрый способ проверить это с помощью std::bitset:

#include <bitset> 
#include <iostream> 

int main() 
{ 
    std::bitset<8> b1(1<<4); 

    std::cout << b1 << std::endl ; 

    return 0; 
} 

и мы можем видеть результат действительно 00010000 так bitwise and установить только немного, чтобы 1 если бит в обоих операндах равен 1, тогда результат flag & (1 << 4) будет только отличным от нуля, если битиз flag также является 1.

+0

Я выше, но упоминание 'std :: bitset' заслуживает, по крайней мере, еще одного;) ... –

+2

Спасибо, я понял это сейчас. Эта функциональность действительно полезна. – LuissRicardo

3

int можно преобразовать в bool. Если его значение равно нулю, преобразованное значение равно false, в противном случае оно равно true. Проверьте это yorself:

bool f = 0; 
bool t = 5; 

Prvalues ​​интегральной с плавающей точкой, незаданного перечисления, указателя и указатель на член типов может быть преобразован в prvalues ​​типа BOOL.

Значение 0 (для целых чисел, с плавающей запятой и без пробелов), а нулевой указатель и значения с нулевым указателем на элемент становятся ложными. Все остальные значения становятся истинными.

См: cppreference

+1

примечание: вы увидите, что это используется довольно сильно, особенно в форме 'if (integer)' –

+0

Спасибо, даже я использовал его, но только с '1' (' true') или '0' (' false '), Я не знал, что' 0' был 'false', а все остальное -' true'. – LuissRicardo

0

Поскольку это также помечено C, C99 это сказать:

6.3.1.2 Boolean type

1 Когда любое скалярное значение преобразуется в _Bool, результат равен 0, если значение сравнивается с 0; в противном случае результат равен 1.

2

Оператор & выполняет побитовое логическое И операцию. Это означает, что бит установлен в конечной продукции, если, и только если он установлен в обоих входах, так, например,

00011100 
& 01010101 
    -------- 
= 00010100 

    11010101 
& 01010101 
    -------- 
= 01010101 

Таким образом, если вы используете маску, которая имеет только один бит установлен он будет return 0, если этот бит не установлен, и отличным от нуля, если он установлен, например

11110111 
& 00001000 
    -------- 
= 00000000 

    00001111 
& 00001000 
    -------- 
= 00001000 

Тогда, так как C++ преобразует лечения любого ненулевого значения, как верно при преобразовании в bool и ноль как ложная функция работает.

Смежные вопросы