结构体
结构体是一种自定义的数据类型,不同于之前学过的int,char,float等简单数据类型,结构体可以把多种不同类型的数据组合成一个整体,构成一个变量。在现实生活中很容易找到这样的例子,例如,一个学生的基本信息包括姓名、性别、年龄、身高、体重等等,利用结构体我们可以把这些信息整合成一个整体进行存储。
声明结构体
struct 结构体名{
类型 变量名;
......
}[变量1,......];
例如:声明一个存放学生成绩的结构体
struct Student{ char name[10]; int yuwen; int shuxue; };
定义结构体变量
struct 结构体名 变量1,......;
一个结构体变量的字节数等于所有成员变量所占字节的总和。结构体变量初始化
struct Student s={"tony",80,70,87};访问结构体成员
s.yuwen=89;结构体应用
结构体变量作为函数参数
将主函数中的结构体变量作为参数传递给子函数,在子函数中访问的是同一个结构体变量。
结构体指针
指针指向结构体变量后,可以通过指针引用结构体变量的成员。但不是用 . 运算符而是用 -> 引用。例如:struct Studen *p,a; p=&a; p->shuxue=80;
结构体中的结构体
结构体的成员变量可以是另一种类型的结构体变量,例如:学生结构体中有一个出生日期成员,出生日期有年、月、日三个构成,本身也可以是一个结构体。
结构体数组
如果需要定义批量的结构体变量,可以定义结构体数组,例如:struct Student a[10]; 这个数组中可以存储10个学生的成绩信息。
链表
如果需要存储N个学生记录,而且N是不确定的,那么用结构体数组无法解决这个问题,只能用动态分配内存的方法,每输入一个学生记录分配一个结构体变量的内存空间。但是每个分配的空间需要一个指针来存储地址。可以在学生结构体重增加一个指针,指向自身类型的结构体指针,如下:
struct Student{ char name[10]; int yuwen; int shuxue; struct Student *next };
这样可以把动态分配的这些结构体变量依次链接起来,形成一个链表。链表相对于数组来说列表长度可随意增减,非常灵活。
共用体
共用体中也可以定义多个成员变量,与结构体不同的是,共用体的所有成员变量共享一个内存空间,因此共用体变量所占的内存字节数取决于成员变量中占字节数最多的那一个。尽管共用体包括多个成员,但它同一时间只能存储一个成员的值。共用体union关键字进行声明,如下:
union Number{
int a; char c;
} x;
x.a=100; x.c='A';
x是一个共用体变量,它占4个内存字节,它有2个成员变量,但是同一时间只能让一个成员变量存储值,因为a和c是共用同一个内存空间。
结构体中的共用体
假如要存储一批学生数据,每个学生有姓名、性别、年级、学号等信息,其中2021届以前的学生学号是一个整数,2021以后的学生学号是一串字符,则可以将学号定义成共用体。
struct Student{
char xm[10]; char xb;int nj;
union Xuehao{int n; char x[10];},xh;
};
共用体中的结构体
假如有一些图形数据需要存储,包括矩形、三角形、圆形,每种图形需要存储的数据不同,矩形需要存两个坐标,三角形需要三个坐标,圆形需要一个圆心坐标和半径。可以将存储这些图形数据的结构体定义在一个共用体内。如下:
union Tuxing{
struct Juxing{char name[10];int x;int y;int x1;int y1;} jx;
struct Sanjiao{char name[10];int x;int y;int x1;int y1;int x2;int y2;} sjx;
struct Yuanxing{char name[10];int x;int y;int r;} yx;
}tx;
共用体变量tx中可以存储一个图形数据,但同时只能是其中一种图形。我们将tx传给一个子函数,子函数根据图形的名字将相应的图形绘制出来。
draw(tx);
共用体变量初始化
用typedef声明新类型
在C语言中,使用用typedef关键字可以定义新的数据类型,例如:
typedef int Integer;
Integer a; //a是整型变量
typedef int* INT;
INT p; // p是整型指针
typedef struct Studet Stu;
Stu x; // x是Student结构体变量
typedef struct{
int year;
int month;
int day;
} Date;