(一) 内存占用规则
首先定义一个简单的结构体,包含四种常用的结构类型。其中char占用1字节、int占用4字节、float占用4字节、double占8字节。
struct Coordinate
{
char x;
int y;
float z;
double t;
}
按照正常计算占用的内存为 1+4+4+8=17但是这不满足struct变量的起始地址存储规则,因此是错的。
为了使CPU能够快速访问,提高访问效率,struct变量的起始地址存储满足以下规则:
1.起始地址为该变量类型所占内存的整数倍,若不足则不足部分用数据填充至所占内存的整数倍。
2.该结构体所占总内存为结构体成员变量中最大数据类型的整数倍。
为了满足以上规则,存储的大小应该为 24。如下图,白色部分为变量所需的空间,红色部分为填充大小。
由于大小刚好为24,忽略第二条。但是若在最后增加一个变量,又该如何存储呢,程序如下:
struct Coordinate_1
{
char x;
int y;
float z;
double t;
char n;
};
前面部分不变,大小为24,在最后加1,占25字符,但是不满足第二条规则,所以必须再填充3,占28字符(4 * 7 = 28)。
(二)结构体的存储空间分配
struct Coordinate
{
char x;
int y;
float z;
double t;
};
(1)在变量类型不一致时,在声明结构体时利用构造函数直接对其初始化。
struct Coordinate()
{
x = 'a';
y = 0;
z = 0.0;
t = 0.0;
}
char x;
int y;
float z;
double t;
};
(2)在一致时,利用calloc函数或memset函数进行初始化比较方便。
a) calloc 函数
#include <malloc.h>
struct Coordinate // 直角坐标系
{
double X;
double Y;
double Z;
double t;
};
struct Coordinate *a = (struct Coordinate *)calloc(3, sizeof(struct Coordinate));
b) memset 函数在主函数中使用以下初始化即可
Coordinate *coor;
memset(coor, 0, sizeof(Coordinate));