《第09章结构体》由会员分享,可在线阅读,更多相关《第09章结构体(79页珍藏版)》请在金锄头文库上搜索。
1、11程序设计基础第九章谌卫军清华大学软件学院2003年秋季22第九章结构体339.1 结构体的定义和使用9.1.1 引言为了实现学校的信息化管理,清华大学决定构造一个学生个人信息的数据库,该数据库包含了每一个学生的各种信息,包括学号、姓名、性别、年龄、电话、宿舍等等。请问:如何来构造该数据库?44问题分析:(1)该数据库涉及到大量的数据;(2)数据库中的数据可能是变化的;(3)有些数据是密切相关的,例如:每一个学生都有一组相关的数据(学号、姓名、性别、年龄等)来描述他。55学号姓名性别年龄电话宿舍020449022345020333021109ZhangLiQianWang男男女女191817
2、1962771100627712336277157662771576紫荆6-401紫荆6-415紫荆5-313紫荆5-313数组法66数组法的弊端:y只是解决了问题1、2,并没有很好地解决问题3,同一位学生的所有信息是密切相关的、在逻辑上应该是一个整体。而现在只能通过数组下标这种松散的方法来建立它们之间的联系;y必须维护另外一个数据结构,来记录每一位学生的数组下标号。因为在访问一个学生的信息时,必须知道相应的数组下标号;y使用起来很不方便,有些功能难以实现,如根据学生的学号、姓名或其他属性来进行排序。77022345Li男1862771233紫荆6-415020449Zhang男1962771
3、100紫荆6-401需要把不同类型的数据组织在一起,而已有方法无法解决此问题,必须引入新的类型,即结构体。学生1学生288结构体:由一个或多个变量(类型可以相同,也可以不同)所组成的一个组合项。该组合项有一个名字,它内部的每个变量(称为字段或成员变量)也有相应的名字。studentchar ID7 020449char name20 Zhangchar sex Mint age 19char phone9 62771100char addr30紫荆6-401999.1.2 结构体的定义在C程序中,有几种方法来定义一个结构体(struct),通常的步骤是:1.定义一个新的结构体类型,并指明它内部
4、的各个成员变量;2.使用该类型来定义相应的结构体变量。结构体类型的定义只在程序的开头出现一次,而结构体变量的声明可以根据需要在程序中出现多次。1010定义一个结构体类型一般形式之一:struct 类型名1 成员变量1;类型名n 成员变量n;;1111一般形式之二:typedef struct类型名1 成员变量1;类型名n 成员变量n;;1212定义结构体变量一般形式之一:struct 变量1, 变量2, ;一般形式之二:变量1, 变量2, ;1313struct student_tagchar ID7;char name20;char sex;int age;char phone9;char
5、addr30;typedef struct char ID7;char name20;char sex;int age;char phone9;char addr30; student_T;定义一个结构体类型,此时并没有定义(创建)任何结构体变量,因此没有分配任何内存空间。1414IDnamesexagephoneaddrxstruct student_tag x;或者:student_T x;定义结构体变量x 后,为它分配相应的内存空间。1515struct student_tagchar ID7;char name20;char sex;int age;char phone9;char a
6、ddr30; x, y;在定义结构体类型的同时,去定义它的变量。16169.1.3 结构体变量的使用对一个结构体变量的最基本的操作就是去访问它的各个成员变量。访问的方式为:结构体变量名.成员变量名一个成员变量就是一个普通的变量,可以对它进行各种通常的变量操作。1717IDnamesexagephoneaddr020449ZhangM1962771100紫荆6-401xstudent_T x;strcpy(x.ID, “020449”);strcpy(x.name, “Zhang”);scanf(“%c”, &x.sex);x.age = 19;strcpy(x.phone, str);scan
7、f(“%s”, x.addr);1818Cant And Cany不能做什么?不能直接比较两个结构体变量(=、!=),student_T x, y;(x = y);(x != y);不能用scanf/printf来输入或输出整个结构体变量。1919Cant And Cany能做什么?能够进行结构体变量的整体赋值,如:student_T x, y;y = x;能够定义一个返回值类型为结构体类型的函数,把被调用函数当中的某个结构体变量的值返回给主调函数。2020student_T x, y;y = x;等价于IDnamesexagephoneaddr020449ZhangM1962771100紫荆
8、6-401xstrcpy(y.ID, x.ID);strcpy(y.name, x.name);y.sex = x.sex;y.age = x.age;strcpy(y.phone, x.phone);strcpy(y.addr, x.addr);21219.1.4 结构体变量的初始化对于一个结构体变量,也可以在定义的时候,指定它的初始值,即把它的各个成员变量的初始值依次列出来。student_T x = 020449, Zhang, M, 19, 62771100, 紫荆6-401 ;22229.2 结构体数组与指针9.2.1 结构体数组如何来构造学生个人信息数据库?为每位学生单独定义一个结
9、构体变量?No可以采用结构体数组的方法,用每一个数组元素来描述一位学生的信息。2323IDnamesexagephoneaddrIDnamesexagephoneaddrstustu0student_T stu1000;或者是:struct student_tag stu1000;stu12424#define MAX_NAME 8#define MAX_STUDENTS 50typedef structchar nameMAX_NAME + 1;int id;double score;StudentRecord_T;StudentRecord_T aMAX_STUDENTS;下列这些变量的类
10、型是什么?a a0 a5.namea4.id, &a6.score a2.name125259.2.2 结构体与指针一种新的指针类型:基类型为结构体类型的指针类型。StudentRecord_T x, *px;px = &x;nameidscorexpx2626nameidscorex *pxpx如何来访问x的成员变量?1. x.成员变量名,如:x.name, x.id;2. (*px).成员变量名,如:(*px).name, (*px).id;3. px-成员变量名,“-”称为指向运算符或箭头运算符,如:px-name, px-id。2727nameidscorepxnameidscorea
11、a0StudentRecord_T a10;StudentRecord_T *px;px = a;a1px 指向a0;px + 1指向a1;px + i 指向ai;28289.3 结构体作为函数参数在使用结构体来作为函数的参数时,它的用法与整型、字符类型、实数类型等其他的、除数组以外的数据类型是完全一样的。也就是说,既可以用结构体变量来作为函数参数,实现单向的值传递;也可以用指向结构体变量的指针来作为函数参数,实现地址的传递。2929问题描述:已知一条直线的2个端点坐标,计算该直线的中点的坐标。.(x1, y1)(x2, y2)/* 用一个结构体来描述一个点*/typedef structdo
12、uble x, y; point_T;3030point_T midpoint(point_T pt1, point_T pt2);void main( )point_T a = 0.0, 0.0, b = 5.0, 10.0, m;m = midpoint(a, b);point_T midpoint(point_T pt1, point_T pt2)point_T mid;mid.x = (pt1.x + pt2.x) / 2.0;mid.y = (pt1.y + pt2.y) / 2.0;return(mid);3131point_T midpoint(point_T pt1, poin
13、t_T pt2);void main( )point_T a = 0.0, 0.0, b = 5.0, 10.0, m;m = midpoint(a, b);point_T midpoint(point_T pt1, point_T pt2)point_T mid;mid.x = (pt1.x + pt2.x) / 2.0;mid.y = (pt1.y + pt2.y) / 2.0;return(mid);在主函数和midpoint函数中各定义了三个结构体变量,需要较多数据传递。maina0.00.0b10.05.0m2.55.0xymidpointpt1 pt2 mid0.00.05.010
14、.02.55.0xy3232指针作为函数参数void main( )point_T a = 0.0, 0.0, b = 5.0, 10.0, m;set_midpoint(&a, &b, &m);void set_midpoint(point_T *pt1, point_T *pt2, point_T *mid)mid - x = (pt1 - x + pt2 - x) / 2.0;mid - y = (pt1 - y + pt2 - y) / 2.0;3333maina0.00.0b10.05.0m2.55.0xyvoid main( )point_T a = 0.0, 0.0, b = 5.0, 10.0, m;set_midpoint(&a, &b, &m);void set_midpoint(point_T *pt1, point_T *pt2, point_T *mid)mid - x = (pt1 - x + pt2 - x) / 2.0;mid - y = (pt1 - y + pt2 - y) / 2.0;pt1 pt2 midset_midpoint343