南京大学《C语言程序设计》课件-第8章 数据封装-结构体_第1页
南京大学《C语言程序设计》课件-第8章 数据封装-结构体_第2页
南京大学《C语言程序设计》课件-第8章 数据封装-结构体_第3页
南京大学《C语言程序设计》课件-第8章 数据封装-结构体_第4页
南京大学《C语言程序设计》课件-第8章 数据封装-结构体_第5页
已阅读5页,还剩79页未读 继续免费阅读

下载本文档

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

文档简介

第8章数据封装—结构体结构体的概述结构体类型的定义结构体类型的变量结构体数组结构体作为函数的参数链表结构体的概念打印学生成绩单,格式如下:学号姓名语文成绩数学成绩英语成绩.00001张三96948800003李四89707600004王五908778如何在程序中表示这组学生信息?可选方案用二维的数组来表示该方案不可行,因为这些信息有不同的类型每一列用一个一维数组来表示,这种方法称为并联数组。要保证每位学生信息的正确性很难为什么要使用记录当我们考虑怎么逻辑地组织数据时,应该将一个人的所有信息项放在一起,即保持相关性。学号姓名语文成绩数学成绩英语成绩.00001张三96948800003李四89707600004王五908778我

构学生一00001张三969488学生二00003李四897076学生三00004王五908778记录在C++中称为结构体结构体类型作用结构体类型允许程序员把一些分量聚合成一个整体,用一个变量表示。一个结构体的各个分量都有名字,把这些分量称为成员(member)。由于结构体的成员可以是各种类型的,程序员能创建适合于问题的数据聚合。结构体的使用定义一个新的结构体类型定义新类型的变量访问结构体变量第8章数据封装—结构体结构体的概述结构体类型的定义结构体类型的变量结构体数组结构体作为函数的参数链表结构体类型的定义定义结构体类型中包括哪些分量格式:struct结构体类型名{字段声明;};如:structstudentT{charno[10];charname[10];intchinese;intmath;intenglish;};注意字段名可与程序中的变量名相同在不同的结构体中可以有相同的字段名结构体成员的类型可以是任意类型,当然也可以是结构体类型structdateT{ intmonth; intday; intyear;};structstudentT{ ... dateTbirthday;};

第8章数据封装—结构体结构体的概述结构体类型的定义结构体类型的变量结构体数组结构体作为函数的参数链表结构体类型的变量结构体变量的定义结构体类型的引用指向结构体的指针动态分配结构体的空间结构体变量的定义结构体变量的定义和普通的变量定义一样。如定义了结构体类型studentT,就可以定义结构体变量:

studentTstudent1;一旦定义了一个结构体类型的变量,系统在分配内存时就会分配一块连续的空间,依次存放它的每一个分量。这块空间总的名字就是结构体变量的名字。内部还有各自的名字

englishmathchinesenamenostudent1结构体变量的初始化studentTstudent1={“00001”,“张三”,87,90,77};

定义结构体类型的同时定义变量struct结构体类型名{

字段声明;}结构体变量;struct{

字段声明;}结构体变量;区别:前者可以继续用结构体类型名定义变量结构体类型的变量结构体变量的定义结构体类型的引用指向结构体的指针动态分配结构体的空间结构体变量的访问成员的表示:

结构变量名.成员名

如:

如结构中还有结构,则一级一级用”.”分开,如如:student1.birthday.year对结构体类型变量的引用一般为引用他的成员结构变量的赋值结构体是一个统称。每个结构体类型在使用前都要先定义自己有哪些分量。系统事先无法知道如何处理他。因此,结构体变量的赋值通常是通过对它的每一个成员的赋值而实现。如:输入student1的内容可用:cin>>student1.no>>>>student1.chinese>>student1.math>>student1.english>>student1.birthday.year>>student1.birthday.month>>student1.birthday.day;同类型的结构变量之间可以相互赋值,如Student1=student2;将student2的成员对应赋给student1的成员结构变量的输出结构体变量的输出通常是通过输出它的每一个成员而实现。如:输出student1的内容可用:cout<<student1.no<<<<student1.chinese<<student1.math<<student1.english<<student1.birthday.year<<student1.birthday.month<<student1.birthday.day;结构体类型的变量结构体变量的定义结构体类型的引用指向结构体的指针动态分配结构体的空间指向记录的指针直接定义指针变量

