C语言程序设计与实践 第3版 课件 第10章 块数据组织:结构与联合_第1页
C语言程序设计与实践 第3版 课件 第10章 块数据组织:结构与联合_第2页
C语言程序设计与实践 第3版 课件 第10章 块数据组织:结构与联合_第3页
C语言程序设计与实践 第3版 课件 第10章 块数据组织:结构与联合_第4页
C语言程序设计与实践 第3版 课件 第10章 块数据组织:结构与联合_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

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

文档简介

第10章块数据组织:结构与联合§10.1

结构体类型变量的定义和引用★为什么引入结构体?如数组的比较★结构体是一种构造数据类型★用途:把不同类型的数据组合成一个整体---自定义数据类型★结构体类型定义:struct[结构体名]{

类型标识符成员名;类型标识符成员名;

…………….};合法标识符可省:无名结构体成员类型可以是基本型或构造型struct是关键字,不能省略例

struct

accommod

{charname[20];

charsex;

intage;

longnumber;

charjob[30];

};结构体类型定义的作用域结构体类型定义描述结构的组织形式,不分配内存namesexagejob2字节20字节1字节30字节…...number8字节...♣结构体类型变量的定义

★先定义结构体类型,再定义结构体变量一般形式:struct结构体名{

类型标识符成员名;类型标识符成员名;

…………….};struct结构体名变量名表列;例structstudent{intnum;

charname[20];

charsex;

intage;

floatscore;

charaddr[30];};

structstudentstu1,stu2;★定义结构体类型的同时定义结构体变量一般形式:struct结构体名{

类型标识符成员名;类型标识符成员名;

…………….}变量名表列;例structdata{intdayintmonth;intyear}time1,time2;★直接定义结构体变量一般形式:struct{

类型标识符成员名;类型标识符成员名;

…………….}变量名表列;例struct{charname[20];charsex;intnum;floatscore[3]}person1,person2;用无名结构体直接定义变量只能一次♣结构体类型变量的引用引用形式为:

<结构体类型变量名>.<成员名>

注意:结构体变量不能整体引用,只能引用变量成员例:structdata{intday;intmonth;intyear;}time1,time2;变量time1和time2各成员的引用形式为:time1.day,time2.month,time2.year★说明◆结构体类型与结构体变量概念不同▶类型:不分配内存;变量:分配内存▶类型:不能赋值、存取、运算;变量:可以◆结构体可嵌套◆结构体成员名与程序中变量名可相同,不会混淆◆结构体类型及变量的作用域与生存期例structdate{intmonth;intday;intyear;};structstudent{intnum;

charname[20];

structdatebirthday;}stu;numnamebirthdaymonthdayyear例structstudent{intnum;charname[20];

structdate{intmonth;intday;intyear;}birthday;}stu;numnamebirthdaymonthdayyear♣结构体类型变量的初始化

★形式一:struct结构体名{

类型标识符成员名;类型标识符成员名;

…………….};struct结构体名结构体变量={初始数据};例structstudent{intnum;charname[20];charsex;intage;charaddr[30];};structstudentstu1={112,“WangLin”,‘M’,19,“200BeijingRoad”};★形式二:struct结构体名{

类型标识符成员名;类型标识符成员名;

…………….}结构体变量={初始数据};例structstudent{intnum;charname[20];charsex;intage;charaddr[30];}stu1={112,“WangLin”,‘M’,19,“200BeijingRoad”};★形式三:struct{

类型标识符成员名;类型标识符成员名;

…………….}结构体变量={初始数据};例struct{

intnum;

charname[20];

charsex;

intage;

charaddr[30];}stu1={112,“WangLin”,‘M’,19,“200BeijingRoad”};

§10.2

结构体数组的定义和引用

