当前位置 博文首页 > 无っ的博客:自定义类型(struct结构体)
1.结构体类型创建
(1)常用创建推荐用这种
struct Student{ //里面是各种信息
int age;
char gender;
float score;’
};
struct Student s; // 定义结构体变量
(2)
typedef struct Student{ //里面是各种信息
int age;
char gender;
float score;
}student;
它更方便使用或建立结构体变量,直接这样:
student s; // s就是一个结构体变量
(3)匿名结构体(基本没用)
struct { //里面是各种信息
int age;
char gender;
float score;
}s;
2.结构体初始化
一般在定义结构体变量时直接进行初始化,或者通过指针指向。
struct Student{ //里面是各种信息
int age;
char gender;
float score;
};
struct Student s = {12,“李楠”,100}; // 定义结构体变量
s.score = 80;
struct Student *p = &s;
p -> score = 70;
(*p). score = 30;
先定义在初始化不行例如
struct Student s;
s = {12,“李楠”,100}; // 这样不行
3.结构体内存对齐
要满足4大原则:
1.第一个成员在与结构体变量偏移量为0的地址处。
2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数与该成员大小的较小值。
例如 vs中默认值为8
3.结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
4.如果嵌套了结构体的情况,嵌套的结构体对齐到自已的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
来看一个简单的例题
struct Test{
char a; //a 放在偏移为 0 的 位置上
int b; // b (8 > 4) => 4 放在偏移量为 4 的整数倍上,则应放在 4上 则 前面浪费了3个字节
char c;c (8 > 1) => 1 放在偏移量为 1 的整数倍上。
}Test;
他在内存中的图应该为:
这样看他就有12个字节了
而且结构体的对齐数可以手动修改,这样默认值就可以挨在一起了。
#pragma pack(1) //这样默认值为1 全连着放也是有多少字节就有多大内存
struct Test{
char a; //a 放在偏移为 0 的 位置上
int b; // b (8 > 1) => 1 放在偏移量为 1 的整数倍上
char c;c (8 > 1) => 1 放在偏移量为 1 的整数倍上。
}Test;
#pragma pack() //还原默认值
4.位段,位段计算机大小
位段:成员必须是int 、unsigned int 和signed int .
位段的成员名后边有一个冒号和一个数字。
计算:位段是按比特位的大小来进行计算的,比如一个字节有8个比特位,存入的时候根据数据类型的不同计算出相应的比特位依次往后存储,若存储不下则开辟下一个字节
struct Test
{
int a:4;
int b:5;
int b:6;
int b:30;
};
s就是一个位段类型
printf("%d\n",sizeof(struct S));//8
分析:int 型具有四个字节,共32个比特位,故存储时将前三个放入第一块空间中,由于第四个是30个比特位存储不下,因此开辟下一快空间存储,即开辟了两快空间,就是好8个字节。其他类型同理可得。
5.枚举+联合
(1)枚举
enum color
{
red;
orange;// 2
yellow = 3;
green;// 4
blue;
};
枚举常量默认值从0开始,依次递增一,在定义时也可赋初值。
enum color purple=blue;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
(2)联合
是一种特殊的自定义类型,特征是这些成员公用同一块空间(所以联合也叫共用体)。
union Un
{
char c;
int i;
};
union Un A;
printf("%d\n",sizeof( A));//4
cs