高级语言程序设计(CC++版) 课件 第8章 结构体_第1页
高级语言程序设计(CC++版) 课件 第8章 结构体_第2页
高级语言程序设计(CC++版) 课件 第8章 结构体_第3页
高级语言程序设计(CC++版) 课件 第8章 结构体_第4页
高级语言程序设计(CC++版) 课件 第8章 结构体_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第8章

结构体目录定义结构体类型定义结构体变量引用结构体成员结构体数组与指针结构体与单链表共用体类型枚举类型用typedef声明新类型名216:12为什么引入结构体在现实问题中,常常需要用一组不同的数据组合来描述一个对象。如一名学生要用学号、姓名、性别、籍贯等信息加以描述,一名教师要用工号、姓名、性别、出生日期等信息加以描述。编程时若利用多个独立的变量来描述一个对象势必会导致极大的不便。C/C++中允许编程人员自定义结构体类型,进而定义该类型的变量来表示现实问题中的对象。316:121.定义结构体类型C/C++中支持在已有数据类型的基础上定义新的复合数据类型,用“struct”关键字定义一个“结构体类型”,也就定义了一个新的复合数据类型。定义结构体的一般格式为:struct结构体类型名{

类型名1变量名1;

……

类型名n变量名n;};例如:structstudent{ longlongnum; stringname; charsex;}; //注意结构体定义最后以分号结束返回416:122.

定义结构体变量定义结构体类型后,就可以进一步定义该结构体类型的变量。C/C++中可使用以下三种方法定义结构体变量。1.先定义结构体类型再定义该类型的变量structstudent{ longlongnum; stringname; charsex;};structstudents1,s2;2.在定义结构体类型的同时定义该类型变量structstudent{ longlongnum; stringname; charsex;}s1,s2;3.不指定结构体类型名而直接定义结构体变量struct{ longlongnum; stringname; charsex;}s1,s2;返回516:123.引用结构体成员在定义结构体变量时,可以对其初始化。同种类型的结构体变量之间可以相互赋值,但是不能将一个结构体变量作为一个整体进行输入、输出,而只能对其成员进行输入、输出。引用结构体变量成员的一般格式为:结构体变量名.成员名例如:structstudentstu={202103061201,"Jack",'M'};cin>>stu.num;cout<<;返回616:12如果结构体的某成员又是一个结构体类型变量,那么必须以级联的方式访问该变量。#include<iostream>usingnamespacestd;structdate{ intyear; intmonth; intday;};structstudent{ longlongnum; stringname; charsex; structdatebirthday;};intmain(){ structstudentstu={202103061201,"Jack",'M',{2003,6,7}}; cout<<stu.num<<""<<<<""<<stu.sex<<""; cout<<stu.birthday.year<<"."<<stu.birthday.month<<"."<<stu.birthday.day<<endl; return0;}716:12例8.1:好多同学报名参加了英语俱乐部举办的“英文金曲歌唱大赛”活动,每名选手均有5位评委打分,对每名选手去掉一个最高分、去掉一个最低分,再计算剩下打分的平均分(结果精确到小数点后两位)。

输入:测试数据包括多个实例,每个实例一行,包括选手姓名,随后是5个实数代表评委打分。

输出:每位选手姓名和最终得分。#include<iostream>usingnamespacestd;structstudent{charname[20];doublea[5];doublegrade;};intmain(){structstudents;while(scanf("%s%lf%lf%lf%lf%lf",,&s.a[0],&s.a[1],&s.a[2],&s.a[3],&s.a[4])!=EOF){doublesum,max,min;sum=max=min=s.a[0];for(inti=1;i<5;++i){sum=sum+s.a[i];if(s.a[i]>max)max=s.a[i];elseif(s.a[i]<min)min=s.a[i];}sum=sum-max-min;s.grade=sum/3;printf("%s%.2lf\n",,s.grade);}return0;}816:124.结构体数组与指针元素为结构体类型变量的数组称为结构体数组,定义结构体数组的方法与定义普通数据类型数组相同。所谓结构体指针就是指向结构体变量的指针,一个结构体变量的起始地址就是该结构体变量的指针。通过结构体指针引用成员的一般格式为:结构体指针名->成员名返回916:12例8.2:潘小姐比武招亲,第一关是身高要合格。潘小姐发现小明擅长编程,所以把首轮根据身高进行选拨的任务交给了小明,如果程序编得好,小明就可以直接进入下一轮选拨,于是小明开心地笑了。

