第12章 自定义数据类型_第1页
第12章 自定义数据类型_第2页
第12章 自定义数据类型_第3页
第12章 自定义数据类型_第4页
第12章 自定义数据类型_第5页
已阅读5页,还剩41页未读 继续免费阅读

下载本文档

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

文档简介

第12章自定义数据类型程序设计语言主要内容结构体类型与变量结构体数组结构体与函数链表在程序里表示一个人(姓名、年龄、性别、成绩),怎么表示?想表示多个人呢?如何用计算机程序实现下述表格的管理?思考I.使用数组MaryJohnPeterRoseKateFMFMF01020304058978.56797.564解决方案:scorenumsexname不能建立数组间的关系II.使用多维数组MaryJohnPeterRoseKateFMFMF01020304058978.56797.564C语言不允许一个数组包含多种数据类型III.使用结构体numnamesexscoreC语言引入了称为结构体的数据存储方式“结构体”是一种构造数据类型,它是由若干数据项组合而成的复杂数据对象,这些数据项称为结构体的成员。结构体简介

structstructurename{ datatypevariable1; datatypevariable2; ...};结构体成员{};结构体名structstudentintnum;charname[20];charsex;定义结构体floatscore;C语言中的有效数据类型结构体类型定义1structstudent{intnum;charname[20];charsex;floatscore;};numnamesexstudent结构体定义并不预留内存结构体定义放置在程序的开始部分,位于头文件声明之后score结构体类型定义2声明结构体变量structstudent{intnum;charname[20];charsex;floatscore;};structstudentstudent1,student2;I.先定义结构体类型,再声明结构体变量structstudent{intnum;charname[20];charsex;floatscore;}student1,student2;II.在定义结构体类型的同时声明结构体变量struct{intnum;charname[20];charsex;floatscore;}student1,student2;III.直接声明结构体变量声明一个类型为student结构体的变量,将会为该变量分配内存,大小等于其所有成员变量的大小之和。

定义结构体变量structdate{intmonth;intday;intyear;};struct{intnum;charname[20];charsex;

structdatebirthday;floatscore;}student1,student2;嵌套结构体类型定义用typedef定义数据类型则structstudents1;与STUs1;具有相同的作用。typedefstructstudent{intnum;charname[20];charsex;

structdatebirthday;floatscore;}STU;内存student3structstudentstudent3={3,"YaoMing",'M',90.5};

3YaoMingM赋值的顺序应与成员声明时的顺序一样;允许初始化语句中的值的数目比结构体成员数目少。student3.numstudent3.sex90.5student3.score结构体变量的初始化student1student1.num=1;scanf("%s",);student1.sex='M';printf("请输入成绩:\n");scanf("%f",&student1.score);1ZhangZiLiangM用输入语句或赋值语句来给结构体变量的各个成员赋值7878student2=student1;student21ZhangZiLiangM78strcpy(,"ZhangSan");结构体变量的引用如果要将“zhang”改为“zhong”,只要将结构变量student1中的数组成员name下标为2的元素‘a’改为‘o’即可。

可以使用下列语句:

[2]='o';/*为结构变量中的数组成员的一个元素赋值*/结构体变量的引用structstudent{intnum;charname[20];charsex;floatscore;}student1;对结构变量的整体操作 要对结构体进行整体操作有很多限制,C语言中能够对结构进行整体操作的运算不多,只有赋值“=”操作。例如:structdatesunday,today;

sunday=today; /*结构变量整体赋值*/结构体变量的引用不能将一个结构变量作为一个整体直接访问。

例如,不能这样引用:printf("%s,%c,%d,%d,%d\n",student1);如果成员本身又是一个结构类型,则要用若干个成员运算符,一级一级地找到最低的一级的成员。例如,对上面定义的结构变量student1,可以这样访问各个成员:

student1.sex student1.birthday.month student1.birthday.day student1.birthday.year结构体变量的引用struct{intnum;charname[20];charsex;

structdatebirthday;floatscore;}student1,student2;问题描述:根据学员的成绩,输出不及格学员的详细信息。

#include<stdio.h>structstudent{ intnum;//学号

charname[10];//姓名 charsex;//性别 floatscore;//成绩};intmain(){structstudentstu1={1,“张亚鹏",'M',61};structstudentstu2={2,"周晶晶",'F',92.5};structstudentstu3={3,"姚光明",'M',59};printf("不及格学员的名单如下:\n");if(stu1.score<60)printf("%d\t%s\t%c\t%5.2f\n",stu1.num,,stu1.sex,stu1.score);if(stu2.score<60)printf("%d\t%s\t%c\t%5.2f\n",stu2.num,,stu2.sex,stu2.score);if(stu3.score<60)printf("%d\t%s\t%c\t%5.2f\n",stu3.num,,stu3.sex,stu3.score);if(stu1.score>=60&&stu2.score>=60&&stu3.score>=60)printf("没有不及格的学员。\n");return0;}不及格学员的名单如下:3姚光明M59.00stu11张亚鹏M78stu22周晶晶F92stu33姚光明M59使用结构体示例structstudent