★结构体数组的定义三种形式:形式一:structstudent{intnum;

charname[20];

charsex;

intage;};structstudentstu[2];形式二:structstudent{intnum;

charname[20];

charsex;

intage;}stu[2];形式三:struct{intnum;

charname[20];

charsex;

intage;}stu[2];numnamesexagenumnamesexagestu[0]stu[1]25B★结构体数组初始化分行初始化:structstudent{intnum;

charname[20];

charsex;

intage;};structstudentstu[]={{100,“WangLin”,‘M’,20},

{101,“LiGang”,‘M’,19},

{110,“LiuYan”,‘F’,19}};全部初始化时维数可省★结构体数组引用引用方式:结构体数组名[下标].成员名structstudent{intnum;

charname[20];

charsex;

intage;}stu[3];stu[1].age++;strcpy(stu[0].name,”ZhaoDa”);例10-1设计一个程序来统计学生姓名、ID、成绩并且通过ID查询学生姓名与该学生成绩。#include<stdio.h>#include<string.h>structinfo{ charname[12]; charID[20]; doublescore;};intreadin(structinfoa[]){ inti=0; while(1) { scanf("%s",a[i].name); if(!strcmp(a[i].name,"#")) break; scanf("%s",a[i].ID); scanf("%lf",&a[i].score); i++; } returni;}例10-1设计一个程序来统计学生姓名、ID、成绩并且通过ID查询学生姓名与该学生成绩。voidfindout(structinfoa[],charb[],intn){ inti=0,j=0; while(1) { if(!strcmp(a[i].ID,b)) { printf("%sscoreis:%lf\n",a[i].name,a[i].score); break; } i++; n--; if(n==0) { printf("notfound\n"); break; } }}例10-1设计一个程序来统计学生姓名、ID、成绩并且通过ID查询学生姓名与该学生成绩。intmain(){ structinfoa[50]; charID[20]; intn; n=readin(a); while(1) { printf("pleaseputinyouID:"); scanf("%s",ID); if(!strcmp(ID,"#")) break; findout(a,ID,n); } return0;}§10.3

结构体指针的定义和引用♣指向结构体类型变量的指针的使

★定义形式:struct结构体名

*结构体指针名;

例structstudent*p;★使用结构体指针变量引用成员形式(*结构体指针名).成员名结构体指针名->成员名结构体变量名.成员名例

对指向结构体类型变量的指针的正确使用。#include<stdlib.h>#include<stdio.h>structdate{ intday,month,year;};structstu{ charname[20]; charnum[11]; structdatebirthday;};intmain(){ structstu*student; student=(structstu*)malloc(sizeof(structstu)); printf("Inputname,number,year,month,day:\n"); scanf("%s",student->name); scanf("%s",student->num); scanf("%d%d%d",&student->birthday.year,&student->birthday.month,&student->birthday.day); printf("\nOutputname,number,year,month,day:\n"); printf("%20s%10s%5d/%d/%d\n",student->name,student->num,student->birthday.year,student->birthday.month,student->birthday.day); return0;}程序运行如下:Inputname,number,year,month,day;Wangjian3419875.23wangjian♣指向结构体类型数组的指针的使用例

在上例中定义了结构体类型,根据此类型再定义结构体数组及指向结构体类型的指针;structdate{ intday,month,year;};structstu /*定义结构体*/{ charname[20]; charnum[11]; structdatebirthday; /*嵌套的结构体类型成员*/};structstustudent[4],*p; /*定义结构体数组及指向结构体类型的指针*/★数组元素引用的方法:

◆地址法

数组元素成员的引用形式为(student+i)->name、(student+i)->num和(p+i)->num等等。

student+i和p+i与&student[i]意义相同。

◆指针法若p指向数组的某一个元素,则p++就指向其后续元素。◆指针的数组表示法

若P=student,则指针p指向数组student,p[i]表示数组的第i个元素,与student[i]等同。例

