《高级语言程序设计教学课件》第9章.ppt
1第九章第九章 结构体结构体2 2学习目标学习目标n n结构体的概念结构体的概念n n结构体类型和结构体变量的差别结构体类型和结构体变量的差别n n运算符运算符“.”和和“-”n n结构体数组、结构体指针结构体数组、结构体指针3 39.1 结构体结构体n问题问题:我们要处理一个学生的信息,包括:我们要处理一个学生的信息,包括:学号、姓名、性别、年龄、成绩、地址学号、姓名、性别、年龄、成绩、地址n按照以往定义变量的方式,我们可以这样定义:按照以往定义变量的方式,我们可以这样定义:struct studentstruct student int num;int num;char name20;char name20;char sex;char sex;int age;int age;float score;float score;char addr50;char addr50;这些变量相互独立,这些变量相互独立,很难反映出它们的内在联系很难反映出它们的内在联系结构体结构体4 4结构类型结构类型 n n【例例】平面上点(平面上点(x,y)的表示)的表示structstruct point point float x;float x;float y;float y;(4,3)(0,0)平面上的点平面上的点关键字关键字结构体名结构体名结构体成员结构体成员5 5n定义一个结构体的一般形式为:定义一个结构体的一般形式为:n注意:注意:1.结构体类型不分配空间,是一种数据类型;结构体类型不分配空间,是一种数据类型;2.结构体成员的类型可以不同结构体成员的类型可以不同structstruct 结构名结构名结构名结构名 数据类型数据类型数据类型数据类型 成员成员成员成员1;1;数据类型数据类型数据类型数据类型 成员成员成员成员n;n;6 6namenamenumnumsexsexageagescorescoreaddraddr4 4字节字节字节字节4 4字节字节字节字节2020字节字节字节字节1 1字节字节字节字节4 4字节字节字节字节5050字节字节字节字节 struct studentstruct student int num;int num;char name20;char name20;char sex;char sex;int age;int age;float score;float score;char addr50;char addr50;结构体类型定义描述结构结构体类型定义描述结构结构体类型定义描述结构结构体类型定义描述结构的组织形式的组织形式的组织形式的组织形式,不分配内存不分配内存不分配内存不分配内存7 7【例例】定义点结构变量并保存平面点定义点结构变量并保存平面点(4,3)struct pointstruct point float x;float x;float y;float y;struct pointstruct point point1point1;point1.xpoint1.x=4;=4;point1.ypoint1.y=3;=3;8 8定义结构体变量的三种形式定义结构体变量的三种形式n n形式形式1:先定义类型:先定义类型,再定义变量再定义变量struct struct 结构名结构名结构名结构名 数据类型数据类型数据类型数据类型 成员成员成员成员1 1;数据类型数据类型数据类型数据类型 成员成员成员成员n n;struct struct 结构名结构名结构名结构名 结构变量结构变量结构变量结构变量1,1,结构变量结构变量结构变量结构变量2 2;struct pointstruct point float x;float y;struct pointstruct point point1,point2;9 9n n形式形式2:在定义类型时:在定义类型时,定义变量定义变量struct struct 结构名结构名结构名结构名 数据类型数据类型数据类型数据类型 成员成员成员成员1 1;数据类型数据类型数据类型数据类型 成员成员成员成员 n n;结构变量结构变量结构变量结构变量1,1,结构变量结构变量结构变量结构变量2 2;struct point float x;float y;point1,point2;1010n n形式形式3:无类型名的变量定义:无类型名的变量定义注意注意注意注意第三种定义形式省略了结构名第三种定义形式省略了结构名第三种定义形式省略了结构名第三种定义形式省略了结构名,在此定义语句后面无在此定义语句后面无在此定义语句后面无在此定义语句后面无法再定义这个类型的其它结构变量法再定义这个类型的其它结构变量法再定义这个类型的其它结构变量法再定义这个类型的其它结构变量structstruct 数据类型数据类型数据类型数据类型 成员成员成员成员1 1;数据类型数据类型数据类型数据类型 成员成员成员成员 n n;结构变量结构变量结构变量结构变量1,1,结构变量结构变量结构变量结构变量2 2;struct float x;float y;point1,point2;结构名结构名结构名结构名1111n说明说明结构体类型与结构体变量概念不同结构体类型与结构体变量概念不同类型类型:不分配内存不分配内存 变量变量:分配内存分配内存类型类型:不能赋值、存取、运算不能赋值、存取、运算 变量变量:可以可以结构体可嵌套结构体可嵌套结构体成员名与程序中变量名可同,不会混淆结构体成员名与程序中变量名可同,不会混淆例例例例 struct date int month;int day;int year;struct student int num;char name20;struct date birthday;struct date birthday;stu;numnamebirthdaymonthdayyear例例例例 struct student int num;char name20;struct date struct date int month;int month;int day;int day;int year;int year;birthdaybirthday;stu;例例例例 main()main()struct student int num;int num;char name20;stu;int num;int num;num=0;stu.num stu.num=1;1212【例例9-1】结构变量初始化结构变量初始化#include include main()main()struct struct student student long int num;long int num;char name20;char name20;char addr20;char addr20;a=a=89031,Li Lin,123 Beijing Road;89031,Li Lin,123 Beijing Road;printf(No.:%ldnname:%snaddress:%sn,printf(No.:%ldnname:%snaddress:%sn,a.num,a.name,a.addr);a.num,a.name,a.addr);初值表初值表初值表初值表1414结构体变量的引用结构体变量的引用n引用规则引用规则结构体变量不能整体进行输入、输出、赋值、结构体变量不能整体进行输入、输出、赋值、运算运算引用方式:引用方式:结构体变量名结构体变量名结构体变量名结构体变量名.成员名成员名成员名成员名可以将一个结构体变量赋值给另一个结构体变可以将一个结构体变量赋值给另一个结构体变可以将一个结构体变量赋值给另一个结构体变可以将一个结构体变量赋值给另一个结构体变量量量量结构体嵌套时结构体嵌套时逐级引用逐级引用逐级引用逐级引用struct studentstruct student int num;int num;char name20;char name20;struct date struct date int month;int month;int day;int day;int year;int year;birthday;birthday;stu1,stu2;stu1,stu2;stu1.birthday.month=12;stu1.birthday.month=12;1515【例例】成员变量引用成员变量引用struct student int num;char name20;char sex;int age;float score;char addr30;stu1,stu2;stu1=101,“Wan Lin”,M,19,87.5,“DaLian”;printf(“%d,%s,%c,%d,%f,%sn”,stu1);if(stu1=stu2stu1=stu2)stu1.name=“WangLin”;stu1.num=101;strcpy(stu1.name,“Wang Lin”);stu1.sex=M;Stu1.age=19;stu1.score=87.5;strcpy(stu1.addr,“DaLian”;stu2=stu1;stu2=stu1;1616【例例】分别定义表示直线和矩形的结构体分别定义表示直线和矩形的结构体struct point float x;float y;struct line struct point startp;struct point endp;struct rect struct point pt1;struct point pt2;struct point pt3;struct point pt4;(0,0)平面上的矩形平面上的矩形pt3pt1pt2pt41717常见编程错误常见编程错误n错例错例1struct stu int no;char name10;float score;=1,“wangbin”,98;错误分析:错误分析:struct stu是结构类型,不占内存空间,不能对其赋值。是结构类型,不占内存空间,不能对其赋值。1818n错例错例2struct stu int no;char name10;float score;stu s;错误分析:错误分析:1)结构体类型定义之后)结构体类型定义之后“”后必须加后必须加“;”2)结构体类型名为)结构体类型名为struct stu,不是,不是stu;申明变量应为:申明变量应为:struct stu s;1919n错例错例3struct stuint no;char name10;float score;struct stu s;scanf(“%d%s%f”,s);错误分析:不能整体读入结构体变量值,错误分析:不能整体读入结构体变量值,应为应为 scanf(“%d%s%f”,&s.no,s.name,&s.score);2020n错例错例4struct stuint no;char name10;float score;struct stu s,*p;scanf(“%d%s%f”,&p.no,&p.name,&p.score);错误分析:错误分析:1)p是结构指针变量,使用之前应赋初值;是结构指针变量,使用之前应赋初值;2)p访问成员的方式应为访问成员的方式应为p-no,p-name,p-score;3)p-name为数组名,读入一个字符串时,前面不能加为数组名,读入一个字符串时,前面不能加“&”。21219.2 结构变量作为函数参数结构变量作为函数参数【例例9-2】平面上两点之间的距离平面上两点之间的距离(x(x1 1,y,y1 1)(x(x2 2,y,y2 2)2222#include#include struct point float x;float y;float GetDis(struct point,struct point);2323main()struct point pt1,pt2;printf(Please input pt1:);scanf(%f%f,&pt1.x&pt1.x,&pt1.y&pt1.y);printf(Please input pt2:);scanf(%f%f,&pt2.x,&pt2.y);printf(pt1:(%.1f,%.1f),pt1.xpt1.x,pt1.ypt1.y);printf(npt2:(%.1f,%.1f),pt2.x,pt2.y);printf(npt1-pt2 is%fn,GetDis(pt1,pt2);2424定义计算两点之间距离的函数定义计算两点之间距离的函数float GetDis(struct point p1,struct point p2struct point p1,struct point p2)return sqrt(p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y);2525【例例9-3】判断点是否在矩形内判断点是否在矩形内n应包含以下功能:应包含以下功能:构造一个点;构造一个点;构造一个矩形;构造一个矩形;判断一个点是否在矩形内。判断一个点是否在矩形内。每一个功能都用函数来实现每一个功能都用函数来实现2626#include#include struct point float x;float y;struct rect struct point pt1;struct point pt2;struct point pt3;struct point pt4;struct pointstruct point makepoint(float x,float y);makepoint(float x,float y);void MakeRect(struct point pt1,struct point pt2,void MakeRect(struct point pt1,struct point pt2,struct point pt3,struct point pt4,struct point pt3,struct point pt4,struct rect*screenstruct rect*screen););int PtInRect(struct point p,struct rect r);2727main()struct point pt1=MakePoint(0,0);struct point pt2=MakePoint(50,0);struct point pt3=MakePoint(50,10);struct point pt4=MakePoint(0,10);struct rect screen;MakeRect(pt1,pt2,pt3,pt4,&screen);struct point middle=MakePoint(screen.pt1.x+screen.pt2.x)/2,(screen.pt1.y+screen.pt4.y)/2);printf(ncenter(%.1f,%.1f)n,middle.x,middle.y);if(PtInRect(middle,screen)printf(nThe middle point is in screen!n);else printf(nThe middle point is not in screen!n);运行结果The middle point of the screen is(25.0,5.0)The middle point is in screen!Press any key to continue2828struct pointstruct point MakePoint(float x,float y)struct point temp;temp.x=x;temp.y=y;return temp;void MakeRect(struct point pt1,struct point pt2,struct point pt3,struct point pt4,struct rect*screen)(*screen).pt1=pt1;(*screen).pt2=pt2;(*screen).pt3=pt3;(*screen).pt4=pt4;2929int PtInRect(struct point p,struct rect r)&p.y=r.pt1.y&p.y r.pt3.y;30309.3 结构体数组结构体数组n结构体数组的定义结构体数组的定义三种形式:三种形式:形式一形式一形式一形式一:struct student int num;char name20;char sex;int age;struct student stu2;形式二形式二形式二形式二:struct student int num;char name20;char sex;int age;stu2;形式三形式三形式三形式三:struct int num;char name20;char sex;int age;stu2;numnamesexagenumnamesexagestu0stu129B3131n结构体数组初始化结构体数组初始化顺序初始化顺序初始化分行初始化分行初始化n结构体数组引用结构体数组引用引用方式:引用方式:结构体数组名结构体数组名结构体数组名结构体数组名 下标下标下标下标 .成员名成员名成员名成员名顺序初始化顺序初始化顺序初始化顺序初始化:struct student int num;char name20;char sex;int age;struct student stu3=100,“Wang Lin”,M,20,101,“Li Gang”,M,19,110,“Liu Yan”,F,19;分行初始化分行初始化分行初始化分行初始化:struct student int num;char name20;char sex;int age;struct student stu=100,“Wang Lin”,M,20,101,“Li Gang”,M,19,110,“Liu Yan”,F,19;全部初始化时维数可省全部初始化时维数可省全部初始化时维数可省全部初始化时维数可省struct student int num;char name20;char sex;int age;stu3;stu1.age+;strcpy(stu0.name,”ZhaoDa”);3232【例例9-7】计算学生的平均成绩和不及格的人计算学生的平均成绩和不及格的人数数#include#include struct stu int num;char*name;char sex;float score;boy5=101,Li ping,M,45,102,Zhang ping,M,62.5,103,He fang,F,92.5,104,Cheng ling,F,87,105,Wang ming,M,58,;3333main()int i,c=0;/循环控制变量、不及格人数循环控制变量、不及格人数 float ave,s=0;/平均成绩、总成绩平均成绩、总成绩 for(i=0;i5;i+)s+=boyi.score;if(boyi.score60)c+=1;printf(s=%fn,s);ave=s/5;printf(average=%fncount=%dn,ave,c);运行结果:s=345.0average=69.0count=2Press any key to continue3434【例例例例9-59-5】编写候选人得票统计程序。设有编写候选人得票统计程序。设有3个候个候选人,选人,10张选票,每次输入一个得票的候选人名字,张选票,每次输入一个得票的候选人名字,统计每个候选人票数并输出统计每个候选人票数并输出#include#include struct person char name20;int count;leader3=Li,0,Zhang,0,Wang,0;namecountLiZhangWang0003535main()char name20;printf(input 10 names:n);for(int i=1;i=10;i+)scanf(%s,name);for(int j=0;j3;j+)if(strcmp(name,leaderj.name)=0)leaderj.count+;printf(result:n);for(i=0;i-成员名成员名成员名成员名结构体变量名结构体变量名结构体变量名结构体变量名.成员名成员名成员名成员名struct student stu1;struct student stu1;struct student *p=&stu1;struct student *p=&stu1;stu1.numstu1.num=101;=101;(*p).num(*p).num=101;=101;p-num=p-num=101;101;numnamesexagestupstruct student int num;char name20;char sex;int age;stu;struct student *p=&stup=&stu;3737【例例例例9-69-6】设图书信息包括:书号、书名、售空标设图书信息包括:书号、书名、售空标志、价格。写程序,输出某本图书信息。志、价格。写程序,输出某本图书信息。#include#include struct booklong num;/书号书号char name20;/书名书名char marking;/售空标志售空标志float price;/价格价格3838main()struct book boo_1,*p;p=&boo_1;boo_1.num=89101;strcpy(boo_1.name,math);boo_1.marking=T;boo_1.price=30;printf(书号书号:%ldn书名书名:%sn售空售空:%cn书价书价:%fn,boo_1.num,boo_1.name,boo_1.marking,boo_1.price);printf(书号书号:%ldn书名书名:%sn售空售空:%cn书价书价:%fn,(*p).num,(*p).name,(*p).marking,(*p).price);printf(书号书号:%ldn书名书名:%sn售空售空:%cn书价书价:%fn,p-num,p-name,p-marking,p-price);运行结果:书号:89101书名:math售空:T书价:30.000000书号:89101书名:math售空:T书价:30.000000书号:89101书名:math售空:T书价:30.000000Press any key to continue3939指向结构数组的指针指向结构数组的指针n n【例例9-7】设学生信息包括:学号、姓名、设学生信息包括:学号、姓名、性别和成绩。写程序,初始化五个学生信性别和成绩。写程序,初始化五个学生信息,然后将其输出息,然后将其输出4040struct student int num;char*name;char sex;float score;stu5=101,Li ping,M,45,102,Zhang ping,M,62.5,103,He fang,F,92.5,104,Cheng ling,F,87,105,Wang ming,M,58,;4141main()struct student*p;printf(“No.Name Sex agen”);for(p=stu;pnum,p-name,p-sex,p-age);42429.5 结构指针作为函数参数结构指针作为函数参数n n【例例例例9-109-10】通通过过调调用用函函输输出出某某个个学学生生的的信信息息。设设学学生生信信息息结结构构体体类类型型有有三三个个成成员员:学学号号、姓姓名名和和3门课成绩门课成绩#include#include struct studentint num;char name20;float score3;void Print(struct student*);4343main()struct student stu;stu.num=1001;strcpy(stu.name,Li Hong);stu.score0=66;stu.score1=78;stu.score2=89;Print(&stu);4444输出学生信息输出学生信息void Print(struct student*pstu)printf(%dn%sn%.2fn%.2fn%.2fn,pstu-num,pstu-name,pstu-score0,pstu-score1,pstu-score2);