C语言程序设计 结构体与共用体ppt课件.ppt

上传人:牧羊曲112 文档编号:1375816 上传时间:2022-11-16 格式:PPT 页数:71 大小:1.07MB
返回 下载 相关 举报
C语言程序设计 结构体与共用体ppt课件.ppt_第1页
第1页 / 共71页
C语言程序设计 结构体与共用体ppt课件.ppt_第2页
第2页 / 共71页
C语言程序设计 结构体与共用体ppt课件.ppt_第3页
第3页 / 共71页
C语言程序设计 结构体与共用体ppt课件.ppt_第4页
第4页 / 共71页
C语言程序设计 结构体与共用体ppt课件.ppt_第5页
第5页 / 共71页
点击查看更多>>
资源描述

《C语言程序设计 结构体与共用体ppt课件.ppt》由会员分享,可在线阅读,更多相关《C语言程序设计 结构体与共用体ppt课件.ppt(71页珍藏版)》请在三一办公上搜索。

1、第12章 结构体与共用体,程序设计语言,C,2,本章主要内容, 结构体数据类型,共用体数据类型、枚举数据类型、定义数据类型的别名 结构体变量、结构体数组、结构体指针的定义和初始化 结构体成员的引用、成员选择运算符、指向运算符 向函数传递结构体变量、结构体数组、结构体指针 动态数据结构、动态链表,3,只能定义单一的数据类型,反映事物单一属性,如定义学生成绩: float score;,能定义复杂的数据类型,反映事物多个属性,存放相同数据类型的一组数据,如: float score30;,12.1 从基本数据类型到抽象数据类型,4,4,12.1从基本数据类型到抽象数据类型,用户自己构造数据类型复合

2、数据类型由基本数据类型迭代派生而来,表示复杂的数据对象典型的代表就是“结构体”抽象数据类型(Abstract Data Type,ADT)在复合数据类型基础上增加了对数据的操作抽象数据类型进而进化为“类(Class)”这是一个跨时代的进步Class是Object-Oriented的一个重要概念,5,12.2.1 问题的提出12.2.2 结构体类型(结构体模板)定义12.2.3 结构体变量的定义12.2.4 结构体变量的初始化12.2.5 结构体变量的引用12.2.6 结构体数组12.2.7 结构体指针12.2.8 结构体作为函数参数,12.2 结构体,6,12.2.1 问题的提出,一个学生的信

3、息有学号、姓名、性别、年龄、成绩等一本图书的信息有分类编号、书名、作者、出版社、出版日期、价格、库存量等如何描述和管理这些类型不同的相关数据?(使用二维数组行吗),问题:,7,12.2.1 问题的提出,解决方案:,1)独立的变量表示:,8,12.2.1 问题的提出,2)使用一维数组,age,no,sex,name,分配内存不集中,寻址效率不高 ;对数组赋初值时,易发生错位 ;结构显得零散,不易管理;,score,9,12.2.1 问题的提出,解决方案:,C 语言引入了称为结构体的数据存储方式,“结构体” 是一种构造数据类型,它是由若干数据项组合而成的复杂数据对象,这些数据项称为结构体的成员。把

4、关系紧密且逻辑相关的多种不同类型的变量,组织到统一的名字之下,占用相邻的一段内存单元,结构体变量表示:把不同类型的数据组合成一个整体,10,12.2.2 结构体类型定义,struct 结构体名 数据类型名1 成员名1; 数据类型名2 成员名2; 数据类型名n 成员名n;,struct是关键字,不能省略,合法标识符可省:无名结构体,成员类型可以是基本型或构造型,以分号;结尾,struct Student char no9; /学号 char name20; /姓名 char sex; /性别 unsigned int age; /年龄 float score; /成绩;,struct Date

