你如何在C ++中使用按位标志?

时间:2009-02-13 18:05:09

标签: c++ bit-manipulation

根据this网站,我希望代表一个具有16位整数的二维数组的迷宫。

每个16位整数需要包含以下信息:

  

这是一种方法(这绝不是唯一的方法):12x16迷宫网格可以表示为16位整数的数组m [16] [12]。每个数组元素都包含网格中单个相应单元格的所有信息,整数位映射如下:

     

alt text
  (来源:mazeworks.com

     

要击倒墙壁,设置边框或创建特定路径,我们需要做的就是在一个或两个数组元素中翻转位。

如何在16位整数上使用按位标志,这样我就可以设置这些位中的每一位并检查它们是否已设置。

我想以易读的方式(即Border.W,Border.E,Walls.N等)来实现。

这通常是如何在C ++中完成的?我是否使用十六进制表示每一个(即Walls.N = 0x02,Walls.E = 0x04等)?我应该使用枚举吗?


另见How do you set, clear, and toggle a single bit?

8 个答案:

答案 0 :(得分:9)

如果你想使用位域,那么这是一个简单的方法:

typedef struct MAZENODE
{
    bool backtrack_north:1;
    bool backtrack_south:1;
    bool backtrack_east:1;
    bool backtrack_west:1;
    bool solution_north:1;
    bool solution_south:1;
    bool solution_east:1;
    bool solution_west:1;
    bool maze_north:1;
    bool maze_south:1;
    bool maze_east:1;
    bool maze_west:1;
    bool walls_north:1;
    bool walls_south:1;
    bool walls_east:1;
    bool walls_west:1;
};

然后你的代码可以测试每个代码的真或假。

答案 1 :(得分:8)

使用std::bitset

答案 2 :(得分:3)

如果您关心哪些特定位意味着什么,请使用十六进制常量/枚举和按位操作。

否则,使用C ++位域(但请注意,整数中位的排序将取决于编译器。)

答案 3 :(得分:2)

了解你的按位操作符:&amp ;, |,^和!。

在很多C / C ++文件的顶部,我看到用十六进制定义的标志来掩盖每个位。

#define ONE 0x0001

要查看某个位是否已打开,请将其与1打开。要将其打开,请将其与1.要切换为开关,请将其与1进行异或。

答案 4 :(得分:2)

要操作位组,您也可以使用....

std::bitset<N>

std::bitset<4*4> bits;
bits[ 10 ] = false;
bits.set(10);
bits.flip();
assert( !bits.test(10) );

答案 5 :(得分:1)

您可以按照建议使用十六进制标记或枚举,但最具可读性/自我记录的可能是使用所谓的“位域”(有关详细信息,Google为C++ bitfields)。

答案 6 :(得分:1)

是的好方法是使用十六进制十进制来表示位模式。然后使用按位运算符来操作16位整数。

例如:

if(x & 0x01){} // tests if bit 0 is set using bitwise AND
x ^= 0x02;     // toggles bit 1 (0 based) using bitwise XOR
x |= 0x10;     // sets bit 4 (0 based) using bitwise OR

答案 7 :(得分:0)

我不是bitset的忠实粉丝。在我看来,这只是打字更多。并且它无论如何都不会隐藏你正在做的事情。你仍然需要&amp; &安培;&安培; |位。除非你只挑选1位。这可能适用于小组旗帜。并不是说我们需要隐藏我们正在做的事情。但是课程的目的通常是为了让用户更轻松。我认为这堂课没有完成它。

比如说,你有一个带有64个标志的标志系统。如果你想测试..我不知道..其中39个如果陈述,看看他们是否都在...使用位域是一个巨大的痛苦。你必须全部输入..课程。我假设你只使用 位域功能,而不是混合和匹配方法。 bitset也是一样。除非我错过了类的东西..这很可能,因为我很少使用它..我没有看到你可以测试所有39个标志的方法,除非你输入洞的东西或诉诸“标准方法”(使用枚举标志列表或39位的一些定义值并使用bitsets&amp;&amp; operator)。根据您的方法,这可能会开始变得混乱。我知道.. 64个标志听起来很多。好吧它取决于你在做什么。就个人而言,我参与的大部分项目都依赖于旗帜系统。所以实际上...... 64并不是闻所未闻的。虽然16~32在我的经历中更为常见。我实际上正在帮助一个项目,其中一个标志系统有640位。它基本上是一个特权系统。因此将它们全部安排在一起是有道理的......但是......不可否认..我想稍微分解一下......但是......呃......我正在帮助......而不是创造。