第7章结构体与共用体.ppt

上传人:本田雅阁 文档编号:3435148 上传时间:2019-08-25 格式:PPT 页数:72 大小:623.04KB
返回 下载 相关 举报
第7章结构体与共用体.ppt_第1页
第1页 / 共72页
第7章结构体与共用体.ppt_第2页
第2页 / 共72页
第7章结构体与共用体.ppt_第3页
第3页 / 共72页
第7章结构体与共用体.ppt_第4页
第4页 / 共72页
第7章结构体与共用体.ppt_第5页
第5页 / 共72页
点击查看更多>>
资源描述

《第7章结构体与共用体.ppt》由会员分享,可在线阅读,更多相关《第7章结构体与共用体.ppt(72页珍藏版)》请在三一文库上搜索。

1、C语言程序设计,信息科学与工程学院,第7章 结构体与共用体,结构体类型的定义 结构体变量的定义、引用和初始化 结构体数组 指针在结构体中的应用 结构体应用举例 共用体 枚举类型,自定义数据类型 顺序表 链表 综合应用,7.1 结构体类型的定义,结构体的一般形式,struct 结构体名 成员列表;,结构体类型的标志,成员列表的一般形式,类型 成员名;,成员名和结构体名的命名应符合标识符的书写规定,例如: struct sd int num; char name20; char sex3; float score; ;,结构体名为sd,4个成员,结构体括号外的分号是必不可少的,7.2 结构体变量的

2、定义、引用和初始化,例如: struct sd int num; char name20; char sex3; float score; ; struct sd b1,b2;,7.2.1 结构体变量的定义,1、先定义结构,再说明结构变量,2、在定义结构类型的同时说明结构变量,例如: struct sd int num; char name20; char sex3; float score; b1,b2;,例如: struct int num; char name20; char sex3; float score; b1,b2;,3、直接说明结构变量,7.2.2 结构体变量的引用,引用的形

3、式,结构变量名 成员分量名,成员运算符,它是左结合的,具有最高的优先级,例如: b1.num1000011; strcpy(b1.name,“zhang song“); b1.birthday.year=1990; b1.birtnday.month=8; b1.birthday.day=25;,7.2.3 结构体变量的初始化,与简单类型变量相似,在定义结构体变量时可以对结构体变量进行初始化。,一般形式,struct 结构体类型名 变量名(初值表),#include “stdio.h“ struct sd int num; char *name; char sex; float score;

4、b2,b1=100,“chen feng“,M,90; void main() b2=b1; printf(“Number=%dnName=%sn“,b2.num,b2.name); printf(“Sex=%cnScore=%fn“,b2.sex,b2.score); ,例 定义结构体变量时进行初始化,运行结果: Number=100 Name=chen feng Sex=M Score=90.000000,7.3 结构体数组,7.3.1 结构体数组的定义,结构体数组的一般形式,struct 结构体类型名 数组名常量表达,例如: struct sd int num; char name20;

5、 char sex; float score; boy5;,定义结构体数组时,也可进行初始化,只要在定义数组的后面加上初值列表。初值列表中,由于一个元素由多项数据项组成,所以每一个元素的初始值间最好用大括号分开,以免混淆或遗漏。,7.3.2 结构体数组的初始化,例如: struct sd int num; char *name; char sex; float score; boy5= 1000,“Hunag Ying“,M,77, 1001,“zhang ting ping “,M,66, 1002,“wang yong “,F,98, 1003,“wang jiao wei “,F,84,

6、 1004,“jiang zhen“,M,44;,#include“stdio.h“ struct txl char name20; char call10; ;,例 建立同学通讯录,main() struct txl man30; int i; for(i=0;i30;i+) printf(“input name:n“); gets(mani.name); printf(“input call:n“); gets(mani.call); printf(“namettcalln“); for(i=0;i30;i+) printf(“%sttt%sn“,mani.name,mani.call);

7、 ,7.4 指针在结构体中的应用,指针变量在编译时并不给它赋值,而是在程序运行时,通过赋值语句或内存分配语句把某个单元的地址赋给它。例如: struct sd *p,stul,stu50; p=stu1;,7.4.1 指向结构体变量的指针,一般形式,struct 结构体类型名 *指针变量名,在引用结构体变量指针时,不能整体引用,只有结构体变量的最低级成员才能进行输入输出以及运算操作。,指针变量的一般形式,1.结构体变量.成员名; 2.(*P).成员名; 3. P-成员名;,其中-称为指向运算符。它是左结合的,具有最高的优先级。,#include“stdio.h“ struct sd int n

