你不知道的C语言知识点 – 位域

你不知道的C语言知识点 – 位域C语言位域是一种特殊的结构体成员,它允许我们按位对成员进行定义,指定其占用的位数。位域可以节省内存空间,并方便对位进行操作。

欢迎大家来到IT世界,在知识的湖畔探索吧!

C语言位域是一种特殊的结构体成员,它允许我们按位对成员进行定义,指定其占用的位数。位域可以节省内存空间,并方便对位进行操作。本文将从以下几个方面介绍C语言位域的概念、用法和注意事项:

– **位域的定义和声明**:位域的定义与结构体定义相似,其形式为:

struct 位域结构名 {
	位域列表;
};

欢迎大家来到IT世界,在知识的湖畔探索吧!

其中,位域列表的形式为:

欢迎大家来到IT世界,在知识的湖畔探索吧!type [member_name] : width;

type 只能为 int、unsigned int、signed int 等整数类型,或者是枚举类型。member_name 是位域的名称,可以省略。width 是位域占用的位数,必须是一个常量表达式。

例如,下面的代码定义了一个名为 flags 的结构体,它包含四个位域成员,每个成员只占用一位:

struct flags {
  unsigned int is_keyword : 1;
  unsigned int is_extern : 1;
  unsigned int is_static : 1;
  unsigned int is_const : 1;
};

– **位域的访问和赋值**:位域的访问和赋值与普通的结构体成员相同,都是通过点运算符(.)来实现的。例如,下面的代码创建了一个 flags 类型的变量 flag,并对其各个成员进行赋值和打印:

欢迎大家来到IT世界,在知识的湖畔探索吧!struct flags flag;
flag.is_keyword = 1;
flag.is_extern = 0;
flag.is_static = 1;
flag.is_const = 0;
printf("is_keyword: %u\n", flag.is_keyword);
printf("is_extern: %u\n", flag.is_extern);
printf("is_static: %u\n", flag.is_static);
printf("is_const: %u\n", flag.is_const);

需要注意的是,位域的取值范围受到其占用的位数和数据类型的限制。例如,如果一个位域占用4位,那么它最多可以表示16种不同的值(从0到15)。如果一个位域是有符号类型,那么它还要考虑符号位。如果给一个位域赋予超出其范围的值,那么会发生截断或溢出。

– **位域的存储规则**:C语言标准并没有规定位域的具体存储方式,不同的编译器有不同的实现方案,但它们都尽量压缩存储空间。一般来说,相邻且类型相同的位域会挨着存储,直到不能容纳为止;如果相邻且类型不同,或者中间穿插着非位域成员,那么可能会有填充或对齐的情况发生。因此,使用 & 获取位域成员的地址是没有意义的,C语言也禁止这样做。

例如,下面的代码定义了一个名为 bs 的结构体,它包含三个不同类型的位域成员:

struct bs {
  unsigned m: 12;
  unsigned char ch: 4;
  unsigned p: 4;
};

在 GCC 下编译运行时,sizeof(struct bs) 的结果为4;在 VC/VS 下编译运行时,sizeof(struct bs) 的结果为12。这是因为 GCC 对不同类型的相邻位域进行了压缩存储,而 VC/VS 则按照各自类型分开存储。

系列文章持续更新,如果觉得有帮助请点赞+关注!

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/36614.html

(0)

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们YX

mu99908888

在线咨询: 微信交谈

邮件:itzsgw@126.com

工作时间:时刻准备着!

关注微信