前言
那么,c语言为了可以很好的描述这些复杂对象,就引入了结构体的概念。
结构体
定义:结构体是一些值的集合,这些值被称为成员变量。结构体的每个成员变量可以是不同类型的变量
结构体的声明:
(1)完全声明
图解如下:
这里的b就是在主函数体内的定义的局部变量,a是定义在函数体外部的全局变量。
(2)不完全声明
其实定义的方式差不多,只不过没有标签名,那么此时只能在全局变量的部位去定义这种结构体类型的变量,不能在其他地方定义了
自定义结构体类型的独立性:在下面的定义中可以看到 struct U 和 struct N 的成员变量虽然相同,但是以两种类型的结构体分别定义的变量和指针,类型不匹配。
(3)结构体的自引用:简单的线性链表
第一种自引用的方式:
第二种自引用方式:
图解如下:
结构体定义的简化(typedef 类型重命名关键字)
结构体的访问:(两种访问方式)
结构体大小的计算:
通过前面的了解,我们已经知道了结构体的创建和访问,那么结构体的大小是怎么样的呢???
或者说成员变量在结构体内部是如何存放的呢????
可以看到,我们定义的结构体 u 只定义了三个变量,按照标准大小来计算,那么结构体变量a应该是6个字节的大小。那为什么这里的结果是12呢????
这里就涉及到了结构体的内存对齐了
结构体的内存对齐:
规则1:结构体的第一个成员,必须放在结构体变量在内存中存储位置的0偏移除开始
这个结构体中的第一个成员变量c 就被放置在图中的位置
规则二:从第二个成员往后,都放在一个对齐数(成员变量自身的字节大小和默认对齐数的较小值)的整数倍的位置 (因为我使用的编译器是vs2019,默认对齐数为8)
结构体的成员 a和b的存储位置
规则三:结构体的总大小是所有成员的对齐数中最大的那个对齐数的整数倍
而这个结构体从0字节位置到第11个字节的位置正好12个字节大小,是这个结构体最大对齐数4的整数倍。最终的结构体大小为12字节。(在上面已经求过了)
规则四:如果这个结构体中嵌套其他的结构体,嵌套的那个结构体对齐到自身最大对齐数的整数倍的位置,结构体的总大小也是结构体所有成员变量的最大对齐数的整数倍。(含嵌套的结构体的对齐数)
所以在为了节省空间,我们在创建结构体时,将听类型的结构体定义在相邻位置。
可以看到两种成员变量相同的结构体,只是成员变量的位置不相同,但是最终的结构体的大小却是不相同的。
最后在c语言中有是可以修改默认对齐数的。