结构体
结构体的声明
结构体是一些值集合的,里面可以包括char,int,double等等的各种类型构成的一个新的类型,也就是说相当于自己基于C语言本身给出的类型自己把它组成一个集合。
它的声明格式如下:
struct 类型名{ 元素1; 元素2; ..... }; `` 例如描述一个学生 ```cpp struct stu { char name[20];//名字 int age;//年龄 char ID[20];//学号 };
结构体的自引用
我们知道结构体里面可以包括char,int ,double等等类型,那么通过上面我们讲的结构体它也是一种类型。只不过是我们自己定义的一种类型,那么我们可以在结构体里面定义一个结构体吗?
struct stu { char name[20];//名字 int age;//年龄 char ID[20];//学号 struct stu next; };
这里我们可以知道直接定义是不行的。
那么正确的自引用方式是下面这个
struct stu { char name[20];//名字 int age;//年龄 char ID[20];//学号 struct stu *next; };
这里在C语言后期链表期间给大家详细讲解
结构体变量的定义和初始化
struct stu { char name[20];//名字 int age;//年龄 char ID[20];//学号 }s1,s2; //直接在结构体类型声明后直接定义 struct stu s1, s2; //定义结构体 struct stu s3 = { "张三",18,2022001 };//定义后直接初始化 struct nau { int num;//号数 char name[20];//名字 } a1={18,"李四"};//直接在结构体类型声明后直接定义并初始化 struct cmp { int i; struct nau;//结构体嵌套初始化 }p1 = { 1,{18,"丽子"} };
结构体内存对齐
基本了解结构体的内容之后,我们就要计算结构体的大小了。
这也是一个特别热门的考点:
那么我们直接上几道练习
#include<stdio.h> struct s { char i; char j; int a; }s1; struct c { char b; int b1; char b2; }s2; int main() { printf("%d\n", sizeof(s1));//大小是多少呢? printf("%d\n", sizeof(s2));//大小是多少呢? return 0; }
如何计算?
首先得掌握结构体的对齐规则:
第一个成员在与结构体变量偏移量为0的地址处。
其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
VS中默认的值为8
结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整 体大小就 是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
为什么存在内存对齐?
平台原因(移植原因):
不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
性能原因:
数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
简单来说就是用空间换取时间
那在设计结构体的时候,我们既要满足对齐,又要节省空间,我们要 让占用空间小的成员尽量集中在一起
struct S3 { double d; //练习1 char c; int i; }; printf("%d\n", sizeof(struct S3)); //练习2-结构体嵌套问题 struct S4 { char c1; struct S3 s3; double d; }; printf("%d\n", sizeof(struct S4));
上面s3的大小是16
s4的大小是32
结构体传参
详细请见结构体详解
对于结构体详解,后期会出改良优化过后的版本