《C语言学习与应用》教学课件11结构体操作_第1页
《C语言学习与应用》教学课件11结构体操作_第2页
《C语言学习与应用》教学课件11结构体操作_第3页
《C语言学习与应用》教学课件11结构体操作_第4页
《C语言学习与应用》教学课件11结构体操作_第5页
已阅读5页,还剩55页未读 继续免费阅读

付费下载

下载本文档

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

文档简介

任务说明

本学习任务通过学习结构体类型的说明,变量、数组和指针的定义,数组元素各成员的遍历等知识,掌握针对结构体类型数据的程序设计技能,能够按照要求编写出处理学生信息的程序,如查找、排序、删除等,并在任务实施中得以实现。微课任务说明知识要求用typedef说明一种新类型。结构体类型的说明。结构体类型变量、数组和指针的定义。结构体成员的引用。了解链表知识。能够输入、输出结构体变量的各成员值。能够编写结构体数组各元素的函数。能够编写针对结构体数组操作的函数。能够认真耐心地调试程序。能够排查程序中的错误。能力要求用typedef说明一种新类型名01

形式:typedef类型名

标识符

类型名是C语言中的数据类型名或前面已有定义的类型标识符,如结构体数据类型,标识符是一个用户命名的新的类型名。

注意:typedef语句的作用仅仅是用标识符来代表已存在的类型名,并未产生新的数据类型且原有类型名仍然有效。

例如:typedefintINTEGER;

表示用INTEGER标识符代表int,则INTEGERm,n;语句,等价于intm,n;语句。结构体类型02

结构体是一种较为复杂但却非常灵活的构造型数据类型,由若干个成员组成,各成员的数量及类型视需要而定。对一个具体的结构体,其成员的数量是固定的,各成员的数据类型可以不同且确定。这点与数组不同,当需要把一些相关信息(数据类型不同)组合在一起时,就需要采用结构体类型。结构体类型021.结构体类型的说明struct结构体标识名{类型名1结构体成员名表1;

类型名2结构体成员名表2;…

类型名n结构体成员名表n;};struct是关键字,是结构体类型的标志。结构体标识名是用户定义的标识符,可省略,成员名表中可以含有多个不同类型的成员,相同类型的多个成员名之间可以用逗号分隔一并类型声明,成员名可以与程序中的其他变量同名,不同结构体中的成员也可以同名,成员声明必须以分号结尾,结构体的说明也可以嵌套。微课结构体类型的说明应用举例11-1结构体类型的说明

(1)说明一个名为data的结构体,含有三个整型成员year、month和day。structdata{intyear,month,day;};(2)说明一个名为student的结构体,它的成员中含结构体类型。structstudent{charname[12];charsex;structdatabirthday;floatsc[4];};(3)嵌套说明student结构体。structstudent{charname[12];charsex;struct{intyear,month,day;}birthday;floatsc[4];};注意:结构体类型的说明并不分配存储空间,占有存储空间的是具有相应结构体类型的变量,数组等。问题11-1说明一个结构体类型

说明一个结构体类型st,含有姓名(name)、年龄(age)和身高(heigh)三个成员。结构体类型022.结构体类型变量的定义(1)紧跟在结构体类型说明之后进行相应结构体变量定义。例如:structdata{intyear,month,day;}birthday;//birthday就是定义的变量(2)说明一个无名结构体类型的同时定义变量。例如:struct{intyear,month,day;}birthday;(3)先说明结构体类型,再单独定义变量。例如:structdata{intyear,month,day;};//先说明名为data的结构体类型structdatabirthday;//再定义变量,birthday就是定义的变量(4)用新类型名定义变量,例如:typedefstructdata{intyear,month,day;}DATA;//先说明一个新结构体类型DATADATAbirthday;//再定义相应结构体变量,birthday就是定义的变量微课结构体类型变量的定义问题11-2定义一个结构体类型的变量

参照问题11-1,使用一种方法定义一个st结构体类型的变量stud。结构体类型023.给结构体变量赋初值应用举例11-2给结构体类型的变量与数组赋初值。#include"stdio.h"structdata{intyear,month,day;};structstudent{charname[12];charsex;structdatabirthday;floatsc[4];}std={"Liming",'M',1962,5,10,67.5,56.8,90,100};/*以上说明两个结构体类型,说明student同时定义变量std并赋初值*/voidmain(){structstudents[2]={{"Wangfan",'W',1954,12,23,56,78,89,67.5},\{"Wumi",'M',1978,11,30,98.6,34.5,67.9,90}};/*定义student类型的数组s[2]并初始化,“\”是续行符*/}问题11-3定义一个结构体类型的变量并赋初值

