一、结构体
由一系列具有相同类型或不同类型的的数据构成的数据集合(但不能包含函数类型)
1.定义
1)第一种形式
- struct 结构体类型名
- {
- 数据类型名1 成员名1;
- .........
- 数据类型名2 成员名2;
- };
- struct 结构体类型名 变量名列表;
2)第二种形式
- struct 结构体类型名
- {
- 数据类型名1 成员名1;
- .........
- 数据类型名2 成员名2;
- }变量名列表;
注意:
结构体的成员也可以是一个结构体变量
C语言允许对两个相同类型的结构体变量之间进行整体赋值,但不允许整体输出;
2.指向结构体的指针
- struct 结构名 * 结构指针变量名;
3.访问成员
- 结构体变量名 . 成员名 或 (*结构体指针变量).成员名
4.结构体与函数
1)结构体变量和结构体指针变量作为函数返回值
- struct struct_function(void);
- struct * struct_function(void);
第一个返回的是结构体对象
当返回值为结构体变量时,是将返回的结构体初始化
第二个返回的是结构体指针(速度比较快)
当返回值为结构体指针变量时,初始化函数返回指针变量时是修改内存中的一个结构体变量的值,并将该结构体变量的初始地址返回
2)结构体变量和结构体指针变量作为函数形式参数
- struct struct_funtion(struct struct_pm,...);
- struct * struct_funtion(struct * pstruct_pm,.....);
A)形参为结构体变量
当结构体变量作为形参时,在调用该函数时,首先复制整个结构体形成结构体副本,然后对副本进行修改,但并没有修改原来的结构体,再将副本作为返回值返回
B)形参为结构体变量指针
当结构体指针作为形参时,在调用该函数时首先复制的是该结构体的地址,形成一个地址副本,然后使用这个地址副本对其指向的结构体变量进行修改,最后将地址副本作为返回值
二、共用体
共用体用来描述类型不同的数据,与结构体不同的是:共用体对成员存储时采用覆盖技术,共享存储空间,成员被分配在同一段内存空间中。成员既可以具有相同的数据类型,也可以具有不同的数据类型
1、定义
- union 共用体名
- {
- 数据类型 成员名1;
- 数据类型 成员名2;
- .........
- 数据类型 成员名3;
- };
2、共用体与结构体的比较:
1)相同的定义方式
2)引用成员的方式也一样
3)共用体变量所占的内存长度等于其成员变量中所占存储空间最大的那个,而结构体变量其所占的内存长度等于其成员变量所占内存之和(不考虑内存对齐)
- struct
- {
- char i;
- float f;
- }sum; //定义一个结构体变量sum
- union
- {
- char i;
- float f;
- }max; //定义一个共用体变量
3、共用体的初始化
初始化共用体变量,只需初始化第一个成员
错误的初始化方法:
- union mark
- {
- int score //表示分数
- char degree[4]; //表示等级
- } liming = {90,"优"}; //出错
正确的初始化方法
- union mark
- {
- int score //表示分数
- char degree[4]; //表示等级
- } liming = {90};
4、注意事项:
1)共用体存放的是最后一次存放成员的值
- max.i = 100;
- max.f = 123.123;
执行完上面两条语句后,只有max.f有效,max.i 已经没有意义了
2)共用体变量的地址和各个成员的地址都是同一个地址值
3)不能把共用体变量用作函数参数和函数返回值,但可以使用指向共用体变量的指针
三、枚举
一种将变量可能取值明确列举出来,变量的取值只限于列举出来的常量。
- enum 枚举名{枚举值表};
- enum 枚举名 变量名列表;
eunm meta_color{ red, green, blue };
- enum meta_color{red, green = 20, blue};
四、自定义类型 typedef
并不是用户自己定义的一种新的数据类型,而是用户根据自己的具体需要给某种数据类型重新命名
1.定义
- //typedef 类型名 标识符
- struct pts
- {
- int x;
- int y;
- };
- typedef struct pts Point;
typedef 实质上是对现有数据类型的另一种说明,并没有增加新的数据类型
2、typedef和define的不同:
1)typedef只针对数据类型,不针对值,define既可以针对数据类型,也可以针对值。
2)typedef是对一种已有数据类型的彻底“封装”,在声明之后不能再往里面添加任何代码,而define只是简单的文本替代
3、typedef的主要作用;
1)使用typedef有利于程序的移植和跨平台开发
- typedef unsigned int size_t;
在所有的计算机平台中,没有哪一种类型是最佳的选择,因此给出了一种新的数据类型size_t,让具体的实现者来这个类型名定义为特定的类型。size_t定义在头文件time.h中
2)使用typedef可以简化代码