一.结构体
1.什么是结构体
(1)因为数组内部的每个元素必须是相同类型的数据。当我们需要不同类型的数据来构成一个整体,这就需要结构体类型。
(2)结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。
2.结构体类型的定义(不会分配存储空间):
struct 结构体名{
类型名1 成员名(变量)1 (这里的变量,我们称为结构体的成员或者属性)
类型名2 成员名(变量)2
类型名3 成员名(变量)3
....
}
struct是个关键字,是结构体类型的标志。上面只是定义了一个结构体类型。就和int类型一样。
3.结构体变量的定义(分配存储空间)
前面只是定义了了一个结构体类型,并非定义了一个结构体变量,就像int一样,只是一种类型。
(1)先定义结构体类型,再定义变量
struct 结构体名{
类型名1 成员名(变量)1
类型名2 成员名(变量)2
类型名3 成员名(变量)3
....
};
struct 结构体名 结构体变量;(struct 结构体 相当于类型)
(2)定义结构体类型的同时定义变量:
struct 结构体名{
类型名1 成员名(变量)1
类型名2 成员名(变量)2
类型名3 成员名(变量)3
....
}结构体变量; (直接在大括号结尾和分号之间定义结构体变量)
struct {
类型名1 成员名(变量)1
类型名2 成员名(变量)2
类型名3 成员名(变量)3
....
}结构体变量; (省略了结构体名,这样的坏处是只能定义1个变量,下次再定义变量需要继续这样写)
4.结构体变量的作用域:
(1)定义在函数外面:全局有效(从定义类型的那行开始,一直到文件结尾)
(2)定义在函数(代码块)内部:局部有效(从定义类型的那行开始,一直到代码块结束)
5.结构体的注意:
(1)在结构体成员变量里面不能有本结构体类型的成员变量,即不允许对结构体本身递归定义
(2)结构体变量里面可以保护其它结构体类型的成员变量。
(3)定义结构体类型的时候,只是说明了有了这个结构体类型,结构体里面有哪些成员变量。但是并不会给他分配存储空间(就像系统不为int类型本身分配空间一样)。只有当定义了结构体类型变量的时候,系统才会分配存储空间给该变量。
(4)结构体变量占用的内存空间是其成员所占内存之和,而且各成员变量在存储中按定义的顺序依次排列。
(5)补齐算法(对齐算法):结构体所占用的存储空间 必须是 最大成员字节数的倍数
(6)结构体类型不能重复定义
(1)struct 结构体名 结构体变量 = {成员变量1的值,成员变量2的值....};(将各个成员的初值,按顺序地放在大括号中,并用逗号隔开,一一对应赋值)。
(2)只能在定义的时候进行初始化赋值,定义后再赋值只能单个赋值。
7.结构体变量的使用
(1)一般对结构体变量的操作是以成员为单位进行的,引用的一般形式为:结构体变量名.成员名(.称为成员运算符,它在所有运算符中优先级最高。这样就可以访问成员变量的值)
(2)如果某个成员也是结构体变量,可以连续使用成员运算符"."访问最低一级成员。
(3)相同类型的结构体变量之间可以进行整体赋值。(就像int变量之间可以赋值一样,前提是同一种结构体类型(结构体名要一样))
8.结构体数组
(1)定义:跟结构体变量一样,结构体数组也有3种定义方式:
<1>
struct 结构体名{
类型名1 成员名(变量)1
类型名2 成员名(变量)2
类型名3 成员名(变量)3
....
};
struct 结构体名 结构体变量[元素个数];
<2>
struct 结构体名{
类型名1 成员名(变量)1
类型名2 成员名(变量)2
类型名3 成员名(变量)3
....
}结构体变量[元素个数];
<3>
struct {
类型名1 成员名(变量)1
类型名2 成员名(变量)2
类型名3 成员名(变量)3
....
}结构体变量[元素个数];
(2)初始化:struct 结构体名 结构体变量[元素个数] = {{},{}...};(有多少个元素里面写多少个括号,括号里按顺序放成员变量值)
也可以用数组下标访问每一个结构体元素,跟普通数组的用法是一样的
9.结构体作为函数参数
将结构体变量作为函数参数进行传递时,其实传递的是全部成员的值,也就是将实参中成员的值一一赋值给对应的形参成员。因此,形参的改变不会影响到实参
10.指向结构体的指针
(1)每个结构体变量都有自己的存储空间和地址,因此指针也可以指向结构体变量
(2)结构体指针变量的定义形式:struct 结构体名称 *指针变量名
(3)有了指向结构体的指针,那么就有3种访问结构体成员的方式
<1>结构体变量名.成员名
<2>(*指针变量名).成员名
<3>指针变量名->成员名
二.枚举
1.枚举的概念
枚举是C语言中的一种基本数据类型,并不是构造类型,它可以用于声明一组常数。当一个变量有几个固定的可能取值时,可以将这个变量定义为枚举类型。比如,你可以用一个枚举类型的变量来表示季节,因为季节只有4种可能的取值:春天、夏天、秋天、冬天。
2.枚举类型的定义
一般形式为:enum 枚举名 {枚举元素1,枚举元素2,……};
3.枚举变量的定义
前面只是定义了枚举类型,接下来就可以利用定义好的枚举类型定义变量。
跟结构体一样,有3种方式定义枚举变量
(1)先定义枚举类型,再定义枚举变量
enum 枚举名 {枚举元素1,枚举元素2,……};
enum 枚举名 枚举变量;
(2)定义枚举类型的同时定义枚举变量
enum 枚举名 {枚举元素1,枚举元素2,……}枚举变量;
(3).省略枚举名称,直接定义枚举变量
enum {枚举元素1,枚举元素2,……}枚举变量;
4.枚举使用的注意
(1)C语言编译器会将枚举元素作为整型常量处理,称为枚举常量。
(2)枚举元素的值取决于定义时各枚举元素排列的先后顺序。默认情况下,第一个枚举元素的值为0,第二个为1,依次顺序加1。
(3)也可以在定义枚举类型时改变枚举元素的值
enum season {spring, summer=3, autumn, winter};
没有指定值的枚举元素,其值为前一元素加1。也就说spring的值为0,summer的值为3,autumn的值为4,winter的值为5
5.枚举变量的基本操作
(1)赋值
可以给枚举变量赋枚举常量或者整型值
enum Season {spring, summer, autumn, winter} s;
s = spring; // 等价于 s = 0;
s = 3; // 等价于 s = winter;
(2)遍历枚举元素
enum Season {spring, summer, autumn, winter} s;
// 遍历枚举元素
for (s = spring; s <= winter; s++) {
printf("枚举元素:%d \n", s);
}