位域的典型用法是声明小于8位的空间有效变量。我不明白的是将这些位声明为short,int,long,bool等的值。例如
typedef struct{
int first:3,
short second:3,
char third:3
} somestruct;
在上述情况下,所有3个变量,即第一,第二和第三变量都是3位长。将变量首先声明为int,将第二个声明为short,将第三个声明为char的值是多少?
或者,为什么甚至需要数据类型?我应该能够将上述内容声明为
typedef struct{
first:3,
second:3,
third:3
} modifiedstruct;
modifiedstruct假定变量first,second和third没有数据类型。将3位解释为字符,数字或浮动的责任应由某事 else负责。
linux上的gcc和g ++都允许上述行为。
答案 0 :(得分:5)
实际上,C标准只允许位域为signed int或unsigned int(以及C99中的_Bool)。如果你可以在那里抛出short,long或char,那就是编译器扩展。
至于为什么,主要原因是签字。考虑:
struct {
int s: 3;
unsigned u: 3;
} bf;
bf.s = 7;
bf.u = 7;
这两个位域都是1。但是,C保留了符号,所以:
(int)bf.s == -1 // Because signed conversions preserve the sign bit
bf.s >> 1 == -1 // So do right shifts on signed values
,同时:
(int)bf.u == 7 // Because the source is unsigned and so just a series of bits
bf.u >> 1 == 3 // Unsigned right shifts are just moving bits around as well
对于允许使用char的编译器,它可能是同样的想法。 char的默认签名是实现定义的,所以如果你想让bitfield的signedness匹配编译器的char的签名,你可以将它定义为char。
答案 1 :(得分:2)
大小用于存储(或传输)数据。数据类型是您打算如何使用和处理该信息。
答案 2 :(得分:0)
对于位字段使用除int
之外的任何其他类型是实现定义的行为。因此,在不知道您使用的是哪种特定编译器的情况下,无法确定该代码的作用,或者甚至是否编译。
一般来说,比特字段的标准定义很差,因此完全不可移植。由于位字段也是C语言的一个多余功能,因此使用逐位运算符进行位操作更为明智。
答案 3 :(得分:0)
bitfield中的类型对我来说唯一重要的时间是签名类型和无符号类型。对于大于1的字段,这可能会影响分配期间数据的解释方式。