使用位域的C中结构的比较

时间:2018-01-17 17:31:52

标签: c memory struct bit-fields

所以我真的无法理解这两个代码段之间的区别。我对bit字段的了解是,我在内存中保留了多少BITS,我将用于此int。但为什么负数出现在第二个结构中?

#include<stdio.h>
#include<string.h>
typedef struct {
        unsigned int i:1;
        unsigned int k:31;
        int x;
}Struc1;
typedef struct{
        int i:1;
        int k:4;
        int x;
}Struc2;
int main()
{
        Struc1 s1={1,13,13};
        printf("%d %d %d\n",s1.i,s1.k,s1.x);
        Struc2 s2={1,13,13};
        printf("%d %d %d\n",s2.i,s2.k,s2.x);
        return 0;
}

输出:

1 13 13
-1 -3 13

3 个答案:

答案 0 :(得分:3)

这是C中intsigned int可能不同的地方。

对于位字段,不intsigned的{​​{1}}可视为unsignedsigned int。根据OP报告的输出,此实现定义unsigned int的行为似乎与int类似。

signed int

typedef struct{ int i:1; // like signed int i:1; for OP int k:4; // like signed int k:4; for OP int x; }Struc2; 位字段的范围可能为i[-1...0]的范围为k。通过[-8...7]初始化带符号整数,其值超出其范围是实现已定义(详情:C11dr 6.3.1.3 3)。

常见的实现定义行为是环绕的。就像Struc2 s2={1,13,13};Struc2 s2 = {1-2, 13-16, 13};

一样

使用位字段时,建议尽可能使用Struc2 s2 = {-1, -3, 13};。如果需要unsigned位字段,请使用int

答案 1 :(得分:1)

结构位提交表示为结构的数据成员保留的内存。在处理bit-field时,如果输入为sign bit类型,则应该处理signed

struc2的内存分配

typedef struct{
        int i:1;
        int k:4;
        int x;
}Struc2;

1)对于会员i,只保留one bits

 -------
|  1    |
 -------
        i
        |
        this is only first and last bit

int i : 1 ;如果变量/常量没有提及类型,则默认编译器会将签名类型视为签名(MSB) 有符号整数位1表示它将否定否。 2's complement的{​​{1}}为1。所以-1

注意:在C中,否定号以二进制补充

的形式存储在内存中 会员s2.i = -1

2),保留k(因为您正在存储4 bits),如下所示

13

在这种情况下, --------------------------- 13 => | 1 | 1 | 0 | 1 | --------------------------- 0x103 0x102 0x101 0x100 | sign bit 也是sign bit,因此1 否定以及多少?取二的补语(一个补码+ 1)。

s2.k

答案 2 :(得分:0)

你的系统是小端,所以第一位是从最右边位的有符号位,这就是为什么在你的第二个String val = postSnapshot.getValue(String.class); PictureUpload pictureUpload = new PictureUpload(postSnapshot.getKey(), val); pictureUploads.add(pictureUpload); 中你插入奇数,所以它将第一位作为有符号位并给出一个负值

struct

如果您不想要负值,请将其作为 typedef struct{ int i:1; //Here you inserting **1** so it will take as signed bit. int k:4; //Here you inserting odd value **13** so it will take negative int x; //This is also signed but it is **32** bit so it has enough space to store your **13** integer value. }Struc2; 或增加比特分配。欢呼..