1、结构体的声明
结构的基础知识:结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
结构体也可以放数组
结构体地址:结构体第一个成员地址
结构体成员地址同数组也是递增的
struct tag(名称一般不省略)
{
member-list;(不能为空)
}variable-listl(可省略);
例如:描述一个学生
struct Stu
{
char name[20];
int age;
char sex[5];
char id[20];
};//(分号不能丢)
struct Stu s;//定义结构体变量
访问结构体成员:“.”,“->”
s.age=20;
结构体访问指向变量的成员,有时我们得到的不是一个结构体变量,而是指向一个结构体的指针
struct Stu*ps;
ps->name;
若出现结构体互相包含,推荐使用结构体不完整声明
例如:
struct B;(不完整声明)
struct A
{
int _a;
struct B* pb;
};
struct B
{
int _b;
struct A* pa;
}
2、结构体的定义初始化
结构体与数组初始化方式一模一样,只允许整体初始化不允许整体赋值
例如:
(1)正确
struct Node
{
int date;
struct Point p;
struct Node* next;
}n1={10,{4,5},NULL};
struct Node n2={20,{5,6},NULL};
(2)错误
struct Node n2;
n2={20,{5,6},NULL};
3、结构体的内存对齐(结构体的内存对齐是拿空间换取时间的做法)
(1)第一个成员在与结构体变量偏移量为0的地址处(第一个成员也有对齐数,但第一个元素不需要内存对齐)
(2)其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数=编译器默认的一个对齐数与该成员大小的较小值。VS中默认的值是8,Linus中的默认值是4
(3)结构体的总大小为最大对齐数的整数倍
(4)如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
可以用#pragma pack 更改对齐数
#pragma pack(1) 以1字节对齐->不对齐
#pragam pack( )不传参数 恢复默认
若传参数大于默认对齐数则无效,还为默认对齐数(在Linux)
4、结构体在传参时不能将结构体变量直接传入,选择指针传参,提高性能
5、位段(省空间有跨平台问题)
位段的声明和结构体类似,但有两个不同:
(1)位段的成员必须是int,unsigned int或signed int
(2)位段的成员名后边有一个冒号和一个数字
例如:
struct A
{
int _a:2;
int _b:5;
int _c:10;
int _d:30;
}
1)压缩存储
2)超出的部分直接被丢弃不会影响其他元素
3)常规情况下不需要内存对齐
6、枚举
把可能的取值一一列举
赋值:定义的枚举常量必须被枚举常量赋值,枚举常量就是整数,但是对枚举变量的赋值不能直接赋整数要赋枚举常量
连续从0开始,可以分段赋值
例如:
enum Color
{
RED=1,
GREEN=2,
BLUE=4