




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、结构体、枚举类型本章主要知识点 (1)结构体类型数据的定义,结构变量的说明及引用方法 结构指针的定义、使用以及结构指针在C程序中的应用链表的建立、输出、删除与插入等操作(2)枚举类型数据的定义,枚举变量的说明及引用方法 (3) 链表的应用1 结构体1.1 结构体与结构变量1.2 结构成员的引用1.3 结构数组1.4 结构指针与链表1.1 结构体与结构变量 “结构体”是一种构造类型,是由数目固定,类型相同或不同的若干有序变量组成的集合。组成结构体的每个数据都称为结构体的“成员”,或称“分量”。1结构体类型的声明2结构变量的定义3结构体类型与结构变量1结构体类型的声明 声明一个结构体类型的一般形式
2、为: struct 成员表列(也称为域表) ; 应注意在括号后的分号是不可少的。成员表列由若干个成员组成,每个成员都是该结构体的一个组成部分。对每个成员也必须作类型说明,其形式为: ; 成员名的命名应符合C语言标识符的书写规定,结构体成员名可与程序中其它变量同名,互不干扰。2结构变量的定义 对于已经声明的结构体类型,就可有对应于该类型的“结构类型变量”,简称为“结构变量”。定义结构变量有以下三种方法: (1)先声明结构体类型,再定义结构变量 即在先前声明的结构体类型后加上以下形式: struct ; (2)在声明结构体类型的同时定义结构变量 即被定义的结构变量直接在结构体类型声明的“”后给出。
3、一般形式为: struct 成员表列 结构变量表列; (3)直接定义结构变量 即省略结构体名。一般形式为: struct ;3结构体类型与结构变量 结构体类型与结构变量的最大区别在于:结构变量占有一定的内存空间,而结构体类型只是一种数据类型的结构描述,并不占用内存空间。 struct box float length; float width; float height; ; 它表明struct box结构体类型由大括号中所列的一些数据项组成,共需占用4x3=12个字节。 在此之后,若进行结构变量的定义如: struct box box1; 表明box1为struct box结构体类型变量,它
4、占用了12个字节的内存单元。1.2 结构成员的引用 对结构变量的访问是通过对结构变量各个成员的访问来进行的,结构变量成员描述为:. 在引用中应遵循以下原则: (1)如果成员本身又是一个结构体类型时,则必须逐级找到最低一级的成员才能使用。 (2)对成员变量的使用与普通变量完全相同,可根据其类型进行相应的运算。 (3)可以引用成员的地址,也可以引用结构体变量的地址。 (4)允许将一个结构变量直接赋值给另一个具有相同结构的结构变量。【例】利用结构体对三名学生的学号、姓名、性别、成绩进行输入与输出。程序名为。#include stdio.hstruct stu long int num;char na
5、me20;char sex;float score;student1,student2=960002,Zhang hong li,W,98,student3;/*对student2初始化*/main() student1.num=960001;/*对student1各成员赋值*/scanf(%s,);student1.sex=M;student1.score=65;student3=student1;/*对student3直接赋值*/printf(n%ldt%20st%ct%f,student1.num,,student1.sex,stude
6、nt1.score);printf(n%ldt%20st%ct%f,student2.num,,student2.sex,student2.score);printf(n%ldt%20st%ct%f,student3.num,,student3.sex,student3.score);运行情况如下:输入:Lilin960001 Lilin M 65960002 Zhang hong li W 98960001 Lilin M 651.3 结构数组数组元素是结构体类型数据,这时的数组就是结构数组。1结构数组的定义2. 结构数组的初始化1结构数组
7、的定义结构数组的定义方法和结构变量相似,只需说明它为数组类型即可。例如: struct stu int num;char name20;char sex;float score;struct stu student3;也可以直接定义一个结构数组或省略结构体名。2.结构数组的初始化 对结构数组可以进行初始化,它的作用在于把成批的数据传递给结构数组中的各个元素。 初始化的一般形式为: struct n=; 其中,n为元素的个数。在初始表列中,以一个元素内容为单位,用一对“”括起来,各元素之间用“,”分隔。 当对数组中的全部元素初始化时,也可将“ ”中的数组元素个数省略。在编译时,系统会根据给出初值
8、的结构体常量的个数来确定数组元素的个数。 数组的初始化也可以先声明结构体类型,然后再定义数组为该结构体类型,并在定义数组时初始化。【例】计算学生的平均成绩并统计出不及格的人数。程序名为。#include stdio.hstruct stu long int num;char name20;char sex;float score;student3=200001,Li li,W,99,200002,Wang hai,M,85,200003,Liu ying,W,50;main() int i,n;float average,sum;n=0;sum=0;for(i=0;i3;i+) sum+=st
9、udenti.score;if(studenti.score60) n+=1;printf(sum=%fn,sum);average=sum/3;printf(average=%fncount=%dn,average,n);运行情况如下:count=1. 1.4 结构指针与链表1结构指针2链表1结构指针 我们把指向结构体的指针称为结构指针,它是一个指针变量。结构指针变量说明的一般形式为: struct *; 这样说明的含义是:一规定了指针的数据特性;二为结构指针本身分配了一定的内存空间。 结构指针变量必须要先赋值后才能使用,赋的值应是一个地址值。 有了结构指针变量,就能更方便地访问结构变量的各
10、个成员。 其访问的一般形式为: . 或为: - 1结构指针在结构指针的使用中可分为以下几种情况:(3)结构指针作函数参数(1)指向结构变量(2)指向结构数组(1)指向结构变量 当使用结构指针指向一个结构变量时,指针变量中的值就是所指向的结构变量的首地址。 这三种用于表示结构成员的形式是完全等效的。 结构变量.成员名 (*结构指针变量).成员名 结构指针变量-成员名 请注意分析下面几种运算: s-n 得到s指向的结构变量中的成员n的值 s-n+ 得到s指向的结构变量中的成员n的值,用完该值后使 它加1 +s-n 得到s指向的结构变量中的成员n的值使之加1【例】通过结构指针引用结构体成员。程序名为
11、。#include stdio.hstruct stu int num;char name20;char sex;float score;student1=102,Zhang ping,M,78.5,*s;main() s=&student1; /*给结构指针变量赋值*/printf(Number=%dtName=%st,student1.num, );printf(Sex=%ctScore=%fn, student1.sex, student1.score);printf(Number=%dtName=%st,(*s).num,(*s).name);printf(S
12、ex=%ctScore=%fn,(*s).sex,(*s).score);printf(Number=%dtName=%st,s-num,s-name);printf(Sex=%ctScore=%fn,s-sex,s-score);(2)指向结构数组 当结构指针指向一个结构数组时,该指针变量的值是整个结构数组的首地址。 当然结构指针也可以指向结构数组中的某个元素,这时指针变量的值是该结构数组元素的首地址。 设s为指向结构数组的指针变量,则s也指向该结构数组的0号元素,s+1指向1号元素,s+i则指向i号元素。【例】用指针变量输出结构数组。程序名为。#include stdio.hstruct
13、stu long int num;char name20;char sex;float score;student3=200001,Li li,W,99,200002,Wang hai,M,85,200003,Liuying ,W,50;main() struct stu *s;printf(NumtNamettSextScoretn);for(s=student;snum,s-name,s-sex,s-score);【例】用结构指针变量作函数参数编程,计算一组学生的平均成绩并统计出不及格人数。程序名为。#include stdio.hstruct stu long int num;char
14、name20;char sex;float score;student3=200001,Li li,W,99,200002,Wang hai,M,85,200003,Liuying ,W,50;void average(struct stu *ps) int n=0,i;float ave,s=0;for(i=0;iscore;if(ps-scorenum=102;strcpy(s-name,Zhang ping);s-sex=M;s-score=62.5;printf(Number=%dnName=%sn,s-num,s-name);printf(Sex=%cnScore=%fn,s-sex
15、,s-score);free(s);运行情况如下:Num=102Name=Zhang pingSex=MScore=62.500000 (2)链表的使用 链表是一种常见的、重要的数据结构,它采用动态的分配办法为一个结构体分配内存空间。 一方面需要时就分配一块空间用来存放,从而节约了宝贵的内存资源;且便于删除与加入。 另一方面,在动态分配时,每个结点之间可以是不连续的(结点内是连续的),结点之间的联系是通过指针来实现的,即在结点结构中定义一个成员项用来存放下一结点的首地址,这个用于存放地址的成员,常把它称为指针域。可在第一个结点的指针域内存入第二个结点的首地址,在第二个结点的指针域内又存放第三个
16、结点的首地址,如此串连下去直到最后一个结点。最后一个结点因无后续结点连接,其指针域可赋为NULL。 这样一种连接方式,如同一条一环接一环的链子,在数据结构中称之为“链表”。(2)链表的使用例如,一个存放学生学号和成绩的结点可以定义为以下结构:struct stu int num;int score;struct stu *next; 在该结构体中前两个成员项组成数据域,最后一个成员项next构成指针域,它是一个指向struct stu类型的结构指针变量。 对链表的基本操作主要有: 建立链表链表的输出 链表的删除操作链表的插入操作 建立链表 (1)建立链表就是指从无到有地建立起一个链表,即一个个
17、地输入各结点数据,并建立起前后相链的关系。【例】编写一个建立单向链表的函数,存放学生数据。函数create可编写如下:#include stdio.h#include malloc.h#define NULL 0 /*令NULL为0,用它表示空地址*/#define LEN sizeof (struct stu)/*LEN代表struct stu结构体类型数据的长度*/ struct stu long int num;float score;struct stu *next; 建立链表 (2上接1)int n;struct stu *creat() /*此函数带回一个指向链表头的指针*/ st
18、ruct stu *head,*p1,*p2;n=0;/*n为结点的个数*/p1=p2=(struct stu *)malloc(LEN);/*开辟一个新单元*/scanf(%ld,%f,&p1-num,&p1-score);head=NULL;while(p1-num!=0) n=n+1; if (n=1)head=p1; else p2-next=p1; 建立链表p2=p1; p1=( struct stu *)malloc(LEN);scanf(%ld,%f,&p1-num,&p1-score); p2-next=NULL; return(head);/*返回链表的头地址*/图7-9(a
19、)链表的输出将链表中各结点的数据依次输出,首先要知道链表头元素的地址。设一个指针变量p,指向第一个结点,待输出p所指的结点数据后,使p后移一个结点再输出,直至链表的尾结点止。程序执行过程可见图7-12所示。【例】写一个函数,输出链表中所有结点。void print(head) /*由实参即将已有的链表的头指针传给被调函数*/struct stu *head; struct student *p; printf(n Now ,these %d records are:n,n);p=head; /* p指向头结点*/while(p!=NULL) printf(%ld,%fn,p-num,p-sco
20、re); /*输出所指结点的数据域*/p=p-next; /*使p指向下一个结点*/ 链表的删除操作 从一个链表中删除一个结点,并不是真正从内存中把它抹去,而是把它从链表中分离开来,可以通过改变链表的链接关系完成。 分析:设两个指针变量p1和p2,先使p1指向第一个结点。删除一个结点有两种情况: 一种情况是要删除结点是第一个结点,此时只需使head指向第二个结点即可,即head=p1-next,其过程如图7-13所示。 另一种情况是被删除结点不是第一个结点,可使被删除结点的前一结点指向被删结点的后一结点,即p2-next=p1-next。【例】写一个函数,删除链表中的指定结点,以指定的学号作为
21、删除结点的标志。函数dele编写如下: struct stu * dele(struct stu *head, long int num) struct stu *p1,*p2; 链表的删除操作if(head=NULL) /*如为空表, 输出提示信息*/ printf(nempty list!n); goto end; p1=head; while (p1-num!=num & p1-next!=NULL) /*当不是要删除的结点,而且也不是最后一个结点时,继续循环*/ p2=p1;p1=p1-next; /*后移一个结点*/ if(p1-num=num) /*找到要删除的结点*/ if(p1
22、=head)head=p1-next; /*为第一结点head指向第二结点*/else p2-next=p1-next; /*不是第一个结点,使要删除结点从链表中脱离*/ 链表的删除操作n=n-1;free(p1); else printf(The node not been foud!n); end: return head; /*返回head值*/链表的插入操作 在一个链表的指定位置插入结点,首先要求链表本身必须是已按某种规律排好序的。按照排序的规律确定好新结点在链表中的位置,并将其连入链表中即可。分析:设被插入结点的指针为p0,p1指向第一个结点。可在四种不同情况下插入: 第一种情况是原
23、链表是空链表,只需使head指向被插入结点即可,。 第二种情况是被插入结点值最小,则应插入到第一个结点之前。这种情况下使head指向被插入结点,被插入结点的指针域指向原来的第一个结点即可,即用p0-next=p1;head=p0;完成)。 第三种情况是在其它位置插入,这种情况下,使插入位置的前一结点的指针域指向被插入结点,使被插入结点的指针域指向插入位置的后一结点,即用p0-next=p1;p2-next=p0;来完成。 链表的插入操作 最后一种情况是在表末插入,这种情况下使原链表中的末结点指针域指向被插入结点,被插入结点指针域置为NULL。即用p1-next=p0p0-next=NULL;来
24、完成。【例】写一个函数,在学生数据链表中,按学号顺序插入一个结点。struct stu * insert(struct stu *head, struct stu *stud) struct stu *p0,*p1,*p2; p1=head;/*指向第一个结点*/ p0=stud; /*指向要插入的结点*/if(head=NULL) /*空表插入*/ head=p0;p0-next=NULL;/*将p0指向的结点作第一个结点*/ 链表的插入操作else while(p0-nump1-num)&(p1-next!=NULL) p2=p1; p1=p1-next;/*找插入位置*/ if(p0-n
25、umnum) if(head=p1)head=p0;/*在第一结点之前插入*/ else p2-next=p0; /*在其它位置插入*/ p0-next=p1;链表的插入操作else p1-next=p0; p0-next=NULL; /*在表末插入*/ n=n+1;return (head); 【例】将以上建立链表、输出链表、删除结点、插入结点的函数组织在一个程序中,用main函数作主调函数。main函数内容如下:(其位置在以上各函数之后)#include stdio.hmain() struct stu * head,stud; long int num; printf(input rec
26、ords:n ); head=creat(); /*调用creat函数建立链表并把头指针返回给head*/print(head); /*调用print函数输出链表*/printf(Input the deleted number: ); scanf(“%ld”,&num); /*输入待删结点的学号*/ head=dele(head,num); /*调用dele函数删除一个结点*/print(head); /*调用print函数输出链表*/ printf(Input the inserted number and score: ); scanf(%ld,%f,&stud.num,&stud.sc
27、ore); /*输入待插入结点的数据域值*/ head=insert(head,&stu); /* 调用insert函数插入pnum所指的结点*/print(head); /*再次调用print函数输出链表*/ 3 枚举类型3.1 枚举类型及变量的定义3.2 枚举元素的引用 语言提供了一种“枚举”类型,在枚举类型的定义中列举出所有可能的取值,被说明为该“枚举”类型的变量取值不能超过定义中列举出来的常量的范围。应该说明的是,枚举类型是一种基本数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型。1枚举类型的声明 枚举类型声明的一般形式为: enum ; 在枚举值表中应罗列出所有可用值,用“,”分隔,这些值也称为枚举元素或枚举常量。枚举元素是用户自己定义的标识符,并不自动代表什么含义。 例如: enum weekday sun,mon,tue,wed,thu,fri,sat ; 该枚举名为weekday,枚举值共有7个,即一周中的七天。凡被声明为enum weekda
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年贵州省铜仁地区单招职业适应性测试题库完美版
- 科技行业在经济危机中的创新与挑战
- 班级纪律教育的未来发展趋势预测
- 科技在办公环境优化中的作用与影响
- 2025年黑龙江建筑职业技术学院单招职业倾向性测试题库必考题
- 社区资源与老年健康教育共享资源共筑健康
- 2025年贵州水利水电职业技术学院单招职业技能测试题库带答案
- 科技中心与商业创新共谋发展新篇章
- 2025年湖南劳动人事职业学院单招职业倾向性测试题库1套
- 2025年甘肃省甘南藏族自治州单招职业倾向性测试题库汇编
- 海洋钻井(平台)
- (完整版)电梯的钢结构施工方案
- 中国近现代史纲要ppt全共64页课件
- 腰椎间盘突出症(腰痹病)中医临床路径
- 教学团队建设总结报告
- 研发经费填报指标说明及核算方法
- 装饰施工进度计划网络图及横道图
- 一年级思维训练(课堂PPT)
- 实木电脑桌书桌安装图
- GB_T 27025-2019 检测和校准实验室能力的通用要求(高清版)
- 俱乐部经营俱乐部经营
评论
0/150
提交评论