4

我有以下自学代码:

#include <iostream>
using namespace std;
struct bitfields{
    unsigned field1: 3;
    unsigned field2: 4;
    unsigned int k:  4;
};

int main(){
    bitfields field;
    field.field1=8;
    field.field2=1e7;
    field.k=18;
    cout<<field.k<<endl;
    cout<<field.field1<<endl;
    cout<<field.field2<<endl;
    return 0;
}

我知道这unsigned int k:4意味着 k 是 4 位宽,或最大值为 15,结果如下。

2
0
1

例如,filed1可以从 0 到 7(包括),field2k0 到 15。为什么会出现这样的结果?也许它应该全部为零?

4

3 回答 3

9

你溢出了你的领域。让我们k举个例子,它是 4 位宽。正如你所说,它可以保存从 0 到 15 的值,以二进制表示形式是

0  -> 0000
1  -> 0001
2  -> 0010
3  -> 0011
...
14 -> 1110
15 -> 1111

因此,当您分配 18 时,具有二进制表示

18 -> 1 0010 (space added between 4th and 5th bit for clarity)

k只能保存低四位,所以

k = 0010 = 2.

等价的也适用于您的其他领域。

于 2010-08-07T09:04:31.087 回答
4

您有这些结果是因为分配溢出了每个位域。

变量filed1是 3 位,但 8 需要 4 位才能呈现(1000)。低三位都是零,所以filed1也是零。

对于filed2,17 用 10001 表示,但filed2只有四位。低四位代表值 1。

最后,对于k,18 用 10010 表示,但k只有四位。低四位代表值 2。

我希望这有助于澄清事情。

于 2010-08-07T09:04:31.260 回答
1

在 C++ 中,任何无符号类型都会在您达到其上限时回绕 [1]。当您定义一个 4 位的位域时,您存储的每个值也会被环绕。大小为 4 的位域的可能值为 0-15。如果存储“17”,则换行到“1”,对于“18”,再换行到“2”。

在数学上,包装的值是原始值以目标类型可能值的数量为模:

对于大小为 4 的位域(2**4 个可能的值):

18 % 16 == 2
17 % 16 == 1

对于大小为 3 的位域(2**3 个可能的值):

8 % 8 == 0.

[1] 对于有符号类型,情况并非如此,在这种情况下会发生什么是未定义的。

于 2010-08-07T09:06:17.120 回答