博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
小议结构体中的大小
阅读量:6638 次
发布时间:2019-06-25

本文共 1577 字,大约阅读时间需要 5 分钟。

一、C语言中结构体的大小计算

当一个结构体中的所有成员都是同一类型的,其大小当然好计算。下面主要讨论成员类型不一样的情况结构体大小的计算。

对此,听说编译器有两条规则:

1、结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)

2、结构体大小必须是所有成员大小的整数倍。

似乎有些难理解。

在32位的操作系统下(内存字长为4字节)做下面的练习:

  1. struct stu1
  2. {
  3. int i;
  4. char c;
  5. int j;
  6. }
  7. sizeof(stu1)=12bytes;
  8.  
  9. struct stu2
  10. {
  11.     int k;
  12.     short t;
  13. };
  14. struct stu3
  15. {
  16.     short t;
  17.     short tt;
  18.     int k;
  19. };
  20. sizeof(stu2)=sizeof(stu2)=8bytes
  21.  
  22. struct stu4
  23. {
  24.     short i;
  25.     struct
  26.     {
  27.         char c;
  28.         int j;
  29.     } ss;
  30.     int k;
  31. };
  32. sizeof(stu4)=16;

上面这些都可以且容易理解。再看下面一例:

  1. struct pack_ucmd
  2. {
  3.   uint16_t cmd;
  4.   union
  5.   {
  6.     uint8_t data[6];
  7.     struct {
  8.       uint16_t seq;
  9.       uint8_t mode;
  10.       uint8_t tag;
  11.     } brcast_cmd;
  12.   } u;
  13.   uint8_t type;
  14.   uint8_t unuse;
  15.   uint16_t datalen;
  16.   uint8_t data[1];
  17. }

    这个大小是多少?sizeof(pack_ucmd)=14

    介绍一个相关的概念——偏移量。偏移量指的是结构体变量中成员的地址和结构体变量地址的差。结构体大小等于最后一个成员的偏移量加上最后一个成员的大小。

依次将这个结构体展开。由于32位系统字长4个字节,为了避免产生过多的内存碎片,像char char int16会放在一个字长内;而char int32就要分两个字长内存存放了。

上面联合体的大小根据其成员中大者data[6]=6bytes而定。更深入者,自己理解。

 

二、面向对象中的结构体的大小:

注    意!C#中调用指针时,要在工程属性中选择[允许不安全代码],还要在代码中的指针部分使用unsafe括起来。

  1. namespace CSharpStruct01
  2. {
  3.     struct CoOrds
  4.     {
  5.         public char c;
  6.         public char c1;
  7.         public int x;
  8.         public int y;
  9.         // string属于托管对象,无法严明指向它的指针
  10.         //public string str;
  11.     }
  12.     class AccessMembers
  13.     {
  14.         static void Main()
  15.         {
  16.             CoOrds home;
  17.             unsafe
  18.             {
  19.                 CoOrds* p = &home;
  20.                 p->c = 'a';
  21.                 p->c1 = 'b';
  22.                 p->x = 1234;
  23.                 p->y = 8765;
  24.                 int* pc = (int*)&p->c;
  25.                 int* pc1 = (int*)&p->c1;
  26.                 int* px = &p->x;
  27.                 int* py = &p->y;
  28.                 System.Console.WriteLine("The coordinates are: c={0},c1={1},x={2}, y={3}",p->c,p->c1, p->x, p->y);
  29.                 System.Console.WriteLine("The address are: &c={0} ,&c1={1},&x={2}, &y={3}",(int)pc, (int)pc1,(int)px, (int)py);
  30.                 Console.ReadLine();
  31.             }
  32.         }
  33.     }

 

 

 

将c1变量相关的屏蔽:

 

参考文献:

转载地址:http://bdpvo.baihongyu.com/

你可能感兴趣的文章
HTTP中Get与Post的区别
查看>>
C#多线程解决界面卡死问题的完美解决方案
查看>>
Revit如何模型导入到InfraWorks中
查看>>
日期关联取最近日期的SQL
查看>>
[深入浅出iOS库]之图形库CorePlot
查看>>
BSON入门
查看>>
android.os.NetworkOnMainThreadException
查看>>
javascript event
查看>>
poj1269
查看>>
SQLite数据库查看工具(免费)
查看>>
优酷土豆2012.9.12校园招聘笔试题
查看>>
mysql源码解读之事务提交过程(一)
查看>>
用鼠标键盘来控制你的Android手机——同屏显示简单教程
查看>>
QQ在线图标 离线 QQ开通在线QQ服务 QQ陌生人直接聊天
查看>>
MFC对话框屏蔽Enter和ESC键
查看>>
as 中的反射 describeType
查看>>
朴素贝叶斯法(一)——贝叶斯定理
查看>>
Linux安装后的系统配置
查看>>
USB设备驱动程序学习笔记(二)
查看>>
区别:ASP.NET MVC的Model、DTO、Command
查看>>