8、um; char *name; char sex; float score; b1=1000,“Wang yong“,M,98,*p;,例 结构体变量成员的三种引用方式,void main() p= ,运行结果: Number=1000 Name=Wang yong Sex=M Score=98.000000 Number=1000 Name=Wang yong Sex=M Score=98.000000 Number=1000 Name=Wang yong Sex=M Score=98.000000,结构体指针变量可以指向一个结构体数组,这时结构体指针变量的值是整个结构体数组的首地址。结构体

9、指针变量也可指向结构体数组的某个元素,这时结构体指针变量的值是该结构体数组元素的首地址。设p为指向结构体数组的指针变量,则p也指向该结构体数组的0号元素,p+1指向1号元素,p+i则指向i号元素。这与普通数组的情况是一致的。,7.4.2 指向结构体数组的指针,#include“stdio.h“ struct student int num; char name20; char sex; int age; stu3=1001,“wang gan“,M,20, 1002,“chen hong“,M,21,1009,“zhao ping“,F,19; void main() struct stude

10、nt *p; for(p=stu;pnum,p-name,p-sex,p-age); ,例 结构体数组元素的使用,运行结果: 1001wang ganM20 1002chen hongM21 1009zhao pingF19,例如: 用stu1.num或stu2.name作函数实参,将实参值传给形参。用法和用普通变量作实参是一样的,属于“值传递“方式。应当注意实参与形参的类型应该保持一致。,7.4.3 用结构体变量和指向结构体的指针作函数参数,将一个结构体变量的值传递给另一个函数, 有3个方法:,1、用结构体变量的成员作参数,采取的也是“值传递”的方式,将结构体变量所占的内存单元的内容全部顺序

11、传递给形参。形参也必须是同类型的结构体变量。在函数调用期间形参也要占用内存单元。,2、用结构体变量作实参,将结构体变量(或数组)的地址传给形参。,3、用指向结构体变量(或数组)的指针作实参,#include“stdio.h“ struct Data int a, b, c; ; void main() void f (struct Data); struct Data AA; AA.a=55; AA.b=30; AA.c= AA.a+ AA.b; printf(“AA.a=%d AA.b=%d AA.c=%dn“, AA.a, AA.b, AA.c); printf(“main()n“); f

12、 (AA); printf(“AA.a=%d AA.b=%d AA.c=%dn“, AA.a, AA.b, AA.c); ,例 用结构体变量作函数参数,void f (struct Data BB) printf(“BB.a=%d BB.b=%d BB.c=%dn“, BB.a, BB.b, BB.c); printf(“f().n“); BB.a=11; BB.b=15; BB.c= BB.a* BB.b; printf(“BB.a=%d BB.b=%d BB.c=%dn“, BB.a, BB.b, BB.c); printf(“Return.n“); ,运行结果: AA.a=55 AA.b

13、=30 AA.c=85 main() BB.a=55 BB.b=30 BB.c=85 f(). BB.a=11 BB.b=15 BB.c=165 Return. AA.a=55 AA.b=30 AA.c=85,7.5 结构体应用举例,#include“stdio.h“ struct sd int num; char *name;char sex; float score;boy5= 10101,“chen gong“,M,88, 10102,“wang ping“,M,66, 10103,“shang fang“,F,90, 10104,“Cheng gang“,F,77, 10105,“Wa

