文章目录
前言
读者朋友们你好,今天主要讲解一下自定义数据类型结构体。共用体和枚举。制作不易,如果有帮助希望点个关注。
3步讲明白结构体内存对齐。
一、结构体声明和创建
声明:
struct tag
{
member - list;//结构体成员可以是任何类型的
}variable - list;//创建变量(可有可无)。
例:
struct Stu
{
char name[20];//名字
int age;//年龄
char sex[5];//性别
};
1.结构体的特殊声明
匿名结构体:
在写结构体时可以不声明:
struct
{
int a;
char b;
};
struct
{
int a;
char b;
}x;
像这种,匿名结构体,只能使用一次。虽然跟下面的内容一样,但这是两个不同的结构体,所以使用这种匿名结构体,应该直接在分号(;)前面创建变量。
2.结构体的自引用
struct Node
{
int data;
struct Node next;
};//这种是不行的,struct Node内部还包含
//一个struct Node变量,最后结果是正无穷大
struct Node
{
int data;
struct Node * next;
};//应该是个指针,因为指针的大小是确定的,
二、结构体内存对齐
1.对齐规则
- 结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处(也就是第一个成员从0开始)
- 其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。
- 结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的整数倍。
- 如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍。
对⻬数 = 编译器默认的⼀个对⻬数(VS默认为8) 与 该成员变量⼤⼩的较⼩值
例:
struct aaa
{
char a[5];//对齐数1<8,所以是1
int ;//对齐数4<8,所以是4
};
第二个为int类型4和8比,对齐数是4,所以对齐到4的整数倍,所以应该最小从4开始,因为第一个地址是char a占5个字节(从0开始)刚好到4,所以b要从8开始往后数(8、9、10、11)。最大对齐数是4,一共占11个字节,离得最近的4的整数倍是12,所以一共占12个字节
接下来讲一下结构体嵌套的讲解
struct aaa
{
char a[5];//对齐数1<8,所以是1
int ;//对齐数4<8,所以是4
};
struct bbb
{
char a;//对齐数1<8,所以是1
struct aaa s1;//对齐数为内部成员的最大对齐数(4)
};
因为第二个成员最大对齐数是4,所以是从4开始一共12个字节,总大小为16个字节
2.为什么有内存对齐
总体来说:内存对齐其实是用空间来换时间
尽量让小的成员在一起可以省略
3.修改默认对齐数
#pragma这个预处理指令,可以改变编译器的默认对齐数
#pragma pack(1)//设置默认对⻬数为1
struct S
{
char c1;
int i;
char c2;
};
#pragma pack()//取消设置的对⻬数,还原为默认
4.结构体传参
结构体传参要传结构体的地址
如果传过去的是值,形参会在内存创建空间,浪费时间
三、结构体实现位段
1.位段的成员必须是整数类型(包括char、int等有符号/无符号类型)
2.位段名字后面有一个冒号(:)一个数字。
struct A
{
int _a : 2;
int _b : 30;
};//数字表示占的比特位的数量。
位段的内存分配
- 位段的空间是以一个int或char类型来开辟的
- 一个字节的内存从左往右还是从右往左是不确定的
- 剩余的空间不能满足下一个成员是否浪费不确定。
- 位段不支持跨平台
struct S
{
char a : 3;
char b : 4;
char c : 5;
char d : 4;
};
struct S s = { 0 };
s.a = 10;//二进制是1010,因为是三个比特位,所以是010
s.b = 12;//1100,四个比特位
s.c = 3;//00011,五个比特位
s.d = 4;//0100,四个比特位
下面是图片

!!注意:
因为有的是多个位段在一个字节,所以不能用取地址符号
int位段被当成有符号还是无符号不确定
位段最大数不确定
四、联合体类型
1.联合体类型的声明、大小、特点
联合体也是由一个或者多个成员构成,这些成员可以是不同的类型。
但是编译器只给最大的成员分配空间,所以联合体是所有成员共用一块空间,所以也叫做:共用体。
例:
union un
{
int a;
char b;
};
联合体每个成员的起始地址是相同的
大小的计算:
1.联合的⼤⼩⾄少是最⼤成员的⼤⼩。
2.当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候,就要对⻬到最⼤对⻬数的整数倍。
union un
{
int a;
char b[7];
};//最大成员为7,最大整数倍为4,所以总大小为8.
五、枚举类型
枚举类型就是一一列举,{}中的内容也叫做枚举常量。
枚举类型的默认值是从0开始的,当然在初始化的时候也可以自己赋值,一旦自己赋值就不可以改了
enum Sex//性别
{
MALE,//默认值为0
FEMALE,//1
SECRET=5,
};
优点
- 增加代码的可读性,一次可以定义多个
- 枚举常量是遵循作⽤域规则的,枚举声明在函数内,只能在数内使⽤,
- 和#define定义的标识符⽐较枚举有类型检查,更加严谨。
237

被折叠的 条评论
为什么被折叠?



