由表1可见,每一个“成绩”都与一名学生和一门课程相关联。比如表1中的数学成绩“88”分,指的是学号为“1”号的学生“刘荫”的数学成绩。如果将学生的学号、姓名、数学成绩、计算机成绩和英语成绩,分别定义为互不相关的简单变量或数组,将不利于后期的实际应用。 例如,下面的代码分别定义了5组不同的变量,分别用以描述表1中的学号、姓名、成绩等信息: char number1[4],number2[4],number3[4]; char name1[8],name2[8],name3[8]; int math1,math2,math3; int pc1,pc2,pc3; int english1, english2, english3;
| //分别存储3名学生的学号 //分别存储3名学生的姓名 //分别存储3名学生的数学成绩 //分别存储3名学生的计算机成绩 //分别存储3名学生的英语成绩 |
那么在实际应用中就会存在如下问题: 当学生人数增加时,变量的数量就会增加。目前,描述3名学生的信息时定义了15个变量,当需要描述30名学生的信息时,变量的个数就增加到了150个。 当然,这个问题可以通过定义数组来解决。即:number[3][4]、name[3][8]、math[3]、pc[3]、english[3](三组成绩也可以用二维数组score[3][3]来表示)。这时,学生信息的描述格式如下所示:
char number[3][4]; char name[3][8]; int score[3][3];
| //存储3名学生的学号 //存储3名学生的姓名 //存储3名学生的三门课成绩 |
|
但是,学号、姓名、成绩这些数据之间是有着内在联系的,即:它们隶属于学生这个整体,而上面的定义方式又不能使它们构成一个有效的整体。如果要进行一些略微复杂的操作,将会很麻烦。例如,我们要对表1中的数据按数学进行降序排序,仅对数学成绩进行降序排列是远远不够的。因为我们必须知道这个数学成绩是谁的数学成绩,换句话说,在对数学成绩排序时,还要把这个成绩关联到一个具体的学生(包括学生的姓名、学号及其他两门课程的成绩),即:需要同时对学号、姓名、计算机成绩、英语成绩进行操作。 为了形象描述“学号-姓名-成绩”这种有内在联系的数据,需要将这种数据组合成一个整体来进行存储和处理,C语言使用一种称为结构体的数据类型来描述这种数据。结构体类型的数据,可以被理解成二维表格,如表1所示。 表格的结构设计可以理解成结构体类型设计; 表格中的每一行可以理解成是一个结构体变量,是一个整体; 表格中的每一列可以理解成是对象的某个属性,在结构体中称为成员变量; 表格中的每一行是一个对象的全部属性的集合,如一个学生的所有属性信息的结合; 表格中有多少行,就相当于是多少个结构体变量; 当表格行数很多时,分别来定义这些结构体变量不但很麻烦而且不容易控制,这时候可以用结构体数组来表示这些数据。
当实际的需要不同时,表格所要表示的信息类型也会不同,表9-1表示了“学生姓名-学号-课程成绩”的信息,有时可能需要表示“学生姓名-性别-年龄”或者“商品名称-价格-数量”等等其他信息。因此,要根据实际需要定义不同的结构体类型,即下一节要讨论的如何定义不同的结构体类型。 |
定义结构体类型后,必须为其定义变量,才能使用该结构体类型,称这种变量为结构体变量。声明结构体变量有三种方法: 方法一:先定义结构体类型,后声明结构体变量。 struct stu_info1 { char number[4],name[8]; int math,pc,english; }; struct? stu_info1 stu1,stu2,stu3;
|
这里,代码行1-5定义了结构体类型sturct stu_info1,代码行6声明了3个结构体变量。 方法二:定义结构体类型同时声明结构体变量。 struct stu_info1 { char number[4],name[8]; int math,pc,english; }stu1,stu2,stu3;
|
这里请注意,代码行5,“}”外没有分号,在定义了结构体类型后紧跟着声明了3个结构体变量。 方法三: 不定义结构体类型,直接定义结构体变量。 struct { char number[4],name[8]; int math,pc,english; }stu1,stu2,stu3;
|
这里请注意,代码行1:关键字“struct”后面省略了结构体名。这时,因为没有定义结构体类型,程序在代码行5后就无法再定义与结构体变量stu1,stu2,stu3相同的新的结构体变量。 声明结构体变量后,系统为变量分配存储空间存储数据,通过结构体变量成员的引用来实现数据的处理。 |
结构体变量的引用,通常是逐个引用其成员,尤其是输入或输出,不可以整体引用结构体变量,都要逐个处理其成员。 struct stu_info1 //结构体类型定义放在主函数内 { char number[N],name[M]; int math,pc,english; }; //先定义结构体类型后声明结构体变量 struct ?stu_info1? stu1={"1","刘荫",88,86,78},stu2; printf("输入学生学号 姓名 数学成绩 计算机成绩 英语成绩(空格间隔)\n"); scanf("%s%s%d%d%d",stu2.number,stu2.name,&stu2.math,&stu2.pc, &stu2. english); printf("学号\t姓名\t数学\t计算机 \t英语\n"); printf("%s\t%s\t%d\t%d\t%d\n",stu1.number,stu1.name,stu1.math,stu1.pc, stu1.english); printf("%s\t%s\t%d\t%d\t%d\n",stu2.number,stu2.name,stu2.math,stu2.pc, stu2.english); |