一、定义:
结构体是C的基本数据类型之一 ,它和数组是C中的聚合数据类型,能够同时存储超出一个的单独数据,但和数组的区别是,可以存储不同类型的数据存储在一起
二、申明方式
struct TAG {
member 1 ;
member 2 ;
...
...
} var1 ,var2 ... ;
TAG 标签用来区分是何种类型的结构体 ,是可选的,可以省略,但是一般申明一个结构体变量的时候带上标签,可以指定是那种类型的结构体 ,例如:
注意:即使两个结构体所有的成员变量都一模一样,还是不同的结构体
三、初始化
方式1 : 申明的时候进行初始化
方式2 :先申明一个结构体变量 然后利用点语法成员变量一一赋值
四、结构体指针
申明一个指针指向一个结构体,然后就可以用->(箭头操作符) 访问和修改结构体内部的成员变量,而且一般函数的参数类型中含有结构体,传的往往是指向结构体的指针,因为如果直接传结构体需要拷贝整个结构体,开销很大。
五、结构体的自引用
一个结构体包含了该结构体本身的成员是否合法呢? 看个例子
这种情况直接报错,编译无法通过,因为结构体B还未申明完整,又包含了类型B的结构体,这样会一直递归下去,永无止境,编译器不允许这种情况的出现。
但是结构体内部包含一个指向该结构体类型的指针是允许的,例如:
因为编译器在知道结构体的长度之前已经知道了这个指针的长度,你可以把内部的指针想象成普通的指针,结构体内部存的就是一个整型和一个指针,长度在编译的时候已经确定了,所以合法
六、结构体的存储分配
编译器会按照成员列表的顺序逐个分配每个成员的内存,存储成员变量的时候需要满足正确的边界对其,所以成员之间可能出现用于填充的额外存储空间。结构体成员变量类型往往不同,所以变量与变量的内存分配之间有间隙
如果某个机器的整型长度是4个字节,并且它的起始位置必须能够被4整除,则结构体内成员a变量后有三个字节空隙,接着是成员变量b、c
提示:我们有足够的理由决定不对结构体成员排序来减少对齐带来的空间损失,因为我们经常会把相关的结构成员存储在一起,提高程序的可读性和可维护性。但是如果不存在这样的理由,那么就应该更具它们的边界进行重排,减少因为边界对齐而造成的内存浪费