C语言学习课件结构体与共用体.ppt_第1页
C语言学习课件结构体与共用体.ppt_第2页
C语言学习课件结构体与共用体.ppt_第3页
C语言学习课件结构体与共用体.ppt_第4页
C语言学习课件结构体与共用体.ppt_第5页
已阅读5页,还剩35页未读 继续免费阅读

下载本文档

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

文档简介

第8章 结构体与共用体,c语言大学实用教程,本章内容,结构体(结构structure) 、共用体(联合union)类型的定义 结构体变量、结构体数组 向函数传递结构体变量、结构体数组,从基本数据类型到抽象数据类型,二进制数 在早期的机器指令及汇编语言中,数据对象均用二进制数表示,没有类型的概念,基本数据类型 在高级语言中引入了基本数据类型:整型、实型、字符型等 基本数据类型不能方便的解决所有问题,有些语言中试图规定较多的类型,如数组、树、栈等,但实践证明不是个好办法,从基本数据类型到抽象数据类型,用户自己构造的数据类型复合数据类型 表示复杂的数据对象,典型的代表就是“结构体”,数组、指针也可算作此类,抽象数据类型(abstract data type,简称adt) 在复合数据类型基础上增加了对数据的操作 类跨时代的进步,思考一个问题,在程序里表示一个人(姓名、年龄、性别、),怎么表示? 想表示多个人呢? 如何用计算机程序实现下述表格的管理?,表8-1 某学校学生成绩管理表,数组的解决方法,int studentid30; /* 最多可以管理30个学生, 每个学生的学号用数组的下标表示*/ char studentname3010; /* 最多可以管理30个学生, 每个学生的姓名是一个字符串*/ char studentsex302; /* 性别是一个字符串*/ int timeofenter30; /*入学时间用int表示*/ int scorecomputer30;/*计算机原理课的成绩*/ int scoreenglish30; /*英语课的成绩*/ int scoremath30; /*数学课的成绩*/ int scoremusic30; /*音乐课的成绩*/,int score 304; /* 30个学生, 每人4门课的成绩*/,无法使一个数组中存放不同类型的数据,数组的解决方法,int studentid30 = 1,2,3,4,5,6; char studentname3010=“令狐冲“,“林平之“, “岳灵珊“,“任莹莹“; char studentsex302=“男“,“男“,“女“,“女“; int timeofenter30 = 1999,1999,1999,1999; int scorecomputer30 = 90,78,89,78; int scoreenglish30 = 83,92,72,95; int scoremath30 = 72,88,98,87; int scoremusic30 = 82,78,66,90;,数组的解决方法,数据的内存管理方式,分配内存不集中,寻址效率不高 对数组进行赋初值时,容易发生错位 结构显得比较零散,不容易管理,希望的内存分配图,结构体的解决方法,struct student int studentid; /*每个学生的序号*/ char studentname10;/*每个学生的姓名*/ char studentsex2; /*每个学生的性别*/ int timeofenter; /*每个学生的入学时间*/ int scorecomputer; /*每个学生的计算机原理成绩*/ int scoreenglish; /*每个学生的英语成绩*/ int scoremath; /*每个学生的数学成绩*/ int scoremusic; /*每个学生的音乐成绩*/ ; struct student是一个类型 struct student students4;/*声明结构体类型的数组*/ students0.studentid students0.scorecomputer 它们都是变量,一般称为结构体的成员变量,声明结构体类型:,用户自定义的数据类型,结构体: 把关系紧密且逻辑相关的多种不同类型的变量组织到统一的名字之下,也称复合数据类型 这种类型的变量占用相邻的一段内存单元 共用体: 把情形互斥但又逻辑相关的多种不同类型的变量组织在一起 这种类型的变量占用同一段内存单元,因此每一时刻只有一个数据起作用,struct student int num; char name20; char sex; int age; float score; char addr30; ;,形成一个样板,用于形成组成结构体的元素。,一般形式:,struct 结构体名 类型关键字 成员名1; 类型关键字 成员名2; . 类型关键字 成员名n; ;,构成结构体的元素(element)称为结构体的成员(member), 也称域(filed)。,结构体的声明只定义了数据类型的组成形式,即声明了一种复杂的数据类型,并未生成任何变量。,结构体的定义,在先前已定义结构体类型的基础上再声明变量,在定义类型的同时定义变量,直接定义结构体变量(不出现结构体名),struct student student1,student2;,struct student int num; char name20; char sex; int age; float score; char addr30; student1,student2;,struct int num; char name20; char sex; int age; float score; char addr30; student1,student2;,结构体变量的定义,定义自己的类型名,struct student student1,student2; /* it works */ student student1,student2; /*can this work?*/ struct student int num; char name20; char sex; int age; float score; char addr30; ; typedef struct student stud; stud student1,student2; /* it works! */ typedef 为一种已存在的类型定义一个新名字 stud与 struct student类型是同义词,结构(structure)的内存占用,double 占用内存字节数 = 8 struct student 占用内存字节数 = ? 是所有成员变量所占内存的总和吗? 事实上,所有数据类型在内存中都是从偶数地址开始存放的,且结构所占的实际空间一般是按照机器字长对齐的 不同的编译器、平台,对齐方式会有变化 我们可以用sizeof来获得结构的大小,与普通变量一样,在定义结构体类型变量的同时也可以对结构体类型变量赋初值。,【例1】 对结构体变量初始化 。,#include main() struct student long int num; char name20; char sex; char addr20; a=10101,“li lin“,m,“123 beijing road“; printf(“no.:%ldnname:%snsex:%cnaddress:%sn“, a.num,,a.sex,a.addr); ,结构体变量的初始化,结构体类型变量的初始化,struct time int hour; int minute; int second; struct date int year; int month; int day; struct time t; ; main() struct date xy=2003,3,15,17,34,55; printf(“date=d/d/d/d:d:dn“, xy.year,xy.month,xy.day,xy.t.hour,xy.t.minute,xy.t.second); ,【例2】,定义:,struct student int studentid; char studentname10; char studentsex4; struct date timeofenter; int scorecomputer; int scoreenglish; int scoremath; int scoremusic; ; struct student stu30;,结构体数组,struct date int year; int month; int day; ;,例8-2.c,struct student int studentid; char studentname10; char studentsex4; struct date timeofenter; int scorecomputer; int scoreenglish; int scoremath; int scoremusic; ; struct student stu30 = 1,“令狐冲“,“男“,1999,12,20,90,83,72,82, 2,“林平之“,“男“,1999,07,06,78,92,88,78, 3,“岳灵珊“,“女“,1999,07,06,89,72,98,66, 4,“任莹莹“,“女“,1999,07,06,78,95,87,90 ;,初始化,结构体数组,结构体指针,struct point int x; int y; ; struct point pt; /*定义结构体变量*/ struct point *ppt; /*定义结构体指针*/ ppt = /*指向运算符*/ 第二种更常用,ppt,pt,思考题,struct point int x; int y; ; struct rect struct point pt1; struct point pt2; ;,struct rect rt; struct rect *rp = 下面表达式哪些合法? rt.pt1.x (*rp).pt1.x rp-pt1.x rt-pt1.x 上面合法的表达式都是等价的吗?,结构体定义可以嵌套,结构体数组的指针,struct student *pt; pt = stu;,stu0,stu1,stu2,pt,pt+,stu3,自增跳过一个数组元素的所有成员所占的字节数,例8.1 :洗牌和发牌模拟 (p323),一付扑克有52张牌,分为4种花色(suit): 黑桃(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“,“2“,“3“,“4“,“5“,“6“,“7“,“8“,“9“, “10“,“jack“,“queen“,“king“;,例8.1 :洗牌和发牌模拟(p324),发牌过程 将52张牌按照随机的顺序存放 算法步骤: 产生051的随机数,将其放于resulti内。 i=i+1 如果i=51,则重复第步,否则,结束循环,执行 输出结果 存在一个致命的问题: 在重复第步时,产生的随机数可能与以前产生的随机数相同,相同意味着52张牌中出现2张以上相同的牌,例8.1 :洗牌和发牌模拟(p307),解决方法 增加一步,判断新产生的随机数以前是否出现过 如果出现过,则放弃;如果以前未出现过,则保留 算法步骤: 产生051的随机数m,将其放于resulti内。 判断resulti在以前(result0resulti-1)是否出现过。如果出现过,则回到第步;如果没出现过,则i=i+1 如果i=51,则重复第步,否则,结束循环 输出结果,例8.1 :洗牌和发牌模拟(p309),算法缺陷: 随着生成随机数数量的增加,新的随机数与已经产生的随机数相同的可能性越来越大,有可能出现算法延迟问题 高效算法 先将52张牌按照花色与牌面顺序存放(cardi) 再将其随机打乱 每次循环,程序选择一个051的随机数j,然后将数组中当前的元素cardi与随机选出的元素cardj进行交换,例8.1 :洗牌和发牌模拟(p313),用结构体数组做函数参数 char *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) int i; for (i=0; i52; i+) strcpy(wcardi.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 6 7 8 9 10 11 12 0 1 2 3 4 5 6 7 8 9 10 11 12 0 1 ,用结构体指针做函数参数 /* 函数功能:将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.1 :洗牌和发牌模拟(p314),用结构体指针做函数参数 /*函数功能:输出发牌结果 函数参数:结构体数组wcard,表示有52张牌 函数返回值:无 */ void deal(struct card *wcard) int i; for (i=0; i52; i+) /*输出发牌结果*/ printf(“%10s%10sn“, wcardi.suit, wcardi.face); ,例8.1 :洗牌和发牌模拟(p314),结构体与函数,向函数传递结构体的单个成员 单向值传递,函数内对结构内容的修改不影响原结构 向函数传递结构体的完整结构 单向值传递,函数内对结构内容的修改不影响原结构,开销大 向函数传递结构体的首地址 用结构体数组或者结构体指针做函数参数 除提高效率外,还可以修改结构体指针所指向的结构体的内容,struct date int year; int month; int day; ; void func(struct date p) p.year = 2000; p.month = 5; p.day = 22; ,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, d.day); ,1999,4,23,1999,4,23,结构体与函数,结构体变量,单向值传递,struct date int year; int month; int day; ; void func(struct date *p) p-year = 2000; p-month = 5; p-day = 22; ,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,结构体变量地址值传递,struct类型的特点,一个普通的类型 可以定义该类型的变量、数组、指针 可以做函数的参数类型和返回值类型 它的成员可以是任意类型 基本类型、数组、指针、结构体、共用体 struct类型的变量 两个结构体变量之间可以相互赋值 所以做为函数的参数时,是传值调用 可以取地址& 不可能直接参与算术和比较运算 面向对象和数据库是struct的思想的发展,思考,下面的结构是什么意思? struct temp int data; struct temp pt; ; vc下的错误提示: pt uses undefined struct temp 下面的结构是什么意思呢? struct temp int data; struct temp *pt; ;,动态数据结构,结构体声明时不能包含自我,但可以包含指向本结构体类型的指针变量 链表(linked table) struct link int data; struct link *next; ;,共用体,或称为联合(union),union number short x; char ch; float y; ; 基本上和struct一样 x、ch和y处于同样的地址 size

温馨提示

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

评论

0/150

提交评论