第8章结构体与共用_第1页
第8章结构体与共用_第2页
第8章结构体与共用_第3页
第8章结构体与共用_第4页
第8章结构体与共用_第5页
已阅读5页,还剩35页未读 继续免费阅读

付费下载

下载本文档

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

文档简介

苏小红第8章结构体与共用体本章内容结构体(结构structure)、共用体(联合union)类型的定义结构体变量、结构体数组结构体变量、结构体数组与指针、函数的关系用结构体实现动态数据结构链表的概念及操作原理从基本数据类型到抽象数据类型二进制数–

在早期的机器指令及汇编语言中,数据对象均用二进制数表示,没有类型的概念基本数据类型–在高级语言中引入了基本数据类型:整型、实型、字符型等–基本数据类型不能方便的解决所有问题,有些语言(如PL/1)中试图规定较多的类型,如数组、树、栈等,但实践证明不是个好办法用户自己构造数据类型-复合数据类型–表示复杂的数据对象,典型的代表就是“结构体”,数组、指针也可算作此类抽象数据类型(Abstract

Data

Type,简称ADT)–在复合数据类型基础上增加了对数据的操作–类——跨时代的进步–例如汽车就是一种ADT思考一个问题在程序里表示一个人(姓名、年龄、性别、……),怎么表示?想表示多个人呢?如何用计算机程序实现下述表格的管理?表8-1

某学校学生成绩管理表学号姓名性别入学时间计算机原理英语数学音乐1令狐冲男1999908372822林平之男1999789288783岳灵珊女1999897298664任莹莹女1999789587905…

…6…

…数组的解决方法int

studentId[30];/*

最多可以管理30个学生,每个学生的学号用数组的下标表示*/char

studentName[10][30];char

studentSex[2][30];int

timeOfEnter[30];/*入学时间用int表示*/int

scoreComputer[30];/*计算机原理课的成绩*/int

scoreEnglish[30];/*英语课的成绩*/intintscoreMath[30];scoreMusic[30];/*数学课的成绩*//*音乐课的成绩*/数组的解决方法int

studentId[30]

=

{1,2,3,4,5,6};char

studentName[10][30]={{"令狐冲"},{"林平之"},{"岳灵珊"},{"任莹莹"}};

char

studentSex[2][30]

=

{{"男"},{"男"},{"女"},{"女"}};int

timeOfEnter[30]

=

{1999,1999,1999,1999};int

scoreComputer[30]

=

{90,78,89,78};int

scoreEnglish[30]

=

{83,92,72,95};int

scoreMath[30]

=

{72,88,98,87};int

scoreMusic[30]

=

{82,78,66,90};数组的解决方法数据的内存管理方式90788978……83927295……72889887……82786690……1234……令狐冲林平之岳灵珊任莹莹……男男女女……1999199919991999……数组的解决方法分配内存不集中,寻址效率不高对数组进行赋初值时,容易发生错位结构显得比较零散,不容易管理希望的内存分配图1令狐冲男1999908372822林平之男1999789288783岳灵珊女1999897298664任莹莹女199978958790结构体的解决方法studentName[10];/*每个学生的姓名*/studentSex[4];timeOfEnter;scoreComputer;scoreEnglish;scoreMath;scoreMusic;/*每个学生的性别*//*每个学生的入学时间*//*每个学生的计算机原理成绩*//*每个学生的英语成绩*//*每个学生的数学成绩*//*每个学生的音乐成绩*/struct

STUDENT{int

studentID;

/*每个学生的序号*/charcharintintintintint};struct

STUDENT是一个类型struct

STUDENT

students[4];students[0].studentNamestudents[0].Sex它们都是变量,一般称为结构的成员变量用户自定义的数据类型结构体:把关系紧密且逻辑相关的多种不同类型的变量组织到统一的名字之下,也称复合数据类型这种类型的变量占用相邻的一段内存单元共用体:把情形互斥但又逻辑相关的多种不同类型的变量组织在一起这种类型的变量占用同一段内存单元,因此每一时刻只有一个数据起作用10010LiFunM1887.5Beijingnumagename

sex

score

addrstruct

student{int

num;char

name[20];};一般形式:struct

结构体名{成员名1;类型关键字类型关键字…...类型关键字成员名2

char

sex;int

age;成员名n

float

score;char

addr[30];};structuredefinition形成一个样板,用于生成结构体变量。构成结构体的变量称为结构体的成员(member),也称元素(element)或域(filed)结构体的定义只定义了数据的形式,即声明了一种复杂的数据类型,并未生成任何变量。结构体的定义直接定义结构体变量(不出现结构体名)先定义结构体类型再定义变量名struct

