c语言bit bdate flag,Bit fields(位域)

本文详细介绍了C语言中位字段的概念和用法,包括它们如何在内存中打包、位字段的类型限制、宽度对值范围的影响以及位字段的地址和大小问题。位字段可用于高效地存储和操作小数据,但其行为在某些方面是未定义或实现定义的,如对齐、顺序和跨越分配单位边界等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以位为单位声明一个明确宽度的成员。相邻的位字段成员可以打包以共享和跨越单个字节。

位字段声明是使用以下声明的结构或联合成员声明:

identifier(optional) : width

标识符-正在声明的位字段的名称。该名称是可选的:无名称位域引入了指定的填充位数宽度-一个整数常量表达式,其值大于或等于零且小于或等于基础类型中的位数。当大于零时,这是该位字段将占用的位数。值零只能用于无名的位域,具有特殊含义:它指定类定义中的下一个位域将从分配单元的边界开始。

说明

位域只能有四种类型之一(可能是 const 或 volatile 限定的):

unsigned int,对于无符号位域(unsigned int b:3;有范围0..7)

signed int,对于有符号位域(signed int b:3;有范围-4..3)

int,对于具有实现定义的签名的位字段(请注意,这与int其他地方的关键字的含义不同,它表示“signed int”)。例如,int b:3;可能有值的范围0..7或-4..3。

_Bool,用于单位位域(bool x:1;具有范围0..1和隐式转换,它遵循布尔转换规则。

额外的实现定义类型可能是可以接受的。它也是实现定义是否一个位域可能有原子类型。(自 C11开始)位域(宽度)中的位数将限制设置为可容纳的值范围:

#include struct S { // three-bit unsigned field, // allowed values are 0...7

unsigned int b : 3;};int main(void){

struct S s = {7};    ++s.b; // unsigned overflow    printf("%d\n", s.b); // output: 0}

允许多个相邻位字段(通常是)打包在一起:

#include struct S {    // will usually occupy 4 bytes:    // 5 bits: value of b1    // 11 bits: unused    // 6 bits: value of b2    // 2 bits: value of b3    // 8 bits: unused

unsigned b1 : 5, : 11, b2 : 6, b3 : 2;};int main(void){    printf("%zu\n",sizeof(struct S)); // usually prints 4}

宽度为零的特殊未命名位字段分隔填充:它指定下一个位字段从下一个分配单元的开始处开始:

#include struct S {    // will usually occupy 8 bytes:    // 5 bits: value of b1    // 27 bits: unused    // 6 bits: value of b2    // 15 bits: value of b3    // 11 bits: unused

unsigned b1 : 5;

unsigned :0; // start a new unsigned int

unsigned b2 : 6;

unsigned b3 : 15;};int main(void){    printf("%zu\n", sizeof(struct S)); // usually prints 8}

由于位字段不一定在字节的开始处开始,所以不能采用位字段的地址。指向位字段是不可能的。位字段不能与 sizeof 和 alignas 一起使用(自 C11开始)。

注意

位字段的以下属性未定义:

调用offsetof位域的效果

位字段的以下属性未指定:

保存位域的分配单元的对齐

位域的以下属性是实现定义的:

类型的位字段是否int被视为有符号或无符号

是否允许 int,signed int,unsigned int和_Bool 以外的类型

原子类型是否被允许

位域是否可以跨越分配单位边界

分配单元中的位字段的顺序(在某些平台上,位字段从左到右打包,其他从右到左)

即使对象表示中的位数_Bool至少CHAR_BIT为_Bool1 ,类型的位字段的宽度也不能大于1。

在 C ++编程语言中,位域的宽度可以超过基础类型的宽度。

参考

C11 standard (ISO/IEC 9899:2011):6.7.2.1 Structure and union specifiers

C99 standard (ISO/IEC 9899:1999):6.7.2.1 Structure and union specifiers

C89/C90 standard (ISO/IEC 9899:1990):3.5.2.1 Structure and union specifiers

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值