输入:首先输入一个整数n(1<=n<=100),表示n名竞选者;然后是n行数据,每行是参加竞选者的姓名name(name无空格且长度<20)和身高h(0<h<100);最后一行是两个整数a,b表示身高的合格范围[a,b]。

输出:把身高合格的竞选者信息按身高从高到低输出,格式与输入相同。#include<iostream>usingnamespacestd;structperson{

charname[21]; inth;};intmain(){structpersonc[101];structpersont;intn,a,b,flag;flag=0;scanf("%d",&n);for(inti=0;i<n;i++) scanf("%s%d",c[i].name,&c[i].h);for(inti=0;i<n;i++) for(intj=0;j<n-i-1;j++){if(c[j].h<c[j+1].h){t=c[j];c[j]=c[j+1];c[j+1]=t;}}scanf("%d%d",&a,&b);for(inti=0;i<n;i++) if(c[i].h>=a&&c[i].h<=b) printf("%s%d\n",c[i].name,c[i].h);return0;}1016:12例8.3:从键盘输入若干个学生的信息,每个学生信息包括学号、姓名、3门课的成绩,计算每个学生的总分,输出总分最高的学生的信息。

输入:首先输入一个整数n(1<=n<=100),表示学生人数,然后输入n行,每行包含一个学生的信息:学号(12位)、姓名(不含空格且不超过20位),以及三个整数,表示语文、数学、英语三门课成绩,数据之间用空格隔开。

输出:输出总成绩最高的学生的学号、姓名、及三门课成绩,用空格隔开。若有多个最高分,只输出第一个。#include<iostream>usingnamespacestd;structstudent{ longlongnum; stringname; inta,b,c;};intmain(){ structstudents[100]; intn; cin>>n; for(inti=0;i<n;i++) cin>>s[i].num>>s[i].name>>s[i].a>>s[i].b>>s[i].c; intv=0; intm=0; structstudent*p=&s[0]; for(inti=0;i<n;i++,p++) if(v<p->a+p->b+p->c)m=i,v=p->a+p->b+p->c; cout<<s[m].num<<""<<s[m].name<<""; cout<<s[m].a<<""<<s[m].b<<""<<s[m].c; return0;}1116:125.结构体与单链表结构体类型的成员可以是基本数据类型,也可以是结构体类型,甚至可以是指针类型。设置一个同类型指针成员存放下一个结点的地址,让每个结点的指针成员指向下一个结点的地址,最后一个结点的指针成员为空,便可构成一个单链表。单链表中结点的结构体描述如下:structnode{ intdata; node*next;};以上定义了一个名为node的结构体类型,该结构体包含两个成员,第一个成员是存放实际整型数据data,第二个成员是指向node结构体类型的指针next,即下一个结点的地址。返回1216:12例8.4:n只猴子围坐成一个圈,按顺时针方向从1到n编号。然后从1号猴子开始沿顺时针方向从1开始报数,报到m的猴子出局,再从刚出局猴子的下一个位置重新报数,…,直至剩下一个猴子它就是大王。

输入:输入两个整数n和m,1<=m<=n<=100。

输出:输出猴王的编号。#include<iostream>usingnamespacestd;structnode{ intdata; node*next;};intmain(){ intn,m; cin>>n>>m; node*p,*q,*head=newnode; head->next=head; for(inti=n;i>=1;i--){ p=newnode; p->data=i; p->next=head->next; head->next=p; } node*prev=head,*cur=head->next; intcount=1; while(head->next->next!=head){ while(count!=m&&cur!=head){ prev=cur; cur=cur->next;

