C 结构体中的 “:” 用法和对齐规则

“:” 用法

以下摘自 redisserve.h

#define LRU_BITS 24

typedef struct redisObject {
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
                            * LFU data (least significant 8 bits frequency
                            * and most significant 16 bits access time). */
    int refcount;
    void *ptr;
} robj;

结构体中的冒号后的数字表示该字段占的位数。

4 + 4 + 24 + 32 + 64 = 128 4 + 4 + 24 + 32 + 64 = 128 4+4+24+32+64=128,所以该结构体占 16 字节(还要符合下述对齐规则,显然该结构体是对齐的)

对齐规则

规则一:每个字段的起始地址都是该字段大小的整数倍

typedef struct {
    char   a; // 1 个字节
    int    b; // 4 个字节
    double c; // 8 个字节
} A;

按照规则一对齐后可得排列 a... bbbb cccc cccc ,所以是 16 个字节。

. 表示填充,一个 a 表示字段 a 的一个字节,四个字节一组方便数数。

规则二:整个结构体大小该是结构体最大字段的整数倍

如果改变结构体顺序。

typedef struct {
    char   a; // 1 个字节
    double c; // 8 个字节
    int    b; // 4 个字节
} A;
  1. 先按照规则一:此时排列将是 a... .... cccc cccc bbbb,也就是 20 字节
  2. 在按照规则二:结构体最大字段大小为 8 个字节,所以要填充到 24 字节,最终排列是 a... .... cccc cccc bbbb ....

优化空间

根据上述例子可知,相同字段的结构体,排列顺序不同,对齐后所占空间也不同。

那没有没有一种通法,能使得结构体所占空间最小?有,按照字段大小降序排列。

优化前

typedef struct {
    char*  a; // 8 个字节
    short  b; // 2 个字节
	double c; // 8 个字节
	char   d; // 1 个字节
	float  e; // 4 个字节
	char   f; // 1 个字节
	long   g; // 8 个字节
	int    h; // 4 个字节
} A;
  1. 先按照规则一:aaaa aaaa bb.. .... cccc cccc d... eeee f... .... gggg gggg hhhh,共 52 字节
  2. 在按照规则二:aaaa aaaa bb.. .... cccc cccc d... eeee f... .... gggg gggg hhhh ....,共 56 字节

优化后

typedef struct {
    char  *a; // 8 个字节
    double c; // 8 个字节
    long   g; // 8 个字节
    float  e; // 4 个字节
    int    h; // 4 个字节
    short  b; // 2 个字节
    char   d; // 1 个字节
    char   f; // 1 个字节
} A;
  1. 先按照规则一: aaaa aaaa cccc cccc gggg gggg eeee hhhh bbdf,共 36 字节
  2. 再按照规则二: aaaa aaaa cccc cccc gggg gggg eeee hhhh bbdf ....,共 40 字节
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值