第9章结构体教学课教_第1页
第9章结构体教学课教_第2页
第9章结构体教学课教_第3页
第9章结构体教学课教_第4页
第9章结构体教学课教_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

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

文档简介

1、第九章 结构体与共用体,结构体,结构体变量的定义,结构体变量的引用,结构体变量的初始化,结构体数组,结构体和指针,共用体,迄今为止,已介绍了基本类型(或称简单类型)的变量(如整型、实型、字符型变量等),也介绍了一种构造类型数据数组,数组中的各元素是属于同一个类型的。但是只有这些数据类型是不够的。有时需要将不同类型的数据组合成一个有机的整体,以便于引用。这些组合在一个整体中的数据是互相联系的。例如,一个学生的学号、姓名、性别、年龄、成绩、家庭地址等项。这些项都与某一学生相联系。见图1。可以看到性别(sex)、年龄(age)、成绩(score)、地址(addr)是属于学号为10010和名为“Li

2、Fun”的学生的。如果将num、name、sex、age、score、addr分别定义为互相独立的简单变量,难以反映它们之间的内在联系。,概述,应当把它们组织成一个组合项,在一个组合项中包含若干个类型不同(当然也可以相同)的数据项。C语言允许用户自己指定这样一种数据结构,它称为结构体(structure)。它相当于其他高级语言中的“记录”。,图1,假设程序中要用到图1所表示的数据结构,但是C语言没有提供这种现成的数据类型,因此用户必须要在程序中建立所需的结构体类型。例如: structstudent int num; charname20; charsex; intage; floatscor

3、e; charaddr30; ;,注意不要忽略最后的分号。上面由程序设计者指定了一个新的结构体类型struct student(struct是声明结构体类型时所必须使用的关键字,不能省略),它向编译系统声明这是一个“结构体类型”,它包括num、name、sex、age、score、addr等不同类型的数据项。应当说明struct student是一个类型名,它和系统提供的标准类型(如int、char、float、double等)一样具有同样的地位和作用,都可以用来定义变量的类型,只不过结构体类型需要由用户自己指定而已。,结构体,结构体是一种构造数据类型 用途:把不同类型的数据组合成一个整体-自

4、定义数据类型 结构体类型定义,struct 结构体名 类型标识符 成员名; 类型标识符 成员名; . ;,成员类型可以是 基本型或构造型,struct是关键字, 不能省略,合法标识符 可省:无名结构体,例 struct student int num; char name20; char sex; int age; float score; char addr30; ;,结构体类型定义描述结构 的组织形式,不分配内存,例子图解,1.先定义结构体类型,再定义结构体变量 一般形式:,struct 结构体名 类型标识符 成员名; 类型标识符 成员名; . ; struct 结构体名 变量名表列;,结

5、构体变量的定义,如上面已定义了一个结构体类型struct student,可以用它来定义变量。如: struct student student1, student2 结构体类型名 结构体变量名; 定义了student1和student2为struct student类型的变量,即它们具有struct student类型的结构。如图2所示。,图2,在定义了结构体变量后,系统会为之分配内存单元。例如student1和student2在内存中各占59个字节(2+20+1+2+4+30=59)。 应当注意:将一个变量定义为标准类型(基本数据类型)与定义为结构体类型不同之处在于后者不仅要求指定变量为结

6、构体类型,而且要求指定为某一特定的结构体类型(例如struct student类型)。因为可以定义出许许多多种具体的结构体类型。而在定义变量为整型时,只需指定为int型即可。,一般形式:,struct 结构体名 类型标识符 成员名; 类型标识符 成员名; . 变量名表列;,例 struct student int num; char name20; char sex; int age; float score; char addr30; stu1,stu2;,2.定义结构体类型的同时定义结构体变量,struct 类型标识符 成员名; 类型标识符 成员名; . 变量名表列;,例 struct i

7、nt num; char name20; char sex; int age; float score; char addr30; stu1,stu2;,用无名结构体直接定义 变量只能一次,3.直接定义结构体变量一般形式:,关于结构体类型,有几点要说明: (1) 类型与变量是不同的概念,不要混同。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是不分配空间的,只对变量分配空间。,(2) 对结构体中的成员(即“域”),可以单独使用,它的作用与地位相当于普通变量。关于对成员的引用方法。 (3) 成员也可以是一个结构体变量。,(4)成员名可以与程序中的变量名相同,二者不

8、代表同一对象。例如,程序中可以另定义一个变量num,它与struct student中的num是两回事,互不干扰。,structdate /*声明一个结构体类型*/ intmonth; intday; intyear; ; structstudent intnum; charname20; charsex; intage; struct date birthday; /*birthday是struct date类型*/ charaddr30; student1,student2;,先声明一个struct date类型,它代表“日期”,包括3个成员:month(月)、day(日)、year(年)

