如何计算结构体及共用体大小

对于结构体
首先理解字节对齐机制:
(1),结构体变量的首地址能够被其最宽基本类型成员大小所整除。
(2),结构体每个成员相对于结构体首地址的偏移量(offset)都是该成员大小的整数倍,如有需要,编译器会在成员之间加上中间填充字节。
(3)结构体总大小为结构体最宽基本类型成员大小的整数倍,如有需要,编译器会在最末一个成员之后加上末尾填充字节。
第(2)、(3)条准则决定了结构体变量占据内存空间的大小。
基本类型指:char,short,int,float,double。
数据宽度即其sizeof的大小。

eg:struct {char c;short s;float f;}A,struct{char c;float f;short s;}B;
则sizeof(A)=?,sizeof(B)=?
解:A中,char占1字节,short占2,则short相对于结构体首地址的offset(偏移量)=1,为满足准则(2),必须添加中间填充字节1;float占4字节,相对于结构体首地址offset=(1+1+2)即4,满足准则(2)。此时结构体大小为(1+1+2+4)=8,是最宽基本类型float整数倍,满足(3)。所以可得出:sizeof(A)=8;

对于B:B中,char占1,float占4,则float相对于结构体首地址的offset=1,为满足准则(2),必须添加中间填充字节3;short占2,相对于结构体首地址offset=(1+3+4)即8,是short所占字节的整数倍,满足准则(2)。此时结构体大小为(1+3+4+2)=10,不是最宽基本类型float的整数倍,这时,末尾必须添加末尾填充字节2,所以最后总大小为12;

总结:分析时只要这样即可:
对于A:1 1 2    4 (红色为插入部分,写时,中间要留够空格)
对于B:1 3 4    2 2
这样就可以直观的得到结构体大小。

迁移eg:struct{float f;int I;short s;}C; 则sizeof(C)=?(答案:12)

知识扩展1:若出现结构体嵌套,则准则(2)、(3)应改为:
(2),复合成员相对于结构体首地址的偏移量是复合成员中最宽基本类型成员大小的整数倍。
(3),结构体总大小为结构体最宽基本类型成员大小整数倍。
eg:
struct
{
float f;
char c;
double d;
struct
{
double d1;
float f1;
double d2;
char c1;
}A
}B;
则sizeof(B)=?
解:先计算A大小:8              7(红色为插入部分),得到为32;
所以对于B,一开始排列为: 4 1 8 32;
1的offset=4,所以4与1间要添上3。变为:
4 3 1      32;
此时8的offset=8,满足准则2,32的offset=16,是A中最宽基本类型double所占字节的整数倍,满足准则2;此时B大小为48,是B中最宽基本类型double的整数倍,满足准则3.所以最后sizeof(B)=48;

知识扩展2,若结构体内部出现数组,则准则2应为:
(2),数组相对于结构体首地址的offset是该数组成员大小的整数倍。
eg :struct {double d[2];char*c;}C; 则sizeof(C)=?
解:double大小为8字节,所以double[2]为16;而指针大小均为4,
所以C可排列为:
16     4 4
得到sizeof(C)=24;


对于共用体:
原则上,共用体大小取决于占据最多内存的成员的长度。但字节对齐准则(3)仍然成立。Eg:
Union
{
char c;
double d;
}e;
则sizeof(e)=16;

由于编译器不同,有的sizeof(e)=8.
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第3章数据结构 3.1 结构体 实例079结构体类型的定义 实例080结构体变量的初始化 实例081如何使用嵌套结构 实例082将结构作为参数传递并返回 实例083共用体数据类型的定义 实例084共用体变量的初始化 实例085如何使用匿名共用体 实例086枚举类型的定义与使用 实例087用new动态创建结构体 实例088使用结构体标识操作员名称密码和级别 实例089创建包括12个月份的枚举类型 实例090带有函数的结构体 3.2 指针、地址与引用 实例091使用指针自增操作输出数组元素 实例092利用指针表达式操作遍历数组 实例093数组地址的表示方法 实例094指针和数组的常用方法 实例095结构指针遍历结构数组 实例096指针作为函数的参数 实例097多维数组的指针参数 实例098指针作为函数的返回值 实例099使用函数指针制作菜单管理器, 实例100使用指针实现数据交换, 实例101使用指针实现整数排序 实例102指向结构体变量的指针 实例103周指针实现逆序存放数组元素值 实例104输出二维数组的有关值 实例105输出二维数组任一行任一列值 实例106使用指针查找数列中的最大值和最小值 实例107用指针数组构造字符串数组 实例108将若干字符串按照字母顺序输出 实例109用指向函数的指针比较大小 实例110用指针函数实现求学生成绩 实例111使用指针的指针输出字符串 实例112实现输入月份号输出该月份英文名 实例113使用指向指针的指针对字符串排序 实例114分解字符串中的单词 3.3 数组 实例115向数组中赋值 实例116遍历数组 实例117求数组中元素的平均和 实例118数组的排序 实例119向数组中插入元素 实例120数组的删除操作 实例121数组冒泡排序法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值