studentT*sp;也可以在定义结构体类型的同时定义指向结构体的指针struct结构体类型名{

字段声明;}*结构体指针;通过指针操作记录给结构体指针赋值,如:

sp=&student1;结构体指针的引用:(*指针).成员

如:(*sp).name

指针->成员如:sp->namestudent1.成员

->是所有运算符中优先级最高的

通常程序员习惯使用第二种方法结构体类型的变量结构体变量的定义结构体类型的引用指向结构体的指针动态分配结构体的空间动态分配结构体的空间指向结构体指针的另一种用法是存储动态申请到的内存的首地址。用法和申请普通的动态变量一样。如:

studentT*sp;sp=newstudentT;第8章数据封装—结构体结构体的概述结构体类型的定义结构体类型的变量结构体数组结构体作为函数的参数链表

结构体数组用于描述个体的集合定义格式:

studentTstudentArray[SIZE];结构体数组的引用引用数组的某一成员的成员

studentArray[3].name数组成员之间相互赋值

studentArray[4]=studentArray[2]结构数组的初始化

studentTstudentArray[5]={{“00001”,张三“,80,90,98},{…},{…},{…}};统计候选人得票。设有三个候选人,每次输入一个得票的候选人名字,要求最后输出各人得票结果。

structpersonT{intid;intcount;}leader[3]={0,0,1,0,2,0};

intmain(){inti,j,inputID;for(i=1;i<=10;++i){cin>>inputID;if(inputID<0||inputID>2){cout<<“废票”;continue;}leader[inputID].count+=1;}cout<<endl;for(i=0;i<3;++i)cout<<leader[i].id<<““<<leader[i].count);return0;}

指针与结构体数组与普通的指针一样,指向结构体的指针也能够用来指向一个结构体数组。此时,对指针加1就是加了该结构体的大小。第8章数据封装—结构体结构体的概述结构体类型的定义结构体类型的变量结构体数组结构体作为函数的参数链表结构体作为参数传递尽管结构体和数组一样也有许多分量组成,但结构体的传递和普通内置类型是一样的。它是将实际参数中的每个分量复制到形式参数的每个分量中。结构体的传递VoidprintPerson(PersonTp)指向结构体的指针作为参数因为结构体是值传递,当希望把函数内部对结构体的修改返回给主调函数时,可以用指针传递或引用传递由于结构体一般占用的内存量都比较大,值传递既浪费空间又浪费时间。因此可用指针传递或引用传递指针传递形式比较繁琐,所以C++通常用引用传递引用传递的问题是函数中可以修改实际参数,要控制函数中不能修改实际参数,可以加const限定指向结构体的指针作为参数和普通的指针传递一样,函数中可以通过指针访问主调函数的记录减少函数调用时的数据传递量VoidPrintPerson(personT&p);VoidPrintPerson(constpersonT&p);结构体传递的实例设计一函数,打印学生信息设计一:值传递VoidPrintStudent(studentTs){cout<<s.no<<‘\t’<<<<‘\t’<<s.chinese<<‘\t’<<s.math<<‘\t’<<s.english<<endl;}缺点:浪费时间空间设计二:指针传递或引用传递VoidPrintStudent(studentT*s){cout<<s->no<<‘\t’<<s->name<<‘\t’<<s->chinese<<‘\t’<<s->math<<‘\t’<<s->english<<endl;}VoidPrintStudent(studentT&s){cout<<s.no<<‘\t’<<<<‘\t’<<s.chinese<<‘\t’<<s.math<<‘\t’<<s.english<<endl;}缺点:不安全设计三:C++的常规做法VoidPrintStudent(conststudentT&s){cout<<s.no<<‘\t’<<<<‘\t’<<s.chinese<<‘\t’<<s.math<<‘\t’<<s.english<<endl;}特点:节约内存,提高函数调用速度,可靠返回结构体类型的函数一个函数返回一个结构体。如:personTGetPersonData(void){personTperson;…….Return(person);}返回的是一个结构体的复制。在主调函数中必须有这样的程序段:Main(){personTp1,p2;p1=GetPersonData();}返回结构体引用的函数函数返回一个结构体的引用。如:personT&GetPersonData(void){personT*person=newpersonT;…….Return(*person);}本质上返回的是结构体的地址。在主调函数中可以有这样的程序段:Main(){personT&p1=GetPersonData();…}

