结构体与共用体zlh.ppt

上传人:za****8 文档编号:14785661 上传时间:2020-07-30 格式:PPT 页数:74 大小:605KB
收藏 版权申诉 举报 下载
结构体与共用体zlh.ppt_第1页
第1页 / 共74页
结构体与共用体zlh.ppt_第2页
第2页 / 共74页
结构体与共用体zlh.ppt_第3页
第3页 / 共74页
资源描述:

《结构体与共用体zlh.ppt》由会员分享,可在线阅读,更多相关《结构体与共用体zlh.ppt(74页珍藏版)》请在装配图网上搜索。

1、高级语言程序设计,计算机基础教研室,第8章 结构体与 共用体,C语言大学实用教程,南京邮电大学计算机学院 计算机基础教研室,3,本章作业,作业本: P338页:8.68.7 课堂练习或直接做在书上: P332337 页:8.18.4, 8.9,4,本章内容,结构体(结构structure) 、共用体(联合union)类型的定义 结构体变量、结构体数组 向函数传递结构体变量、结构体数组 用结构体实现动态数据结构 链表的概念及操作原理 选学内容,5,从基本数据类型到抽象数据类型,二进制数 在早期的机器指令及汇编语言中,数据对象均用二进制数表示, 有类型的概念,基本数据类型 在高级语言中引入了基本数

2、据类型:整型、实型、字符型等 基本数据类型不能方便的解决所有问题,有些语言(如PL/1)中试图规定较多的类型,如数组、树、栈等,但实践证明不是个好办法,用户自己构造数据类型-复合数据类型 表示复杂的数据对象,典型的代表就是“结构体”,数组、指针也可算作此类,抽象数据类型(Abstract Data Type,简称ADT) 在复合数据类型基础上增加了对数据的操作 类跨时代的进步,6,用户自定义的数据类型,结构体: 把关系紧密且逻辑相关的多种不同类型的变量组织到统一的名字之下,也称复合数据类型 这种类型的各成员变量占用相邻的一段内存单元 共用体: 把情形互斥但又逻辑相关的多种不同类型的变量组织在一

3、起 这种类型的各成员变量占用同一段内存单元,因此每一时刻只有一个成员数据起作用,7,8.1问题的提出,在程序里表示一个人(姓名、年龄、性别、),怎么表示? 想表示多个人呢? 如何用计算机程序实现下述表格的管理?,表8-1 某学校学生成绩管理表,8,8.1问题的提出数组的解决方法,int studentId30; /* 最多可以管理30个学生, 每个学生的学号用数组的下标表示*/ charstudentName3010; charstudentSex302; int timeOfEnter30; /*入学时间用int表示*/ int scoreComputer30;/*计算机原理课的成绩*/ i

4、nt scoreEnglish30; /*英语课的成绩*/ int scoreMath30; /*数学课的成绩*/ int scoreMusic30; /*音乐课的成绩*/,9,8.1问题的提出数组的解决方法,int studentId30 = 1,2,3,4,5,6; charstudentName3010=令狐冲,林平之, 岳灵珊,任莹莹; charstudentSex302=男,男,女,女; int timeOfEnter30 = 1999,1999,1999,1999; int scoreComputer30 = 90,78,89,78; int scoreEnglish30 = 83

5、,92,72,95; int scoreMath30 = 72,88,98,87; int scoreMusic30 = 82,78,66,90;,10,8.1问题的提出数组的解决方法,数据的内存管理方式,分配内存不集中,寻址效率不高 对数组进行赋初值时,容易发生错位 结构显得比较零散,不容易管理,11,8.1问题的提出希望的内存分配图,12,struct student int num; char name20; char sex; int age; float score; char addr30; ;,形成一个样板,用于生成结构体变量。,一般形式:,struct 结构体名 类型关键字 成

6、员名1; 类型关键字 成员名2; . 类型关键字 成员名n; ;,构成结构体的变量称为结构体的成员(member), 也称元素(element)或域(field),结构体的定义只定义了数据的形式,即声明了一种复杂的数据类型,并未生成任何变量。,8.2结构体类型与结构体变量,13,8.2结构体类型与结构体变量,前面学生管理的例子可以声明为以下结构体 struct STUDENT /*定义一个类型*/ int studentID; /*每个学生的序号*/ char studentName10;/*每个学生的姓名*/ char studentSex4; /*每个学生的性别*/ inttimeOfEn