指向结构体数组的指针变量的使用structdate /*定义结构体类型*/{ intyear,month,day;};structstu /*定义结构体类型*/{ charname[20]; charnum[11]; structdatebirthday;};intmain(){inti;structstu*p,student[4]={{"liying","1012150101",1978,5,23},{"wangping","1012150102",1979,3,14}, {"libo","1012150103",1980,5,6},{"xuyan","1012150104",1980,4,21}}; p=student; /*将数组的首地址赋值给指针p,p指向了一维数组student*/ printf("1----Outputname,number,year,month,day\n"); for(i=0;i<4;i++) //采用指针法输出数组元素的各成员 printf("%20s%12s%6d/%d/%d\n",(p+i)->name,(p+i)->num,(p+i)->birthday.year,(p+i)->birthday.month,(p+i)->birthday.day); printf("2----Outputname,number,year,month,day\n"); for(i=0;i<4;i++,p++) //采用指针法输出数组元素的各成员 printf("%20s%12s%6d/%d/%d\n",p->name,p->num,p->birthday.year,p->birthday.month,p->birthday.day); printf("3-----Outputname,number,year,month,day\n"); for(i=0;i<4;i++) //采用地址法输出数组元素的各成员 printf("%20s%12s%6d/%d/%d\n",(student+i)->name,(student+i)->num,(student+i)->birthday.year,(student+i)->birthday.month,(student+i)->birthday.day); p=student; printf("4-----Outputname,number,year,month,day\n"); for(i=0;i<4;i++)//采用指针的数组描述法输出数组元素的各成员 printf("%20s%12s%6d/%d/%d\n",p[i].name,p[i].num,p[i].birthday.year,p[i].birthday.month,p[i].birthday.day);}10.4链表1.链表概述链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。1249

A1356head1249135614751021

B1475

C1021

DNULL头指针(头结点)链表中的元素称为”结点”由两部分组成1链表概述—链表的特点链表中各元素在内存中可以不是连续存放的。要找某一元素,必须先找到上一个元素,根据它提供的下一元素地址才能找到下一元素。链表的数据结构,必须利用指针变量才能实现。即:一个结点中应包含一个指针变量,用它存放下一结点的地址。1链表概述—链表结点的特点链表的结点是结构体变量,包含若干成员链表结点的某些成员可以是任意类型(标准类型、结构体类型)链表结点的另一些成员是指针类型的,用来存放与之相连的结点的地址structstudent{longnum;floatscore;structstudent*next;};例:一个学生结点的定义3.1链表概述课堂练习:以下定义的结构体类型拟包含两个成员,其中成员变量number用来存入整型数据,成员变量link是指向自身结构体的指针,请将定义补充完整。structnode{intnumber;

link;};★对链表的基本操作

◆建立链表:即往空链表中依次插入若干结点,并保持结点之间的前驱和后继关系。

◆输出元素:通过头指针逐个输出链表中的数据。

◆删除元素:把链表中的某些元素从表中分离出来。

◆插入元素:把一个新的数据插入到链表中。

◆查询元素:把链表中满足一定条件的元素显示出来。♣链表的建立例10-6建立一个含有若干个单位电话号码的链表。structunit_tele*creat_list(){structunit_tele*q,*p,*head;charuname[50];head=q=NULL;while(1) { printf("pleaseinputunitname:"); scanf("%s",uname); if(strcmp(uname,"#")==0)break; p=(structunit_tele*)malloc(sizeof(structunit_tele)); /*建立结点*/ printf("pleaseinputtelephone:"); scanf("%s",p->telephone); strcpy(p->unitname,uname); if(q==NULL) head=q=p; else{q->next=p;q=p;} } q->next=NULL; returnhead;}structunit_tele{charunitname[50];chartelephone[15];structunit_tele*next;};★元素加到链表尾部的两种情况:

◆情况a:加入前,链表是空的

插入y前:Head=Null

▶插入y后:

情况b:加入前,链表中已有结点

▶插入y前:

▶插入y后:♣输出链表元素例10-7输出例10-6建立的链表的元素voidprint_1(structunit_tele*head){structunit_tele*p;for(p=head;p!=null;p=p->next)printf(“%s,%s\n”,p->unitname,p->telephone);}♣删除链表元素例如图所示删除操作:10-8删除例10-6所建链表中某指定的单位结点。structunit_tele*delete_list(structunit_tele*head,charuname[]){structunit_tele*q,*p;for(p=head,q=NULL;p!=NULL;q=p,p=p->next) /*检索结点*/ if(strcmp(p->unitname,uname)==0) break; if(p!=NULL) {if(q==NULL) head=p->next; else q->next=p->next; free(p);}

returnhead;}♣插入链表元素例10-9把新输入的单位及电话号码插入到例10-6建立的链表中structunit_tele*insert_list(structunit_tele*head,charuname[],chartele[]){ structunit_tele*q,*p; for(q=head;q!=NULL;q=q->next) if(strcmp(q->unitname,uname)==0)break; if(q==NULL){p=(structunit_tele*)malloc(sizeof(structunit_tele)); strcpy(p->unitname,uname); strcpy(p->telephone,tele); p->next=head; head=p; }returnhead; }xyheadx…♣查询链表元素例10-10查询例10-6所建链表中某指定单位的结点。#include<stdio.h>structunit_tele{ charunitname[50]; chartelephone[15]; structunit_tele*next; };intmain(){ structunit_tele*head; charuname[50],tele[15]; head=creat_list(); print_list(head); printf("inputunit_namefordelete:\n"); scanf("%s",uname); head=delete_list(head,uname); printf("inputunit_nameforquery:\n"); scanf("%s",uname); query_list(head,uname); printf("inputunit_nameandit'stelephoneforinsert:\n"); scanf("%s%s",uname,tele); head=insert_list(head,uname,tele); printf("inputunit_namefordelete:\n"); scanf("%s",uname); head=delete_list(head,uname); print_list(head); return0; }voidquery_list(structunit_tele*head,charuname[]){structunit_tele*p;for(p=head;p!=NULL;p=p->next)if(strcmp(p->unitname,uname)==0)break;if(p!=NULL) printf("unit_name:%s,telephone:%s\n",uname,p->telephone);else printf("nothisunit\n");printf("pressanykeyreturn");getchar();return;}§10.5

联合♣联合:即构造数据类型,也叫共用体。

★联合类型的一般格式:union<联合标识符>{<类型标识符><成员标识符>;};例uniondata

{inti;

charch;

floatf;

};fchi类型定义不分配内存★联合成员的使用◆联合变量引用方式:共用体指针名->成员名共用体变量名.成员名(*共用体指针名).成员名◆使用联合时应注意:

1)联合成员所占内存的起始地址都一样,但实际所占内存长度依成员类型的不同而不同。2)在某一时刻只有一个成员占用该内存段,其他成员不使用该内存段。可以增设一个标志项,以便能确定当前有效的成员是哪一个。3)联合类型可以出现在结构和数组中,结构和数组也可以出现在联合中。structstudent{charclass[15];charname[10];intenglish,math;charselect;unioncourse{intcomputer;charmusic;};};增设了标识符select,用于识别联中存放的是哪一个成员。uniondata{inti;

charch;

floatf;};

uniondataa,b,c,*p,d[3];a.ia.cha.fp->ip->chp->f(*p).i(*p).ch(*p).fd[0].id[0].chd[0].f★例10-11按以上定义的structstudent,输入5个学生成绩,然后输出它们。#include<stdio.h>intmain(){

structstudent{charclassname[15]; charname[10]; intenglish,math; charselect;unioncourse{

intcomputer; charmusic;}selective;}stud[5];inti;

for(i=0;i<5;i++) {

scanf("%s,%s,%d,%d,%c",stud[i].classname,stud[i].name,&stud[i].english,&stud[i].math,&stud[i].select);

stud[i].select=toupper(stud[i].select);

if(stud[i].select=='M')

scanf("%c",&stud[i].selective.music); /*选修音乐*/

else scanf("%d",&stud[i].puter);}

/*选修计算机*/} printf("classnameenglishmathematicmusiccomputer\n"); for(i=0;i<5;i++) {

printf("%s%s%d%d",stud[i].classname,stud[i].name,stud[i].english,stud[i].math); if(stud[i].select=='M')

printf("%c\n",stud[i].selective.music); else

printf("%d\n",stud[i].puter);

}return0;

}♣数组、结构和联合三种数据类型的比较比较类型数组结构联合概念相同类型元素的有序集合不同类型元素的有序集合不同类型元素共同用以存储单元。在某一时刻,只有其中一个元素使用存储单元长度元素类型长度×元素个数元素类型长度之和最大的元素类型长度元素的引用通过下标或指针引用元素通过成员运算符.和->引用元素参数传递数组名做参数表示地址允许不允许初始化允许允许不允许赋值允许对数组元素赋值和访问允许对结构整体和成员进行赋值,但不能整体输入/输出只能对联合体成员赋值,不能对联合体变量进行整体赋值函数返回值不允许作为“整体数值”返回§10.6

枚举类型

★枚举类型:就是把变量的取值一一列举出来。

★定义枚举类型和枚举变量的一般格式:

◆enum<类型标识符><枚举表>;

◆enum<类型标识符><变量表>;

◆enum[<类型标识符>]<枚举表><变量表>;

例enumtvsize{c9,c12,c14,c16,c18,c21};例enumtvsizex;例enumtvsize{c9,c12,c14,c16,c18,c21}x;例:enummonthtype{jan,feb,mar,apr,jun,jul,ang,sep,oct,nov,dece};注意:C语言中,枚举类型中的枚举元素是与整型相对应的

。011011……10.7用typedef定义类型功能:用自定义名字为已有数据类型命名类型定义简单形式:t

温馨提示

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

最新文档

评论

0/150

提交评论