函数中返回的结构体不能是局部变量第8章数据封装—结构体结构体的概述结构体类型的定义结构体类型的变量结构体数组结构体作为函数的参数链表单链表链表的概念链表的存储链表的操作循环链表单链表nilhead头结点只指出后继关系的链表双链表

head循环链表

head同时存储前趋和后继单链表链表的概念链表的存储链表的操作循环链表单链表的存储structlinkRec{datatypedata;linkRec*next;}

存储链表就是存储链表中的一个节点的地址,因此需要定义一个节点类型单链表链表的概念链表的存储链表的操作循环链表单链表操作—插入申请空间输入数据放入申请到的空间链入p后在结点p后插入一个结点

headp

tmptmp=newLinkRec;//创建一个新节点tmp->data=x;//把x放入新节点的数据成员中tmp->next=p->next;//把新节点和p的下一成员相连p->next=tmp;//把p和新节点连接起来

单链表操作—删除把结点p后的结点删除headpdelPtr

delPtr=p->next;p->next=delPtr->next;deletedelPtr;

单链表操作--建立定义头指针:linkRec*head;建立头结点申请空间设为头结点head单链表操作--建立(续)逐个从键盘输入数据,存入链表

接受输入申请空间输入数据放入申请到的空间链入链表尾置链表结束标志headabcd^head=newlinkRec;rear=head;Cin>>in_data;while(输入未结束){p=newlinkRec;p->data=in_data;rear->next=p;rear=p;cin>>in_data;}rear->next=NULL;

单链表操作—输出headabcd^p=head->next;while(p!=NULL){cout<<p->data;p=p->next;}

创建并访问一个带头结点的、存储整型数据的单链表,数据从键盘输入,0为输入结束标志。#include<iostream>usingnamespacestd;

structlinkRec{intdata;linkRec*next;};intmain(){intx;//存放输入的值

linkRec*head,*p,*rear;

head=rear=newlinkRec;

while(true){//创建链表的其他结点

cin>>x;if(x==0)break;p=newlinkRec; p->data=x;rear->next=p;rear=p; }

rear->next=NULL; //设置rear为表尾,其后没有结点了

//读链表

cout<<"链表的内容为:\n";p=head->next;while(p!=NULL){cout<<p->data<<'\t';p=p->next;}cout<<endl;

return0;}单链表链表的概念链表的存储链表的操作循环链表例:n个人围成一圈,从第一个人开始报数1、2、3。凡报到

3者退出圈子。找出最后留在圈子中的人的序号。

解。用循环链表

01243head当n=5时,其删除的节点的顺序为2,0,4,1,最后剩下的节点为3。

循环链表的应用—约瑟夫环structnode{intdata;node*next;};intmain(){node*head,*p,*q;//head为链表头

intn,i;//输入ncout<<"\ninputn:";cin>>n;//建立链表

head=p=newnode;p->data=0;//p指向表尾

for(i=1;i<n;++i){q=newnode;//q为当前正在创建的节点

q->data=i;p->next=q;p=q;//将q链入表尾

}p->next=head;//头尾相连

//删除过程

q=head;while(q->next!=q)//只要表非空

{for(i=0;i<2;++i)//报数,

{p=q;q=p->next;}p->next=q->next;//绕过节点qcout<<q->data<<'\t';//显示被删者的编号

deleteq; //回收被删者的空间

q=p->next;//让q指向报1的节点

}//打印结果

cout<<"\n最后剩下:"<<q->data<<endl;return0;}

