带有符号整数位域的结构导致减去输出

时间:2014-07-26 18:56:18

标签: c struct bit-fields

这是带有结构的C代码。

#include <stdio.h>
#include <stdlib.h>

int main()
{
    struct{
        int a : 4;
        unsigned int b : 3;
        int c : 3;
    } x;

    x.a = 7;
    x.b = 7;
    x.c = 7;

    printf("%d\n",x.a);
    printf("%d\n",x.b);
    printf("%d\n",x.c);
    return 0;
}

在上面的C程序中,x.c已经从内存中分配了3位,但输出结果为-1。这是什么原因?

3 个答案:

答案 0 :(得分:1)

two's complement中,-1表示为11111111 ......... {尽可能多的位数} 当您指定7(二进制为111)时,符号位为1,其余位为1和1.

现在,
符号位= 1 =&gt;数字是负数 剩余比特= 11 =&gt;两分之二的补充。

因此结果是否定的

注意:从行为来看,您的机器似乎实现了两个补码

答案 1 :(得分:1)

intunsigned数据类型之间的差异是符号位的重要性。在上面的代码中,您使用int for x.c,其中3位存储值7,二进制转换为111.当您使用%d打印x.c中的值时,将其作为要设置的符号位。如果你是在一个小端机器上,如果用任何高于4的值初始化它,你将设置符号位并获得两个补码的结果,正如MAKZ在他的回答中所说的那样。 所以

7将打印为-1,6将打印为-2,5将打印为-3,4将打印为-4

答案 2 :(得分:1)

数据成员c被定义为具有int类型(在编译器的情况下为signed int)并且只有3位来表示有符号值。因此,最重要的位被视为符号位,二进制表示法中的7看起来为

111

由于定义

,最左边的位用作符号位
int c : 3;

因此,这个位组合意味着该数字为负且等于-1。 可以存储在此位字段中的最大正值等于3

011

且最小负值等于-4

100

考虑到实现定义是否将定义为int类型的位字段解释为unsigned intsigned int。您的编译器将int类型的某个字段视为类型signed int 因此,最好为位字段明确指定signed intunsigned int

来自C标准

  

...除了 for bitfields ,它是实现定义是否   specifier int指定与signed int或相同类型相同的类型   as unsigned int。