7、ter; /*每个学生的入学时间*/ intscoreComputer; /*每个学生的计算机原理成绩*/ intscoreEnglish; /*每个学生的英语成绩*/ intscoreMath; /*每个学生的数学成绩*/ intscoreMusic; /*每个学生的音乐成绩*/ ; struct STUDENT students4;/*定义一个结构体数组*/,14,students0.studentIDstudents0.scoreComputer 它们都是变量,一般称为结构的成员变量,15,8.2结构体类型与结构体变量 typedef的用法,struct student student1

8、,student2; /* It works !*/ student student1,student2; /*Can this work?*/ typedef为已经定义的数据类型定义一个“别名” 格式: typedef 原类型名 新类型名,16,8.2结构体类型与结构体变量 typedef的用法,struct student int num; char name20; char sex; int age; float score; char addr30; ; typedef struct student STUD; STUD student1,student2; /* It works!

9、*/,STUD与 struct student类型是同义词,17,先定义结构体类型再定义变量名,在定义类型的同时定义变量,struct student student1,student2;,struct student int num; char name20; char sex; int age; float score; char addr30; student1,student2;,8.2结构体类型与结构体变量结构体变量的定义,18,8.2结构体类型与结构体变量结构体变量的定义,struct int num; char name20; char sex; int age; float s

10、core; char addr30; student1,student2;,直接定义结构体变量(不出现结构体名),19,8.2结构体类型与结构体变量,double 占用内存字节数 = 8 struct student 占用内存字节数 = ? 是所有成员变量的内存总和吗? 事实上,所有数据类型在内存中都是从偶数地址开始存放的,且结构所占的实际空间一般是按照机器字长对齐的 不同的编译器、平台,对齐方式会有变化 我们可以用sizeof来获得结构的大小 int size; size=sizeof(struct student);,20,定义:,struct STUDENT intstudentID;

11、charstudentName10; char studentSex4; struct date timeOfEnter; int scoreComputer; int scoreEnglish; int scoreMath; int scoreMusic; ;,8.2结构体类型与结构体变量结构体的嵌套定义,struct date intyear; charmonth; char day; ;,结构体定义可以嵌套,21,8.2结构体类型与结构体变量指向结构体变量的指针,指向结构体的指针 说明形式: struct 结构名 *结构指针名; 例如: struct STUDENT *pt,stud1;

12、 pt pt-scoreMath=88;,25,8.2结构体类型与结构体变量结构体变量的引用和初始化,还可以用上述两种方法的结合 (*指向结构体的指针变量名).成员名 例如: (*pt).studentID=12; (*pt).scoreMath=88;,26,8.2结构体类型与结构体变量结构体变量的引用举例,struct pointint x;int y; struct point pt; /*定义结构体变量*/ struct point *ppt; /*定义结构体指针*/ ppt = ,ppt,pt,怎样通过pt访问pt的成员? pt.x = 0; /*成员运算符*/ 怎样通过ppt访问p

13、t的成员? (*ppt).x = 0; ppt-x = 0; /*指向运算符*/ 第二种更常用,27,思考题,struct pointint x;int y; struct rectstruct point pt1;struct point pt2;,struct rect rt; struct rect *rp = 下面表达式哪些合法? rt.pt1.x (*rp).pt1.x rp-pt1.x rt-pt1.x,上面合法的表达式都是等价的吗?,28,8.2结构体类型与结构体变量结构体变量的引用和初始化,结构体类型与其他数据类型一样,可在变量定义时初始化,因为结构体的成员类型千差万别,初始化

14、时要注意数据类型的匹配. 例如: struct STUDENT stud1=1, “令狐冲” , “男“ , 1999,12,20,90,83,78,92,29,8.3结构体数组结构体数组的定义,它定义了一个数组,最多可以包含30个元素,每个元素类型为struct STUDENT,struct STUDENT stu30;,按数组的定义,数组元素是连续存放的,每个元素又是一个结构体.,30,struct STUDENT stu30 = 1,令狐冲,男,1999,12,20,90,83,72,82, 2,林平之,男,1999,07,06,78,92,88,78, 3,岳灵珊,女,1999,07,

15、06,89,72,98,66, 4,任莹莹,女,1999,07,06,78,95,87,90 ;,8.3结构体数组结构体数组的初始化,31,8.3结构体数组结构体数组的指针,struct STUDENT *pt; pt = stu;,利用vc环境讲解例8.2,注意结构体数组的使用,32,8.4结构体与函数结构体与函数,向函数传递结构体的单个成员 单向值传递,函数内对结构内容的修改不影响原结构 向函数传递结构体的完整结构 单向值传递,函数内对结构内容的修改不影响原结构,开销大 向函数传递结构体的首地址 用结构体数组或者结构体指针做函数参数 除提高效率外,还可以修改结构体指针所指向的结构体的内容,

