内置复杂类型:结构体类型,枚举,联合

1.结构体的声明:结构是一些值得集合,这些值称为成员变量,结构体每个成员变量可以是不同类型的变量。

struct tag(标签)                                            这个整体是一个结构体类型,想成int也是类型

{                                                                       类型 不占空间。

member-list;成员变量

}variable-list;变量列表 (列如s1,s2是全局变量)  

typedef给类型重新起个名字,放在结构体声明前相当于把结构体类型重命名。就是省略个结构体标签。

2.结构体类型的定义:struct stu s1定义结构体变量s1

变量放在结构体声明后为全局变量,放在主函数里面创建自定义为局部变量。

2.结构体自引用,结构体里面成员自己包含自己,考虑sizeof(结构体变量)无穷大,

结构体里面成员列表可以包括自己结构体类型的指针,相当于结构体里面放一个数据,再放下一个结构体变量地址

3.结构体内存对齐:结构体对齐规则

a。第一个成员在结构体变量偏移量为0的地址处

b.其他成员变量对齐到某个数字(对齐数)的整数倍的地址

对齐数指编译器默认的一个对齐数与该成员大小的较小值  vs默认为8

c。结构体的总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍

d。如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍,结构体的整体大小就是所有最大对齐数

(含嵌套体对齐数)的整数倍

在设置结构体时,既要满足对齐又要节省空间,让占用空间小的成员集中在一起。

自己设置默认对齐数,#pragma pack(4),要取消还得在结构体后面写#pragma pack().

4.offsetof可以用来算偏移量,结构体成员变量相当于起始位置的偏移量。如offsetof(struct S,c)算结构体成员列表c相对于起始位置偏移量。

结构体可以传参也可以传地址,一般传地址比较好,地址就是一个指针的大小,结构体有时候太大,所所以传地址比较好一点。


位段;结构体实现位段的能力,位段和结构体声明是类似的,有两个不同,

1.位段的成员必须是int,unsigned int,signed int,char属于整型家族 2.位段的成员名后有一个冒号和一个数字

struct A          A就是一个位段类型,位是二进制位,冒号后面的数字说明a只需要2个bite位,

{                      位段内存分配规则;1.位段空间上是以4个字节或者1个字节来开辟的

int a:2;                                      2.位段涉及很多不确定因素,位段是不跨平台的,可移植程序避免位段使用

};

位段可以节省空间

2.枚举类型把可能的取值一一列举。

枚举的定义   enum DAY                                                                       enum Sex

                     {Mon,Tues,Wed,Thur,Fri,Sat,Sun};                                   {MALE,FEMALE,SECRET };         

注意:枚举常量在定义部分可以赋初值,假如首元素赋值为7后面8,9,10

C语言源代码-预编译-编译-链接-可执行程序     

3.联合:联合也是一种特殊的自定义类型,这种类型定义的变量包括一系列的成员,特征是这些成员公共用同一块空间。也叫共用体。

   union un

{int;                                 联合体的成员共用一块内存空间,这样一个联合体变量的大小,

char c;                              至少是最大成员的大小,当最大成员大小不是最大对齐数的整数倍时,

};                                     就要对齐到最大对齐数的整数倍。数组对齐数是里面元素的对齐数。        

前面都是铺垫也很重要可以实现通讯录

搞个通讯录,创建test.c,用来测试   contact.c,实现函数的功能   contact.h声明函数

通讯录功能,1.存放好友信息,2.增加好友信息,3.删除指定好友的信息,4.查找好友的信息,5.修改好友信息

6.打印好友信息7.排序