C ++中的Bitfields

时间:2010-08-07 08:54:37

标签: c++ bit-fields

我有以下自学代码:

#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(包含),field2k从0到15.为什么会有这样的结果?也许应该全部为零?

3 个答案:

答案 0 :(得分: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.

同样适用于其他字段。

答案 1 :(得分:4)

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

变量filed1是3位,但8位需要4位(1000)。低三位全为零,因此filed1为零。

对于filed2,17由10001表示,但filed2仅为4位。低四位代表值1.

最后,对于k,18由10010表示,但k仅为4位。低四位代表值2.

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

答案 2 :(得分:1)

在C ++中,任何 unsigned 类型都会在你达到它的上限时回绕[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]对于已签名的类型,情况并非如此,因为未定义会发生什么。