按位标志随意设置

时间:2015-03-28 13:40:07

标签: c++ bit-manipulation bitflags

我只学习了一周的C ++(以及编程),所以这个问题可能缺乏对基本编程原理的理解,但这里什么都没有:

unsigned int bitFlags()
{
unsigned char option1 = 0x01; // hex for 0000 0001
unsigned char option2 = 0x02; // hex for 0000 0010
unsigned char option3 = 0x04; // hex for 0000 0100
unsigned char option4 = 0x08; // hex for 0000 1000
unsigned char option5 = 0x10; // hex for 0001 0000
unsigned char option6 = 0x20; // hex for 0010 0000
unsigned char option7 = 0x40; // hex for 0100 0000
unsigned char option8 = 0x80; // hex for 1000 0000

unsigned char myflags; // byte-size value to hold some combination of the above 8 options

myflags |= option1|option2|option3;

if (myflags&option8)
    return 1;
else
    return 0;
}

int main()
{
   std::cout << bitFlags() << "\n";
    return 0;
}

所以,我只设置了3个标志(option1,option2,option3)。现在,标志查询按预期工作(对于选项1/2/3返回1,对于其余选项返回0)up-until option7 / 8。即使没有设置option7 / 8,函数返回1.这使我得出结论,unsigned char myflags在二进制文件中看起来像这样:1100 0000.那么,

1)这里发生了什么?为什么2位已经在使用?如何使用2位的无符号字符?不应该是&#34;最高&#34;是仅为签名变量保留?

2)为什么我们使用按位赋值运算符| =在它提供意外结果时设置位标志。如果我们只是分配myflags = option3 | option2 | option3它按预期工作 - 对option7 / 8的查询返回0。

(很有可能我不知道我在谈论什么!)

2 个答案:

答案 0 :(得分:4)

您没有将myflags初始化为0,因此在您或标记之前存在未知的垃圾。

答案 1 :(得分:0)

在C和C ++中,如果定义基本类型 2 的变量 1 而不显式初始化它,它将以未定义状态启动,这解释了您看到的行为在这里:你向未定义状态的变量“添加”(|=)标志,因此除了实际指定的内容之外,你还可以得到其他东西。

你的案例中的“垃圾”来自之前在堆栈上已经发生的事情:它可能来自之前的函数调用(在main C ++运行时运行其自己的初始化代码份额之前) ,或整个堆栈可能会开始预先填充垃圾值,以帮助您发现这样的问题(这是典型的调试版本)。

  

如果我们只是分配myflags = option1 | option2 | option3按预期工作

这就是为什么你分配 option1 | option2 | option3,首先覆盖myflags中的内容。

  

首先使用2位的无符号字符怎么样?不应该仅为签名变量保留“最高”位吗?

最高位用于有符号变量以保存符号 3 ,在无符号类型中,您拥有可用于所有目的的所有位。


  1. 例外:全局和static本地自动归零。
  2. 实际上,没有用户提供的构造函数的任何类型
  3. 这实际上是一种依赖于实现的行为。