count++; } if(cur!=head){ q=cur; cur=cur->next; prev->next=cur; deleteq; count=1; }else{ prev=head; cur=head->next; } } cout<<head->next->data; return0;}1316:126.共用体类型共用体是一种特殊的数据类型,允许在相同的内存位置存储不同的数据。可以定义一个包含多个成员的共用体,但是任何时候只能有一个成员有值。共用体提供了一种使用相同的内存位置的有效方式。定义共用体使用关键词union,定义共用体类型的一般格式为:union共用体类型名{

类型名1变量名1;

……

类型名n变量名n;};例如:unionData{ //表示不同类型的变量i,ch,f可以存放到同一段存储单元中 inti; charch; floatf;}a,b,c; //在声明类型同时定义变量“共用体”与“结构体”的定义形式相似,但它们的含义是不同的。结构体变量所占内存长度是各成员所占内存长度之和,每个成员分别占有其自己的内存单元。而共用体变量所占的内存长度等于最长的成员的长度,几个成员共用一个内存区。共用体中起作用的是最后一次存放的成员,给一个新成员赋值后,旧成员就因被覆盖而失去了作用。返回1416:12例8.5:有多名教师和学生参加会议,学生的数据包括:姓名、性别、职业、班级,教师的数据包括姓名、性别、职业、职务。要求用结构体和共用体编程实现输入输出。

输入:输入一个正整数n(n<10)及n名教师或学生的信息。

输出:输出n名教师或学生的信息。#include<iostream>usingnamespacestd;structperson{ charname[10]; charsex; charjob; union{ //声明无名共用体类型 intclas; //成员clas(班级) charposition[10]; //成员position(职务) }category; //成员category是共用体变量};intmain(){ intn; cin>>n; personp[100]; for(inti=0;i<n;i++){ scanf("%s%c%c",p[i].name,&p[i].sex,&p[i].job); //输入前3项 if(p[i].job=='s')scanf("%d",&p[i].category.clas);

//如是学生,输入班级 elseif(p[i].job=='t')scanf("%s",p[i].category.position); //如是教师,输入职务 } for(inti=0;i<n;i++) if(p[i].job=='s')printf("%s%c%c%d\n",p[i].name,p[i].sex,p[i].job,p[i].category.clas); elseprintf("%s%c%c%s\n",p[i].name,p[i].sex,p[i].job,p[i].category.position); return0;}1516:127.枚举类型若某变量只有几种可能的取值,则可将其定义为枚举类型。所谓“枚举”就是指把可能的值一一列举出来,变量的值仅限于所列举出的值范围。声明枚举类型的一般格式为:enum[枚举名]{枚举元素列表};例如:enumWeekday{sun,mon,tue,wed,thu,fri,sat};enumWeekdayworkday,weekend;也可以声明没有名字的枚举类型,而直接定义枚举变量。例如:enum{sun,mon,tue,wed,thu,fri,sat}workday,weekend;说明C编译对枚举类型的枚举元素按常量处理,故称枚举常量。不要因为它们是标识符(有名字)而把它们看作变量,不能对它们赋值。每一个枚举元素都代表一个整数,C语言编译按定义时的顺序默认它们的值为0,1,2,3,4,5…。也可以在定义枚举类型时显式地指定枚举元素的数值。枚举元素可以用来作判断比较。枚举元素的比较规则是按其初始化时指定的整数比较。返回1616:12例8.6:口袋中有红、黄、蓝、白、黑5种颜色的球各一个。每次从口袋中先后取出3个球,问得到3种不同颜色的球的可能取法,输出每种取法。

输入:无。

输出:每种取法(按红、黄、蓝、白、黑字典序)。#include<iostream>usingnamespacestd;intmain(){ enumColor{red,yellow,blue,white,black}; intcnt=0,cur,loop; for(inti=red;i<=black;i++) for(intj=red;j<=black;j++) for(intk=red;k<=black;k++) if((i!=j)&&(i!=k)&&(j!=k)){ cnt++; printf("%-4d",cnt); for(loop=1;loop<=3;loop++){ switch(loop){ case1:cur=i;break; case2:cur=j;break; case3:cur=k;break; default:break; } switch(cur){ //根据球的颜色输出相应的文字 casered:printf("%-10s","red");break; caseyellow:printf("%-10s","yellow");break; caseblue:printf("%-10s","blue");break; casewhite:printf("%-10s","white");break; caseblack:printf("%-10s","black");break; default:break; } } printf("\n"); } return0;}1716:128.用typedef声明新类型名1.简单地用一个新的类型名代替原有的类型名2.命名一个简单的类型名代替复杂的类型表示方法①命名一个新的类型名代表结构体类型

命名一个新的类型名代表数组类型③命名一个新的类型名代表指针类型

④命名一个新的类型名代表指向函数的指针类型typedefstruct{ intmonth; intday;intyear;}Date; //声明了一个新类型名Date,代表结构体类型Datebirthday; //定义结构体类型变量birthday,不要写成structDatebirthday;Date*p; //定义结构体指针变量p,指向此结构体类型数据typedefintNum[100]; //声明Num为整型数组类型名Numa; //定义a为整型数组名,它有100个元素typedefchar*String; //声明String为字符指针类型Stringp,s[10]; //定义p为字符指针变量,s为字符指针数组typedefint(*Pointer)(); //声明Pointer为指向函数的指针类型,该函数返回整型值Pointerp1,p2; //p1,p2为Pointer类型的指针变量18typedefintInteger; //指定用Integer为类型名,作用与int相同typedeffloatReal; //指定用Real为类型名,作用与float相同返回16:12用typedef声明新类型名声明一个新的类型名的方法是:①先按定义变量的方法写出定义体(如:inti;)

②将变量名换成新类型名(例如:将i换成Count)③在最前面加typedef(例如:typedefintCount)

④然后可以用新类型名去定义变量简单讲,就是按定义变量的方式把变量名换上新类型名,并在最前面加typedef,就声明了新类型名代表原来的类型。以定义上述的数组类型为例来说明:①先按定义数组变量形式书写:inta[100] ②将变量名a换成自己命名的类型名:intNum[100]③在前面加上typedef,得到typedefintNum[100] ④用来定义变量:Numa;相当于定义了:inta[100];同样,对字符指针类型,也是:①char*p; //定义变量p的方式

②char*String; //用新类型名String取代变量名p③typedefchar*String; //加typedef ④Stringp; //用新类型名String定义变量,相当char*p;习惯上,常把用typedef声明的类型名的第1个字母用大写表示,以便与系统提供的标准类型标识符相区别。1916:12用typedef声明新类型名(1)

typedef的方法实际上是为特定的类型指定了一个同义字(synonyms)。(2)用typedef只是对已经存在的类型指定一个新的类型名,而没有创造新的类型。(3)用typedef声明数组类型、指针类型,结构体类型、共用体类型、枚举类型等,使得编程更加方便。(4)typedef与#define表面相同实质不同。#define是在预编译时处理的,它只能作简单的字符串替换,而typedef是在编译阶段处理的,且并非简单的字符串替换。(5)当不同源文件中用到同一类型数据(尤其是像数组、指针、结构体、共用体等类型数据)时,常用typedef声明一些数据类型。可以把所有的typedef名称声明单独放在一个头文件中,然后在需要用到它们的文件中用#include指令把它们包含到文件中。这样编程者就不需要在各文件中自己定义typedef名称了。(6)使用typedef名称有利于程序的通用与移植。有时程序会依赖于硬件特性,用typedef类型就便于移植。2016:12例8.7:一个藏宝山洞出现在阿里巴巴面前,山洞里堆满了n件宝物,每件物品有价值和质量两种属性。可是阿里巴巴身上只有一个口袋,他只能挑选三件宝物。请按价值降序,若价值相同则按质量升序排列一下这n件宝物。

输入:第一行输入一个整数n(1<=n<=1000)表示n件宝物;第二行有n个正整数pi代表每件物品的价值,第三行有n个正整数wi代表每件物品的质量(1<pi,wi<10000)。

输出:输出共n行,每行两个数pi,wi,顺序如题所述。#include<iostream>usingnamespacestd;structtreasure{intp;intw;};intmain(){structtreasures[10001];structtreasuret;intn;while(scanf("%d",&n)!=EOF){for(inti=0;i<n;i++) scanf("%d",&s[i].p);for(inti=0;i<n;i++) scanf("%d",&s[i].w);for(inti=0;i<n;i++)for(intj=0;j<n-i-1;j++){if(s[j].p<s[j+1].p){t=s[j];s[j]=s[j+1];s[j+1]=t;}elseif(s[j].p==s[j+1].p){if(s[j].w>s[j+1].w){t=s[j];s[j]=s[j+1];s[j+1]=t;}}}for(inti=0;i<n;i++)printf("%d%d\n",s[i].p,s[i].w);}return0;}2116:12例8.8:二叉排序树二叉排序树,也称为二叉查找树。可以是一颗空树,也可以是一颗具有如下特性的非空二叉树:(1)若左子树非空,则左子树上所有节点关键字值均不大于根节点的关键字值;(2)若右子树非空,则右子树上所有节点关键字值均不小于根节点的关键字值;(3)左、右子树本身也是一颗二叉排序树。现在给定N个关键字值各不相同的节点,要求按顺序插入一个初始为空树的二叉排序树中,每次插入成功后求相应的父亲节点的关键字值,如果没有父亲节点,则输出-1。输入:

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论