14、ng he“,M,24, ;,例 计算一组学生的平均成绩和不及格人数。用结构 指针变量作函数参数编程。,void main() struct sd *pb; void ave(struct sd *pb); pb=boy; ave(pb); ,void ave(struct sd *pb) int c=0,i; float ave,s=0; for(i=0;iscore; if(pb-score60) c+=1; printf(“s=%fn“,s); ave=s/5; printf(“average=%fncount=%dn“,ave,c); ,运行结果: s=345.000000 avera

15、ge=69.000000 count=1,7.6 共用体,7.6.1 共用体及共用体变量的定义,共用体的一般形式,union 共用体名 成员表 ;,定义共用体类型变量有3种方法,例如:union data a;,1、定义共用体类型后,再定义共用体类型变量。,例如:union data int i; char ch; float f;a;,2、定义共用体类型的同时定义共用体类型变量。,例如:union int i; char ch; float f;a;,3、如果定义的共用体类型只使用一次,共用体类型名可以省略。,7.6.2 共用体变量的引用方式,引用共用体的一般形式,共用体变量名. 成员名,7

16、.6.3 共用体类型数据的特点,必须先定义了共用体变量才能引用它。,不能引用共用体变量整体,而只能引用共用体变量中的成员。,共用体变量起作用的成员是最后一次被赋值的成员。,共用体变量它的各成员的地址都是同一地址。,不能对共用体变量名赋值,也不能企图引用变量名来得到一个值,还不能在定义共用体变量时对它进行初始化。,7.7 枚举类型,例如: enum weekday sun,mon,tue,wed,thu,fri,sat ,7.7.1 枚举类型的定义,定义枚举类型的一般形式,enum 枚举类型名 枚举值表,7.7.2 枚举变量的定义,定义枚举类型后。能够以三种方法定义枚举变量:,例如:enum w

17、eekday g1,g2,g3;,1、定义枚举类型后,再定义枚举类型变量。,例如:enum weekday sun,mon,tue,wed,thu,fri,satg1,g2,g3;,2、定义枚举类型的同时定义枚举类型变量。,例如:enum weekday g1,g2,g3;,3、如果定义枚举类型只用一次,枚举类型可省略。,只能把枚举值赋予枚举变量,不能把元素的数值直接赋予枚举变量。,注意:,在“枚举”类型的定义中列举出所有可能的取值,被说明为该“枚举”类型的变量取值不能超过定义的范围。,枚举值是常量,不是变量。不能在程序中用赋值语句再对它赋值。,#include“stdio.h“ void m

18、ain() enum weekday sun,mon,tue,wed,thu,fri,sat a,b,c; a=sun; b=mon; c=tue; printf(“%d,%d,%d“,a,b,c); ,例 枚举应用,运行结果: 0,1,2,7.8 自定义数据类型,自定义数据类型,不是定义新的数据类型,而是把原来的数据类型改名,也就是说允许由用户为数据类型取“别名”。以便于记忆和阅读程序或增加程序的可移植性。类型定义符typedef即可用来完成此功能。,一般形式,typedef 类型名 新名称,定义的新数据类型名,通常用大写字母的标识符,定义的“别名”STU表示struct student的结

19、构体类型,然后可用STU来说明结构体变量:STU body1,body2; 和直接用struct student来说明结构体变量是一样的。,例如:,typedef struct student char name20; int age; char sex; STU;,7.9 顺序表,7.9.1顺序表的定义和创建,1、顺序表的定义,2、创建顺序表就是输入数据元素,设置表的长度。,void create() int i,n; printf(“输入元素个数:“); scanf(“%d“, ,7.9.2 顺序表的基本操作,1、顺序表元素的插入,要在i的位置上插入一个新数据d,必须先将元素Di,Dn-1

20、的位置向后移,然后在第i个位置上放入d的值。同时,顺序表的长度增加一个长度。,i: 插入的位置;d:插入的数据元素; void insert(int i,int d) int k; if(ilist.last); printf(“错误!“); else for(k=list.last-1;k=i;k-) list.lastk+1= list.lastk; list.lasti=d; list.last= list.last +1; ,2、顺序表元素的删除,要在i的位置上删除第i个元素,只要将元素Di+1,Dn-1的位置向前移一个位置。同时,顺序表的长度减少一个长度。,i: 删除的位置; voi

21、d delete(int i) int k; if(ilist.last-1); printf(“错误!“); else for(k=i+1;k=list.last-1;k+) list.lastk-1= list.lastk; list.last-; ,7.10 链表,所谓链表是指若干个数据项(每个数据项称为一个“结点”)按一定的原则连接起来。每个数据项都包含有若干个数据和一个指向下一个数据项的指针,依靠这些指针将所有的数据项连接起来。,链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。我们知道用数组存放数据时,必须事先定义元素的个数。如果事先难以确定个数,则必须把数组定得足

22、够大,足以存放上限的数据。显然这将会很浪费内存。用动态存储的方法可以很好地解决这些问题。,7.10.1 链表概述,另一方面,用数组的方法必须占用一块连续的内存区域。 而使用动态分配时,每个结点之间可以是不连续的。 结点之间的联系可以用指针实现。 即在结点结构中定义一个成员项用来存放下一结点的首地址,这个用于存放地址的成员,常把它称为指针域。,可在第一个结点的指针域内存入第二个结点的首地址, 在第二个结点的指针域内又存放第三个结点的首地址, 如此串连下去直到最后一个结点。最后一个结点因无后续结点连接,其指针域可赋为0。这样一种连接方式,在数据结构中称为“链表”。,1800,0324,3012,用

23、结构体变量作链表中的结点是最合适的。一个结构体变量包含着若干成员,这些成员可以是数值类型、字符类型、数组类型,当然也可以是指针类型。我们用这个指针类型成员来存放下一个结点的地址。,例如,可以这样来设计一个存放学生学号和成绩的结点: struct student int num; int score; struct student *next; ,7.10.2 链表的存储分配,分配内存空间函数malloc,调用形式:(类型说明符*) malloc (size),功能: 在内存的动态存储区中分配一块长度为“size“ 字节的连续区域。函数的返回值为该区域的首地址。(类型说明符*)用于强制类型转换。

24、如果此函数未能成功地执行(例如内存空间不足)。则返回空格针(NULL)。,分配内存空间函数calloc,调用形式:(类型说明符*) calloc (n,size),功能: 在内存动态存储区中分配n块长度为“size“字节的连续区域。函数的返回值为该区域的首地址。(类型说明符*)用于强制类型转换。calloc函数与malloc 函数的区别仅在于一次可以分配n块区域。如果此函数未能成功地执行。则返回空格针(NULL)。,释放内存空间函数free,调用形式:free(void *ptr);,功能: 释放ptr所指向的一块内存空间,ptr 是一个任意类型的指针变量,它指向被释放区域的首地址。被释放区应

25、是由malloc或calloc函数所分配的区域。,7.10.3 链表的建立及输出,1、链表的建立,从头到尾建立链表:新结点插入到链尾,从尾到头建立链表:新结点插入到链头,q=malloc(sizeof(struct node); p-data=ai;,例 建立一个N个结点的链表,存放学号和成绩数 据。编写一个建立链表的函数creat。,#define NULL 0 struct student int num; float score; struct student *next; ;,struct student *creat(int n) struct student *head,*pf,*

26、pb; int i; for(i=0;inum, ,将链表中各结点的数据依次输出的操作很简单,首先要知道表头元素的地址,这可由head得到,然后顺着链表输出各结点中的数据,直到最后一个结点。,2、链表的输出,void print(struct student * head) printf(“NnmtScoren“); while(head!=NULL) printf(“%dtt%dn“,head-num,head-score); head=head-next; ,例 编写一个输出链表的函数print,7.10.4 链表的基本操作,1、链表的插入,例 编写在学生数据链表中,按学号顺序插入一 个结

27、点。设被插结点的指针为pi。,struct student * insert(struct student * head, struct student *pi) struct student *pf,*pb; pb=head; if(head=NULL) /*空表插入*/ head=pi;pi-next=NULL; else while(pi-numpb-num) /*找插入位置*/,if(pi-numnum) if(head=pb)head=pi;/*在第一结点之前插入*/ else pf-next=pi;/*在其它位置插入*/ pi-next=pb; else pb-next=pi;pi

28、-next=NULL; /*在表末插入*/ return head; ,2、链表的删除,已有一个链表,希望删除其中某个结点,并不是真正从内存中把它抹掉,而是把它从链表中分离开来,只要撤消原来的链接关系即可,例 写一个删除链表中的指定结点的函数。,struct student * delete(struct student * head,int num) struct student *pf,*pb; if(head=NULL) /*如为空表, 输出提示信息*/ printf(“nempty list!n“); return 0; pb=head; while (pb-num!=num /*pf

29、指向当前结点,pb指向下一结点*/,if(pb-num=num) if(pb=head) head=pb-next; else pf-next=pb-next; free(pb); printf(“The node is deletedn“); else printf(“The node not been foud!n“); return head; ,7.11 综合应用,例 输入某班学生信息:学号、姓名、3门课程成绩, 要求按总分由高到低把该班学生信息输出。,#include struct stu int num; /*学号*/ char name10; /*姓名*/ int score3;

30、 /*3门课成绩*/ int total; /*总分*/ ;,void input(struct stu a,int n) int i,j; printf(“请输入学生信息(学号 姓名 三门课成绩):n“); for(i=0;in;i+) scanf(“%d%s“, /*求每个学生总分*/ ,/*由高到低排序*/ void sort(struct stu a,int n) int i,j,p; struct stu temp; for(i=0;iap.total) p=j; if(p!=i) temp=ai;ai=ap;ap=temp; ,void output(struct stu a,in

31、t n) int i,j, rink=1; /* rink表示名次*/ printf(“n名次表:n“); printf(“学号 姓名 cj1 cj2 cj3 总分 名次n“); for(i=0;in;i+) printf(“%4d %s“,ai.num,ai.name); for(j=0;j3;j+) printf(“%4d“,ai.scorej); printf(“%d%dn“,ai.total, rink); rink = rink +1; ,main() void input(struct stu a,int n); void sort(struct stu a,int n); void output(struct stu a,int n); int n; printf(“请输入该班学生人数:“); scanf(“%d“, ,本章小结,结构体和共用体以及各自的成员的表示方法 “.”是成员运算符,结构体和共用体变量用它操作成员项。“-”是指向运算符,结构体和共用体指针用它操作成员项。,结构体变量可以作为函数参数,函数的返回类型。而共用体变量不能作为函数参数和函数得返回类型。 结构体和共同体都可以组成数组。 结构体和共用体可以相互嵌套。 链表便于实现动态的存储分配。,本章结束,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1