




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
掌握结构类型和结构变量的定义;掌握结构变量的引用和初始化;掌握结构数组的定义、引用;掌握如何应用指向结构类型数据的指针;掌握共用型和枚举型的概念、定义、引用、初始化;熟悉Typedef的使用;教学目标第十一章结构与链表本章的教学重点:理解结构体的含义、定义与使用方法理解共用体的含义、定义与使用方法理解枚举类型的含义、定义与使用方法理解typedef的作用与使用方法掌握链表操作的基本方法有关链表的操作用结构体变量和指向结构体的指针作函数参数本章的教学难点:
教学任务任务一结构体;任务二用结构体指针操作链表;任务三共用体;任务四枚举类型;任务五typedef类型声明;有时,需将不同类型的数据组合成一个有机的整体,以便于引用。这些数据是相互联系的。如一个学生的有关信息:可采用结构体数据结构描述上述信息。一、概述任务一结构体例如:structstudent{intnum;charname[20];charsex;intage;charaddr[30];};定义一个结构体类型的一般形式为:struct结构体名{成员表列};对各成员都要进行类型说明;成员名定名规则与变量名同。是类型,不是变量名声明的一般形式为:struct结构名{成员1的说明;成员2的说明;……成员n的说明;}
;structmedicine{
charcode;/*药品代号*/
charname;/*药品名称*/
floatprice;/*单价*/
charplace;/*产地*/
stuctgoodscaption;
/*来源地*/};一、结构体类型的声明 #definestustructstudent stu{
成员1的说明; 成员2的说明;
……
成员n的说明;
};思考:如何用宏定义的模式来写结构体?方法一:先定义结构体类型再定义变量名structstudent{intnum;charname[20];charsex;intage;charaddr[30];};structstudentstudent1,student2;定义studet1和sudent2为structstudent类型变量不能只指定一个变量为“struct型”而不指定结构体名二、结构体变量有时,可用符号常量代表一个结构体类型,如:#defineSTUDENTstructstudentSTUDENT{intnum;charname[20];charsex;intage;charaddr[30];};这样,可直接用STUDENT定义变量,如:STUDENTstudent1,student2;此时,不必再写关键字struct方法二:在定义类型的同时定义变量,如:structstudent{intnum;charname[20];charsex;intage;charaddr[30];}student1,student2;一般形式是:struct结构体名
{
成员表列
}变量名表列;方法三:直接定义结构类型变量。其一般形式是:struct{
成员表列
}变量名表列;此时,不出现结构体名结构体变量的存储structtest{intm1[10];charm2;floatm3;doublem4;}aa;
sizeof(structtest)的值为2*10+1+4+8=33
一个结构体变量所占用内存空间的字节数可以用sizeof运算符求出,它的一般形式为:sizeof(变量名或类型标识符);几点说明:1.类型与变量是不同概念,不要混淆;2.结构体中的成员,可以单独使用,其作用与地位相当于普通变量;3.成员也可以是一个结构体变量;例如:structdate{intmonth;intday;intyear;};Structstudent{intnum;charname[20];intage;structdatebirthday;}student1,student2;4.成员名可以与程序中的变量名相同,二者不代表同一对象。规则:1.不能将一个结构体变量作为一个整体进行赋值和输出;只能对其各个成员分别输出(引用形式为:结构体变量名.成员名)。printf(“………..”,student1);printf(“%d”,student1.num);输出10010错!正确!2.若成员本身又属一个结构体类型,只能对最低级的成员进行赋值或存取以及运算。如:student1.birthday.year三、结构体变量的引用与初始化3.对成员变量可以象普通变量一样进行各种运算,如:
sumage=student1.age+student2.age;4.可以引用成员的地址,也可以引用结构体变量的地址,如
scanf(“%d”,&student1.num);printf(“%o”,&student1);scanf(“%d,%s,%c,%d,%s”,&student1);错!输入student1.num的值输出student1的首地址结构体变量的初始化(一)对外部存储类型的结构体变量初始化:
structstudent{longintnum;charname[20];charsex;charaddr[20];}a={9801,”Wanghong”,’W’,”2LinggongRoad”};main(){printf(“No.:%ld\nname:%s\nsex:%c\naddress:%s\n”,a.num,,a.sex,a.addr);}运行结果为:No.:9801name:Wanghongsex:Waddress:2LinggongRoad(二)对静态存储类型的结构体变量初始化,如:main(){staticstructstudent{longintnum; charname[20]; charsex; charaddr[20];}a={9801,”Wanghong”,’W’,”2LinggongRoad”};printf(“No.:%ld\nname:%s\nsex:%c\naddress:%s\n”,a.num,,a.sex,a.addr);}(一)结构体数组的定义,如structstudent{intnum;charname[20];charsex;intage;charaddr[30];};structstudntstu[3];也可直接定义,如structstudent{intnum;…}stu[3];或struct{intnum;…}stu[3];
四、结构体数组
(每个数组元素都是一个结构体类型的数据)structstudent{intnum;charname[20];charsex;intage;charaddr[30];}stu[3]={{111,”Li”,’M’,18,”Dalian”},{…},{…}};也可采用:structstudent{intnum;
…};structstudentstu[]={{…},{…},{…}};结构体数组的初始化的一般形式是在定义数组后面加上:={初值表列};(二)结构体数组的初始化(只能对全局的或静态存储类别的数组初始化)structperson{charname[20];intcount;}leader[3]={“Li”,0,”zhang”,0,”Liu”,0};main(){inti,j;charleader_name[20];for(i=1;i<=10;i++){scanf(“%s”,leader_name);for(j=0;j<3;j++)if(strcmp(leader_name,leader[j].name)==0)leader[j].count++);}for(i=0;i<3;i++)printf(“%5s:%d\n”,leader[i].name,leader[i].count);}例:设有三个候选人,每次输入一个得票的候选人的名字,要求最后输出各人得票结果。定义格式为:struct结构名{结构体};struct结构名变量名1,变量名2,……,变量名n,*指针变量名1,*指针变量名2,……,*指针变量名n;指针变量名1=&变量名1;指针变量名2=&变量名2;……指针变量名n=&变量名n;不允许如下的定义指针变量:struct结构名*指针变量名1=&变量名1;1.指向结构变量的指针变量
五、结构体指针结构体变量的指针:是该结构体变量所占居的内存段的起始地址。例如:main(){structstudent{longintnum;charname[20];charsex;};structstudentstu_1;structstudent*p;p=&stu_1;stu.num=9901;strcpy(stu_1.name,”LiMin”);stu_1.sex=‘W’;printf(“No.:%ld\nname%s\nsex:%c\n”,stu_1.num,stu_1.name,stu_1.sex);printf(“\nNo.:%ld\nname%s\nsex:%c\n”,(*p).num,(*p).name,(*p).sex);}
定义stu_1是类型为structstudent的结构体变量,p是可以指向该类型对象的指针变量。但应该注意的是:经过上面的定义,此时pa尚未指向任何具体的对象。为使p指向stu1,必须把stu1的地址赋给pa:
p=&stu_1;注意,在定义了*p之后,应该知道:(1) *p不是结构变量,因此不能写成p.num,必须加上圆括号(*p).num。为此,C语言引入一个指向运算符“–>”,连接指针变量与其指向的结构体变量的成员。“–>”为间接成员运算符,其一般引用的格式为:指针变量名–>结构成员名说明:运算符“–>”是由连字符和大于号组成的字符序列,它们要连在一起使用。C语言把它们作为单个运算符使用。所以我们可以将(*p).num改写为p–>num。
(2) 指向运算符“–>”的优先级别最高,
引用结构体成员的三种形式:结构体变量名.成员名(*p).成员名p->成员名指向运算符。其优先级高于自增、自减运算符试分析以下运算:p->n
得到p指向的结构体变量中的成员n的值p->n++
得到p指向的结构体变量中的成员n的值,用完后使它加1;++p->n
得到p指向的结构体变量中的成员n的值使其先加12.指针变量的引用
3.指向结构数组的指针变量
我们知道,数组和指针有密切的关系。同样,结构数组和结构数组指针也紧密相关。当定义一个结构数组后,我们还可以定义一个结构指针变量,使该指针变量指向这个数组。那么,程序中既可以利用数组下标访问一个数组元素,也可以通过指针变量的操作来存取结构数组元素。例如,定义一个结构类型worker和结构数组class:structworker{ charname[20]; floatsalary; intage; intnum[12]; };structworkerstu1[3];structworker*pa;pa=stu1;/*指针变量pa指向结构体数组的首地址*/
六、结构体与函数1.结构体作为函数参数结构体变量做函数参数有三种方法:
1)C语言允许用结构变量的成员做函数参数例如:structstu{
floatscore;
……}stu1;voidshow(stu1.score)
……voidshow(floatx){语句序列;}2)C语言允许用结构变量做函数的参数例如:show(stu1)
{……}3)结构指针做函数参数。
和普通变量一样,结构体变量作为函数参数,用于在函数之间传递数据。同时,函数的返回值也可以是结构变量。结构变量作函数参数的传递方式与简单变量作函数参数的处理方式完全相同,即采用值传递的方式,形参结构变量中各成员值的改变,对相应实参结构变量不产生任何影响,但在函数定义时需要对其类型进行相应的说明。如:
intget_month(x)
{structmonthx;
{…
x.day=25;
…}}它说明了形参x是structmonth型结构变量。
在定义结构体类型的函数时,需要说明返回值的类型为相应的结构类型。例如:structdatafunc(floatn)floatm;{structdataf;…return(f);}
其中,函数名func前面的类型说明符就是用于对函数返回值f的类型进行说明。
2.结构体类型的函数结构体函数的一般定义形式为:struct结构类型名函数名(形式参数列表){函数体}七、结构体嵌套例如:structdate{ intyear; intmouth; intday;};structhome{ charpost[6]; charadd[80]; chartele[40];};structstu{ charname; charsex; structdatebirthday; structhomeh; floatscore;}s1[10];如果一个结构成员是另一个结构体的成员变量,这种数据组织叫着结构嵌套。
一、链表概述链表是将若干数据项按一定规则连接起来的表,链表中的每个数据称为一个结点。即链表是由称为结点的元素组成的,结点的多少根据需要确定。链表连接的规则是:前一个结点指向下一个结点;只有通过前一结点才能找到下一个结点。因此,每个结点都应包括两方面的内容:(1) 数据部分,该部分可以根据需要由多少个成员组成,它存放的是需要处理的数据。(2) 指针部分,该部分存放的是一个结点的地址,链表中的每个结点通过指针连接在一起。
我们可以对链表进行归类:当然一个链表必须要知道其表头的头指针。如果一个链表中的结点只有一个指向其他结点的指针,则称为单链表;若结点有两个指向其他结点的指针,则称为双链表。
任务二、用结构体指针操作链表单链表结点的类型定义:struct结构名{
数据成员列表;
struct结构名*指针名;};结构体中struct结构名*指针名;表示成员指针所指对象的类型就是自身结点类型。
例如:structsture{ intnum; charname[10]; charsex;};structstu_node{structstures1; /*定义结点数据域*/structstu_node*next;/*定义结点指针域*/}structstu_node*head; /*定义可指向结点的指针变量head*/二、动态内存管理函数1.malloc(size)函数函数原型:void*malloc(unsignedsize)
功能:在内存的动态存储区的自由内存部分中分配一个长度为size字节的连续内存区域。
返回值:如果执行成功,它的返回值是该内存区域首字节的指针;如果执行不成功,它的返回值是0,即NULL。
2.calloc(n,size)函数函数的原型:void*calloc(unsignedn,unsignedsize)
功能:在内存的动态存储区的自由存储部分中分配n个长度为size字节的连续内存区域。
返回值:如果执行成功,它的返回值为连续内存区域首字节的指针;如果执行不成功,它的返回值是0,即NULL。3.free(ptr)函数函数原型为:voidfree(void*ptr)
功能:释放由ptr指向的内存,被释放的内存还回给系统,并成为自由内存。ptr是指针或指针变量,它的值通常是由malloc或calloc函数调用时返回的值。三、链表的基本操作对链表的基本操作有建立、查找、删除和修改等。(1) 建立链表是指从无到有建立一个链表,即往空链表中依次插入一个结点,并保持结点之间的前驱和后继的关系。(2) 查找操作是指在给定的链表中,查找具有检索条件的结点。(3) 插入操作是指在某两个结点之间插入一个新的结点。(4) 删除操作是指在给定的链表中,删除某个特定的结点,也就是插入的逆过程。(5)
修改操作是指在给定的链表中,首先根据某已知的条件,查找到该结点,再修改数据域中的某些数据项。
四、结点的插入与删除1.结点的插入
链表的插入是将一个结点插入到已存在的线性链表的指定位置。假设已经存在线性链表的长度为N,将一个给定的结点插入到它的第i个结点之前,其中1<=i<=N+1。插入分三种情况进行讨论。
1)i=1,这时需将一个待插入结点插入在线性链表的第一个结点之前。方法是:将待插入结点的指针域设置为原来的头指针(即将原来的第一个结点作为待插入结点的直接后续),置头指针变量为待插入结点的指针。
2)1<i<n+1这时需将一个待插入结点插入在线性链表第i-1与第i个结点之间。方法是:将待插入结点的指针域置为第i-1个结点的指针域。
3)i=n+1这时需将一个待插入结点插入在线性链表的尾结点之后。方法是:待插入结点的指针域置空(即尾结点的指针域值)。将线性链表的尾结点的指针置为待插入结点的指针(即将线性链表尾接点作为待插入接点的直接前驱)。2.结点的删除
所谓链表的删除就是删除存在的线性链表的指定的结点。假设已存在的线性链表的长度为n,删除第i个结点,其中1<=i<n,则删除的问题分三种情况进行讨论。
1)i=1这时需要删除的结点是线性链表的第一个结点。方法是:置头指针变量为第一个结点的指针域(即将原来的第二个结点的指针作为新链表的头指针)
2)1<i<n这时需要将第i+1个结点作为第i-1个结点的直接后续。方法是:将第i-1个结点指针域置为第i个结点指针域。
3)i=n这时需要删除的结点是线性链表的尾结点,方法是:将第i-1个结点指针域置为空(即尾结点的指针域值)例题:假设学生链表的接点类型为structst,请编写函数structst*(structst*head,longkey),功能是从头指针为head的学生链表中删除学号为key的那个结点structst{ longnum; charname[12]; intscore structst*next;};structst*del(structst*head,longkey){structst*p,*pre;p=head;while((p->num!=key)&&(p->next!=NULL)){ pre=p; p=p->next;/*p后移一个结点*/}if(p->num==key){ if(p==head)/*被删结点为首结点*/ head=head->next; else pre->next=p->next; free(p);}else printf(“num=%ldnotbeenfound!\n”,key);
returnhead;/*返回结点删除以后链表的头指针*/}一、共用体变量的定义共用体:使几个不同的变量共占同一段内存的结构,称为“共用体”类型的结构。“共用体”类型变量的定义形式为:union共用体名
{成员表列
}变量表列;
例如:uniondata{inti;charch;floatf;}a,b,c;或uniondata{inti;charch;floatf;};uniondataa,b,c;或union{inti;charch;floatf;}a,b,c;直接定义先定义类型任务三共
用
体二、共用体变量的引用注意:只能引用共用体变量中的成员,不能引用共用体变量本身。如:可以引用
a.i(引用共用体变量中的整型变量i)
a.ch(引用共用体变量中的字符变量ch)
a.f(引用共用体变量中的实型变量f)不能只引用共用体变量,如:
printf(“%d”,a);错误!总结:共用体类型数据的特点1.每一瞬时只有一个成员起作用;2.
共用体变量中起作用的成员是最后一次存放的成员;3.共用体变量的地址和它的各成员的地址都是同一地址;4.不能对共用体变量名赋值,也不能企图引用变量名来得到成员的值,又不能在定义共用体变量时对它初始化。5.
不能把共用体变量作为函数参数,也不能使函数带回共用体变量,但可使用指向共用体变量的指针;6.
共用体类型可以出现在结构体类型定义中,也可以定义共用体数组。而结构体也可以出现在共用体类型定义中,数组也可以作为共用体的成员。注意:共用体类型变量与结构体类型变量的区别结构体类型变量所占内存长度是各成员占的内存长度之和。共用体类型变量所占内存长度等于最长的成员的长度。共用体与结构体的嵌套例设有一个教师与学生通用的表格,教师数据有姓名,年龄,职业,教研室4项,学生有,姓名,年龄,职业,班级4项。编程输入人员数据,再以表格输出。main(){ struct{ charname[10]; intage; charjob; union{ intclass; charoffice[10]; }depa; }boby[2]; intn,i;for(i=0;i<2;i++){ printf(“inputname,age,jibanddepartment\n”); scanf(“%s%d%c”,boby[i].name,&boby[i].age,&boby[i].job); if(boby[i].job==’s’) scanf(“%d”,&boby[i].depa.class); else scanf(“%s”,boby[i].depa.office);}printf(“name\tagejobclassoffice\n”);for(i=0;i<2;i++){ if(boby[i].job==’s’) printf(“%s\t%3d%3c%d\n”,boby[i].name,boby[i].age, boby[i].job,boby[i].depa.class); else printf(“%s\tt%3d%3c%s\n”,boby[i].name,boby[i].age, boby[i].job,boby[i].depa.office);}
若一个变量只有几种可能的值,可以定义为枚举类型。所谓“枚举”是指将变量的值一一列举出来,变量的值只限于列举出来的值的范围内。定义方法:先定义枚举类型
enumweekday{sun,mon,tue,wed,thu,fri,sat};再用此类型定义变量,如:enumweekdayworkday,week_end;或直接定义枚举变量。如:enumweekday{sun,mon,tue,wed,thu,fri,sat}workday,week_end;任务四枚举类型
枚举元素为常量,不是变量,故不能对它们赋值枚举常量有值。如上面定义中,sun、mon、tue······sat的值依次为0、1、2······7也可改变枚举元素的值,在定义时指出,如:
enumweekday{sun=7,mon=1,tue,wed,thu,fri,sat};
枚举值可用来作判断比较,如:
if(workday==mon)if(workday>sun)一个整数不能直接赋值给一个枚举变量,应先进行强制类型转换才能赋值,如:
workday=(enumweekday)2;(相当于将序号为2的枚举元素值赋给workday,即:workday=tue;说明:例枚举类型运用main(){ enumworkday {sun=7,mon=1,tue,wed,fri,thu,sat}today,tomorrow; toda
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 安阳数显精密真空干燥箱
- 2024年6月广告语征集
- 方格梁施工方案
- 2025年城市居民燃气工程实施合同书(合同样本)
- 保健食品职业采购员培训
- 陕西省南郑县2024年高中生物 第三章 基因的本质 3.1 DNA是主要的遗传物质A教学设计 新人教版必修2
- 算法对生活的影响(教学设计)2024-2025学年六年级上册信息技术浙教版
- 年产3万吨果蔬净菜项目可行性研究报告写作模板-备案审批
- 操作步骤介绍:如何做得更美观
- 《字母表示数》(教学设计)-2024-2025学年四年级下册数学北师大版
- 化工原理第三章离心沉降
- 工会内部控制管理制度范文六篇
- 主副食品质量验收参考标准
- TCALC 003-2023 手术室患者人文关怀管理规范
- 颅骨骨折患者的护理查房
- 防止校园欺凌安全教育课件
- 四川公路工程施工监理统一用表汇编附表1-2工序质量检查表格填报规定(路基、隧道)
- 北师大版小学六年级数学下册期第三单元检测试卷2(附答案)
- JCT890-2017 蒸压加气混凝土墙体专用砂浆
- 曲臂式高空作业车施工方案
- 人工智能在口腔颌面部创伤诊疗中的应用
评论
0/150
提交评论