参照应用举例11-2,定义一个student结构体类型的变量stud并赋初值,其值参照个人信息确定。结构体类型024.对结构体成员的引用使用成员运算符:结构体变量名.成员名;

使用结构体指向运算符:指针变量名->成员名;

通过指针变量引用:(*指针变量名).成员名;应用举例11-3引用结构体成员的多种方式#include"stdio.h"structdata{intyear,month,day;};structstudent{charname[12];charsex;structdatabirthday;floatsc[4];}std={"Wangfan",'W',1954,12,23,56,78,89,67.5},*p;/*定义一个变量和一个指针,并为变量赋初值*/voidmain(){p=&std;//为指针赋值

printf("NameSexBirthdayScore\n");printf("%s\t%c\t%d-%d-%d\t%.1f%.1f%.1f\%.1f\n",\,p->sex,(*p).birthday.year,\(*p).birthday.month,p->birthday.day,std.sc[0],\p->sc[1],std.sc[2],(*p).sc[3]);}

应用举例11-3引用结构体成员的多种方式。程序运行结果:NameSexBirthdayScoreWangfanW1954-12-2356.078.089.067.5注意:此例的输出中给出了多种引用成员的方法,是有规律的,由于有p=&std则(*p)就是std,(*p).birthday.month就是std变量的birthday成员的month成员,还可以表示为:p->birthday.month;p->sc[0]就是std变量的sc数组成员的第1个数组元素。也就是运算符要对应运算对象。

微课应用举例11-3应用举例11-4用函数输出结构体类型变量的各成员值。下面这段程序,首先定义了结构体类型STU含有学号、姓名、性别、和成绩成员,在主函数中定义了一个结构体类型的变量x,通过调用函数输出变量的各成员值。#include"stdio.h"typedefstruct{charnum[3];//定义结构体类型STUcharname[9];charsex;floatscore[2];}STU;voidshow(STUy)//函数定义,形参是结构体类型的变量{