student

student1,student2;在定义类型的同时定义变量struct

student{int

num;

char

name[20];char

sex;int

age;float

score;char

addr[30];}

student1,student2;struct{int

num;char

name[20];char

sex;int

age;float

score;char

addr[30];}

student1,student2;结构体变量的定义结构体变量的定义用typedef为已存在的类型定义新名字struct

student{int

num;char

name[20];char

sex;int

age;float

score;char

addr[30];}

;typedef

struct

student

STUD;STUD

student1,student2;用STUD代替struct

student类型;结构体定义可以嵌套struct

date{int

month;int

day;int

year;};typedef

struct

date

DATE;struct

student{int

num;char

name[20];char

sex;int

age;DATE

birthday;char

addr[30];}

student1,student2;numnamesexagebirthdayaddrmonthdayyeardouble

占用内存字节数=8struct

student

占用内存字节数=?结构体变量的定义结构(Structure)的内存占用m1m2m3m1m2m3一个结构变量的成员变量在内存中是相邻的整个结构变量的将占用多少内存呢?是所有成员变量的内存总和吗?事实上,所有数据类型在内存中都是从偶数地址开始存放的,且结构所占的实际空间一般是按照机器字长对齐的不同的编译器、不同的平台,对齐方式会有变化,不过一般的编译器都可以设定按照多大对齐我们可以用sizeof来获得结构的大小char

int

char

char

int

char结构体指针struct

point{int

x;int

y;};struct

pointpt;

/*定义结构体变量*/struct

point

*ppt;/*定义结构体指针*/ppt=&pt;怎样通过pt访问pt的成员?–

pt.x

=0;/*成员运算符*/怎样通过ppt访问pt的成员?–

(*ppt).x=

0;/*指向运算符*/–

ppt->x

=

0;–第二种更常用xypptpt定义:struct

STUDENT{intcharstudentID;studentName[10];char

studentSex[4];struct

date

timeOfEnter;intintintintscoreComputer;scoreEnglish;scoreMath;scoreMusic;};struct

STUDENT

stu[30];结构体数组学号姓名性别入学时间计算机原理英语数学音乐年月日STUDENT{studentID;studentName[10];studentSex[4];date

timeOfEnter;intcharcharstructintintintintscoreComputer;scoreEnglish;scoreMath;scoreMusic;};struct

STUDENT

stu[30]

