一.结构体
1.结构体的声明
struct tag //tag是标签
{
member -list; //成员列表
}variable //是变量列表
2.结构体可以不完全声明--也就是可以去掉tag
通过类型创建内存空间,实例化
3.结构体成员的访问
结构体成员可以用符号 . 来访问,例如:variable.member
有时我们用结构体指针来访问成员,例如:p->member,他就相当于 (*p).member
4.结构体自引用
自引用,在数据结构链表里最常见
struct node
{
int data;
struct node *next
}node;
5.最重要的是了解结构体内存对齐
结构体是如何内存对齐的?
举个栗子:下面结构体的字节大小是多少呢?
struct s1
{
char c1; //1
int i ; //4
char c2; //1
}
它的总大小是8个字节
struct s1
{
char c1; //1
int i; //4
char c2; //1
}
它的总大小是12个字节
首先要掌握结构体对齐规则
1.第一个成员在与结构体变量偏移量为0的地址处
2,其他成员要对齐到某个对齐数的整数倍的地址处。对齐数=编译器默认的一个对齐数与该成员大小的比较值。(其中VS为8,
LINUX 为4)
3.结构体总大小为最大对齐数的整数倍
4.如果嵌套了结构体情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数的整数倍
如果你不明白的话,多找几个题练习下,就会了
6.为什么要存在内存对齐?
内存对齐需要浪费一部分空间,为什么需要它呢?
1.平台原因:
不是所有平台都能访问任何地址上的任意数据的,某些平台只能在某些地址处取某些特定的类型数据,否则抛出硬件异常
2.性能原因:
数据结构应该尽可能的对齐,原因在于为了访问未对齐的的内存,处理器需要作两次访问,而对齐的内存只需要访问一次
二,位段
1.什么是位段?
1.位段和结构体成员类似
2,位段成员必须是int ,unsigned int, sign int,char
3.位段的成员名后面有一个冒号和一个数字
4.位段是不跨平台使用的
(1)int 位段被当成有符号数和无符号数是不确定的
(2)位段中的最大为的数目不能确定
(3)位段中的成员不知道向左还是向右分配内存
(4)舍弃问题,不知道是舍弃还是利用
三,枚举
enum 是全局变量
枚举的优点:
1.增加代码的可读性,可维护性
2.防止命名污染
3.利用调试
4,有类型检查,更加严谨
5一次可以定义多个变量
四,联合
联合是一种自定义类型,它定义的变量包含一系列的成员,它们公用同一块空间(所以他也叫共用体)
联合计算小的方式:
1.联合的大小至少也是最大成员的大小,
2.当最大成员大小不是最大对齐数的整数倍的时候,就需要对齐到最大对齐数的整数倍