所以我真的无法理解这两个代码段之间的区别。我对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
答案 0 :(得分:3)
这是C中int
,signed int
可能不同的地方。
对于位字段,不int
或signed
的{{1}}可视为unsigned
或signed 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;
或增加比特分配。欢呼..