C语言——第10章结构体与公用体.ppt_第1页
C语言——第10章结构体与公用体.ppt_第2页
C语言——第10章结构体与公用体.ppt_第3页
C语言——第10章结构体与公用体.ppt_第4页
C语言——第10章结构体与公用体.ppt_第5页
已阅读5页,还剩48页未读 继续免费阅读

下载本文档

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

文档简介

第十章,结构体与共用体,本章要点,结构体的概念 结构体的定义和引用 结构体数组,10.1 定义一个结构体的一般形式,定义一个结构体的一般形式为: struct 结构体名 成员表列 ;,对每个成员也必须作类型说明,其形式为:,类型说明符 成员名;,例如: struct stu int num; / 学号 char name20; / 姓名 char sex; / 性别 float score; / 成绩 ;,10.2 结构体变量的说明,说明结构体变量有以下三种方法。,struct stu int num; char name20; char sex; float score; ; struct stu boy1,boy2;,struct stu int num; char name20; char sex; float score; boy1,boy2;,struct int num; char name20; char sex; float score; boy1,boy2;,1.三种方法中说明的boy1,boy2变量都具有下图所示的结构。,2.成员也可以又是一个结构体类型,即构成了 嵌套的结构体。,struct date int month; int day; int year; ; struct int num; char name20; char sex; struct date birthday; float score; boy1,boy2;,3.类型定义符typedef,语言允许由用户为数据类型取“别名”。类 型定义符typedef即可用来完成此功能。 例如: typedef int INTEGER 以后就可用INTEGER来代替int作整型变量的类型 说明了。 例如: INTEGER a,b; 它等效于: int a,b;,typedef定义的一般形式为:,typedef 原类型名 新类型名,例如: typedef struct char name20; int age; char sex; STU; 定义STU表示stu的结构体类型, 然后可用STU来说明结构体变量: STU body1,body2;,又如:表示二维坐标平面上 的一个点(x,y) typedef struct float x; float y; POINT; 接下来定义两个点p1,p2: POINT p1,p2; 此语句即可实现。,10.3 结构体成员变量的表示方法,表示结构体变量成员的一般形式是: 结构体变量名.成员名,例如: boy1.num 即第一个人的学号 boy2.sex 即第二个人的性别 如果成员本身又是一个结构体则必须逐级找到最低级的 成员才能使用。 例如: boy1.birthday.month 即第一个人出生的月份成员可以在程序中单独使用, 与普通变量完全相同。,结构体成员运算符 (优先级别最高),10.4 结构体变量的赋值,结构体变量的赋值就是给各成员赋值。可用输 入语句或赋值语句来完成。结构体变量不能进行整 体赋值。相同类型的结构体变量之间可以赋值。,如: typedef struct float x; float y; POINT; POINT p1,p2; p1=3.5,6; / 整体赋值发生错误。 但可以给成员变量赋值。如: p1.x=3.5; 等。 也可以结构体变量之间赋值.如:p2=p1;,【例10.1】给结构体变量赋值并输出其值。 #include void main() struct stu int num; char *name; char sex; float score; boy1,boy2; boy1.num=102; =“Zhang ping“; printf(“input sex and scoren“); scanf(“%c %f“, ,10.5 结构体变量的初始化,【例10.2】对结构体变量初始化。各成员变量的存储如图所示。 #include void main() struct stu /*定义结构体*/ int num; char *name; char sex; float score; boy2,boy1=102,“Zhang ping“,M,78.5; /*boy1初始化*/ boy2=boy1; /*结构体变量赋值*/ printf(“Number=%dnName=%sn“,boy2.num,); printf(“Sex=%cnScore=%fn“,boy2.sex,boy2.score); ,10.6 结构体数组,10.6.1 结构体数组的定义 1. 先定义结构体,再说明结构体数组。,struct stu int num; char *name; char sex; float score; ; struct stu boy5;,2. 在定义结构体类型的同时说明结构体数组。,struct stu int num; char *name; char sex; float score; boy5;,3. 直接说明结构体数组。,struct int num; char name20; char sex; float score; stu15,stu210;,10.6.2 结构体数组的初始化,以第一种为例,初始化的格式为: struct 结构体类型名 ; struct 结构体类型名 结构体数组size=初值表1,初值表2, 初值表n;,struct stu int num; char *name; char sex; float score; boy5= 101,“Li ping“,M,45, 102,“Zhang ping“,M,62.5, 103,“He fang“,F,92.5, 104,“Cheng ling“,F,87, 105,“Wang ming“,M,58, ;,10.6.3 结构体数组元素的引用,结构体数组元素的引用格式为: 结构体数组名下标.成员名;,10.6.4 结构体数组的应用,【例10.3】计算学生的平均成绩和不及格的人数。学生信息如图10-4所示。,#include struct stu int num; char *name; char sex; float score; boy5= 101,“Li ping“,M,45, 102,“Zhang ping“,M,62.5, 103,“He fang“,F,92.5, 104,“Cheng ling“,F,87, 105,“Wang ming“,M,58, ; void main() int i,c=0; float ave,s=0; for(i=0;i5;i+) s+=boyi.score; if(boyi.score60) c+=1; printf(“s=%fn“,s); ave=s/5; printf(“average=%fncount=%dn“,ave,c); ,例10.4 同学录,#include #define NUM 3 struct mem char name10; char phone12; void main() struct mem manNUM; int i; for(i=0;iNUM;i+) printf(“input name:n“); gets(); printf(“input phonen“); gets(mani.phone); printf(“namettphonenn“); for(i=0;iNUM;i+) printf(“%stt%sn“,,mani.phone); ,根据下面的定义,能打出字母M的语句是( )。 struct person char name9; int age; ; struct person class10= John,17, Paul,19, Mary,18, Adam,16; A.printf(%cn,); B.printf(%cn,1); C.printf(%cn,1); D.printf(%cn,0);,D,下面程序的输出是( )。 main() struct cmplx int x; int y; cnum2=1,3,2,7; printf(“%dn“,cnum0.y/cnum0.x*cnum1.x); A.0 B.1 C.3 D.6,D,10.7 结构体指针变量的说明和使用,10.7.1 指向结构体变量的指针变量,结构体指针变量说明的一般形式为:,struct 结构体名 *结构体指针变量名,例如,在前面的例题中定义了stu这个结构体, 如要说明一个指向stu的指针变量pstu,可写为: struct stu *pstu; 如果boy是被说明为stu类型的结构体变量,则: pstu=&boy 而: pstu=&stu,结构体名和结构体变量是两个不同的概 念,不能混淆。结构体名只能表示一个结构 形式,是用户自定义的数据类型,与基本数 据类型一样,编译系统并不对它分配内存空 间。只有当某变量被说明为这种类型的结构 体变量时,才对该变量分配存储空间。,有了结构体指针变量,就能更方便地访问结构体变量 的各个成员。 指针变量访问的一般形式为: (*结构体指针变量).成员名 或为: 结构体指针变量-成员名 例如: (*pstu).num 或者: pstu-num 应该注意(*pstu)两侧的括号不可少,因为成员符“.”的优 先级高于“*”。如去掉括号写作*pstu.num则等效于*(pstu.num),这样,意义就完全不对了。,指针引用结构体成员,【例10.5】结构体指针变量的使用。 #include“stdio.h“ struct stu int num; char *name; char sex; float score; boy1=102,“Zhang ping“,M,78.5,*pstu; void main() pstu= ,从运行结果可以看出 结构体变量.成员名 (*结构体指针变量).成员名 结构体指针变量-成员名 三种表式等效,boy1.num,(*pstu).num,pstu-num,10.7.2 指向结构体数组的指针,结构体指针变量也可指向结构体数组的一 个元素,这时结构体指针变量的值是该结构 体数组元素的首地址。这与普通数组的情况 是一致的。,【例10.6】用指针变量输出结构体数组。,#include “stdio.h“ struct stu int num; char *name; char sex; float score; boy5= 101,“Zhou ping“,M,45, 102,“Zhang ping“,M,62.5, 103,“Liou fang“,F,92.5, 104,“Cheng ling“,F,87, 105,“Wang ming“,M,58, ; void main() struct stu *ps; printf(“NotNametttSextScoretn“); for(ps=boy;psnum,ps-name,ps-sex,ps-score); ,10.7.3 结构体变量和指针变量作函数参数,结构体变量作函数参数。但是发生函数调 用时参数是“值传递”,特别是成员为数组时 将会使传送的时间和空间开销很大,严重地 降低了程序的效率。最好的办法就是使用结 构体指针这时由实参传向形参的只是地址, 从而减少了时间和空间的开销。,【例10.7】计算一组学生的平均成绩和不及格人数。用结构体指 针变量作函数参数编程。 #include “stdio.h“ struct stu int num; char *name; char sex; float score;boy5= 101,“Li ping“,M,45, 102,“Zhang ping“,M,62.5, 103,“He fang“,F,92.5, 104,“Cheng ling“,F,87, 105,“Wang ming“,M,58, ; void main() struct stu *ps; void ave(struct stu *ps); ps=boy; ave(ps); ,void ave(struct stu *ps) int c=0,i; float ave,s=0; for(i=0;iscore; if(ps-score60) c+=1; printf(“s=%fn“,s); ave=s/5; printf(“average=%fncount=%dn“,ave,c); ,10.8 动态存储分配,语言提供了一些内存管理函数,这些 内存管理函数可以按需要动态地分配内存空 间,也可把不再使用的空间回收待用,为有 效地利用内存资源提供了手段。常用的内存 管理函数有三个malloc、calloc、free,使 用时要包含头文件 #include “malloc.h”,1.分配内存空间函数malloc 调用形式: 功能:在内存的动态存储区中分配一块长度为 “size”字节的连续区域。函数的返回值为该区域的首地 址。 “类型说明符” 表示把该区域用于何种数据类型。 (类型说明符*) 表示把返回值强制转换为该类型指针。 “size”是一个无符号数。,(类型说明符*)malloc(unsigned size),例如: pc=(char *)malloc(100);,表示分配100个字节的内存空间,并强制转换为字符数组类型,函数的返回值是该区域的首地址,把首地址赋给指针变量ps。,2. 分配内存空间函数 calloc,calloc 也用于分配内存空间。 调用形式:,(类型说明符*)calloc(unsigned n, unsigned size),功能:在内存动态存储区中分配n块长度为“size”字节的 连续区域。函数的返回值为该区域的首地址。 (类型说明符*)用于强制类型转换。 calloc函数与malloc 函数的区别仅在于一次可以分配 n块区域。,按stu的长度分配2块连续区域,强制转换为stu类型,并把其首地址赋予指针变量ps.,例如: ps=(struet stu*)calloc(2,sizeof(struct stu);,3.释放内存空间函数free 调用形式:,free(void *ptr);,功能:释放ptr所指向的一块内存空间,ptr是一个任意 类型的指针变量,它指向被释放区域的首地址。被释放区 应是由malloc或calloc函数所分配的区域。,【例10.8】分配一块区域,输入一个学生数据。 #include “stdio.h“ #include “malloc.h“ void main() struct stu int num; char *name; char sex; float score; *ps; ps=(struct stu*)malloc(sizeof(struct stu); ps-num=102; ps-name=“Zhang ping“; ps-sex=M; ps-score=62.5; printf(“Number=%dnName=%sn“,ps-num,ps-name); printf(“Sex=%cnScore=%fn“,ps-sex,ps-score); free(ps); ,10.10 联合体(Union),联合体类型的定义格式为:,union 联合体类型名 数据类型名1 成员名1; 数据类型名2 成员名2; 数据类型名n 成员名n; ;,例如,定义一个联合体类型: union Data short i; char ch; float f; ;,联合体Data包含有三个成员,它们使用 同一起始地址的内存空间,联合体变量 的内存大小是成员中占内存最大的成员 的大小。因此,Data的大小也是4。,10.10.2 联合体变量的定义和引用,1联合体变量的定义 与结构体变量的定义一样,联合体变量的定义也有三种形式,见表10-2:,2联合体变量的引用 对联合体成员的引用格式与对结构体成员的引用格 式相同,如果通过联合体变量来引用成员,用“.” 运算符,如果通过联合体指针变量来引用成员,用 “-”运算符.例如: union Data data1,*p,d10; 则其引用的方式可为data1.i, data1.f, p-ch, p-f, (*p).ch, (*p).f, d5.ch等。,union Data short i; char ch; float f; ,10.10.3 联合体变量的赋值,1联合体变量的初始化 定义联合体变量时对变量赋初值,但只能对变量的第一 个成员赋初值,不可像结构体变量那样对所有的成员赋初 值。 例如: union Data data1=10; / 10赋给成员i union Data data1= A;/ A赋给成员i,即i的值为65 union Data data1= 10,A,3.14; /错误,只能有一个赋值 union Data data1=10; / 错误,初值必须用 括起来,union Data short i; char ch; float f;,2联合体变量在程序中赋值 定义联合体变量后,如果要对其赋值,则只能通过对其 成员赋值,不可整体赋值。 例如: union Data data1,*p,d10; data1=10; / 错误,不能整体赋值 data1.i=10; / 正确 p= / 正确,union Data short i; char ch; float f;,说明:,1.由于联合体变量的各成员共享同一块内存空间,因此每一瞬时只有一个成员作用,其他成员不起作用。规定起作用的成员是最后一次存放的成员。 例: union Data data1; date1.i=10; data1.ch=a; data1.f=3.14; printf(“%d,%c,%f”),data1.i,data1.ch,data1.f); 执行后输出为: -2621,?,3.140000 最后起作用的是data1.f,再操作i和ch成员已无意义。 但有时在数值兼容的情况下,对一个成员变量赋值,其他的成员变量发生相改变。,union Data short i; char ch; float f;,例如: Union Data data1; date1.i=10; data1.ch=A; printf(“%d,%c”),data1.i,data1.ch); 执行后输出为: 65,A 结果是由最后输入的A决定的。,2.因为联合体变量每一瞬间只有一个成员变量有效,因此联合变量的地址和它的各成员的地址相同,即&data1与&data1.i等其他成员的地址都是相同的。,3.联合体变量不可作为函数的参数,但可以出现在结构体类型定义中,反之,结构体也可以出现在联合体定义中,数组也可以作为联合体的成员。,union Data short i; char ch; float f;,【例10.14】联合体变量成员间的相互影响。 #include “stdio.h“ void main() union short a2; long k; char c4; r,*s= ,10.11 枚举类型,10.11.1 类型的定义和枚举变量的说明 1.枚举的定义 枚举类型定义的一般形式为:,enum 枚举名 枚举值表 ;,在枚举值中应罗列出所有可用值。这些值也称为枚举元素。,2.枚举变量的说明 同结构体一样,枚举变量也可用不同的方式说明,即先定义后说明,同时定义说明或直接说明。设有变量a,b,c被说明为上述的weekday类型,可采用下述任一种方式: enum weekday sun,mou,tue,wed,thu,fri,sat ; enum weekday a,b,c; 或者为: enum weekday sun,mou,tue,wed,thu,fri,sat a,b,c; 或者为: enum sun,mou,tue,wed,thu,fri,sat a,b,c;,10.10.2 枚举类型变量的赋值和使用,枚举类型在使用中有以下规定: 1.枚举值是常量,不是变量。不能在程序中用赋值语 句再对它赋值。 例如对枚举weekday的元素再作以下赋值: sun=5; mon=2; sun=mon; 都是错误的。 2.枚举元素本身由系统定义了一个表示序号的数值,从0开 顺序定义为0,1,2。如在weekday中,sun值为0,mon值 为1,,sat值为6。,例10.14 枚举类型变量的使用,#include “stdio.h“ void main() enum weeday sun,mon,tue,ved,thu,fri,sata,b,c; a=sun; b=mon; c=tue; printf(“%dn%dn%dn“,a,b,c); ,说明:,只能把枚举类型赋予枚举变量,不能把枚举元素的数值直接赋予枚举变量。如: a=sum; b=mon; 是正确的。 a=0; b=1; 是错误的。 a=(enum weekday)2; 其意义是将顺序号为2的枚举元素赋予枚举变量a,相当于: a=tue;,还应该说明的是枚举元素不是字符变量也不是字符串常量,使用时不要加单、双引号,10.9 链表的概念,简单链表的示意图,图中,第0个结点(head)称为头结点(表头),它存 放有第一个结点的首地址,它没有数据,只是一个指针变 量。 以下的每个结点都分为两个域,一个是数据域,存放 各种实际的数据,另一个域为指针域,存放下一结点的首地址。,例如,一个存放学生学号和成绩的结点应定义为下面结构体: struct stu int num; int score; struct stu *next; ,10.9.1 创建动态链表,创建链表是指从无到有地建立起一个链表,即向空链表中依次插入若干节点,并保持节点之间的前驱和后继关系。 基本思想:首先创建一个头结点,让头结点head和尾结点tail都指向该结点,并设置该结点的指针域为NULL。然后创建一个结点,用指针pNew指向它,并将实际数据放在该结点的数据域,其指针域为NULL;最后将该结点插入到tail所指向结点的后面,在数据结构中也叫尾插法。,程序如下: struct stu int num; int age; struct stu *next; ; typedef struct stu STUDENT; STUDENT *CreatLList (int n) /返回链表的头结点 STUDENT *head,*tail,*pNew; int i; for(i=0;inum, ,10.9.2 链表结点的查找与输出,查找操作是指,将要查找的某个成员变量值,与链表中的结点该成员分量的值进行比对,当相同时,即找到所要找的结点,然后进行输出。输出操作是指,将链表中满足条件的结点的数据域的值显示出来。 基本思想:通过链表头指针head,使指针p指向实际数据链表的第一个结点,移动p找到要求查找的数据域,判断是否是要找的结点,如果是输出结点的数据,如此进行,有时会找到尾结点。,【例10.11】对链表进行查找并输出所有满足要求的结点数据, 用函数Display实现。 struct stu int num; int age; struct stu *next; ; typedef struct stu STUDENT; void Display(STUDENT *head) STUDENT *p; int no; printf(“Input No Your will findn“); scanf(“%d“, ,10.9.

温馨提示

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

评论

0/150

提交评论