前言
C语言的数据类型包括基本类型(内置类型)、构造类型(自定义类型)、指针类型和空类型(void)。详细介绍可以看笔者之前的写一篇文章:【c语言】数据在内存中的存储。今天我们主要来学习一下结构体、枚举和联合体。
一、知识点回顾
1.1 内置类型
char
short
int
long
long long – c99
float
double
Bool 布尔类型 – c99
1.2 自定义类型
struct
enum
union
二、 结构体的基础知识
结构是一些值的集合,这些值成为成员变量。结构的每个成员可以是不同类型的变量。
2.1结构体的声明
// 1. 正常初始化
struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
char id[20];//学号
}stu; //分号不能丢;同时可接变量,也可不加,另外单独初始化。
// 2. 匿名(省略标签)初始化
struct
{
char name[20]; //名字
int age; //年龄
char sex[5]; //性别
char id[20]; //学号
}stu; //结构体变量
2.2结构体的对齐规则
- 第一个成员在与结构体变量偏移量为0的地址处。
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。(VS中默认的值为8)- 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
- 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处;结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
2.3 为什么存在内存对齐
性能原因: 如果不做内存对齐,cpu在读取内存数据时,会增加许多耗时的动作。 而做了内存对齐后,虽然会产生一部分内存碎片,但极大提高了cpu访问内存数据的速度,属于空间换时间的做法。
平台原因(移植原因): 提高访问速度是内存对齐的原因之一,另外一个原因是某些平台(arm)不支持未内存对齐的访问。
2.4 内存对齐计算练习
题目:
int main()
{
//练习1
struct S1
{
char c1;
int i;
char c2;
};
printf("%d\n", sizeof(struct S1));
//练习2
struct S2
{
char c1;
char c2;
int i;
};
printf("%d\n", sizeof(struct S2));
struct S3
{
double d;
char c;
int i;
};
printf("%d\n", sizeof(struct S3));
//练习4-结构体嵌套问题
struct S4
{
char c1;
struct S3 s3;
double d;
};
printf("%d\n", sizeof(struct S4));
return 0;
}
答案:
解析:练习1和练习4;练习2和练习3自己练习。