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

下载本文档

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

文档简介

1、第8章 结构体与共用体,8.1结构体概述 8.1.1结构体的引入 在事务处理中,常需要将一些关系密切但类型不同的数据项组织在一起,并为其取一个整体名字,形成一个结构。在C语言中,就称其为结构体(有些高级语言称之为记录)。结构体通常由不同数据类型的数据项(成员)组成;可以说:一个结构体可包含若干成员,每个成员具有自己的名字及数据类型。 结构体的引入为处理复杂的数据结构提供了有力的手段,也为函数间传递一组不同数据类型的数据提供了方便。,结构体类型的定义,和简单类型不同,结构体类型是根据需要由程序员 自行定义,因此在使用之前必须先定义结构体类型,一般格式:,struct 结构体名 结构体成员表; ;

2、,struct是关键字,称为结构体定义标识符,而结构 体名则由程序员自己命名。大括号中的结构体成员 表包含若干成员,每一个成员都具有如下的形式:,数据类型标识符 成员名;,struct stud_type char name10; long num; char sex; int age; float score5; char address10; ;,对一个学生的描述,其结构体类型定义如下:,说明 (1)定义一个结构体类型只是描述了此结构体的组织形式,在编译时并不为其分配存储空间,即仅描述此数据结构的形态或者说模型,故不能对定义的一个结构体类型进行赋值、存取或运算。 (2) 结构体的成员可以是

3、简单变量、数组、指针、结构体或公用体等。 (3) 结构体类型定义可以放在函数内部,也可以放在函数外部。若放在内部,则只在函数内有效;若放在外部,则从定义点到源文件尾之间的所有函数都有效。 (4) 结构体成员的名字可以同程序中的其它变量同名,二者不会相混,系统会自动识别它。,8.2 结构体变量 8.2.1 结构体变量的定义与初始化 1结构体变量的定义 同其它变量一样, 结构体变量也必须先定义, 后引用。结构体变量的定义可以有以下三种方式: (1) 先定义类型再定义变量 其形式:,struct stud_type char name10; long num; char sex; int age;

4、float score5 ; ; struct stud_type student1, student2;,(2) 在定义类型的同时定义变量,其形式: struct stud_type char name10; long num; char sex; int age; float score5 ; student1, student2; (3) 直接定义结构体变量,其形式: struct char name10; long num; char sex; int age; float score5 ; student1, student2;,说明 (1)在定义结构体类型时,系统并不分配内存空间,

5、仅当定义结构体变量时,系统才为被定义的每一变量分配相应的存储单元。如上面定义的结构体变量student1、student2在内存中各占37个字节(10+4+1+2+4*5=37) (2)结构体变量的定义一定要在结构体类型定义之后或同时进行,对尚未定义的结构体类型,不能用它来定义结构体变量。 如:对一个教师 teach_type 的结构体类型未作定义,则下面的变量定义 struct teach_type teacher;是错误的。,2. 结构体变量的初始化 所谓结构体变量初始化,就是在定义结构体变量的同时,对其成员变量赋初值,在赋值时应注意按顺序及类型依次为每个结构体成员指定初始值。 结构体初始

6、化的一般格式为: struct 结构体类型名 结构体变量=初始化值列表;,struct date_type int year; int month; int day; ; struct stud_type char name10; long num; char sex; struct date_type birthday; float score; ; main() struct stud_type s1=wang,196103,m,1978,10,12,98 ; struct stud_type s2=liu,196105,m,1980,9,22,88 ; ,说明:,(1) 初始化值列表中初

7、始化数据之间用逗号分隔。,(2)初始化数据的个数一般与成员的个数相同,若 小于成员数,则剩余的成员将被自动初始化为0。,(3)初始化数据的类型要与相应成员变量的类型一致。 初始化时只能对整个结构体变量进行,不能仅对结 构体类型中的某些成员进行初始化赋值。,8.2.2 结构体变量的引用 1. 对结构体变量成员的引用 在C语言程序中, 不允许对结构体变量整体进行输入输出操作和除赋值外的各种运算,只能是对其成员进行此类操作。引用结构体变量成员的一般形式: 结构体变量名.成员名 其中“.”是结构体成员运算符, 其优先级别最高, 结合性是自左至右。对结构体成员可进行简单变量同样的操作。 如: 对上例定义