5、short year; /年 short month; /月 short day; /日;,11,12.2.2 结构体类型定义,struct Student char no9; /学号 char name20; /姓名 char sex; /性别 short int age; /年龄 float score; /成绩;,结构体类型定义描述结构的组织形式,注意:结构体类型只是用户自定义的一种数据类型,用来定义描述结构的组织形式,不分配内存,只有用它来定义某个变量时,才会为该变量分配结构类型所需要大小的内存单元。,12,在结构体中数据类型相同的成员,既可逐个、逐行分别定义,也可合并成一行定义,就象

6、一次定义多个变量一样。,struct Student_Info char no9; /学号 char name20; /姓名 char sex; /性别 unsigned int age; /年龄 unsigned int classno; /班级 float grade; /成绩;,struct Student_Info char no9, name20, sex; unsigned int age, classno; float grade; ;,12.2.2 结构体类型定义,13,12.2.3 结构体变量定义,struct 结构体类型名 数据类型名1 成员名1; 数据类型名n 成员名n;

7、struct 结构体类型名 变量列表;,先定义结构类型,再定义结构变量,struct Student char no9; char name20; char sex; unsigned int age; float score; ;struct Student stu1, stu2;,定义一个类型为 struct student 结构体的变量,将会为该变量分配内存,大小是等于其所有成员变量的大小之和。 sizeof(struct Student),14,12.2.3 结构体变量定义,定义结构体类型的同时定义结构体变量,struct 结构体类型名 数据类型名1 成员名1; 数据类型名n 成员名n

8、; 变量名列表;,struct Studentchar no9; char name20; char sex; unsigned int age; float score; stu1, stu2;,struct char no9; char name20; char sex; unsigned int age; float score; stu1, stu2;,或,无名结构体定义,15,12.2.3 结构体变量定义,成员可以是结构体,结构体可以嵌套,struct dateint month; int day; int year;struct student int no; char name2

9、0; struct date birthday; stu;,struct student int no; char name20; struct date int month; int day; int year; birthday; stu;,16,12.2.4 结构体变量的初始化,定义结构体变量时给结构体成员赋值,注意:赋初值时, 中间的数据顺序必须与结构体成员的定义顺序一致,否则就会出现混乱。,struct Student stu = “09122325, YangFan, M, 19, 90;,struct Student stu = 19, YangFan , M, “0912232

10、5, 90;,17,12.2.4 结构体变量的初始化,定义结构体变量时给结构体成员赋值,struct date int year, month,day; ;struct Stu_Info char no9; /学号 char name20; /姓名 char sex; /性别 struct date birthday; /生日 float score; /成绩;,struct Stu_Info stu = 20020306, ZhangMing, M, 1986, 12, 10, 90;,18,12.2.5 结构体变量的引用,引用规则:不能整体引用,只能引用变量的成员,引用方式:,结构体变量名

11、.成员名,成员(分量)运算符结合性:从左向右,struct student char no9; char name20; char sex; unsigned int age; float score; stu1, stu2;,if (stu1 = stu2) . (),stu1.score = 85.5;,stu1.age = stu2.age;,strcpy(stu1.no,“09122414”;),19,12.2.5 结构体变量的引用,可以将一个结构体变量赋值给另一个结构体变量结构体嵌套时逐级引用,struct student int no; char name20; struct da

12、te int month; int day; int year; birthday; stu1,stu2;,stu1.birthday.month=12;,结构体变量名.成员名.子成员名最低级子成员名,20,12.2.5 结构体变量的赋值,strcpy (stu1.no, stu.no); strcpy (stu1.name, stu.name);stu1.sex = stu.sex;stu1.age = stu.age;stu1.score = stu.score;,struct Student stu; strcpy (stu.no, “09122424); strcpy (stu.nam

13、e, “XuTeng);stu.sex = M;stu.age = 21;stu.score = 90;struct Student stu1;stu1 = stu;,如果在定义结构体变量时并未对其赋初始值,那么在程序中要对它赋值的话,就只能一个一个地对其成员逐一赋值,或者用已赋值的同类型的结构体变量对它赋值,21,12.2.5 结构体变量应用举例,【例】计算某个学生5门课的平均成绩,最高分和最低分,#include struct Student float score5; float avescore, maxscore, minscore;void main ( ) int i; stru

