-1

我只学习了一个星期的 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 个标志(选项 1、选项 2、选项 3)。现在,标志查询按预期工作(选项 1/2/3 返回 1,其余返回 0)直到选项 7/8。即使未设置 option7/8,该函数也会返回 1。这让我得出结论,unsigned char myflags 在二进制中看起来像这样:1100 0000。那么,

1)这里发生了什么?为什么 2 位已经在使用?首先如何使用 2 位的无符号字符?不应该只为有符号变量保留“最高”位吗?

2) 为什么我们使用按位赋值运算符 |= 来设置位标志,当它提供意外结果时。如果我们简单地分配 myflags = option3 | 选项2 | option3 它按预期工作 - option7/8 的查询返回 0。

(我很可能不知道我在说什么!)

4

2 回答 2

4

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

于 2015-03-28T13:43:20.317 回答
0

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

在您的情况下,“垃圾”来自之前堆栈中已经存在的内容:它可能来自先前的函数调用(在mainC++ 运行时运行自己的初始化代码共享之前),或者整个堆栈可能开始 pre - 完全填充垃圾值以帮助您发现此类问题(这是调试构建的典型)。

如果我们简单地分配 myflags = option1 | 选项2 | option3 它按预期工作

这就是为什么你在这里分配 option1 | option2 | option3,覆盖myflags最初的内容。

首先如何使用 2 位的无符号字符?不应该只为有符号变量保留“最高”位吗?

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


  1. 例外:全局变量和static局部变量会自动进行零初始化。
  2. 实际上,任何没有用户提供的构造函数的类型
  3. 这实际上是一个依赖于实现的行为。
于 2015-03-28T13:50:35.447 回答