【发布时间】:2018-01-17 17:31:51
【问题描述】:
所以我真的无法理解这两个代码段之间的区别。我对位域的了解是,我在内存中保留了多少位用于这个 int。但是为什么负数出现在 2nd Struct 中呢?
#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
【问题讨论】:
-
你知道负数在 C 中是如何表示的吗?提示:最左边的位是符号。
-
几乎所有关于位域的内容都是实现定义的。当您将
13存储到一个 4 位位字段中时,您可能会存储一个有符号或无符号值。13具有位模式1101;高位被设置;如果您的普通int位域是有符号类型,它将被视为负数。如果您希望它未签名,请这样说:unsigned k:4;(int在此上下文中是可选的)。 -
C11 §6.7.2.1 footnote 125 如上面 6.7.2 所述,如果实际使用的类型说明符是
int或定义为int的 typedef-name,那么它是否是实现定义的 bit-字段是有符号或无符号的。并且C11 §6.7.2 ¶5 每个逗号分隔的多重集都指定相同的类型,除了位域,说明符int指定与signed int相同的类型还是与@ 相同的类型是实现定义的987654335@. -
这些注释意味着您无法分辨
int x:1;位域中存储的值。它可以存储零或非零;除了阅读编译器文档或实验之外,您无法判断非零值是-1还是+1。它没有可移植的解释,但这不是主要问题,因为位域通常没有可移植的解释。 -
@ZeyadIbrahim: 通常情况下,
int的含义与signed int相同;位域是我能想到的唯一地方,它有时与unsigned int相同——这取决于你的编译器。因此,默认情况下,大多数人会期望结构的int成员是有符号数量。
标签: c memory struct bit-fields