14、ct Student m; printf (input the score of five course:n); for (i = 0; i 5; i+) /输入5门课的成绩 scanf (%f, ,m.avescore = 0; m.maxscore = m.score0; m.minscore = m.score0; for (i = 0; i m.maxscore) m.maxscore=m.scorei; if (m.scorei m.minscore) m.minscore=m.scorei; m.avescore /= 5; printf (“avescore=%4.1f, max

15、score=%4.1f, minscore=%5.1fn, m.avescore, m.maxscore, m.minscore);,运行结果(设5门课的成绩为:75 80 86 90 68 ):avescore = 79.8 maxscore = 90.0 minscore = 68.0,22,12.2.6 结构体数组,元素为结构体类型的数组称为结构体数组。在实际应用中,经常用结构体数组来表示具有相同数据结构体的一个群体。例如一个班的学员档案,一个公司的职工档案等。,结构体数组的定义,形式一:struct Student char no9, name20, sex; unsigned int

16、 age; float score; ;struct Student stu10;,形式二:struct Student char no9, name20, sex; unsigned int age; float score; stu10;,形式三:struct char no9, name20, sex; unsigned int age; float score; stu10;,23,12.2.6 结构体数组与二维表的对应关系,结构体数组就相当于一张二维表,表的框架对应的就是某种结构体类型,表中的每一列对应该结构体的成员,表中每一行信息对应该结构体数组元素各成员的具体值,表中的行数对应结

17、构体数组的大小。,结构体类型Student,struct Student char no9; char name20; char sex; unsigned int age; float score; stu10;,24,12.2.6 结构体数组的初始化,基本格式:struct 结构体类型 数组size = 初值表1,初值表n;,例:,全部初始化时维数可省,25,12.2.6 结构体数组的引用,引用格式:结构体数组名下标.成员名;,struct Student char no9; char name20; char sex; unsigned int age; float score; stu

18、10;,strcpy (stu0.name, WangFei);,stu1.age+;,printf (%s, stu0.name);,26,12.2.6 结构体数组举例,#include #include struct person char name20; /候选人姓名 int count; /得票数 leader3 = Li, 0, Zhang, 0, Wang, 0 ;,void main ( ) int i, j; char leader_name20; printf(input name: n); while (1) /统计候选人得票数 gets( leader_name); /输

19、入候选人姓名 if (strcmp(leader_name, 0) = 0) /输入为0结束 break; for (j = 0; j 3; j+) /比较是否为合法候选人 if (strcmp(leader_name, leaderj.name) = 0) /合法 leaderj.count+; /得票数加1 for (i = 0; i 3; i+) /显示候选人得票数 printf (%5s : %dn, leaderi.name, leaderi.count);,【例】统计侯选人选票(输入0结束),27,12.2.6 结构体数组举例,【例12.3】利用结构体数组计算每个学生的平均分,28

20、,29,12.2.7 结构体指针,定义: struct 结构体类型名 *指针变量名;,struct Student stu;struct Student *p=,结构体指针的引用: 指针变量名-成员名 或 (*指针变量名).成员名,stu.age=18; (*p).age=18; p-age=18;,30,12.2.7 指向结构体类型数据的指针,#include #include struct Studentlong int num; char name20;char sex; float score;void main()struct Student stu_1;struct Student

21、 *p;p = ,31,12.2.7 指向结构体数组的指针,#include struct Studentlong int num;char name20;char sex;int age;void main( )struct Student *p;struct Student stu = 10101, 李林, M, 18, 10102, 张奋, M, 19, 10103, 王敏, F, 20;printf( 学号 姓名 性别 年龄n);for(p = stu; p num, p-name, p-sex, p-age);,32,12.2.7 指向结构体数组的指针,p = stu,p+1,p+2

22、,stu0,stu1,stu2,33,12.2.8 结构体作为函数参数,可以将结构体作为参数传递给函数,也可以定义返回结构体值的函数。结构体作为函数参数有三种不同方法:将结构体变量成员的值传递给函数处理。将整个结构体变量作为参数值传递给函数。将结构体指针变量做函数的参数。,把结构体作为整体来处理,但作用方式和效果不同。,34,整个结构体作为参数,struct date int year; int month; int day;void func(struct date p) p.year = 2000; p.month = 5; p.day = 22;,void main() struct d

23、ate 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, d.day);,1999,4,23,1999,4,23,12.2.8 结构体作为函数参数,35,函数返回值为结构体,struct date int year; int month; int day;struct date func(struct date p) p.year = 2000; p.month = 5; p.day =

