如何表示状态标志以及如何使用按位 OR 来处理位标志?

Swi*_*nds 1 c++ fstream

如果我们打开一个文件进行读取,我们可能会定义一个或多个状态标志,例如:ios::out以及ios::out | iso::app

我阅读了按位或,以及它如何“合并”两个位集,

例如:1010 | 0111 = 1111

话虽如此,当我们使用诸如此类的方法时,我不明白它是如何在“幕后”工作的ifstream.open(filename, stateflagA | stateflagB | stateflagC)

有人可以详细说明这些状态标志的内部工作原理及其内存表示吗?

编辑:为了更加强调我想要理解的内容(如果有帮助的话),我假设 open 方法可以接收一个或多个状态标志作为签名中的单独参数,而不是由按位或分隔,所以我想了解按位 OR 如何在这些状态标志上工作以在组合多个标志时产生不同的最终状态,因此允许我仅对一个状态标志或一组状态标志使用一个参数。IE:

ifstream.open(filename, stateflagA | stateflagB | stateflagC)
Run Code Online (Sandbox Code Playgroud)

并不是

ifstream.open(filename, stateflagA , stateflagB , stateflagC)
Run Code Online (Sandbox Code Playgroud)

das*_*ght 5

位标志以完全相同的方式表示所有整数值。使它们成为“标志”的是您的程序对其值的解释

位标志用于小型值集的紧凑表示。每个值都分配了一个位索引。该索引处的位设置为的所有整数1都被解释为包含相应成员的集合。

考虑一个小例子:假设我们需要表示一组三种颜色 - 红色、绿色和蓝色。我们分配红色的索引为零,绿色的索引为 1,蓝色的索引为 2。这对应于以下表示:

BINARY DECIMAL COLOR
------ ------- -----
   001       1  Red
   010       2  Green
   100       4  Blue
Run Code Online (Sandbox Code Playgroud)

请注意,每个标志都是 2 的幂。这是单个位设置为 的二进制数的属性1。这是它在 C++ 中的样子:

enum Color {
    Red   = 1 << 0
,   Green = 1 << 1
,   Blue  = 1 << 2
};
Run Code Online (Sandbox Code Playgroud)

1 << n是在位置n设置为的单个位构造整数的标准方法1

有了这个表示,我们可以构建具有这些颜色的任意组合的集合:

BINARY DECIMAL COLOR
------ ------- -----
   001       1  Red
   010       2  Green
   011       3  Red+Green
   100       4  Blue
   101       5  Blue+Red
   110       6  Blue+Green
   111       7  Blue+Green+Red
Run Code Online (Sandbox Code Playgroud)

这是位操作发挥作用的时候:我们可以使用它们来构造集合并在单个操作中检查成员资格。

例如,我们可以构建一套RedBlue|这样的:

Color purple = Red | Blue;
Run Code Online (Sandbox Code Playgroud)

在幕后,所有这些都是分配5purple,因为4 | 15。但是由于您的程序解释5为一组两种颜色,因此它的含义与表示袋子中物品数量5的整数的含义不同5

您可以通过应用&来检查集合是否具有特定成员:

if (purple & Red) {
    // returns true
}
if (purple & Green) {
    // returns false
}
Run Code Online (Sandbox Code Playgroud)

I/O 库使用的标志以相同的方式工作。一些标志被组合以产生位掩码。它们的工作方式与单个标志相同,但不是让您找到成员资格,而是让您在单个位操作中找到集合交集:

Color yellow = Blue | Green;
Color purple = Red | Blue;
Color common = yellow & purple; // common == Blue
Run Code Online (Sandbox Code Playgroud)