"检查位标志"是如何工作的?

3

我看过其他关于这个问题的提问,但它们没有回答我的问题。

在下面的代码中,我明白它检查那个位是否设置了,但我的问题是为什么要这么做?

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

我不明白为什么它返回一个bool类型并且可以工作,flag是uint8_t类型且1 << 4应该是这样的00010000(我想)。为什么该代码会返回所需单个位的值而不是最右边的或类似的值?


你能选择一种编程语言吗?你是在使用 C 还是 C++?看起来像是 C++,但我想确认一下。 - Shafik Yaghmour
1
@KarolyHorvath:看到使用bool关键字,我会认为C与此无关。 - PlasmaHH
1
@PlasmaHH: #include <stdbool.h>。C++的提示是按引用传递(顺便说一下,在这里没有意义),但除此之外,两种语言的答案是相同的。 - Karoly Horvath
3
那还不包括标题中的 C++ 呢。 :) - ctor
是的,我正在使用C++。对于造成的困惑,我很抱歉。 - LuissRicardo
4个回答

6

C++草案标准的第4.12布尔转换指出(重点在此):

算术、未作用域枚举、指针或成员指针类型的prvalue可以转换为bool类型的prvalue。零值、空指针值或空成员指针值转换为false;任何其他值转换为true。对于直接初始化(8.5),std::nullptr_t类型的prvalue可以转换为bool类型的prvalue;结果值为false。

因此,任何非零值都将被转换为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, 因为按位与只有在两个操作数的位都为1时才将一个位设置为1,因此flag & (1 << 4)的结果只有当flag的第五个位也是1时才会是非零


我以前已经点赞过了,但提到 std::bitset 至少值得再加一个赞 ;) ... - πάντα ῥεῖ
2
谢谢,我现在明白了。那个功能确实很有用。 - LuissRicardo

3

一个int可以转换为一个bool。如果它的值是零,转换后的值是false,否则它是true。 自己来试一下:

bool f = 0;
bool t = 5;

整型、浮点型、无作用域枚举类型、指针类型和成员指针类型的 prvalues 可以被转换为 bool 类型的 prvalues。

值为零(对于整型、浮点型和无作用域枚举类型)以及空指针和空成员指针值变为 false。所有其他值变为 true。

参见:cppreference


1
注意:您会经常看到这个用法,特别是形如if (integer)的表达式。 - Karoly Horvath
谢谢,即使我已经使用它了,但只使用1true)或0false),我不知道0代表false,而其他任何值都代表true - LuissRicardo

2

&运算符执行按位布尔AND操作。这意味着仅当两个输入都设置了一个位时,最终输出中才会设置该位,例如:

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

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

因此,如果您使用的掩码只有一个位被设置,如果该位未被设置,则它将返回0,如果已设置,则返回非零值,例如:

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

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

那么,由于C++在转换为布尔值时将任何非零值视为true,将零视为false,因此该函数有效。

0

由于这也被标记为C,C99有如下规定:

6.3.1.2 布尔类型

1 当任何标量值被转换为_Bool时,如果该值与0相等,则结果为0;否则,结果为1。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接