24、 22; return p;,void main() struct date d; d.year = 1999; d.month = 4; d.day = 23; printf(“%d,%d,%dn”, d.year, d.month, d.day); d = func(d); printf(“%d,%d,%dn”, d.year, d.month, d.day);,12.2.8 结构体作为函数参数,1999,4,23,2000,5,22,36,结构体指针做为参数,struct date int year; int month; int day;void func(struct date *p

25、) p-year = 2000; p-month = 5; p-day = 22;,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(,1999,4,23,2000,5,22,12.2.8 结构体作为函数参数,37,【例12.7】修改例12.3程序,用结构体数组作函数参数编程并输出计算学生的平均分,12.2.8 结构体作为函数参数,38,12.2.8 结构体作为函数参数,39,12.2.8 结构体作为函数参数,4

26、0,12.2.8 结构体作为函数参数,41,12.3 共用体(P362-365),共用体(union)又称联合体,把情形互斥但逻辑相关的多种类型的数据组织在一起,共同占用同一段内存的用户自定义数据类型。,该栏目按性别填写不同内容,共用体,42,12.3 共用体,共用体类型的定义,union 共用体类型名 数据类型名1 成员名1; 数据类型名2 成员名2; 数据类型名n 成员名n;,类型定义不分配内存,共占4字节sizeof(union UData) = sizeof(f),共用体的大小是成员中占内存最大的成员的大小,union UData short i; char ch; float f;,

27、43,12.3 共用体,共用体与结构体的异同共用体与结构体都是由多个成员分量组成的一个整体;共用体与结构体在定义、说明和使用(成员引用、指针)上十分相似。结构体:多个成员分量分别占用不同的存储空间构成一个整体;成员分量之间是相互独立的,所进行的各种操作互不影响。共用体:多个成员分量共同占用同一存储空间;成员分量之间是相互联系的,所进行的操作相互依赖。共用体:同一内存单元在每一瞬时只能存放其中一种类型的成员;起作用的成员是最后一次存放的成员,不能作为函数参数,不能进行比较操作,只能对第一个成员初始化,44,【例1】设有一个教师与学生通用的表格,教师数据有姓名、年龄、职业,教研室四项。学生有姓名、

28、年龄、职业、班级四项。编程输入人员数据, 再以表格输出。,#include struct Stu_Tea char name10; /姓名 int age; /年龄 char job; /工作s-表示学生,t-表示教师 union int classno; /学生班级号 char office10; /教师教研室名 depart;,void main ( ) struct Stu_Tea body2; int i; for (i = 0; i 2; i+) /输入学生或教师信息 printf (input name,age,job and departmentn); scanf (%s %d

29、%c, bodyi.name, ,/显示输入的学生、教师信息 printf (nametage job class/officen); for (i = 0; i 2; i+) if (bodyi.job = s) printf (%st%3d%3c%dn, bodyi.name, bodyi.age, bodyi.job, bodyi.depart.classno); else printf (%st%3d %3c %sn, bodyi.name, bodyi.age, bodyi.job, bodyi.depart.office); ,45,12.4 用typedef定义数据类型(P343

30、-344),标准类型(如int、char、long、double等):系统已经定义好的数据类型,用户可以直接使用,无须再进行定义。用户自定义类型:用户根据自己的实际要求,自己定义的新的数据类型。除结构体、共同体等类型外,还可以用类型说明语句typedef为已定义类型说明符起别名。,typedef语句的格式为:,typedef 类型名 类型名的别名;,必须是已经定义的数据类型名或C语言提供的基本类型名,必须是合法的标识符,通常用大写字母来表示,必须以分号结尾,46,12.4 用typedef定义数据类型,typedef int INTEGER; /INTEGER是别名struct teacher

31、_info char name20, char sex, unit30; unsigned int age, workyears; float salary;typedef struct teacher_info TEACHER; /TEACHER是别名INTEGER a; /相当于int a;TEACHER t; /相当于struct teacher_info t;,47,12.5 枚举数据类型(P365-366),如果一个变量只有几种可能的值,可以把它定义成枚举类型。所谓“枚举”,顾名思义,就是把这种类型数据可取的值一一列举出来。一个枚举型变量取值仅限于列出值的范围。枚举数据类型通常的定义

32、形式为:,enum 枚举类型名 枚举元素表;,由多个标识符组成,标识符之间用逗号分开,定义枚举类型:enum weekday sun, mon, tue, wed, thu, fri, sat;,定义枚举类型变量:enum weekday today, nextday;,enum weekday sun, mon, tue, wed, thu, fri, sat today, nextday;,48,12.5 枚举数据类型(P365-366),enum weekday sun, mon, tue, wed, thu, fri, sat today, nextday;,today = sun;n

33、extday = mon;if (today = sat) nextday = sun;,today = 100;,C编译对枚举元素实际上按整型常量处理,当遇到枚举元素列表时,编译程序就把其中第一个标识符赋0值,第二、三、个标识符依此赋1,2,。,enum weekday sun, mon, tue, wed, thu, fri, sat today, nextday;,today = sun;printf(today = %d, today);,运行结果:today = 0,49,12.5 枚举数据类型(P365-366),if (today = 6) nextday = 0;,if (to

34、day = sat) nextday = sun;,可以在枚举类型定义时指定枚举元素的值,enum weekday sun = 7, mon = 1, tue, wed, thu, fri, sat;,注意:枚举元素是常量,在程序中不可对它赋值。 例如:sun = 0; mon = 1;将产生错误。,定义枚举类型的好处:,用标识符表示数值增加了程序的可读性,清晰,不清晰,可限制了变量的取值范围,如today只能取sunsat中的值,50,12.6 动态数据结构 单向链表(P366-376),线性链表概述,线性表:当一组数据元素形成了“前后”关系时,我们称之为线性表,线性表在内存中的两种形式,顺

35、序表:以数组的形式存放,元素在内存中是连续存放的,线性链表:数据元素在内存中不需要连续存放,而是通过指针将各数据单元链接起来,就象一条“链子”一样将数据单元前后元素链接起来,特点:插入或删除一个数据元素时,需要移动其它数据元素,特点:插入或删除一个数据元素时,不需要移动其它数据元素,51,12.6 动态数据结构 单向链表,struct Link int data; struct Link *next;,链表(Linked Table):线性表的链式存储结构特点:用一组任意的存储单元存储线性表的数据;存储单元可以是连续的,也可是不连续的,52,链表(Linked table):线性表的链式存储结

36、构为表示每个元素与后继元素的逻辑关系,除存储元素本身信息外,还要存储其直接后继信息,两部分信息组成一个节点,struct Link int data; struct Link *next;,12.6 动态数据结构 单向链表,53,数据域:存储数据元素信息,指针域:存储直接后继的节点信息,链表(Linked Table):线性表的链式存储结构为表示每个元素与后继元素的逻辑关系,除存储元素本身信息外,还要存储其直接后继信息,struct Link int data; struct Link *next;,n个节点链接成一个链表(因为只包含一个指针域,故又称线性链表或单向链表),12.6 动态数据结

37、构 单向链表,54,12.6链表的基本操作-链表的建立,空指针NULL表示链表结尾,链表的头指针:访问链表的关键,向链表中添加一个新节点,struct Link int data; struct Link *next;,55,若原链表为空表(head = NULL) ,则将新建节点p置为头节点,(1)head = p,(2) pr = p,(3) pr-next = NULL,12.6链表的基本操作-链表的建立,56,若原链表为非空,则将新建节点p添加到表尾,(1) pr-next = p,(2) pr = p,(3) pr-next = NULL,next,12.6 链表的基本操作-链表的建

38、立,57,struct Link *AppendNode(struct Link *head)struct Link *p=null,*pr=head; int data;p=(struct Link *)malloc(sizeof(struct Link ); if(p=NULL) printf(“No enough memory to allocate!n”); exit(0); if(head= NULL) head=p; else while(pr-next!=NULL) pr=pr-next; pr-next=p; printf(“Input node data:”); scanf(

39、“%d”,58,若原链表为空表,则退出程序 若待删除节点p是头节点,则将head指向当前节点的下一个节点即可删除当前节点,(1) head = p-next,head,(2) free(p),从链表中删除一个节点,12.6链表的基本操作-链表的删除,59,若待删除节点不是头节点,则将前一节点的指针域指向当前节点的下一节点即可删除当前节点,(1) pr-next = p-next,若已搜索到表尾(p-next = NULL)仍未找到待删除节点,则显示“未找到”,(2) free(p),12.6链表的基本操作-链表的删除,struct Link *DeleteNode(struct Link *h

40、ead,int data)struct Link *p=head,*pr=head; if(p=NULL) printf(“Link Table is empty!n”); return head; while(data!=p-data ,若原链表为空表,则将新节点p作为头节点,让head指向新节点p,(1) head = p,p = (struct link *)malloc(sizeof(struct link);p-next = NULL;p-data = nodeData;,12.6链表的基本操作-链表的插入,62,若原链表为非空,则按节点值(假设已按升序排序)的大小确定插入新节点的位

41、置若在头节点前插入新节点,则将新节点的指针域指向原链表的头节点,且让head指向新节点,(2) head = p,(1) p-next = head,12.6链表的基本操作-链表的插入,63,若在链表中间插入新节点,则将新节点的指针域指向下一节点且让前一节点的指针域指向新节点,(2) pr-next = p,(1) p-next = pr-next,12.6链表的基本操作-链表的插入,若在表尾插入新节点,则末节点指针域指向新节点,(1) pr-next = p,next,12.6链表的基本操作-链表的插入,struct Link *InsertNode(struct Link *head,in

42、t data)struct Link *p=head,*pr=head,*temp=NULL; p=(struct Link *)malloc(sizeof(struct Link ); if(p=NULL) printf(“No enough memory n”); exit(0); p-data=data; p-next=NULL; if(head= NULL) head=p; else ,while(pr-datanext!=NULL) temp=pr; pr=pr-next; if(pr-data=data) if(pr=head) p-next=head;head=p; else p

43、r=temp; p-next=pr-next; pr-next=p; else pr-next=p; return head;,67,遍历链表的所有节点,12.6链表的基本操作-链表的输出,68,对于动态链表,必须由程序员自己来进行内存的分配与释放。,void DeleteMemory(struct Link *head ) struct Link *p, *q; p = head; while(p != NULL) q = p; p = p-next; free(q); ,12.6链表的基本操作-链表的释放,69,数据,指针,数据,前指针,后指针,12.6 链表的类型,70,12.6 链表的类型,环形链表:一种特殊的链表,其尾结点的next指针,又指向了链表的首结点,从而形成了一个圆环。从环形链表的任何一个结点出发,都可以遍历整个的链表。,71,Question?,

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

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号