9、。然后在声明struct student类型时,将成员birthday指定为struct date类型。struct student的结构见图3所示。已声明的类型struct date与其他类型(如int,char)一样可以用来定义成员的类型。,图3,结构体变量的引用 在定义了结构体变量以后,当然可以引用这个变量。但应遵守以下规则: (1) 不能将一个结构体变量作为一个整体进行输入和输出。例如,已定义student1和student2为结构体变量并且它们已有值。不能这样引用: printf (%d,%s,%c,%d,%f,%sn,student1); 只能对结构体变量中的各个成员分别进行输入和

10、输出。引用结构体变量中成员的方式为 结构体变量名.成员名 例如: student1.num表示student1变量中的num成员,即student1的num(学号)项。可以对变量的成员,赋值,例如: student1.num=10010; “.”是成员(分量)运算符,它在所有的运算符中优先级最高,因此可以把student 1.num作为一个整体来看待。上面赋值语句的作用是将整数10010赋给student 1变量中的成员num。 (2) 如果成员本身又属一个结构体类型,则要用若干个成员运算符,一级一级地找到最低的一级的成员。只能对最低级的成员进行赋值或存取以及运算。例如,对上面定义的结构体变量

11、student1, 可以这样访问各成员: student1.num,student1.birthday.month 注意:不能用student1.birthday来访问student1变量中的成员birthday,因为birthday本身是一个结构体变量。 (3) 对结构体变量的成员可以像普通变量一样进行各种运算(根据其类型决定可以进行的运算)。例如: student2score=student1score; sum=student1score+student2score; student1age+; +student1age; 由于“”运算符的优先级最高,因此student1age+是对st