链表总结实现较复杂插入、删除效率高,但查找第i个元素效率低无表满的问题适合于动态表总结本章介绍了结构体作用:处理更复杂的数据使用:定义类型定义变量链表

struct

sp

{

inta;

int*b;

}*p;

intd[3]={10,20,30};

structspt[3]={70,&d[0],80,&d[1],90,&d[2]};

voidmain()

{

p=t;

cout<<++(p->a)<<*++p->b;}7120若有下面的定义:struct{intx;inty;}s[2]={{1,2},{3,4}},*p=s;则表达式++p->x的值为___________;表达式(++p)->x的值为_________。23已知head指向一个带头结点的单向链表,链表中每个结点包含数据域(data)和指针域(next),数据域为整型。下面的sum函数是求出链表中所有结点数据域值的和,作为函数值返回。请填空完善程序。structlink{ intdata; structlink*next;}main(){ structlink*head;ints;┆ s=sum(head);┆}intsum(

){ structlink*p; ints=0; p=head->next; while(p) { s+=

; p=

; } return(s);}已知head指向一个带头结点的单向链表,链表中每个结点包含数据域(data)和指针域(next),数据域为整型。下面的sum函数是求出链表中所有结点数据域值的和,作为函数值返回。请填空完善程序。structlink{ intdata; structlink*next;}main(){ structlink*head;ints;┆ s=sum(head);┆}intsum(structlink*head){ structlink*p; ints=0; p=head->next; while(p) { s+=p->data; p=p->next; } return(s);}设有定义语句“struct{intx;inty;}d[2]={{1,3},{2,7}};”,则cout<<d[0].y/d[0].x*d[1].x;的输出是:()A.0B.1C.3D.6设有如下定义,则对data中的a成员的正确引用是:()structsk{inta;floatb;}data,*p=&data;A.(*p).data.aB.(*p).aC.p->data.aD.p.data.a

阅读程序,写出程序的运行结果。main(){structstudent{charname[10];floatk1;floatk2;}a[2]={{“zhong”,100,70},{“wang”,70,80}},*p=a;Cout<<p->name<<p->k1+p->k2;cout<<a[1].name<<a[1].k1+a[1].k2;}structSTU{intnum;floatTotalScore;};voidf(structSTUp){structSTUs[2]={{20088,550},{20099,537}};p.num=s[1].num;p.TotalScore=s[1].TotalScore;}main(){structSTUs[2]={{20098,703},{20089,580}};f(s[0]);Cout<<s[0].num<<s[0].TotalScore;} chars1[50]="jack"; chars2[50]="jill"; chars3[50]; cout<<strcpy(s3,s2)<<endl; cout<<strcat(strcat(strcpy(s3,s1),"and"),s2)<<endl; cout<<strlen(s1)+strlen(s2)<<endl; cout<<strlen(s3)<<endl;下面程序做了什么?intmain(){ charstring1[80]; cin>>string1; cout<<mystery2(string1)<<endl; return0;}intmystery2(constchar*s){ intx; for(x=0;*s!=‘\0’;s++) ++x; returnx;}指出下面程序段的错误,并改正int*number; cout<<number<<endl;Double*realPtr; Long*integerPtr; integerPtr=realPtr;Int*x,y; x=y;d)Chars[]=“thisisatest” for(;*s!=‘\0’;s++) cout<<*s<<‘‘;doublex=19.34; DoublexPtr=&x; Cout<<xPtr<<endl;Char*s; Cout<<s<<endl;指出以下程序的功能Boolmystery3(constchar*,constchar*);Intmain(){ charstring1[80],string2[80]; cin>>string1>>string2; cout<<“theresultis”<<mystery3(string1,string2)<<endl; return0;}Boolmystery(constchar*s1,constchar*s2){ f

温馨提示

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

评论

0/150

提交评论