printf("学号姓名性别成绩\n");printf("%s%6s%3c%.2f%.2f",y.num,,y.sex,y.score[0],y.score[1]);}voidmain(){

STUx={"01","张楠",'W',67,94.5};//定义结构体类型的变量xshow(x);//调用函数,实参是x}

程序输出:学号姓名

性别

成绩01张楠W67.0094.50微课应用举例11-4结构体类型02知识链接1:用函数更改主函数中的结构体变量的成员值C语言中,主函数与函数之间的数据传递是实参到形参的单向传递方式来传递数值。如果通过函数更改主函数中结构体类型变量的成员值,在调用函数时,实参必须是变量的地址。以应用举例11-4为例,如果变量是x,函数是fun,调用函数时写作:fun(&x),而在fun函数的定义中,函数形参应写作:fun(STU*y),在函数体内(*y)就是主函数中的x了,(*y).name就是主函数中的,更改name成员值可调用:strcpy((*y).name,”某某”)库函数实现。问题11-4定义一个结构体类型STU参照应用举例11-4,定义一个结构体类型STU,并写出show函数和fun函数,fun函数的功能是更改x变量的name成员值,参照程序的执行结果,将代码补充完整。#include"stdio.h"#include"string.h"typedefstruct{.............................}STU;voidshow(STUy){....................................}voidfun(STU*z)//此函数用于更改name成员值{.........................................}

问题11-4定义一个结构体类型STUvoidmain(){STUx={"01","张楠",'W',67,94.5};show(x);fun(&x);//调用fun函数,更改x变量的name成员值show(x);}程序运行结果:学号姓名

性别

成绩01张楠W67.0094.50学号姓名

性别

成绩01张楠楠W67.0094.50应用举例11-5结构体类型数组的操作。

这个例子将应用举例11-4中,对单个变量的操作扩充为数组,在show函数中实现对数组的遍历输出,在sort函数中实现按结构体类型数组中的姓名成员排序。#include"stdio.h"#include"string.h"#defineN3typedefstruct{charnum[3];charname[9];charsex;floatscore[2];}STU;应用举例11-5结构体类型数组的操作。voidshow(STU*x){inti;printf("学号姓名性别成绩\n");for(i=0;i<N;i++)printf("%s%6s%3c%.2f%.2f\n",\x[i].num,x[i].name,x[i].sex,x[i].score[0],x[i].score[1]);}voidsort(STU*x)//函数定义,形参是STU类型的指针{inti,j;STUt;for(i=0;i<N-1;i++)//冒泡排序

for(j=i+1;j<N;j++)if((strcmp(x[i].name,x[j].name))>0)/*数组元素的姓名成员是字串,比较用strcmp函数*/

t=x[i],x[i]=x[j],x[j]=t;}

应用举例11-5结构体类型数组的操作。voidmain(){STUx[N]={{"01","张楠",'W',67.5,74.5},\{"02","李小涵",'M',98,91.5},\{"03","郭金晶",'W',69,84.5}};show(x);//调用输出函数,实参是数组名sort(x);//调用排序函数printf("按姓名排序后:\n");show(x);}程序输出:学号姓名性别

成绩01张楠W67.5074.5002李小涵M98.0091.5003郭金晶W69.0084.50按姓名排序后:学号姓名性别

成绩03郭金晶W69.0084.5002李小涵M98.0091.5001张楠W67.5074.50微课应用举例11-5结构体类型02知识链接2:按总成绩排序

应用举例11-5中,若是按总分降序,可将if语句改为:if(x[i].score[0]+x[i].score[1]<x[j].score[0]+x[j].score[1])问题11-5姓名排序改为按总成绩降序排序。将应用举例11-5中,按姓名排序改为按总成绩降序排序,将代码补充完整#include"stdio.h"#include"string.h"#defineN3typedefstruct{.........................}STU;voidshow(STU*x){..........................}voidsort(STU*x){...........................}

问题11-5姓名排序改为按总成绩降序排序。voidmain(){STUx[N]={{"01","张楠",'W',67.5,74.5},\{"02","李小涵",'M',98,91.5},\{"03","郭金晶",'W',69,84.5}};show(x);sort(x);printf("按总成绩降序后:\n");show(x);}注意:应用举例11-5中,如果学生人数为100,程序应该怎么修改?

若是学生人数不定,可能是3位也可能是100位,就必须定义数组长度为100,有时会造成存储空间的浪费,而链表的应用就可以很好地解决这个问题。

链表03

利用结构体变量可以构成链表,形成动态的存储结构,每个节点含有两部分内容:数据域和指针域,数据域就是要处理的数据,指针域存放下一个存储单元的地址,每个节点没有自己的名字,靠指针维系节点元素之间的接续关系,可以设置一个“头结点”,该结点的数据域不存放数据,链表最后一个结点的指针域不存放地址,置成’\0’(或NULL),标志着链表的结束。

应用举例11-6

建立带头结点的单向链表并输出。用链表知识输入和输出应用举例11-5中的学生信息。#include"stdio.h"#include"string.h"typedefstruct{charnum[3];charname[9];charsex;floatscore[2];}STU;typedefstructslist//说明节点的结构体类型{STUst;//数据域成员

structslist*next;//指针域成员}SLIST;

应用举例11-6

建立带头结点的单向链表并输出。SLIST*create_slist()//创建链表的函数{STUx;SLIST*h,*s,*r;h=(SLIST*)malloc(sizeof(SLIST));//动态分配一个存储单元,地址赋给hr=h;while(1){if(strcmp(x.num,"00")==0)//当学号为“00”时结束输入break;fflush(stdin);//清空标准输入缓存s=(SLIST*)malloc(sizeof(SLIST));//分配一个存储单元,地址赋给ss->st=x;//为结点的数据成员赋值r->next=s;//与前一个结点链接上

r=s;//指针r后移puts("请输入学号:");gets(x.num);puts("请输入姓名:");gets();puts("请输入性别和两科成绩:");scanf("%c%f%f",&x.sex,&x.score[0],&x.score[1]);}r->next=NULL;//为链表最后一个结点的指针成员赋结束标志returnh;//返回链表头地址}

应用举例11-6

建立带头结点的单向链表并输出。;

voidprint_slist(SLIST*head)//输出链表的函数,形参为链表的头地址{SLIST*p;p=head->next;//p指向第一个有数据的结点。

if(p=='\0')printf("Linklistisnull!\n");else{printf("学号姓名

性别成绩\n");do{printf("%2s%6s%c%.2f%.2f\n",\p->st.num,p->,p->st.sex,p->st.score[0],p->st.score[1]);p=p->next;//指向下一个结点

}while(p!='\0');}}

应用举例11-6

建立带头结点的单向链表并输出。;

main(){SLIST*head;head=create_slist();//调用函数创建链表,带回链表的头地址。

print_slist(head);/*实参是链表的头地址,调用函数输出链表中各节点值*/}程序运行情况:请输入学号:01请输入姓名:张楠请输入性别和两科成绩:W67.574.5请输入学号:02应用举例11-6

建立带头结点的单向链表并输出。;

请输入姓名:李小涵请输入性别和两科成绩:M9891.5请输入学号:03请输入姓名:郭金晶请输入性别和两科成绩:W6984.5请输入学号:00请输入姓名:无请输入性别和两科成绩:M9890学号姓名

性别

成绩01张楠W67.5074.5002李小涵M98.0091.5003郭金晶W69.0084.50微课应用举例11-6问题11-6输出平均分。;

更改应用举例11-6中的输出函数,在输出成绩的基础上,再输出平均分。#include"stdio.h"#include"string.h"typedefstruct//说明STU结构体类型,参照应用举例11-6{...........................................................................................................}STU;typedefstructslist//说明节点的结构体类型,参照应用举例11-6{....................................................................................................................................................}SLIST;问题11-6输出平均分。;

SLIST*create_slist()//创建链表的函数,参照应用举例11-6{....................................................................................................................................................................................}

voidprint_slist(SLIST*head)//输出函数,参照应用举例11-6再补充{................................................................................................................................................................................}

问题11-6输出平均分。;

main(){SLIST*head;head=create_slist();print_slist(head);getchar();getchar();}程序运行情况:................................

任务实施

任务学生信息处理工作内容及要求:

现有某个班的学生学号、姓名和三科成绩信息存放在数组中,姓名与他的成绩是对应的、一体的关系型的数据,对这批数据进行按姓名的查找、删除、排序、计算平均分等操作。

说明一个结构体类型STU,其成员有:整型的学号sno,字符串的姓名name和单精度实型的三科成绩score[3]。编程训练11-1按要求说明结构体

以下程序中,在main函数已定义了含5位学生信息的数组,请写出show函数用于输出数组元素,然后在VC环境调试程序,写出程序执行结果。#include<stdio.h>#defineN5typedefstructstudent{intsno;charname[10];floatscore[3];}STU;voidshow(STU*a){.........................}编程训练11-2编写输出函数voidmain(){STUt[N]={{10001,"曹凯",91,92,77},\{10002,“马利超",75,60,88},\{10003,"李斯",85,70,78},\{10004,"刘芳菲",90,82,87},\{10005,"张萨欧",95,80,88}};show(t);}程序运行结果:.................................编程训练11-2编写输出函数

在编程训练11-2的基础上,编写一个fun函数,依据姓名查找相应的信息,如果找到了指定姓名的数组元素,函数返回值是数组元素的下标,否则函数返回值为“-1”,然后在VS环境调试程序,并写出分别输入:“刘娜”和“刘芳菲”时程序的执行结果。编程训练11-3编写输出查找函数结构体类型02知识链接:查找姓名

查找哪一个数组元素的姓名与指定的姓名相等,可采用对数组元素搜一遍,用strcmp函数实现字串比较,可参考以下代码:for(i=0;i<N;i++)if((strcmp(t[i].name,s))==0)returni;/*s是要找姓名的首地址,如果数组中没有相应的信息,则返回“-1”*/\#include<stdio.h>#include<string.h>#defineN5typedefstructstudent{intsno;charname[10];floatscore[3];}STU;intfun(STU*a,char*s)//形参依据实参写{..................................}

结构体类型02知识链接:查找姓名voidmain(){STUt[N]={{10001,"曹凯",91,92,77},{10002,"马利超",75,60,88},{10003,"李斯",85,70,78},{10004,"刘芳菲",90,82,87},{10005,"张萨欧",95,80,88}};charsname[10];intn,i;printf("请输入要查找的姓名:");gets(sname);n=fun(t,sname);//实参是数组名和一个字符串

if(n>=0){printf("您要查找的是:");printf("\n%-8d%-8s",t[n].sno,t[n].name);for(i=0;i<3;i++)printf("%6.2f",t[n].score[i]);printf("\n");}else

printf("查无此人!:");}

结构体类型02知识链接:查找姓名程序运行结果:请输入要查找的姓名:刘娜...............................................................................................................请输入要查找的姓名:刘芳菲.....................................

..........................................................................

编程训练11-3是查找某姓名的数组元素,本次训练是删除找到的数组元素,请将代码补充完整,写出当输入:1)“刘娜”时,程序的运行结果。2)“刘芳菲”,回答“N”时,程序的运行结果。3)“刘芳菲”,回答“Y”时,程序的运行结果。编程训练11-4编写删除某下标元素的函数#include<stdio.h>#include<string.h>#defineN5typedefstructstudent{intsno;charname[10];floatscore[3];}STU;voidshow(STU*a,intm)//输出a地址开始的m个数组元素{................................

}编程训练11-4编写删除某下标元素的函数intfun(STU*a,char*s)//查找某姓名的函数{inti;for(i=0;i<N;i++)if((strcmp(a[i].name,s))==0)returni;return-1;}voiddel(STU*a,int*k,intn)//删除a数组*k个元素中下标为n的元素{............................................

}编程训练11-4编写删除某下标元素的函数编程训练11-4编写删除某下标元素的函数voidmain(){STUt[N]={{10001,"曹凯",91,92,77},{10002,"马利超",75,60,88},{10003,"李斯",85,70,78},{10004,"刘芳菲",90,82,87},{10005,"

温馨提示

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

最新文档

评论

0/150

提交评论