一、C语言中结构体的大小计算
当一个结构体中的所有成员都是同一类型的,其大小当然好计算。下面主要讨论成员类型不一样的情况结构体大小的计算。
对此,听说编译器有两条规则:
1、结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)
2、结构体大小必须是所有成员大小的整数倍。
似乎有些难理解。
在32位的操作系统下(内存字长为4字节)做下面的练习:
- struct stu1
- {
- int i;
- char c;
- int j;
- }
- sizeof(stu1)=12bytes;
-
- struct stu2
- {
- int k;
- short t;
- };
- struct stu3
- {
- short t;
- short tt;
- int k;
- };
- sizeof(stu2)=sizeof(stu2)=8bytes
-
- struct stu4
- {
- short i;
- struct
- {
- char c;
- int j;
- } ss;
- int k;
- };
- sizeof(stu4)=16;
上面这些都可以且容易理解。再看下面一例:
- struct pack_ucmd
- {
- uint16_t cmd;
- union
- {
- uint8_t data[6];
- struct {
- uint16_t seq;
- uint8_t mode;
- uint8_t tag;
- } brcast_cmd;
- } u;
-
- uint8_t type;
- uint8_t unuse;
- uint16_t datalen;
- uint8_t data[1];
- }
这个大小是多少?sizeof(pack_ucmd)=14
介绍一个相关的概念——偏移量。偏移量指的是结构体变量中成员的地址和结构体变量地址的差。结构体大小等于最后一个成员的偏移量加上最后一个成员的大小。
依次将这个结构体展开。由于32位系统字长4个字节,为了避免产生过多的内存碎片,像char char int16会放在一个字长内;而char int32就要分两个字长内存存放了。
上面联合体的大小根据其成员中大者data[6]=6bytes而定。更深入者,自己理解。
二、面向对象中的结构体的大小:
注 意!C#中调用指针时,要在工程属性中选择[允许不安全代码],还要在代码中的指针部分使用unsafe括起来。
- namespace CSharpStruct01
- {
- struct CoOrds
- {
- public char c;
- public char c1;
- public int x;
- public int y;
- // string属于托管对象,无法严明指向它的指针
- //public string str;
- }
- class AccessMembers
- {
- static void Main()
- {
- CoOrds home;
- unsafe
- {
- CoOrds* p = &home;
- p->c = 'a';
- p->c1 = 'b';
- p->x = 1234;
- p->y = 8765;
- int* pc = (int*)&p->c;
- int* pc1 = (int*)&p->c1;
- int* px = &p->x;
- int* py = &p->y;
- System.Console.WriteLine("The coordinates are: c={0},c1={1},x={2}, y={3}",p->c,p->c1, p->x, p->y);
- System.Console.WriteLine("The address are: &c={0} ,&c1={1},&x={2}, &y={3}",(int)pc, (int)pc1,(int)px, (int)py);
- Console.ReadLine();
- }
- }
- }
将c1变量相关的屏蔽:
参考文献: