c语言课件   结构和联合体.ppt_第1页
c语言课件   结构和联合体.ppt_第2页
c语言课件   结构和联合体.ppt_第3页
c语言课件   结构和联合体.ppt_第4页
c语言课件   结构和联合体.ppt_第5页
已阅读5页,还剩83页未读 继续免费阅读

下载本文档

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

文档简介

第九章结构体和联合体,本章目录,9.1 结构体,9.2结构体数组,9.3指向结构体类型数据的指针,9.4链表,9.5 共用体,9.1如何用计算机程序实现下述表格的管理?,表9-1 某学校学生成绩管理表,9.1 结构体,数组的解决方法,int studentId30; /* 最多可以管理30个学生, 每个学生的学号用数组的下标表示*/charstudentName3010;charstudentSex302;int timeOfEnter30; /*入学时间用int表示*/int scoreComputer30;/*计算机原理课的成绩*/int scoreEnglish30; /*英语课的成绩*/int scoreMath30; /*数学课的成绩*/int scoreMusic30; /*音乐课的成绩*/,9.1 结构体,数据的内存管理方式,9.1 结构体,希望的内存分配图,9.1 结构体,C语言提供了一种数据结构,可以把这些不同类型的数据组成一个整体,这就是结构类型。 结构类型是各种结构的总称,是一种构造类型。一个结构变量可以由不同类型的成员变量组成,这些成员变量又称为结构的域、分量。结构的所有成员除自身的名字外,还拥有共同的名字,即结构变量名。,9.1 结构体,struct 结构体名 数据类型1 成员名1; 数据类型2 成员名2; 数据类型n 成员名n; ;,结构体类型定义的一般形式:,struct为关键字;结构体名是用户定义的类型标识。 中是组成该结构体的成员。成员的数据类型可以是C语言所允许的任何数据类型。,9.1 结构体,9.1 结构体,例如,描述日期定义的结构体类型: struct date int year; int month; int day; ; 其中date是结构体名,该结构体类型是由三个成员组成。成员都是整型,编者可根据自己需求编写成员,成员的数据类型可以是任何数据类型,当然也可以包含结构体类型。注意最后大括号后要加上分号“;”作为结束。,struct STUDENT int studentID; /*每个学生的序号*/ char studentName10;/*每个学生的姓名*/ char studentSex4; /*每个学生的性别*/ inttimeOfEnter; /*每个学生的入学时间*/ intscoreComputer; /*每个学生的计算机原理成绩*/ intscoreEnglish; /*每个学生的英语成绩*/ intscoreMath; /*每个学生的数学成绩*/ intscoreMusic; /*每个学生的音乐成绩*/ ;struct STUDENT是一个类型struct STUDENT students4;students0.studentIDstudents0.scoreComputer它们都是变量,一般称为结构的成员变量,9.1 结构体,在定义结构体类型的同时定义变量,例如: struct student char num8,name20,sex; int age; float score; st30;,struct 结构体名 成员定义表; 变量名表;,9.1 结构体,直接定义结构体类型变量,例如: struct char num8,name20,sex; int age; float score; st30, a, b, c;,struct 成员定义表; 变量名表;,9.1 结构体,例如学生类型的定义:struct student char num8; /* 学号是字符数组类型 */ char name30; /* 姓名是字符数组类型 */ char sex; /* 性别是字符型 */ int age; /* 年龄是整型 */ char addr60; /* 住址是字符数组类型 */ int score6; /* 成绩是整型数组类型 */ ;,9.1 结构体,在结构的说明中,结构成员可以为任何类型且结构成员还可以和结构外部的其它变量同名,不同结构的成员也可以同名,但同一结构的成员不能同名。,利用已定义的结构体类型名定义变量 struct 结构体名 变量名表;例如:struct student s30, t1, t2;,按照结构体类型的组成,系统为定义的结构体变量分配内存单元。结构体变量的各个成员在内存中占用连续存储区域。,9.1 结构体,1结构的初始化 结构变量在说明时可以初始化,初值是由常量表达式组成的初值表。例如,struct student char name10; short sex; int age; float score; student1“zhangsan”,1,20,88.8;,9.1 结构体,2结构变量的引用 对结构变量的引用只允许下列5种情况:(1)同类型的结构变量相互赋值。例如 student2=student1;(2)函数返回的结构成员给同类型的结构变量。(3)对结构变量取地址。例如,9.1 结构体,3结构成员的引用 结构成员的引用通过“”运算符构成的表达式。 结构变量名成员名其中“” 称为结构成员运算符。连接结构变量名和成员名,属于最高级运算符。,9.1 结构体,例如student1.sex=1;student1.score=90;scanf(“%s”,);但=”zhang san”; 则为非法。结构体变量的成员不允许用赋值语句将一组常量直接赋给一个结构体变量。输入下面语句不合法: Student1=WangLi,18,M,12,15,1974,89101,89.5;,9.1 结构体,4嵌套的结构 结构的一个成员可以是一个结构,含有结构成员的结构称为嵌套的结构。,如果成员本身又属于一个结构体类型,则需要再次使用取成员运算符“”,这样逐级的应用成员运算符找到最低级的成员。 例如: student1.birthday.year,9.1 结构体,struct date int year,month,day; struct student char num8; char name30; char sex; struct date birthday; /* 成员为结构体类型 */ char addr60; int score6; ;,9.1 结构体,9.1 结构体,例9.1 学生信息输出。 struct date int month; int day; int year; ; struct stud_type char name20; int age; char sex; struct date birthday; long num; float score; ;,9.1 结构体,main ( ) struct stud_type student1=Wang Li,20,M,12,15,1978,89101,89.5; struct stud_type student2; student2=student1; printf(student1:%s,%d,%c,%d,%d,%d,%ld,%5.2fn,,student1.age,student1.sex,student1.birthday.month,student1.birthday.day,student1.birthday.year,student1.num,student1.score); printf(student2:%s,%d,%c,%d,%d,%d,%ld,%5.2fn,,student2.age,student2.sex,student2.birthday.month,student2.birthday.day,student2.birthday.year,student2.num,student2.score); ,结构数组定义的一般格式为: struct 结构体名 结构体数组名元素个数,结构体数组名元素个数,;例如:struct student int num; char name10; char sex; int age; float score; char addr30;struct student stu3; 以上定义了一个数组stu,其元素为struct student类型数据,数组有3个元素。,9.2结构体数组,2、结构体数组的初始化struct 结构体名 结构体数组名=初始数据表列; struct STUDENTintstudentID;charstudentName10;char studentSex4;struct date timeOfEnter;int scoreComputer;int scoreEnglish;int scoreMath;int scoreMusic; struct STUDENT stu30;,9.2结构体数组,struct STUDENT stu30 = 1,令狐冲,男,1999,12,20,90,83,72,82, 2,林平之,男,1999,07,06,78,92,88,78, 3,岳灵珊,女,1999,07,06,89,72,98,66, 4,任莹莹,女,1999,07,06,78,95,87,90 ;,9.2结构体数组,【例】对候选人得票的统计程序。设有三个侯选人,每次输入一个得票的候选人的名字,要求最后输出各人得票结果。 #include struct personchar name18; int count;leader3=Li,0,Zhang,0,Wang,0;,9.2结构体数组,void main ()int i,j; char leader_name18; for(i=1;i=10;i+) scanf (%s,leader_name);for (j=0;j3;j+)if(strcmp(leader_name,)=0) leaderj.count+; printf (n); for (i=0;i3;i+)printf(%5s,%dn,,leaderi.count);,9.2结构体数组,例9.4 计算学生的平均成绩和不及格的人数。#include struct stu /* 定义结构体 */ int num; char *name; char sex; float score;boy5=101,Liping,M,45,102,Zhangping,M,62.5,103,Hefang,F,92.5,104,Cheng ling,F,87,105,Wang ming,M,58; /* 对结构体数组元素初始化 */,9.2结构体数组,程序运行结果:s=345.00average=69.00count=2,void main() int i,c=0; float ave,s=0; for(i=0;i5;i+) s+=boyi.score; if(boyi.score成员名;,用结构体变量名的引用形式: d.year d.month d.day,用结构体指针变量的引用形式: (*p).year (*p).month (*p).day p-year p-month p-day 注意:成员引用表达式中的( )不能省,如(*pd).day不能写成*pd.day,因为“.”运算符的优先级高于*,所以*pd.day等同于*(pd.day),在该例中为非法操作。 结构成员运算符“-”和“.”的优先级相同,它们与()、 属于同一优先级,按从左到右结合。,9.3指向结构体类型数据的指针,struct pointint x;int y;struct rectstruct point pt1;struct point pt2;,struct rect rt;struct rect *rp = 下面表达式哪些合法?rt.pt1.x(*rp).pt1.xrp-pt1.xrt-pt1.x上面合法的表达式都是等价的吗?,9.3指向结构体类型数据的指针,【例】利用结构体指针输出一组化学元素名称及其原子量。 struct list int i; char name4; float w; tab4=1,H,1.008,2,He,4.0026, 3,Li,6.941,4,Be,9.01218;,9.3.2 用结构的指针引用结构数组的成员,9.3.2指向结构体数组的指针 对构体数组及其元素可以用指针变量来指向。,main( ) struct list *p; printf(NotNametAtomic Weightn); for (p=tab; pi, p-name, p-w); ,No Name Atomic Weight,1 H 1.008,2 He 4.0026,3 Li 6.941,4 Be 9.01218,9.3.2 用结构的指针引用结构数组的成员,例9.2指向结构体数组的指针的应用。 #include main() struct student int num; char name20; char sex; int age; stu3=10101,LiLin,M,18,10102,Zhang Fun,M,19,10104,Wang min,F,20; struct student *p; printf(No. Name sex agenn); for(p=stu;pnum, p-name, p-sex, p-age); ,9.3.2 用结构的指针引用结构数组的成员,9.3指向结构体类型数据的指针,p是指向struct student结构体类型数据的指针变量。执行p+,使p自加1。p指向了结构体数组中的stu1即“走“过了本例中2+20+1+225字节的存储单元,p指向了stu1,输出stu1中的各成员值之后,再进行下一次循环。注意: 程序已定义了p是一个指向struct student类型数据的指针变量,它用来指向一个struct student类型的数据,不应用来指向stu数组元素中的某一成员。下面的用法是不对的: p=; 编译时将给“警告”信息,表示地址的类型不匹配。,9.3指向结构体类型数据的指针,例9.3指向结构体变量的指针的应用 #include #include struct student long num; char name20; char sex; float score; ; main( ) struct student stu_1,* p;,9.3指向结构体类型数据的指针,p= 运行结果:,9.4 动态数据结构,9.4.1 问题的提出 例:学生成绩管理 struct student stu30; 问题: (1) 数组的存储容量是固定的,若实际学生人数超过元素最大个数或远小于元素最大个数,都会存在问题。 (2)能否根据实际情况,要添加元素时,动态分配内存,删除元素时,动态释放内存呢?,C语言提供了相关的存储管理库函数。这里仅介绍其中三个,它们的原型说明在“stdlib.h”头文件和“malloc.h”头文件中,使用这三个函数时,应选择其中一个头文件包含到源程序中。,9.4 动态数据结构, 动态分配存储区函数malloc( ) 函数原型:void *malloc(unsigned size); 调用格式:malloc(size) 功能:在内存分配一个size字节的存储区。调用 结果为新分配的存储区的首地址,是一个void 类型指针。若分配失败,则返回NULL(即0)。,struct student *pt; pt=(struct student *)malloc(5*sizeof(struct student);,动态分配和释放存储单元,9.4 动态数据结构,【例】调用malloc函数分配所需存储单元。 #include main( ) struct st int n; struct st *next; *p; p=(struct st *)malloc(sizeof(struct st); p-n=5; p-next=NULL; printf(p-n=%dtp-next=%xn,p-n,p-next); ,将函数返回值转换成结构体指针,9.4 动态数据结构, 动态分配存储区函数calloc( ) 函数原型: void *calloc(unsigned int n,unsigned int size); 调用格式:calloc(n,size) 功能:在内存分配一个n倍size字节的存储区。调用结果为新分配的存储区的首地址,是一个void类型指针。若分配失败,则返回NULL(即0)。,9.4 动态数据结构,【例】调用calloc函数分配所需存储单元。 #include main( ) int i,*ip; ip=(int *)calloc(10,2); for (i=0; i10; i+) scanf(%d,ip+i); for (i=0; idata); p=p-next;,链表的删除操作,从链表中删除一个指定的结点: (1)遍历链表,搜索待删结点 (2)若找到: 如果待删结点是首结点: 如果待删结点是中间结点:,在链表中,如果要删除第i个结点,一般是将第(i-1)个结点直接与第(i+1)个结点相连接,然后再释放第i个结点的存储单元 。,删除单向链表中指定的结点,【例】删除学生电话簿链表中指定学生的信息。,删除第一个结点,删除中间结点或尾结点,学生姓名,当姓名不同并且不是尾结点循环,【例】删除学生电话簿链表中指定学生的信息。,(a) 删除第一个结点 (head=p-next),【例】删除学生电话簿链表中指定学生的信息。,(b) 删除中间结点或尾结点 (q-next=p-next),【例】删除学生电话簿链表中指定学生的信息。,(c) 未找到指定的结点 (strcmp(x,p-name)!=0),链表的插入操作,将一个新结点插入到链表中: (1)遍历链表,搜索待出入位置 (2) 如果在首结点前插入: 如果在链表中间插入: 如果在链表尾部插入:,将一个新结点插入到链表中,首先要寻找插入的位置。如果要求在第i个结点前插入,可设置三个工作指针p0、p和q,p0是指向待插入结点的指针。利用p和q指针查找第i个结点,找到后再将新结点链接到链表上。,q,q,新的第i个结点,在单向链表中插入结点,【例】在学生电话簿链表中插入一个学生的信息。要求将新的信息插入在指定学生信息之前,如果未找到指定学生,则追加在链表尾部。,(a) 在表头插入结点 (head=p0; p0-next=p),(b) 在表中间插入结点 (q-next=p0; p0-next=p),(c) 在表尾追加结点 (p-next=p0; p0-next=NULL),9.4链表,【例9.7】 建立、插入、删除链表的示例程序。#include #include #define LEN sizeof (struct stu)struct stuint num;int age;struct stu *next;,9.4链表,struct stu *delete(struct stu *head,int deletenum)/* 返回头指针 */ struct stu *p,*t;if(head-num = deletenum)p = head;head = head-next; /* 从链表中删除结点 */free(p); /* 释放被删除的结点空间 */else,9.4链表,p = head;while(p-next != NULL ,9.4链表,void insert(int num,int age,struct stu *head,intinsertnum) struct stu *new,*p;new = (struct stu*) malloc(LEN); /* 建立新结点 */new-num=num;new-age=age;p=head;while(p-num != insertnum) p= p-next; /* 定位num= insertnum的结点 */new-next = p-next;p-next = new; /* 思考:该条语句与上一条语句的次序能否互换*/,9.4链表,void output(struct stu *head)while(head != NULL)printf(num = %d , age = %dn, head-num, head-age);head = head-next;,struct stu *creat(int n) struct stu *head,*pf,*pb;int i;for(i=0; inum=i+10;pb-age=i+23;if(i=0) pf=head=pb;else pf-next=pb;pb-next=NULL;pf=pb;return(head);,9.4链表,void main() struct stu *h;puts(Create List Table: );h=creat(3);output(h);insert(13,26,h,11);puts(After insert: );output(h);h=delete(h,13);puts(After delete:);output(h);,9.4链表,9.5 联合(共用体),在实际处理中为了方便处理,有时需要在不同的时刻将不同类型的值存放在同一变量中,而在任一时刻,该变量仅含特定类型的值,这种变量就是联合类型的变量(简称联合或联合类型变量)。联合的定义方式就是将struct用union代替,其它形式同结构相同。如:假定一个常量可能是int、double或字符串,为了用同一个存储区域来存放,可以说明如下的联合,union unode int ival; double dval; char str100; u; 分配存储单元时,编译程序按联合的成员中最长的那一个类型为联合变量分配存储空间。,9.5 联合(共用体),1、先定义共用体类型,再定义共用体类型变量定义形式为:共用体类型名 共用体变量名;例如: union data char name10; char sex; int age; float score; ; /*定义union data 共用体类型*/ union data stu1,stu2;,9.5 联合(共用体),2、在定义共用体类型的同时定义变量,定义形式为:union 共用体名 类型名1 成员名1; 类型名2 成员名2; 类型名n 成员名n;变量名列表;例如:union data char name10; char sex; int age; float score; stu1,stu2; /* 定义stu1,stu2为union data类型变量*/,9.5 联合(共用体),3、直接定义共用体类型变量,定义形式为:union 类型1 成员名1; 类型2 成员名2; 类型n 成员名n;变量名列表;例如:union char name10; char sex; int age; float score; stu1,stu2;,9.5 联合(共用体),联合变量有地址,可以用&运算符对联合取地址,可以说明指向联合的指针。联合成员的引用和结构成员的引用形式相同,一般为下列三种形式之一 联合变量名.成员名 指向联合的指针-成员名 (*指向联合的指针).成员名 注意:联合成员彼此不是并存的,任一时刻联合变量中指含有其中一个成员,该成员是最近一次存入联合的那一个成为当前成员。,9.5 联合(共用体),union shuju int i; char c; float f; s1,s2; 定义了共用体变量s1,s2,它们分别占用4个字节的存储单元。因为3个成员中float类型所占的字节数最多,所以共用体变量在内存中占用4个字节。2、共用体类型变量的引用方式 共用体类型变量的引用方式与结构体类型变量的引用方式也很相似。只能引用共用体类型变量的成员,而不能引用共用体类型变量。引用的一般形式: 共用体变量名.成员名对于上面的定义,下面的引用是合法的: s1.i=123; printf(“%d”,s1.i);,9.5 联合(共用体),例如: union char name10; int age; float score; stu1,stu2; stu1.age=28; stu1.score=90.5;执行完这两条语句后,只有stu1.score成员有效,stu1.age成员内容已经被stu1.score成员覆盖了。,9.5 联合(共用体),说明: 1. 共用体的成员的使用和普通变量一样。 2.对共用体的某一个成员赋初值,会覆盖其他成员原来的值,因此共用体变量的值是最后一次存入的值。3. 共用体变量的地址与其各成员的地址是相同的。即&stu1、&stu1.age、&stu1.score和&都是同一个值。4. 不能直接对共用体变量赋值,也不能直接引用共用体变量,更不能对共用体变量进行初始化。5. 共用体变量不能作为函数的参数,函数的返回值不能为共用体变量。6. 共用体类型可以用于结构体类型定义中,也可以定义共用体类型数组。结构体类型也可以出现在共用体类型定义中,另外,数组可以作为共用体成员。7. 可以使用指向共用体变量的指针变量。,9.5 联合(共用体),例9.7共用体应用举例 #include union shuju int i; st

温馨提示

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

评论

0/150

提交评论