C 语言结构体及位域内存大小

C 语言结构体及位域内存大小

小白一枚,最近线学习野火stm32,写个博客记录下自己学习之路。
以下资料来自野火论坛以及其他网站。

存对齐的规则很简单:
1.起始地址为该变量类型所占内存的整数倍,若不足则不足部分用数据填充至所占内存的整数倍。
2.该结构体所占总内存为结构体成员变量中最大数据类型的整数倍。

一.看如下例子:(假设char 是 1个字节,double是8个字节,int是2个字节 ,float4字节)

typedef struct
{
char a;
double b;
}test;
求sizeof(test)的值?
答案:1+7 +8 = 16;

typedef struct
{
char a;
double b;
int c;
}test;
求sizeof(test)的值?
答案:1+7+8+4+4=24;(最后还加了4是因为总长度是8的整数倍,所以补齐+4);

当结构体中的变量的位置变化时,其结果也会不一样哦~
typedef struct
{
double b;
char a;
int c;
}test;
答案是:8+1+3+4=16;

再看下一个,当存在: #pragma pack(4)

#pragma pack(4) //规定以4字节对齐
typedef struct
{
char a;
double b;
int c;
}test;
求sizeof(test)的值?
答案:1+3+8+4=16;

现在再插个联合体试试 = =

struct stu
{
union{
char bj[5];
int bh[2];
}class;
char xm[8];
float cj;
}xc;
//则 sizeof(xc)的值为?
答案:联合体占用5字节 但是对齐方式int(2字节),所以再加1,为6;接着6+8位14字节,为了对齐float的4字节,这里补充2字节,最后的结果是:5+1+8+2+4=20;

现在再进一步看看:

struct stu
{
union{
char bj[5];
int bh[2];
}class;
char xm[8];
float cj;
}xc;
//若 xc 地址为0x1000 则求 &xm[0] 的值?
答案:0x1000+6=0x1006;

二.位域

使用位域的主要目的是压缩存储,其大致规则为:
1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的 sizeof 大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止*
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的 sizeof 大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6 采取不压缩方式,Dev-C++采取压缩方式;
4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。

例子:
struct test
{
char f1 : 3;
short f2 : 4;
char f3 : 5;
};
求 sizeof(test)大小?
这个好像比较简单:3+4,占了7位了,再来个5的话,一个字节就塞不住了,所以f3存入下一个字节,总的也就是2字节。

当存在非位域的字段时,则不会进行压缩。

struct C{
char f1 : 3;
char f2;
char f3 : 5;
};
求 sizeof(test)大小
答案:1+1+1=3;

所以一般情况下占用空间小的类型排在前面,占用空间大的类型排在后面,这样可以相对节约一些对齐空间 。

*第一次写,不足之处还请指正~~~~*

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦还乡、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值