16、33,8. 4结构体与函数结构体与函数举例,有结构体类型定义如下 struct date int year; int month; int day; ;,void func(struct date p) p.year = 2006; p.month = 12; p.day = 25; ,void main() struct date d; d.year = 1999; d.month = 4; d.day = 23; printf(“%d,%d,%dn”, d.year, d.month, d.day); func(d); printf(“%d,%d,%dn”, d.year, d.month

17、, d.day); ,1999,4,23,1999,4,23,单向值传递,void func(struct date *p) p-year = 2006; p-month = 12; p-day = 25; ,main() struct date d; d.year = 1999; d.month = 4; d.day = 23; printf(“%d,%d,%dn”, d.year, d.month, d.day); func( ,1999,4,23,2006,12,25,结构体指针做函数参数,36,例8.1 :洗牌和发牌模拟 (P306),一付扑克有52张牌,分为4种花色(Suit): 黑

18、桃(Spades)、红桃(Hearts)、草花(Clubs)、方块(Diamonds) 每种花色有13张牌面(Face): A,2,3,4,5,6,7,8,9,10,Jack,Queen,King 设计一个结构体表示一张牌,由两个成分组成:花色、牌面: struct CARD char suit10; char face10; ; struct CARD card52; /*顺序存放扑克牌*/ int result52=70; /*存放洗发牌结果,初值可选为051以外的任意值*/ char *suit = Spades,Hearts,Clubs,Diamonds; char *face = A

19、,2,3,4,5,6,7,8,9, 10,jack,Queen,King;,0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 0 1 2 3 4 5 6 7 8 9 10 11 12 0 1 2 3 4 5 6 7 8 9 10 11 12 0 1 2 3 4

20、 5 6 7 8 9 10 11 12 0 1 ,37,例8.1 :洗牌和发牌模拟(P306),发牌过程 将52张牌按照随机的顺序存放 算法步骤: 产生051的随机数,将其放于resulti内。 i=i+1 如果i=51,则重复第1步,否则,结束循环 输出结果 存在一个致命的问题: 在重复第1步时,产生的随机数可能与以前产生的随机数相同,相同意味着52张牌中出现2张以上相同的牌,38,例8.1 :洗牌和发牌模拟(P307),解决方法 增加一步,判断新产生的随机数以前是否出现过 如果出现过,则放弃;如果以前未出现过,则保留 算法步骤: 产生051的随机数m,将其放于resulti内。 判断res

21、ulti在以前(result0resulti-1)是否出现过。如果出现过,则回到第1步;如果没出现过,则i=i+1 如果i=51,则重复第12步,否则,结束循环 输出结果,39,例8.1 :洗牌和发牌模拟(P309),算法缺陷: 随着生成随机数数量的增加,新的随机数与已经产生的随机数相同的可能性越来越大,有可能出现算法延迟问题 高效算法 先将52张牌按照花色与牌面顺序存放(cardi) 再将其随机打乱 每次循环,程序选择一个051的随机数j,然后将数组中当前的元素cardi与随机选出的元素cardj进行交换,40,例8.1改进 :洗牌和发牌模拟(P313),用结构体数组做函数参数 char *

22、suit = Spades,Hearts,Clubs,Diamonds; char *face = A,2,3,4,5,6,7,8,9, 10,jack,Queen,King; /*函数功能:将52张牌按黑桃、红桃、草花、方块花色顺序,面值按AK顺序排列 函数参数:结构体数组wCard,表示不同花色和面值的52张牌 指针数组wFace,指向面值字符串 指针数组wSuit,指向花色字符串 函数返回值:无 */ void FillCard(struct CARD wCard,char *wFace,char *wSuit) inti; for (i=0; i52; i+) strcpy(wCard

23、i.suit, wSuiti/13); strcpy(wCardi.face, wFacei%13); ,i 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 i/13 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 3 3 i%13 0 1 2 3 4 5 6 7 8 9 10 11 12 0 1 2 3 4 5

24、 6 7 8 9 10 11 12 0 1 2 3 4 5 6 7 8 9 10 11 12 0 1 ,41,用结构体指针做函数参数 /*函数功能:将52张牌的顺序打乱, 函数参数:结构体数组wCard,表示52张牌 函数返回值:无 */ void Shuffle(struct CARD *wCard) int i,j; struct card temp; for (i=0; i52; i+) j = rand()%52; /*j=random(52);TC的库函数*/ temp = wCardi; wCardi = wCardj; wCardj = temp; /* 洗牌过程 */ ,例8.

25、1 :洗牌和发牌模拟(P314),42,用结构体指针做函数参数 /*函数功能:输出发牌结果 函数参数:结构体数组wCard,表示有52张牌 函数返回值:无 */ void Deal(struct CARD *wCard) int i; for (i=0; i52; i+)/*输出发牌结果*/ printf(%10s%10sn, wCardi.suit, wCardi.face); ,例8.1 :洗牌和发牌模拟(P314),43,struct类型的特点,一个普通的类型 可以定义该类型的变量、数组、指针 可以做函数的参数类型和返回值类型 它的成员可以是任意类型 基本类型、数组、指针、结构体、共用体

26、 struct类型的变量 两个结构体变量之间可以相互赋值 所以做为函数的参数时,是传值调用 可以取地址 struct temp pt; TC下的错误提示: Undefined structure temp Structure size too large VC下的错误提示: pt uses undefined struct temp 下面的结构是什么意思呢? struct temp int data;struct temp *pt; ;,45,实验十四 结构体编程练习在屏幕上模拟显示一个数字式时钟,定义一个时钟结构体类型: struct clock int hour; int minute;

27、int second; ; typedef struct clock CLOCK;,时:分:秒,46,void update(CLOCK *t) t-second+; if (t-second = 60) t-second = 0; t-minute+; if (t-minute = 60) t-minute = 0; t-hour+; if (t-hour = 24) t-hour = 0; ,void display(CLOCK *t) printf(%2d:%2d:%2dr, t-hour, t-minute, t-second); ,实验十四 结构体编程练习在屏幕上模拟显示一个数字式时

28、钟,47,9.2返回指针的函数,数据类型 *函数名(参数表) int *Te(int m,float x) *号作为单目操作符比( )的优先级低,只能说明函数的函数值是一个指向整型变量的指针,或者说函数返回一个地址变量,该地址变量是指向一个整型数据. 例9.3,char * MyStrcat (char *s,char *t) char *p=s; while(*s!=0)s+; while(*t!=0)*s+=*t+; *s=0; return p; ,#include #define ARR_SIZE 80 main() char first ARR_SIZE =“hello”; char

29、 secondARR_SIZE =“world”; char *result=null; result=MyStrcat(first,second); printf(“nThe result is :%sn”,result); ,49,9.3函数指针,指向函数的指针变量的定义形式: 数据类型 (*指针名)( ); 含义:定义一个指针变量用来存放函数的入口地址。 Note 1)指向是不固定的。 2)不能使用*(p+1),例9.4求a,b,c三个数中的最大者,#include int Max(int ma,int mb,int mc); main() int a,b,c,max=0; int (*