stu,*pstu;*pstu=&stu;(*pstu).num

或者:pstu->num一个指针当用来指向一个结构体时,称之为结构体指针变量。结构体指针变量中的值是所指向的结构体变量的首地址。结构体指针变量声明的一般形式为:

struct结构体名*结构体指针变量名通过结构体指针可以访问该结构体变量的成员,一般形式为:

(*结构体指针变量).成员名或者结构体指针变量->成员名

结构体指针变量#include<stdio.h>structstudent{ intnum; char*name; charsex; floatscore;}stu={1,"张宾",'F',55},*pstu;intmain(){pstu=&stu;printf("学号:%d姓名:%s\n",stu.num,);printf("性别:%c成绩:%5.2f\n\n",stu.sex,stu.score);printf("学号:%d姓名:%s\n",(*pstu).num,(*pstu).name);printf("性别:%c成绩:%5.2f\n\n",(*pstu).sex,(*pstu).score);printf("学号:%d姓名:%s\n",pstu->num,pstu->name);printf(“性别:%c成绩:%5.2f\n\n",pstu->sex,pstu->score);return0;}学号:1姓名:张宾性别:F成绩:55.00学号:1姓名:张宾性别:F成绩:55.00学号:1姓名:张宾性别:F成绩:55.00Pressanykeytocontinue结构体指针变量主要内容结构体类型与变量结构体数组结构体与函数链表structstudent{intnum;charname[20];charsex;floatscore;}stu[30];元素为结构体类型的数组称为结构体数组。在实际应用中,经常用结构体数组来表示具有相同数据结构体的一个群体。例如一个班的学员档案,一个公司的职工档案等。定义了一个结构体数组stu,共有30个元素,stu[0]~stu[29]。每个数组元素都具有structstudent的结构体形式。结构体数组结构体数组的初始化structstudentstu[3]={{1,"李芳",'F',45},

{2,"于红",'F',62.5},

{3,"何万山",'M',92.5},

{4,"程亚丽",'M',87},

{5,"王明",'M',58}};structstudent{intnum;charname[20];charsex;floatscore;}stu[30];结构体数组示例学生结构体类型定义如下:找出N个学生分数最低的学生,输出其姓名和成绩。输入:依次输入每个学生姓名与成绩输出:分数最低的学生姓名与成绩typedefstruct{charnum[10];ints;}STREC;主要内容结构体类型与变量结构体数组结构体与函数链表可以将结构体作为参数传递给函数,也可以定义返回结构体值的函数。结构体作为函数参数有两种不同方法:将结构体变量作为参数值传递给函数。将结构体指针作函数的参数。结构体作为函数参数结构体变量作参数【例1】编写程序,计算二维平面上两点p1和p2间的直线距离。输入:两点的坐标值输出:两点的距离输入样例:10-10输出样例:2.000000结构体变量作参数#include<stdio.h>#include<math.h>structpoint{doublex,y;}intmain(){structpointp1,p2;

doublee;

scanf(“%lf%lf”,&p1.x,&p1.y);scanf(“%lf%lf”,&p2.x,&p2.y);e=fun(p1,p2);printf(“%lf\n”,e);return0;}doublefun(structpointa, structpointb){doublex,y;

x=a.x

–b.x;

y=a.y–b.y;returnsqrt(x*x+y*y);结构体指针作参数【例2】修改学生信息#include<stdio.h>#include<string.h>structstudent{longsno;charname[10];floatscore[3];};voidfun(structstudent

*b)

{

b__1__=10004;

strcpy(b__2__,"LiJie");

}intmain()

{

structstudent

t={10002,"ZhangQi",

{93,85,87}};

int

i;

fun(__3__);

printf("No:%ld

Name: %s\nScores:",t.sno,);

for(i=0;i<3;i++)

printf("%6.2f", t.score[i]);

printf("\n");

return0;

}【例3】学生信息的排序#include<stdio.h>#include<string.h>structstudent{longsno;charname[10];floatscore[3];};voidfun(structstudent

a[],int

n)

