一、结构体介绍
结构体是一种自定义的数据类型。和C语⾔已经提供了内置类型,如:char、short、in、float等等类似,只是结构体结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。简单来说,当我们要来描述一个学生时,需要定义名字,身高,体重,性别,成绩等等,那单单使用int类型就定义不了名字这些,而使用char类型又定义不了身高,体重这些,而我们就可以根据需要在结构体定一多种类型定义不同类型的数据,结构体就是解决这个问题的,可以让我们自己创造合适的类型已适用不同场景。
二、结构体的声明
struct
Name
{
成员列表;
}
变量列表
;
创建结构体是需要关键字
struct
,
后面加上结构体的名称(自定义)
,然后接个{ },
里面一个或有多个成员列表
,
括号后面可以有变量也可以没有
,
但必须有;
。
eg: 一个学生有名字,成绩,学号,年龄的信息。
struct
Student
{
char name[20]; //名字
float score; //分数
int id; //学号
int age; //年龄
} stu1 ; // 创造struct Student类型的变量stu1,和 int a类似(创造int类型的变量a)
{
char name[20]; //名字
float score; //分数
int id; //学号
int age; //年龄
} stu1 ; // 创造struct Student类型的变量stu1,和 int a类似(创造int类型的变量a)
int main()
{
struct Student stu1 = { "李四",95.5,10,21 };//对stu1赋值
printf("%s %.2f %d %d\n", stu1 . name, stu1 . score, stu1 . id, stu1 . age); //将信息打印出来
return 0;
}
{
struct Student stu1 = { "李四",95.5,10,21 };//对stu1赋值
printf("%s %.2f %d %d\n", stu1 . name, stu1 . score, stu1 . id, stu1 . age); //将信息打印出来
return 0;
}
在打印信息的时候用到了点操作符,结构体成员的直接访问是通过点操作符(.)访问的
上述代码结果:
![](https://img-blog.csdnimg.cn/direct/79c0ce1fbb8f41a5838ef833fb27656c.png)
这样就描述了一位名字叫李四,分数为95.5,学号为10,年龄为21的学生。
三、结构体内存对齐
我们知道char类型占1个字节,short类型占2个字节,int类型和float类型占4个字节,double类型和long long类型占8个字节,那一个结构体占多少个字节?
再来看一个例子:
#include<stdio.h>
struct s1
{
int a;
char b;
char c;
};
struct s2
{
char b;
int a;
char c;
};
int main()
{
printf("%zd\n", sizeof(struct s1));
printf("%zd\n", sizeof(struct s2));
return 0;
}
struct s1
{
int a;
char b;
char c;
};
struct s2
{
char b;
int a;
char c;
};
int main()
{
printf("%zd\n", sizeof(struct s1));
printf("%zd\n", sizeof(struct s2));
return 0;
}
上述代码结果:
![](https://img-blog.csdnimg.cn/direct/3a1bf552e81943399df4e358a1f93605.png)
可以看得出来结构体s1 和s2 里面的的成员列表一样,只是顺序不一样,可为什么计算出来的内存大小不一样?这就要说到
结构体内存对齐。
对齐规则:
1.结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处
2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对⻬数 = 编译器默认的⼀个对齐数与该成员变量⼤⼩的
较小值
。
VS 中默认的值为
8
Linux中 gcc 没有默认对⻬数,对⻬数就是成员自身的大小
eg: 在VS中的 int a;由于int类型占
4
个字节,VS中默认的值为
8
,所以int a的对齐数为
4
。
3.结构体总大小为最大对齐数(结构体中每个成员变量都有⼀个对齐数,所有对齐数中最大的)的
整数倍。
4.如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最⼤对齐数的整数倍处,结构
体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对⻬数)的整数倍
。
当我们创建一个结构体变量s1时内存会开辟一块空间来存放s1的数据,如下图:
![](https://img-blog.csdnimg.cn/direct/4bc8ab85fc4b4d10885c2cc3aac40a23.png)
结构体s2的内存计算如下图:
![](https://img-blog.csdnimg.cn/direct/48164a85966f452e88730f6ae37f059f.png)
(
注:图中 3.下面有误,是在s2中的最大对齐数为 int a 的4,而不是s1,红色字体是结构体s2的内存大小为12个字节,而不是s1)
那如果结构体里面有定义结构体类型,该如何计算
eg:
#include<stdio.h>
struct s2
{
char b;
int a;
char c;
};
struct s3
{
int a;
struct s2 b;
char c;
};
int main()
{
printf("%zd\n", sizeof(struct s3));
return 0;
}
{
char b;
int a;
char c;
};
struct s3
{
int a;
struct s2 b;
char c;
};
int main()
{
printf("%zd\n", sizeof(struct s3));
return 0;
}
上述代码结果如下:
![](https://img-blog.csdnimg.cn/direct/ff6b2a7c8b154ae19fdbc849afdd2576.png)
结构体s3的内存计算如下图:
![](https://img-blog.csdnimg.cn/direct/77e09112e7fb4f9598dbb54690d5a941.png)