结构中的字符

Characters in structures

本文关键字:字符 结构      更新时间:2023-10-16

一个快速问题:char c:4在下面给出的结构

中是什么意思?
struct s 
 { 
 char c:4;
 }

这是一个位域char的4位部分组成。您可以定义更多的位字段,将较大的类型细分为"nibblets",如下所示:

struct s 
 { 
 char c:4;
 char d:2;
 char e:2;
 };

这个struct定义了三个字段,全部"打包"到一个char中。c字段可以保存16个不同的值;字段de可以分别保存4个值

char c:4表示它是char大小的变量,其中4位是变量c。换句话说,c并不是指整个8位char内存空间,而只是其中的4位。这是一种将位包装标志和不常见的数据大小放入结构的机制。

位字段是C语言的一个奇怪的特性,它的确切规范和行为多年来一直有些不一致;C标准的后期版本已经确定了行为的某些方面,足以阻止编译器做一些有用的事情,但还不足以使它们以任何有用的方式移植。

如果一个结构体的两个或多个连续成员具有相同的底层整数类型,并且它们的字段名后面跟着一个冒号和一个数字,编译器将尝试将第一个之后的每个成员打包到与前一个相同的存储元素中。如果不能这样做,它将前进到下一个存储元素

因此,在unsigned short为16位的机器上,声明:
struct {
  unsigned short a1 : 5;
  unsigned short a2 : 5;
  unsigned short a3 : 7;
  unsigned short a4 : 5;
  unsigned short a5 : 4;
  unsigned short a6 : 6;
}

编译器将a1和a2打包成一个16位整数;由于a3不适合与a1和a2相同的整数(总数将是17位),它将开始一个新的整数。虽然a4会与a1和a2位在一起,但a3挡在中间的事实意味着它将与a3放在一起。然后a5将与a3和a4放在一起,填补第二个位置。A6将获得一个单独的16位位置。

请注意,如果所有这些结构元素的底层类型都是32位的unsigned int,那么所有内容都可以打包到一个这样的项中,而不是三个16位的项。

坦率地说,我真的不喜欢比特域的规则。这些规则足够模糊,以至于一个编译器为位域数据生成的底层表示可能无法被另一个编译器读取,但它们足够具体,以至于编译器被禁止生成可能有用的数据结构(例如,应该可以将四个6位数字打包成3字节(24位)结构,但除非编译器碰巧具有24位整数类型,否则有办法请求)。然而,规则就是规则。