结构体和共用体(正式).ppt_第1页
结构体和共用体(正式).ppt_第2页
结构体和共用体(正式).ppt_第3页
结构体和共用体(正式).ppt_第4页
结构体和共用体(正式).ppt_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

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

文档简介

1,第6章 结构体与公用体,6.1 结构体概述 6.1.1 结构体的引入 为了方便处理多个数据项的数据,常常把这些关系密切但类型不同的数据项组织在一起,即“封装”起来,并为其取一个名字,在C语言中,就称其为结构体(有些高级语言称之为记录)。所以,结构体通常是由不同数据类型的数据项组成,一般也称是由不同成员组成,因此可以说:一个结构体可包含若干成员,每一个成员可具有不同的名字及数据类型。 结构体的引入为处理复杂的数据结构提供了有力的手段,也为函数间传递一组不同数据类型的数据提供了方便,特别是对于数据结构较为复杂的大型程序提供了方便。,2,6.1.2 结构体类型的定义 结构体类型和简单类型不同,简单类型是由系统预定义的,如int、float、char,直接可以使用。而结构体类型是根据需要由程序员自行定义,因此在使用之前必须先定义结构体类型。 结构体类型定义,struct 结构体名 类型标识符 成员名; 类型标识符 成员名; . ;,合法标识符 可省:无名结构体,成员类型可以是 基本型或构造型,struct是关键字, 不能省略,3,例 struct student int num; char name20; char sex; int age; float score; char addr30; ;,结构体类型定义描述结构 的组织形式,不分配内存,4,说明 (1) 定义一个结构体类型只是描述了此结构体的组织形式,在编译时并不为其分配存储空间,即仅描述此数据结构的形态或者说模型,故不能对定义的一个结构体类型进行赋值、存取或运算。 (2)结构体的成员可以是简单变量、数组、指针、结构体或公用体等。 (3)结构体类型定义可以放在函数内部,也可以放在函数外部。若放在内部,则只在函数内有效;若放在外部,则从定义点到源文件尾之间的所有函数都有效。 (4)结构体成员的名字可以同程序中的其它变量同名,二者不会相混,系统会自动识别它。,5,6.2 结构体变量 6.2.1 结构体变量的定义与初始化 1结构体变量的定义 同其它变量一样,结构体变量也必须先定义,然后才能引用。一个结构体变量的定义可以有以下三种方式: (1) 先定义类型再定义变量 其形式:,struct stud_type char name10; long num; char sex; int age; float score ; char address10; ; struct stud_type student1, student2;,6,(2) 在定义类型的同时定义变量 其形式: struct stud_type student1, student2; (3) 直接定义结构体变量 其形式: struct student1,student2;,7,说明 (1) 在定义结构体类型时,系统并不分配内存空间,仅当定义结构体变量时,系统才为被定义的每一变量分配相应的存储单元。如上面定义的结构体变量student1、student2在内存中各占31个字节(10+4+1+2+4+10=31) (2) 结构体变量的定义一定要在结构体类型定义之后或同时进行,对尚未定义的结构体类型,不能用它来定义结构体变量。 例如:对一个教师teacher的结构体类型未作定义,则下面的变量定义 struct teacher teah1 是错误的;反之亦然;对某变量birthday (也称结构体成员变量),若其类型未作定义,就写struct date_type birthday; 也是错误的。,8,2. 结构体变量的初始化 所谓结构体变量初始化,就是在定义结构体变量的同时,对其成员变量赋初值,在赋值时应注意按顺序及类型依次为每个结构体成员指定初始值。 结构体初始化的一般格式为: struct 结构体类型名 结构体变量=初始化值; 说明 (1)初始化数据之间用逗号分隔。 (2) 初始化数据的个数一般与成员的个数相同,若小于成员数,则剩余的成员将被自动初始化为0(若成员是指针,则初始化为NULL)。 (3) 初始化数据的类型要与相应成员变量的类型一致。 初始化时只能对整个结构体变量进行,不能对结构体类型中的某个成员进行初始化赋值。,9,例: struct date_type int year; int mouth; int day; ; struct stud_type char name10; long num; char sex; struct date_type birthday; float score; char address10; ; main() struct stud_type student1=“wang“,196103,m,1978,10,12,98,“Xian“; struct stud_type student2=“liu“,196105,m,1980,9,22,88,“Benjing“; ,10,6.2.2 结构体变量的引用 1. 对结构体变量成员的引用 在C语言程序中,不准许对结构变量整体进行各种运算、赋值或输入输出操作,而只能是对其成员进行此类操作。 引用结构体变量成员的一般形式: 结构体变量名.成员名 其中“.“是结构体成员运算符,其优先级别最高,结合性是自左至右。由此对结构体成员就完全可以像操作简单变量一样操作它。 如:对上例定义的结构体变量student1或student2,可作如下的赋值操作: 10= “wang“; student1.num=196103; student1.sex=m; student1.birthday.year=1978; student1.birthday.mouth=10; student1.birthday.day=12; student1.score=98;,11,2. 对结构体变量整体的引用 结构体变量和简单变量相比,除了上面所述在参加各种运算、赋值或输入输出方式上有所不同外即是由结构体变量成员完成,其它同简单变量一样,如: (1) 可以相互赋值,但注意相互赋值的两个结构体变量必须是同一个结构体类型; 如:student1=student2; (2) 可作为函数的形参、实参或函数返回值,详见下节。,12,6.2.3 结构体变量作为函数参数 结构体变量成员作函数参数 结构体变量中的所有成员都可作为函数参数 struct stud_type char name10; long num; char sex; student1; 现将结构体变量student1的三个成员分别传递给函数 func1(),func2(),func3(): func1(); func2(student1.num); func1(student1.sex);,13,若需要将成员地址传递给函数,则只需在其前加取地址符“ 其中字符数组名name代表其成员地址,故不许要写“&”。,2. 结构体变量整体作函数参数 老板本的C系统不允许用结构体变量作函数参数,只允许用指向结构体变量的指针作函数参数(第7章),传递的是结构体变量的首地址。而ANSI C取消了这一限制,规定按值传递方式。在函数调用时,系统为形参结构体变量分配存储空间,并从相应的实参结构体变量中取得各成员的值,若对形参中结构体变量各成员值进行修改,并不能修改实参结构体变量各成员的值。这里要注意,实参和形参结构体变量类型应当完全一致。,14,6.3 结构体数组 6.3.1 结构体数组的定义与初始化 1. 结构体数组的定义 在定义结构体数组时其定义方法与定义结构体变量方法类似,也有三种形式。 定义如下: struct date_type int year;int mouth;int day; ; struct stud_type char name10; long num; char sex; struct date_type birthday; float score; char address10; ; struct stud_type student3;,15,由此就定义了一个结构体数组student3,它有3个元素,每个元素都是struct stud_type类型,各占35个字节(10+4+1+(2+2+2)+4+10=35)。,16,2. 结构体数组的初始化 结构体数组在定义的同时可以初始化。其一般格式是在定义之后紧跟一个用花括号括起来的一组初始数据,为了增强可读性,最好使每一个数组元素的初始数据也用花括弧括起来,以此来区分各个数组元素。 对上所定义的结构体数组student初始化如下: stuct stud_type student2= “wang“,196103, m,1978,10,12,98, “xian“, “zhang“,196102, f,1977,1,10,87, “Beijing“;,17,说明 (1) 可以将一个结构体数组元素赋值给同一结构体类型数组中另一个元素,或赋给同一类型的变量。 如: struct stud_type student3, student1; 现在就定义了一个结构体数组student,又定义了一个结构体变量student1,则下面的赋值合法。 studentlstudent0; student0=student1; studnet1=student1; (2) 不能把结构体数组元素作为一个整体直接进行输入或输出。 如 printf (“%d“,student0);或scanf(“%d“,&student0); 只能以单个成员为对象进行输入输出,如: scanf(“%s“, ); scanf(“%ld“,student0.num); printf (“%s%ldn“, , student0.num);,18,例 统计后选人选票,struct 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); ,19,6.3.3 结构体数组作函数参数 与结构体变量一样,结构体数组作为函数参数传递也只有在C的高版本中才支持,但它们是有本质区别的,当然在定义形参与实参的结构体类型时还是必须一致,当实参为结构体数组时,其形参须定义为同类型结构的结构体数组或结构体指针 ;,20,6.4 共用体 在C语言中,允许不同数据类型使用同一存储区域,共用体就是一种同一存储区域由不同类型变量共享的数据类型。它提供种方法能在同一存储区中操作不同类型的数据,也就是说共用体采用的是覆盖存储技术,准许不同类型数据互相覆盖。 6.4.1 共用体类型定义 共用体类型的定义与结构体类似,其一般定义格式如下: union 共用体名 共用体成员表; ; 其中union是关键字,称为共用体定义标识符,共用体名同样由程序员来命名。大括号中的共用体成员表包含若干成员,每一个成员都具有如下的形式: 数据类型标识符 成员名;,21,如: union data int i; char ch; float f; ;,6.4.2 共用体变量定义与引用 1.共用体变量的定义 union 共用体名 共用体成员表; 变量列表; 如: union data int i; char ch; float f; a,b,c;,22,2. 共用体变量的引用 (例6.5 p133) 共用体变量名.成员名; 如上例所示:a.i; a.ch; a.f 说明: (1)共用体变量不能同时存放多个成员的值,而只能存放其中一个值,即只能存放当前(最新)的一个成员的值; (2)就共用体变量整体而言,和结构体变量一样是不能进行整体的输入、输出,但可以在两个同一类型的共用体变量之间赋值; (3)由于共用体变量不能同时存放多个成员的值,因此共用体变量不能进行初始化。,23,例6.5共用体变量的引用 main() union int_char int i; char ch2; x; x.i=24897; printf(“i=%dn i=%0 n”,x.i,x.i); printf(“ch0=%0,ch1=%0 n ch0=%c,ch1=%c n”, x.ch0,x.ch1,x.ch0,x.ch1); ,24,结构体与共用体 区别: 存储方式不同,联系: 两者可相互嵌套,25,6.5 枚举类型 在实际应用中,有些变量的取值范围是有限的,仅可能只有几个值,如一个星期7天,一年12个月,一副扑克有4种花色,每一花色有13张牌等等。此时用整型数来表示这些变量的取值,其直观性很差,如在程序中使用1,对于非编称者来说,它是代表星期一呢?还是一月份?很难区分。若在程序中使用“Mon”,则不会有人认为是代表一月份。由此看出,为提高程序的可读性,引入非数值量,即一些有意义的符号是非常必要的。 对于这种应用,C语言引入枚举类型,所谓“枚举”,就是将变量可取的值一一列举出来。,26,对枚举类型也要先定义其类型,再定义其变量。 枚举类型定义的一般形式是: enum 枚举名 枚举值列表; ; 其中enum是关键字,称为枚举类型定义标识符,枚举名由程序员命名。,27,标识符也是由程序员自定义,都是一些描述性标识符,要求不能重名,这些标识符分别代表不同枚举元素,通常称为枚举常量。 如: enum weekday sun, mon, tue, wed, thu, fri, sat ; 由此定义了一个枚举类型enum weekday,它有7个枚举元素(常量)。 在定义了类型之后,就可以用该类型来定义变量: 如: enum weekday workday;,28,说明 (1) 在C语言中,每一个枚举常量的值取决于在说明时排列的先后次序,第一个枚举常量的序号为0(规定序号从0编起),因此,此枚举常量值为0,以后顺序加1,故不允许对枚举常量进行赋值操作。若想改变枚举常量的值,在枚举变量定义时可由程序员指定, 如:enum fruit apple=7,pear,orange=3,lemon,peach t; 此时apple的值为7,pear的值为8,orange的值为3,lemon, peach的值分别为4,5。,29,(2) 一个枚举变量的值只能是这几个枚举常量之一,可以将枚举常量赋给一个枚举变量,但不能将一个整数赋给它。如: workday=sun; 正确 workday=7; 错误 (3)若想将整数值赋给枚举变量须作强制类型转换。 如: workday=(enum weekday)2; 相当于workday=tue; 此时,转换后的值亦应在枚举范围内。,30,6.6 用typedef定义类型 功能:用自定义名字为已有数据类型命名 类型定义简单形式: 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 预编译时处理 编译时处理 简单字符置换 为已有类型命名,31,typedef定义类型步骤 按定义变量方法先写出定义体 如 int i; 将变量名换成新类型名 如 int INTEGER; 最前面加typedef 如 typedef int INTEGER; 用新类型名定义变量 如 INTEGER i,j;,例 定义数组类型 int a100; int ARRAY100; typedef int ARRAY100; ARRAY a,b,c;, int a100,b100,c100;,例 定义结构体类型 struct date int month; int day; int year; d;,例 定义结构体类型 struct date int month; int day; int year; DATE;,例 定义结构体类型 typedef struct date int month; int day; int year; DATE;,32,说明: (1) 定义的新类型名一般使用大写字母,以便与系统的标准类型标识符相区别。 (2) 仅给已有的类型名重新命名,并不产生新的数据类型,原有的数据类型也没有被取代,即只是此类型的一个“别名”。如typedef int INTEGER;,只是给int 起了一个新的名字而已,int仍可用。 (3) 定义一个新的数据类型名,并没有定义变量,因而谈不上分配存储单元。 (4) typedef与#define有相似之处,如typedef int INTEGER; #defint INTEGER int;作用都是用INTEGER 代替int,但二者有本质的区别,前者是为int 定义了一个别名,而后者是宏代换。,33,第九章 编译预处理,作用:对源程序编译之前做一些处理,生成扩展C源程序 种类 宏定义 #define 文件包含 #include 条件编译 #if-#else-#endif等 格式: “#”开头 占单独书写行 语句尾不加分号,34,如 if(x=YES) printf(“correct!n”); else if (x=NO) printf(“error!n”); 展开后: if(x=1) printf(“correct!n”); else if (x=0) printf(“error!n”);,9.1 宏定义 不带参数宏定义 一般形式: #define 宏名 宏体 功能:用指定标识符(宏名)代替字符序列(宏体),宏展开:预编译时,用宏体替换宏名-不作语法检查,如 #define YES 1 #define NO 0 #define PI 3.1415926 #define OUT printf(“Hello,World”);,宏体可缺省,表示宏名 定义过或取消

温馨提示

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

评论

0/150

提交评论