如何计算结构体大小_第1页
如何计算结构体大小_第2页
如何计算结构体大小_第3页
如何计算结构体大小_第4页
免费预览已结束,剩余1页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、运算符 sizeof 可以计算出给定类型的大小,对于32 位系统来说,sizeof(char) = 1; sizeof(int) = 4 。基本数据类型的大小很好计算,我们来看一下如何计算构造数据类型的大小。C 语言 中的构造数据类型有三种:数组、结构体和共用体。数组是相同类型的元素的集合,只要会计算单个元素的大小,整个数组所占空间等于基础元素大小乘上元素的个数。结构体中的成员可以是不同的数据类型,成员按照定义时的顺序依次存储在连续的内存 空间。和数组不一样的是,结构体的大小不是所有成员大小简单的相加,需要考虑到系统在存储结构体变量时的地址对齐 问题。看下面这样的一个结构体:ST ruct s

2、tu1int i;char c;int j;;先介绍一个相关的概念 偏移量。偏移量指的是结构体变量中成员的地址和结构体变量地址的差。结构体大小等于最后一个成员的偏移量加上最后一个成员的大小。显然,结构体变量中第一个成员的地址就是结构体变量的首地址。 因此, 第一个成员i 的偏移量为0。 第二个成员c 的偏移量是第一个成员的偏移量加上第一个成员的大小 (0+4),其值为4;第三个成员j的偏移量是第二个成员的偏移量加上第二个成员的大小(4+1 ) ,其值为5。实际上,由于存储变量时地址对齐的要求,编译器在编译程序时会遵循两条原则:一、结构体变量中成员的偏移量必须是成员大小的整数倍(0 被认为是任何

3、数的整数倍)二、结构体大小必须是所有成员大小的整数倍。对照第一条,上面的例子中前两个成员的偏移量都满足要求,但第三个成员的偏移量为5,并不是自身(int)大小的整数倍。编译器在处理时会在第二个成员后面补上3个空字节,使得第三个成员的偏移量变成 8。对照第二条,结构体大小等于最后一个成员的偏移量加上其大小,上面的例子中计算出来的大小为12,满足要求。再看一个满足第一条,不满足第二条的情况struct stu2int k;short t;;成员 k 的偏移量为0;成员 t 的偏移量为4,都不需要调整。但计算出来的大小为6,显然不是成员k大小的整数倍。因此,编译器会在成员t 后面补上2 个字节,使得

4、结构体的大小变成8 从而满足第二个要求。 由此可见,大家在定义结构体类型时需要考虑到字节对齐的情况,不同的顺序会影响到结构体的大小。对比下面两种定义顺序struct stu3char c1;int i;char c2;struct stu4char c1;char c2;int i;虽然结构体stu3 和 stu4 中成员都一样,但 sizeof(struct stu3) 的值为 12 而 sizeof(struct stu4) 的值为8。如果结构体中的成员又是另外一种结构体类型时应该怎么计算呢?只需把其展开即可。但有一点需要注意,展开后的结构体的第一个成员的偏移量应当是被展开的结构体中最大的

5、成员的整数倍。看下面的例子:struct stu5short i;structchar c;int j; ss;int k;结构体 stu5 的成员 ss.c 的偏移量应该是4,而不是2。整个结构体大小应该是16。如何给结构体变量分配空间由编译器决定,以上情况针对的是Linux 下的 GCC 。 其他平台的C 编译器可能会有不同的处理。内存对齐节约内存许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐,而这个k 则被称为该数据类型的对齐模数 (alignment modulus) 。当一种类型S 的

6、对齐模数与另一种类型T 的对齐模数的比值是大于1的整数,我们就称类型S的对齐要求比T强(严格 ),而称 T 比 S 弱 (宽松)。这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以提升读取数据的速度。比如这么一种处理器, 它每次读写内存的时候都从某个8 倍数的地址开始,一次读出或写入 8 个字节的数据,假如软件能保证double 类型的数据都从8 倍数地址开始,那么读或写一个double 类型数据就只需要一次内存操作。否则,我们就可能需要两次内存操作才能完成这个动作,因为数据或许恰好横跨在两个符合对齐要求的8 字节内存块上三个原则:1) 结构体变量的首地址能够被其最宽基本类型成员

7、的大小所整除;2) 结构体每个成员相对于结构体首地址的偏移量(offset )都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internaladding ) ;3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding )另外还可以用 prgam pack(n) 来指定偏移量的大小,n 为字节对齐数,其取值为1 、2、 4、 8、 16,默认是8,如果这个值比结构体成员的sizeof 值小,那么该成员的偏移量应该以此值为准,即是说,结构体成员的偏移量应该取二者的最小值。比如:对32 位机器,指针大小

8、为4struct P1 int a; char b; int c; char d;/16struct P2 int a; char b; char c; int d;/12struct P3 short a3; char b3; ;/10struct P4 short a3; char *b3; ;/20struct P5 struct P2 *a; char b; struct P1 c2; ; / 40而:struct P6 int a; int b; char c; char d; ; /12 struct P7 int a; char b; char c; int d; ; /12struct P8 short a3; char b3

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论