内置复杂类型:结构体类型,枚举,联合
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.排序