12、udent1age进行自加运算,而不是先对age进行自加运算。 (4) 可以引用结构体变量成员的地址,也可以引用结构体变量的地址。如:scanf(%d, (输入student1num的值)printf(%o, char name20; char sex; int age; char addr30; ; struct student stu1=112,“Wang Lin”,M,18, “200 Beijing Road”;,结构体变量的初始化,struct 结构体名 类型标识符 成员名; 类型标识符 成员名; . 结构体变量=初始数据;,例 struct student int num; cha

13、r name20; char sex; int age; char addr30; stu1=112,“Wang Lin”,M,18, “200 Beijing Road”;,结构体变量的初始化形式二:,struct 类型标识符 成员名; 类型标识符 成员名; . 结构体变量=初始数据;,例 struct int num; char name20; char sex; int age; char addr30; stu1=112,“Wang Lin”,M,18, “200 Beijing Road”;,结构体变量的初始化形式三:,结构体数组的定义 三种形式:,形式一: struct stude

14、nt int num; char name20; char sex; int age; ; struct student stu2;,形式二: struct student int num; char name20; char sex; int age; stu2;,形式三: struct int num; char name20; char sex; int age; stu2;,结构体数组,例 struct int num; char name20; char sex; int age; stu =,;,结构体数组引用,引用方式: 结构体数组名下标.成员名,结构体数组初始化,struct

15、person char name20; int count; leader3=“Li”,0,“Zhang”,0,”Wang“,0; main() int i,j; char leader_name20; for(i=1;i=10;i+) scanf(%s,leader_name); for(j=0;j3;j+) if(strcmp(leader_name,)=0) leaderj.count+; for(i=0;i3;i+) printf(%5s:%dn,,leaderi.count); ,例 统计后选人选票,指向结构体变量的指针 定义形式:st

16、ruct 结构体名 *结构体指针名; 例 struct student *p;,使用结构体指针变量引用成员形式,存放结构体变量在内存的起始地址,指向运算符 优先级: 1 结合方向:从左向右,struct student stu1; struct student *p= (*p).num=101,结构体和指针,用结构体变量的成员作参数-值传递 用指向结构体变量或数组的指针作参数-地址传递 用结构体变量作参数-多值传递,效率低,用指向结构体的指针作函数参数(看书自学),有时需要使几种不同类型的变量存放到同一段内存单元中。例如,可把一个整型变量、一个字符型变量、一个实型变量放在同一个地址开始的内存单

17、元中。以上3个变量在内存中占的字节数不同,但都从同一地址开始存放。也就是使用覆盖技术,几个变量互相覆盖。这种使几个不同的变量共占同一段内存的结构,称为“共用体”类型的结构。,构造数据类型,也叫联合体 用途:使几个不同类型的变量共占一段内存(相互覆盖) 共用体类型定义 定义形式:,union 共用体名 类型标识符 成员名; 类型标识符 成员名; . ;,例 union data int i; char ch; float f; ;,类型定义不分配内存,共用体,形式一: union data int i; char ch; float f; a,b;,形式二: union data int i;

18、char ch; float f; ; union data a,b,c,*p,d3;,形式三: union int i; char ch; float f; a,b,c;,共用体变量定义分配内存, 长度=最长成员所占字节数,共用体变量任何时刻 只有一个成员存在,共用体变量的定义,引用方式:,例 a.i=1; a.ch=a; a.f=1.5; printf(“%d”,a.i); (编译通过,运行结果不对),引用规则 不能引用共用体变量,只能引用其成员,共用体变量中起作用的成员是最后一次存放的成员,例 union int i; char ch; float f; a; a=1; (),不能在定义

19、共用体变量时初始化,例 union int i; char ch; float f; a=1,a,1.5; (),可以用一个共用体变量为另一个变量赋值,例 float x; union int i; char ch; float f; a,b; a.i=1; a.ch=a; a.f=1.5; b=a; () x=a.f; (),共用体变量引用,main() union int_char int i; char ch2; x; x.i=24887; printf(i=%on,x.i); printf(ch0=%o,ch1=%on ch0=%d,ch1=%dn, x.ch0,x.ch1,x.ch0

20、,x.ch1); ,例 将一个整数按字节输出,区别: 存储方式不同,联系: 两者可相互嵌套,结构体与共用体,结构体变量所占内存长度是各成员占的内存长度之和。每个成员分别占有其自己的内存单元。 有些C变量所占的内存长度等于最长的成员的长度。例如,上面定义的“共用体”变量a、b、c各占4个字节(因为一个实型变量占4个字节),而不是各占2+1+4=7个字节。,枚 举 类 型 枚举类型是ANSI C新标准所增加的。 如果一个变量只有几种可能的值,可以定义为枚举类型。所谓“枚举”是指将变量的值一一列举出来,变量的值只限于列举出来的值的范围内。声明枚举类型用enum开头。例如:,enum weekdays

21、un,mon,tue,wed,thu,fri,sat; 声明了一个枚举类型enum weekday,可以用此类型来定义变量。如:enumweekdayworkday,week-end; workday和week-end被定义为枚举变量,它们的值只能是sun到sat之一。例如: workday=mon; week-end=sun; 是正确的。 当然,也可以直接定义枚举变量,如:,enumsun,mon,tue,wed,thu,fri,sat workday,week-end; 其中sun、mon、sat等称为枚举元素或枚举常量。它们是用户定义的标识符。这些标识符并不自动地代表什么含义。例如,不因

22、为写成sun,就自动代表“星期天”。其实不写sun而写成sunday也可以。用什么标识符代表什么含义,完全由程序员决定,并在程序中作相应处理。 说明: (1) 在C编译中,对枚举元素按常量处理,故称枚举常量。它们不是变量,不能对它们赋值。例如:sun=0;mon=1;是错误的。,(2) 枚举元素作为常量,它们是有值的,C语言编译按定义时的顺序使它们的值为0,1,2,。 在上面定义中,sun的值为0,mon的值为1sat为6。如果有赋值语句: workday=mon; workday变量的值为1。这个整数是可以输出的。如:printf(%d,workday);将输出整数1。 也可以改变枚举元素的

23、值,在定义时由程序员指定,如:enum weekdaysun=7,mon=1,tue,wed,thu,fri,satworkday,week-end;定义sun为7,mon=1,以后顺序加1,sat为6。,(3) 枚举值可以用来做判断比较。如 if(workday=mon) if(workdaysun) 枚举值的比较规则是按其在定义时的顺序号比较。如果定义时未人为指定,则第一个枚举元素的值认作0。故mon大于sun,satfri。 (4) 一个整数不能直接赋给一个枚举变量。如: workday=2; 是不对的。它们属于不同的类型。应先进行强制类型转换才能赋值。如: workday=(enumw

24、eekday)2; 它相当于将顺序号为2的枚举元素赋给workday,相当于workday=tue; 甚至可以是表达式。如: workday=(enumweekday)(5-3);,功能:用自定义名字为已有数据类型命名 类型定义简单形式: typedef type name;,例 typedef int INTEGER;,类型定义语句关键字,已有数据类型名,用户定义的类型名,例 typedef float REAL;,类型定义后,与已有类型一样使用,例 INTEGER a,b,c; REAL f1,f2;,说明: 1.typedef 没有创造新数据类型 2.typedef 是定义类型,不能定义变量 3.typedef 与 define 不同,define typedef 预编译时处理 编译时处理 简单字符置换 为已有类型命名,用typedef定义类型,按定义变量方法先写出定义体 如 in

温馨提示

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

评论

0/150

提交评论