1.结构体类型的概念
在C语言中提供了很多基本的数据类型,但在实际开发中,无法满足程序中各种复杂数据的要求。有时需要将不同类型的数据组合成一个有机的整体,一边引用。例如:
num | name | sex | age | score |
001 | lemon | F | 18 | 90 |
在图中列举了学生的学号、姓名、性别、年龄和成绩几个项目,这几个项目都是相互联系的。如果将这些项目分别存成相互独立的一些变量,很难反映它们之间的内在联系。应该把这些项目组合成一个组合项,在这个组合项中可以包括若干个类型相同或者不同的数据项。这种数据结构就称为结构体。
结构体是一种构造类型,由若干成员组成,每一个成员可以是一种基本的数据类型或者另一种构造类型。因为结构体是一种用户自定义的数据类型,所以在使用之前需要先定义,也就是先构造。定义一个结构体的一般格式如下:
struct 结构体名
{
成员列表;
};
其中,“结构体名”是结构体的标志;花括号内是该结构体中的各个成员,每个成员都需要进行类型说明。声明格式如下: 类型名 成员名;
根据结构体的一般格式,将前面提到的学生结构体定义如下:
注意:
1.不要忽略最后的分号。
2.struct student 是一个类型名,它和系统中提供的标准的数据类型具有相同的地位和作用,都可以用来定义变量类型,只不过结构体类型需要由用户自己定义而已。
3.结构类型体和变量是不同概念,程序员只能对变量进行相应的运算,不能对结构体类型进行运算。系统在进行编译时,仅对变量进行储存空间的分配,并不对结构体类型进行空间分配。
4.结构体类型中的成员相当于变量的作用,并且,结构体中的变量可以单独使用。
5.结构体是可以嵌套的。在使用结构体嵌套时,要先声明内部的结构体struct date再声明外部的结构体struct student.在定义结构体类型struct student时,使用结构体
6.结构体类型中的成员变量可用于程序中其他变量同名。
2.结构变量
1.结构体变量的定义
上文介绍了结构体类型,该类型就相当于一个模型,在这个模型中没有具体的数据,编译器也不为其分配实际的内存单元。结构体类型定义后就可以使用了,下面介绍三种定义结构体类型变量。
1.先定义结构体类型,再声明结构体变量
在前面定义了结构体类型struct student,可以用该结构体类型定义变量。
例如,定义一个结构体类型的变量stu如下:
struct student (结构体类型名) stu ;(结构体变量名)
这里定义了一个名为stu的struct student类型的变量,也就是说它拥有struct student的结构。
变量stu被定义后,系统会为其分配内存单元。对于每一个struct student类型的变量,系统都会为其分配33个字节的内存空间(4+20+1+4+4)。
说明:
如果要编写的程序规模比较大,经常会将这些结构体类型的声明存放在一格后缀名为.h的文件中,如果某个程序需要该结构体,就可以用#include命令将该头文件包括进来,从而便于程序员的修改和使用。
2.在定义结构体类型的同时声明结构体变量
一般格式为:例子:
3.直接声明结构体变量
直接声明结构体变量,是指不声明结构体名称,直接定义结构体类型。它与第二种方法比较类似,不同的是,它不需要定义结构体名称。其一般格式如下:
例子:
4.typedef
typedef相当于struct 结构体名;就像人的小名一样
可以直接定义结构体变量。
2.结构体类型变量的引用
(1) 不能将 结构体变量作为 一个整体进行引用,比如s1,s2都是结构体变量,但不能拿过来直接用,只能对结构体变量中的 各个成员分别引用;引用的方式为:
结构体变量名 . 成员名 [这个 . 叫做结构成员运算符,该运算符优先级 非常高 ,与()平级,所以可以把 s1.num 看作是一个整体]
例如:s1.num=1001; //将1001赋值给s1变量中的成员num
(2) 如果成员本身 又属于一个结构体类型,则要用若干个成员运算符,一级一级的找到最低一级成员,只能对最低级成员进行赋值或者存取。
s1.birthday.month=12;
s1.birthday.day=30;
s1.birthday.year=2018;
(3) 成员变量,就当成普通变量,可以像普通变量一样进行各种运算
s2.age=s2.age; //赋值
int agesum=s2.age+s2.age; //求年龄和
s1.age++; //年龄自加1,因为 . 的优先级最高,所以s1.age是个整体。
//s1++; 这样是不可以的这样写的。也不可以这样写:s1.brithday++;
(4) 因为成员变量我们也是当成普通变量的,所以它们 也是有地址的。
int *p=&s1.num;
pritntf("%d\n",*p); //结果是:1001
3.结构体变量的初始化
1.基本初始化
基本初始化是最常用的结构体初始化方法,通过使用“{}”括号来初始化结构体变量。例如:
2.指定成员初始化
指定成员初始化可以通过指定成员名来初始化结构体的成员变量。例如
3.常量表达式初始化
常量表达式初始化可以在结构体定义时用常量表达式对结构体成员进行初始化。
4. 定义后逐个赋值
5. 定义时乱序赋值
3.结构体的嵌套
4.结构体数组
1.定义结构体数组
类型定义结构体数组和定义结构体类型变量的方法类似,都有3种方法。下面有3种方法定义一个结构体类型数组emp,该数组有10个元素,每个元素都是student结构体类型。
1.先定义结构体类型,再声明结构体数组
2.在定义结构体类型的同时定义结构体数组
3.直接定义结构体数组
2.初始化结构体数组
3.结构体数组的赋值
4.结构体指针
1.指向结构体变量的指针
结构体指针变量的定义格式为:struct 结构体名称 *结构体指针变量名;
2.指向结构体数组的指针
此时指针变量的值就是结构体数组的首地址。
例如定义一个结构体数组student[5],使用结构体指针指向该数组
代码为:struct Student*p; p=student;
也可以直接指向结构体数组的元素例:p=&student[2];