30、p)(); printf(“please input 3 numbers(a,b,c):”); scanf(“%d,%d,%d”, ,int max(int ma,int mb,int mc) int tempMax; tempMax=mamb?ma:mb; tempMax=tempMaxmc?tempMax:mc; return tempMax; ,51,8.5动态数据结构链表的定义,结构体声明时不能包含自我,但可以包含指向本结构体类型的指针变量 链表(Linked table) struct Link int data; struct Link *next; ;,52,8.5动态数据结构,

31、对链表的基本操作 对链表的基本操作有:创建、检索(查找)、插入、删除和修改等。 (1)创建:即往空链表中依次插入若干结点,并保持结点之间的前驱和后继关系。 (2)检索:按给定的结点索引号或检索条件,查找某个结点。如果找到指定的结点,则称为检索成功;否则,检索失败。 (3)插入:在结点ki-1与ki之间插入一个新的结点k,使线性表的长度增1。 (4)删除:删除结点ki,使线性表的长度减1。,53,8.5动态数据结构-动态链表的建立,准备工作 #include #define NULL 0 #define LEN sizeof(struct nodetype) /*定义结点长度*/ struct

32、Link int data; struct Link *next; ; struct Link *head; /*建立一个指向链表头的全局变量*/,struct Link *CreateNode(int nodeNumbers ) struct Link *p; p=(struct Link *) malloc(LEN); if (p=NULL) printf(“No enough memory to alloc”); exit(0); p-data=nodeNumbers*10; p-next=NULL; printf(“nCreate a new node!”); return p; ,函

33、数功能:建立一个新的节点,并为该节点赋初值,函数返回值:指向该节点的指针,55,动态链表的访问,void DispLink(struct Link *head) struct Link *p; int j=1; p=head; do printf(“n%d%dn”,j,p-data); p=p-next; j+; while (p!=NULL) ,函数功能:显示所有节点的节点号和数据项内容,main( ) int i=0; struct Link *pr; char c; head =NULL; while(1) printf(“nPlease press i to insert one ne

34、w node”); c=getch(); if(c!=i,if (i=0) head=CreateNode(i); pr=head; else pr-next=CreateNode(i); pr=pr-next; i+; DispLink(head); ,演示过程:,NULL,head,0,30 NULL,head,pr=p,Step1:找到需要删除的节点,保留该节点的上一个节点于pr中; Step2:取该节点指向下一个节点的指针p-next,将此指针赋给上一个节点的指针域中的pr-next; Step3:要删除的节点已经脱离了链表,删除完成,释放被删除的节点,链表的删除操作,59,8.5动态

35、数据结构-链表的删除操作,struct Link *Delnode(struct Link *head,int num) struct Link *p,*pr; if(head=NULL) printf(“nNo Linked Table”); return(head); p=head; while(num!=p-a ,if(num=p-data) if(p=head) head=p-next; else pr-next=p-next; free(p); printf(“delete the node”); else printf(“nNot found the Node”); return

36、head; ,插 入结点,Step1:申请一段内存,建立一个新节点; Step2:找到要插入的位置,保存前一个节点指针到pr中; Step3:将新节点的指针域p-next指针指向原链表的后一个节点,p-next=pr-next; Step4:将前一个节点的指针域赋为新节点,pr-next=p;,pr,head,先下后上,struct Link *insertNode(struct Link *head,int tData) struct Link *pr,*p; p=(struct Link*)malloc(LEN); if(p=NULL) printf(“Cant enough memory

37、 to alloc”); exit(0); pr=head; p-next=NULL; p-data=tData*10; if (head=NULL) head=p; else while(pr-datadata ,if(pr=head) p-next=head; head=p; return head; if(pr-next=NULL) pr-next=p; else p-next=pr-next; pr-next=p; return head; ,if(pr-next) p-next=pr-next; pr-next=p;,64,实验十五 链表操作,建立一个单链表用于存储若干学生信息,包括

38、:学号、姓名、某门课成绩,需要先定义节点数据类型 noteType,65,8.6共用体,union numbershort x;char ch; float y; 基本上和struct一样 x、ch和y处于同样的地址 sizeof(union number)取决于占空间最多的那个成员变量,同一内存单元在每一瞬时 只能存放其中一种类型的成员; 起作用的成员是最后一次存放的成员 不能作为函数参数,66,struct person char name20; char sex; int age; union int single; struct char spouseName20; int child

39、; married; struct date divorcedDay; marital; int marryFlag; ;,共用体的应用,union int single; struct char spouseName20; int child; married; struct date divorcedDay; marital;,struct char spouseName20; int child; married;,67,C语言的核心学习到此结束,教材P425列出的关键字(常用32个)和围绕它们的语法、符号构成了C语言的核心 26个字母以及围绕它们的构词法、语法构成了英语的核心 本课程对

40、C语言核心的讲述并非面面俱到,而是紧抓核心的核心,在理解了核心的核心基础上讲解各种常用和有代表性的外延。 一些比较少见,或者很容易理解的,要么一带而过,要么干脆没有涉及 仅掌握语言的核心当然不能熟练运用语言 背下英语的所有单词和语法,你就能写出莎士比亚一样的诗句了吗?,68,C语言中的三大定律,表达式定律 任何能产生数值结果的运算、操作都可以作为表达式 并可以放到任何需要数值结果的地方,只要数值类型能够匹配 常见的可以产生数值结果的运算和操作 算术、逻辑、位运算等 ? :、 结构类型的层次结构: struct student 学号 字符串 int 姓名 字符串 char name10 (汉字)

41、 M门课成绩整型数组 int scorenumofcourse 总分 float 平均分 float,72,系统结构图,开始,键盘输入选择功能,数据统计与显示,数据录入,成绩排序,成绩查询,退出系统,73,函数集,void PrintScore(STU *pt,int n) /*打印学生信息*/ STU *InputStudent(STU *pt) /*录入学生信息*/ void Total(STU *pt) / *计算总成绩和平均分*/ void Sort(STU *pt) /*按总成绩由高到低排序*/ int Search(STU *pt,int n) /*查找学号*/ void FindNum (STU *pt) /*查找学号并显示结果*/ char Menu(void) /*构造菜单*/ main() /*由swich多分支结构构筑程序框架*/,74,这一章我们学习了,两种新的数据类型 结构体和共用体 几种重要的应用 结构体数组 结构体指针 用结构体数组或者结构体指针做函数参数 用结构体指针实现动态数据结构 在所学习知识的基础上完成综合程序设计,

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!