C语言应用笔记:能降低结构体内存占用的位域操作

内容分享3周前发布
0 1 0

C语言应用笔记:能降低结构体内存占用的位域操作

示例1

在C语言中,结构体位域(Bit Fields)允许准确控制结构体成员占用的内存位数,这在嵌入式系统、网络协议等内存敏感场景中超级有用。以下是位域的核心知识点和示例:

位域定义语法

struct 结构体名 {
类型 [成员名] : 位宽;
};
  • 类型:必须为整型(intunsigned intsigned int
  • 位宽:指定成员占用的比特数(0 ≤ 位宽 ≤ 类型位数)
  • 匿名位域:无成员名的位域,用于占位填充(如 unsigned int : 4;

关键特性

  • 内存压缩:多个位域成员可能共享同一存储单元
  • 地址不可取:无法对位域成员使用取地址运算符 &(因小于1字节)
  • 赋值行为:无法赋予超出bit位的值

基础示例

#pragma pack(1) // 1字节对齐

typedef struct {
  	// 占1个字节
    uint8_t byte;
		// 共占4个字节
    uint32_t a : 2;
    uint32_t b : 4;
    uint32_t c : 6;
} example;

#pragma pack()

static example t = {
    .a = 2,  .b = 5, .c = 6,
};

int main(void) {
    printf("example size: %d
", sizeof(example));
    printf("a = %d
", t.a);
    printf("b = %d
", t.b);
    printf("c = %d
", t.c);
    return 0;
}

高级用法

将原始数据拷贝给带位域成员的结构体变量,可自动解析出占用不同bit位的数值,省去了手动解析的步骤。具体实现如下:

#pragma pack(1)

// 定义占用2字节的位域结构体
typedef struct {
    uint16_t a : 5; // 5位 (0-31)
    uint16_t b : 7; // 7位 (0-127)
    uint16_t c : 4; // 4位 (0-15)
} BitFieldStruct;

#pragma pack()

int main() {
    // 定义位域结构体变量
    BitFieldStruct data;
    // 十六进制值: 1010 1011 1100 1101
    uint16_t raw_value = 0xABCD;
    // 使用内存拷贝确保正确赋值
    memcpy(&data, &raw_value, sizeof(data));
    // 打印结果
    printf("原始值: 0x%04X (%d)
", raw_value, raw_value);
    printf("结构体大小: %d 字节
", sizeof(data));
    printf("解析结果:
");
    printf("  a (5位): %d
", data.a); // 低5位: 0b01101 = 13
    printf("  b (7位): %d
", data.b); // 中间7位: 0b1011110 = 94
    printf("  c (4位): %d
", data.c); // 高4位: 0b1010 = 10
    return 0;
}

输出结果

原始值: 0xABCD (43981)
结构体大小: 2 字节
解析结果:
 a (5位): 13
 b (7位): 94
 c (4位): 10
© 版权声明

相关文章

1 条评论

您必须登录才能参与评论!
立即登录
  • 头像
    小荳訝 投稿者

    收藏了,感谢分享

    无记录