={{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结构体数组结构体数组的指针struct

STUDENT

*pt;pt

=

stu;1…2…3…4…stu[0]ptpt++stu[1]stu[2]stu[3]for

(pt=stu;

pt<stu+30;

pt++){sum[0]

=

sum[0]

+

pt->scoreComputer;sum[1]

=

sum[1]

+

pt->scoreEnglish;sum[2]

=

sum[2]

+

pt->scoreMath;sum[3]

=

sum[3]

+

pt->scoreMusic;}for

(i=0;

i<4;i++){average[i]

=

sum[i]/4;printf("%20s

:

%4.2f\n",

name[i],

*(average+i));}例8.2:利用指向结构体数组的指针计算学生各科的平均成绩学号姓名性别入学时间计算机原理英语数学音乐年月日例8.2main(){struct

STUDENT

*pt;sum[4]

=

{0.0},average[4]

=

{0.0};i;floatintchar*name[]={"score

of

Computer","score

of

English","score

of

Math","score

of

Music"};pt=stu;

/*pt指向结构体数组的第一个元素*/for

(pt=stu;pt<stu+30;pt++){sum[0]

=

sum[0]

+

pt->scoreComputer;sum[1]

=

sum[1]

+

pt->scoreEnglish;sum[2]

=

sum[2]

+

pt->scoreMath;sum[3]

=

sum[3]

+

pt->scoreMusic;}for

(i=0;

i<4;i++){average[i]

=

sum[i]/4;printf("%20s

:

%4.2f\n",

name[i],

*(average+i));}}例8.1:洗牌和发牌模拟一付扑克有52张牌,分为4种花色(Suit):黑桃(Spades)、红桃(Hearts)、草花(Clubs)、方块(Diamonds)每种花色有13张牌面(Face):A,2,3,4,5,6,7,8,9,10,Jack,Queen,King设计一个结构体表示一张牌,由两个成分组成:花色、牌面:struct

CARD{charcharsuit[10];face[10];};struct

CARD

card[52];int

result[52];/*顺序存放扑克牌*//*存放洗牌发牌结果*/char*suit[]={"Spades","Hearts","Clubs","Diamonds"};char*face[]={"A","2","3","4","5","6","7","8","9","10","jack","Queen","King"};例8.1:洗牌和发牌模拟发牌过程将52张牌按照随机的顺序存放算法步骤:产生0~51的随机数,将其放于result[i]内。i=i+1如果i<=51,则重复第2步,否则,结束循环输出结果存在一个致命的问题:在重复第2步时,产生的随机数可能与以前产生的随机数相同,相同意味着52张牌中出现2张以上相同的牌例8.1:洗牌和发牌模拟解决方法增加一步,判断新产生的随机数以前是否出现过如果出现过,则放弃;如果以前未出现过,则保留算法步骤:产生0~51的随机数m,将其放于result[i]内。判断result[i]在以前(result[0]~result[i-1])是否出现过。如果出现过,则回到第2步;如果没出现过,则i=i+1如果i<=51,则重复第2~3步,否则,结束循环输出结果例8.1:洗牌和发牌模拟算法缺陷:随着随机数数量的增加,新的随机数与已经产生的随机数相同的可能性越来越大,有可能出现算法延迟问题高效算法将按照花色与牌面的顺序存放的牌(card[i])随机打乱每次循环,程序选择一个0~51的随机数j,然后将数组中当前的CARD结构card[i]与随机选出的j所在的数组元素

card[j]结构进行交换例8.1:洗牌和发牌模拟(P313)用结构体数组做函数参数/*

函数功能:将52张牌按黑桃、红桃、草花、方块花色顺序,面值按A~K的顺序排列函数参数:结构体数组wCard[],表示不同花色和面值的52张牌指针变量wFace,表示指向面值字符串数组face[]的指针指针变量wSuit,表示指向花色字符串数组suit[]的指针函数返回值:无*/void

FillCard(struct

CARD

wCard[],char

*wFace[],char

*wSuit[]){int

i;for

(i=0;

i<52;

i++){strcpy(wCard[i].suit,

wSuit[i/13]);strcpy(wCard[i].face,

wFace[i%13]);}}用结构体指针做函数参数/*

函数功能:将52张牌的顺序打乱,函数参数:结构体数组变量wCard[],表示52张牌函数返回值:无*/void

Shuffle(struct

CARD

*wCard){int

i,j;struct

card

temp;for

(i=0;

i<52;

i++){j

=

rand()%52;/*j=random(52);TC的库函数*/temp

=

wCard[i];wCard[i]

=

wCard[j];wCard[j]

=

temp;/*

洗牌过程*/}}例8.1:洗牌和发牌模拟(P313)用结构体指针做函数参数/*函数功能:输出发牌结果函数参数:结构体数组变量wCard[],表示有52张牌函数返回值:无*/void

Deal(struct

CARD

*wCard){int

i;for

(i=0;i<52;i++)

/*输出发牌结果*/printf("%10s%10s\n",wCard[i].suit,wCard[i].face);}例8.1:洗牌和发牌模拟(P313)结构体与函数向函数传递结构体的单个成员单向值传递,函数内对结构内容的修改不影响原结构向函数传递结构体的完整结构单向值传递,函数内对结构内容的修改不影响原结构,开销大向函数传递结构体的首地址用结构体数组或者结构体指针做函数参数除提高效率外,还可以修改结构体指针所指向的结构体的内容思考下面的结构什么意思?struct

temp{int

data;struct

temp

pt;}TC下的错误提示:Undefined

structure

‘temp’Structure

size

too

largeVC下的错误提示:‘pt’

uses

undefined

struct

‘temp’下面的的呢?struct

temp{int

data;struct

temp*pt;}动态数据结构结构体声明时不能包含自我,但可以包含指向本结构体类型的指针变量链表(Linked

table)struct

Link{int

data;struct

Link

*next;}datanextheaddatanextdatanextdataNULL图8-9链表原理图位字段想表达人的姓名、出生年、月、日,都定义什么类型的成员变量?struct

person{char

name[12];int

year;char

month;char

day;};这样有很多的空间浪费,比如month只可能取值1-12,4bits足够位字段struct

person{charunsignedintname[12];year :

12;unsignedintmonth

:

4;unsignedintday :

5;};调整成员顺序可以让结构更紧凑每个位段都可以当作一个无符号整型数使用–表达范围当然受限,而且当然不能取地址共用体,或称为联合(Union)un

温馨提示

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

评论

0/150

提交评论