8、的结构体变量s1,s2, 可如下操作: scanf(%s,); scanf(%s,2. 对结构体变量整体的引用 对结构变量整体只能做赋值类的操作,如: (1) 可以相互赋值,但注意相互赋值的两个结构体变量必须是同一个结构体类型; 如:s2=s1; s2.birthday=s1.birthday; (2) 可作为函数的实参到形参的值传递、或函数返回值,详见下节。 注意: 不允许在赋值语句中以定义初值的形式对结构变量整体赋值。 不允许对结构变量整体输入输出。 如:scanf(%d %d %d, /* 3句都是错的*/,8.2.3 结构体变量作为函数参数 1.结构体变量成员作函数参数

9、结构体变量中的所有成员都可作为函数参数 struct stud_type char name10; long num; char sex; s1; 现将结构体变量s1的成员分别传递给函数 f1,f2,f3: f1(); f2(s1.num); f3(s1.sex); 若需要将成员地址传递给函数, 则加“ name是数组,不加“ int mouth; int day; ; struct stud_type char name10; long num; char sex; struct date_type birthday; float score; char address10;

10、s13; struct stud_type s25; 定义了结构体数组s1,s2,分别有3个5个元素, 每个元素都是struct stud_type类型。,2. 结构体数组的初始化 结构体数组在定义的同时可以初始化; 其一般格式是在定义之后紧跟一个用花括号括起来的一组初始数据, 为了增强可读性, 最好使每一个数组元素的初始数据也用花括弧括起来, 以此来区分各个数组元素。 对上所定义的结构体数组s3初始化如下: stuct stud_type s32= wang, 196103, m, 1978, 10, 12, 98,xian, zhang, 196102, f,1977,1,10,87, B

11、eijing;,8.3.2 结构体数组元素的引用 结构体数组元素引用和其它数组元素的引用方法类似,还要遵循引用结构体变量的规则。其一般形式如下: 数组名下标 /* 引用整个元素 */ 数组名下标. 成员名 /*引用元素的成员*/ 如: = wang; s31.num=196102; 说明 (1)可以将一个结构体数组元素赋值给同一结构体类型数组中另一个元素,或赋给同一类型的变量。 s12= s30; (2)不能把结构体数组元素整体直接进行输入或输出。,8.3.3 结构体数组作函数参数 与结构体变量一样, 结构体数组作为函数参数传递也只有在 C 的高版本中才支持, 但它们是有本质区

12、别的, 当实参为结构体数组时, 其形参应定义为同类型结构的结构体数组 (或指向结构体的指针) , 若形参被修改会使实参同时改变。 例8.4 从键盘输入5名学生信息,用排序函数sort对学生按成绩降序排序,并输出排行榜。#include struct stud_type char name10; int num; int score; ; struct stud_type s5; void sort(struct stud_type s );,main() int i,j,k; printf(n请输入 5 个学生的n姓名 学号 成绩 n); for(i=0;iN;i+) scanf (%s%d%

13、d, , ,void sort(struct stud_type stu ) int i,k,j; struct stud_type t; for(i=0;iN-1;i+) k=i; for(j=i+1;jN;j+) if(stuk.scorestuj.score) k=j; t=stui; stui=stuk; stuk=t; ,请输入 5 个学生的 姓名 学号 成绩 zhang 101 65 wang 102 80 chen 103 79 qian 104 98 liu 105 68 排序结果如下 qian104 98 wang 102 80 chen 103 79 liu

14、105 68 zhang 101 65,8.3.3 返回值为结构体类型的函数,定义返回值为结构体类型函数的一般形式为:,结构体类型名 函数名(形参表),例.main函数中定义一个结构体数组,多次调用 input函数输入各学生的信息,返回值赋给 结构体数组元素,再多次调用print函数输出。,#include stdio.h struct st_type char num7; char name21; char sex; int age; float score; ; main() int i; struct st_type s2; for(i=0;i2;i+) si=input(); for(

15、i=0;i2;i+) print(si); ,struct st_type input() struct st_type s0; printf(请输入姓名(其中可以包含空格):); gets(); printf(请输入学号、性别、年龄、成绩n); scanf(%s %c %d %f,s0.num, ,void print(struct st_type s0) printf(输出:学号 姓名 性别 年龄 成绩n); printf(%11s , s0.num); printf(16s, ); printf(%4c, s0.sex); printf(%8.2fn, s0.

16、score); ,8.5 共用体,共用体变量所占的内存长度等于最长的成员的长度,在C语言中, 允许不同数据类型使用同一存储区域, 共用体就是在同一存储区域由不同类型变量共享的数据类型。它采用的是覆盖存储技术,允许不同类型数据互相覆盖。 8.5.1 共用体类型定义 共用体类型的定义与结构体类似, 其一般定义格式如下: union 共用体类型标识符 共用体成员表; ; union关键字是共用体定义标识符, 共用体类型标识符由用户命名, 它们共同组成共用体类型名; 花括号中的共用体成员中的 每个成员都具有如下的形式: 数据类型标识符 成员名;,如: union data int i; char ch

17、; float f; ;,共用体变量的引用方式,只有先定义了共用体变量才能引用它,不能引用共用体变量,只能引用共用体变量中的成员,如:union data int i; char ch; float f; a,b,c; 注意:同一共用体变量的各共用体各成员共占同一段内存。,共用体类型数据的特点,1.同一个内存段可以用来存放几种不同类型的成员, 但在每一瞬间只能存放其中一种,而不是同时都存放;,2.共用体变量中起作用的成员是最后一次存放的成员, 在存入一个新的成员后原有的成员就失去作用;,3.共用体变量的地址和它的成员的地址都是同一地址;,4.共用体类型可以出现在结构体类型定义中。,共用体应用举

18、例,例8. 通过共用体变量,将一个整数的两个字节分别按十六进制和字符方式输出,如图所示。,union int_char int i; char ch2; ; print(union int_char x) printf(i=%dni=%Xn,x.i,x.i); printf(ch0=%X,ch1=%X n ,x.ch0,x.ch1); printf(ch0=%c,ch1=%cn,x.ch0,x.ch1); main() union int_char x; x.i=25419; print(x); ,例. 一个班体育课成绩,男生测验1500米成绩为 分秒,女生测验柔韧性(分A、B、C、D 和E5

19、等)和俯卧撑次数,将测验数据放在一 张表中,表中包括学号、姓名、性别和体育 成绩。最后一项“体育成绩”的内容根据性别 填写不同的内容,编写程序,若输入、输出 表中的信息。,#define N 2 #include struct ms int m; float s; struct fn char f; int n; struct student char num7; char name10; char sex; union struct ms sm; struct fn sw; score; stN;,main() int n,i; for(i=0;iN;i+) printf(请输入:学号、姓名

20、、性别n); scanf(%s%s%c,sti.num,, /*输出成绩*/ ,/*输出成绩*/ for(i=0;iN;i+) if(sti.sex=m | sti.sex=M) printf(%-8s %-10s 男1500米成绩:%d分 %4.1f秒n, sti.num,,sti.score.sm.m,sti.score.sm.s); else printf(%-8s %-10s 女 俯卧撑:%d次 柔韧性:%c等n, sti.num,,sti.score.sw.n,sti.score.sw.f);,8.6 枚举类型 在实际应用中,有些数据的

21、取值范围是可枚举的几个值, 如星期几,月份等等; 可用整数来表示这些取值, 但可读性差, 如在程序中出现1, 它是代表星期一呢?还是一月份?很难区分; 若在程序中使用Mon、Jan, 则非常明确。可见, 为提高程序的可读性, 用有意义的标识符来表示取值是非常必要的; C语言称之为枚举类型。 枚举类型也要先定义其类型,再定义该类型的变量。 枚举类型定义的一般形式是: enum 枚举类型标识符 枚举值名表; ; enum是枚举类型定义的关键字, 它与枚举类型标识符组成枚举类型名。枚举值名表由以逗号分隔的若干个用户定义标识符组成, 由程序员命名。,枚举值名标识符由程序员自定义,分别代表不同枚举值,通

22、常称为枚举常量。如: enum weekday sun, mon, tue, wed, thu, fri, sat ; 它定义了枚举类型enum weekday,该类型数据的取值范围是7个枚举值。在定义了类型之后,就可以用该类型来定义变量,如: enum weekday workday; 可将枚举类型定义和变量定义合并,如: enum weekday sun, mon, tue, wed, thu, fri, sat workday;,说明: (1) 各枚举常量不是枚举变量的成员, 而是它可能取的值。枚举常量是常量, 不允许对它进行赋值操作。 (2)C语言的枚举常量是有序的, 每个枚举常量对应

23、一个固定的整数序号, 它取决于在定义时排列的次序, 第一个枚举常量的序号隐含为0, 以后顺序加1,可在枚举类型定义时显式指定枚举常量的序号。 如:enum fruit apple=5, pear, lemon, orange=2, peach t; 显式指定apple的序号为5, pear和lemon的序号分别为6和7, orange的序号为2, peach的序号为3.不要误认为apple=5是给apple赋初值5,枚举常量与对应序号的类型不同, 它仅表示apple的序号为5,(3)枚举变量取值只能是这几个枚举常量之一, 可将枚举常量赋给一个枚举变量, 但不能将一个整数赋给它。如: workd

24、ay=sun; 正确 workday=7; 错误 (4) 可将整数强制类型转换为以它为序号的枚举常量,再赋值给枚举变量, 该整数值应在枚举序号范围内。 如: workday=(enum weekday)2; (5)在同一程序中所有定义的枚举常量不能重名,在同一程序中如果还定义了另一个枚举类型 enum star sun, 则因枚举常量重名出错。,(6)允许用%d对枚举变量进行输出,但输出的是其序号。若要输出其所对应的枚举常量的对应值,则应先对其序号进行判断,再行输出。,例. 输入一整数,转换为枚举类型,并存入枚 举类型的变量,再显示与之对应的星期值。,#include stdio.h main

25、() enum weekSun=7,Mon=1,Tue,Wed,Thu,Fri,Sta; enum week weekday; int i; printf(input integer:n); scanf(%d, ,enum language English=6, French, Chinese=1, Japanese, Italian ; 则枚举Italian的值为 。 A10 B4 C3 D5,8.7 用typedef定义类型 类型定义的含义及形式 可用typedef类型定义语句给某数据类型定义一个新类型名(别名), 形式为: typedef 类型 别名; 此后别名或原名都可用来定义变量。 如: typedef int INTEGER; /* 定义别名INTEGER */ struct st_type char name10; float score3; typedef struct st_type STUDENT; /* 定义别名 */ INTEGER I,j

温馨提示

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

评论

0/150

提交评论