{

__1__t;

int

i,j;

for(i=0;i<__2__;i++)

for(j=i+1;j<n;j++)

if(strcmp(__3__)>0)

{

t=a[i];

a[i]=a[j];

a[j]=t;

}

}结构体数组作参数intmain(){structstudent s[4]={{10001,"ZhangSan",{95,80,88}},

{10002,"LiSi",{85,70,78}},

{10003,"CaoKai",{75,60,88}},

{10004,"FangFang",{90,82,87}}};inti,j;fun(s,4);printf("Thedataaftersorting:\n");for(j=0;j<4;j++){printf("\nNo:%ldName:%-8s

Scores:",s[j].sno,s[j].name);for(i=0;i<3;i++)printf("%6.2f",s[j].score[i]);}printf("\n");return0;}主要内容结构体类型与变量结构体数组结构体与函数链表29链表是种常见的重要数据结构。

链表作用:动态地进行存储分配,根据需要开辟内存单元。

链表结构:

1249

head1249A13561356B14751475C10211021DNull链表有一个头指针变量,存放一个地址,指向一个元素(结点)结点:包括两部分:①用户需要的实际数据。②下一个结点的地址。1.链表概述30错误:

structList{charname[20];List*pN;Listm;};链表特点:链表中各元素在内存中可以不是连续存放,对链表中数据只能进行顺序存取。

链表实现:利用指针变量实现,即:一个结点中应包括一个指针变量,用它存放下一个结点的地址。

next:是指针类型成员名,指向 structstudent数据类型( 即所在的结构体类型)。 每个结点都属于struct student类型,它的next成 员存放下一个结点的地址。例如:学生链表

structstudent{intnum;charname[20];floatscore;student*next;};链表的分类: 单向链表 单向环形链表 双向链表 双向环形链表1.链表概述2.链表的操作31(1)建立(2)输出链表(3)查找结点(4)删除结点(5)插入结点(6)释放链表以学生链表为例:

structStudent{intnumber;floatscore;Student*next;};(1)创建链表

是指从无到有的建立起一个链表,即一个一个的输入各结点数据,并建立起前后相连的关系。

32

head

p1

p28910189.5

8910390

(n=2)(n=1)

p18910785

(n=3)

p100

p2

p2

p1NULL(1)创建链表33

是指从无到有的建立起一个链表,即一个一个的输入各结点数据,并建立起前后相连的关系。

算法:

开辟一个新结点,并使p1,p2指向它

读入一个学生数据给p1所指的结点

head=NULL

当读入的p1->num

不是零Head==NULL

head=p1(把p1所指的结点作为第一个结点)

p2->next=p1(把p1所指的结点连接到表尾)

p2=p1(p2移到表尾)

再开辟一个新结点,使p1指向它读入一个学生数据给p1所指结点

表尾结点的指针变量置NULL真假34structStudent*Create(){structStudent*head;

//开始头指针为空

head=NULL;//当前创建的结点指针

structStudent*p1;//当前链尾的结点指针,

//新的结点插入到其后

structStudent*p2;//开始生成结点

p1=(structStudent*)malloc(sizeof(structStudent));printf(“Inputnumberandscoreof astudent,endwith00:\n”);scanf(“%d%f”,p1->number,p1->score);p2=p1;//连接

while(p1->number!=0){

if(head==NULL)head=p1;elsep2->next=p1;p2=p1; p1=(structStudent*)malloc(sizeof(structStudent));scanf(“%d%f”,p1->number, p1->score);}

//尾结点

p2->next=NULL;free(p1);returnhead;}//主函数的调用voidmain(){structStudent*head;head=Create();}(1)创建链表(2)输出链表35将链表中各结点的数据依次输出。

head

NULLp=head,使p指向第一个结点

p指向的不是尾结点

当p指的不是表尾

输出p所指向的结点P移向指向下一个结点真假ppp36voidShowList(structStudent*head){ structStudent*p=head; printf(“Theitemsoflistare:\n”);

while(p!=NULL) { printf(“%d,%f\n”,p->number,p->score);

p=p->next; }}//主函数的调用voidmain(){structStudent*head;head=Create();ShowList(head);}(2)输出链表(3)释放链表37链表使用完毕后,需要释放各个结点空间。遍历链表,释放当前结点,直到所有结点均释放为止。voidFreeList(structStudent*head){printf(“Freetheitemsoflist\n”);structStudent*p;

while(head!=NULL){p=head;

head=head->next;free(p);}}(4)查询链表-查找某个结点38遍历链表,比较结点信息,直到找到相应结点或链表结束仍然没找到。例如:查询学生链表,找学号为number的结点,显示信息

调用函数struct

Student*search(structStudent*head,intnumber);39structStudent*Search(structStudent*head,intnumber){ structStudent*p;//当前结点指针,

p=head;

while(p!=NULL) { if(p->number==number) { printf(“该学生的成绩为:”); printf(“%f\n”,p->score);

returnp; }

p=p->next; } printf(“查找的学生不存在\n”); returnp;}(4)查询链表(5)删除链表结点40遍历链表,比较结点信息,直到找到相应结点或链表结束仍然没找到。如果找到则将该结点删除。关键要保证结点的连接不会因删除而中断。p2删除前:p1p1->next删除:关键代码:p2->next=p1->next; deletep1;41

删除链表结点1

structStudent*Delete(structStudent*head,intnumber){ structStudent*p1,*p2;//当前结点指针,前一结点指针

p2=p1=head; while(p1!=NULL) { p2=p1; p1=p1->next; }

returnhead;}//如果发现结点,删除if(p1->number==number){p2->next=p1->next;free(p1);printf(“foundanddelete!\n”);returnhead;}//如果发现结点,删除if(p1->number==number){ if(p1==head)//如果是首结点

head=p1->next; else//其他结点

p2->next=p1->next; free(p1); printf(“foundanddelete!”);

returnhead;}?Head=NULL?尾结点?首结点printf(“NotFound!”);head=p1->next;deletep1;p2headp1p1->nextheadp2if(head==NULL){cout<<“ListisNull”<<endl;returnhead;}42主函数的调用voidmain(){structStudent*head;head=Create();

温馨提示

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

评论

0/150

提交评论