一、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变量相关的屏蔽:
参考文献: