核心
- 结构体类型创建
- 结构体初始化
- 结构体内存对齐 (对齐数,最大对齐数)
- 位段,位段计算机大小
- 枚举(常量)
- 联合(共用体)
具体
- 结构体 : 结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
//结构体的声明
struct Student{
char name[20];
int age;
char sex[5];
};
//结构体变量的定义,并初始化(结构体变量只有一次整体赋值的机会,就是在定义的时候)
struct Student stu = {"老王",20,"男"};
//声明的时候定义结构体变量 stu
struct Student{
char name[20];
int age;
char sex[5];
} stu;
//声明结构体的时候定义结构体变量并初始化
struct Student{
char name[20];
int age;
char sex[10];
} stu = {"老王",18,"未知"};
//结构体的自引用
struct Student{
char name[20];
int age;
char sex[5];
struct Student* node;//指向这个类型变量的指针
};
//结构体嵌套并初始化
struct People{
int age;
int weight;
char name[10];
}
struct Student{
char name[20];
int age;
char sex[5];
struct People peo;
} stu = {"老王",18,"女",{20,180,"老李"}};
- 结构体的内存对齐规则 :
- 第一个成员在与结构体变量偏移量为 0 的地址处
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
- 对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值
- VS中默认的值为8 : Linux中的没有默认值
- 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍
- 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所 有最大对齐数(含嵌套结构体的对齐数)的整数倍
struct Student{
char name[20];//在偏移量为 0 的地方,占 20 个字节
int age;//自身对齐数为 4,在vs默认值为 8,所以对齐数是 4,偏移量在 4 的整数倍处,偏移量为 20,占4个字节
char sex[5];//对齐数为 1,偏移量为 24,占 5 个字节
//结构体的总大小是每个对齐数的最大值的整数倍,最大对齐数是 4,总大小是 32
};
//结构体的嵌套
struct People{
int age;//偏移量为 0,占 4 个字节
int weight;//对齐数为 4,偏移量为 4,占 4 个字节
char name[10];//对齐数为 1,偏移量为 8,占 10 个字节
//总大小为 最大对齐数 4 的整数倍,为 20
};
struct Student{
char name[20];//偏移量为 0,占 20 个字节
int age;//对齐数为 4,偏移量为 20,占 4 个字节
char sex[5];//对齐数为 1,偏移量为 24,占 5 个字节
struct People peo;//此结构体的最大对齐数为 4,偏移量为 28,占 20 个字节
//结构体的总大小为最大对齐数 4 的整数倍,为 52
} ;
//可以用 #pragma pack() 修改默认对齐数
#pragma pack(2) //把默认对齐数修改为 2
struct People{
int age;//偏移量为 0,占 4 个字节
int weight;//对齐数为 2,偏移量为 4,占 4 个字节
char name[10];//对齐数为 1,偏移量为 8,占 10 个字节
//总大小为 最大对齐数 2 的整数倍,为 18
};
#pragma pack() //还原为默认
- 结构体传参 : 由于参数需要压栈,会有时间和空间上的系统开销。当一个结构体过大时,参数压栈的开销比较大, 会导致性能的下降.
- 所以, 在传参时, 最好传结构体的地址
- 位段 : 位段和结构体类似
- 位段的成员必须是 int、unsigned int 或signed int
- 位段的成员名后边有一个冒号和一个数字
- 位段的内存分配 :
- 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
- 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的
- 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段
struct Student{
int age: 3;
int height: 3;
char sex: 4;
}
- 枚举 :
- 增加代码的可读性和可维护性
- 和#define定义的标识符比较枚举有类型检查,更加严谨。
- 防止了命名污染(封装)
- 便于调试
- 使用方便,一次可以定义多个常量
enum A{
RED,
GREEN,
YELLOW,
WHITE
};
//RED GREEN 都是常量,在没有赋初始值的时候,从 0 开始,依次增加
//RED 0
//GREEN 1
//YELLOW 2
//赋初始值
enum A{
RED,// 0
GREEN = 4,//此时,GREEN 代表的常量是 4
YELLOW,// 5
WHITE// 6
};
//枚举变量
enum A clr = RED;
clr = 6;
union un{
char a;
int b;
};
- 联合内存 :
- 联合的大小至少是最大成员的大小
- 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
union un{
char a[9];//最大成员 9 个字节,最大对齐数 4,联合的大小 12
int b;
};
union un{
char a[19];//最大成员 19 个字节,最大对齐数 4,联合的大小 20
int b;
};
over