《第8章C语言计算机二级结构体和共用体.ppt》由会员分享,可在线阅读,更多相关《第8章C语言计算机二级结构体和共用体.ppt(49页珍藏版)》请在三一办公上搜索。
1、第8章 结构体和共用体,学习目标,掌握结构体类型、结构体变量、结构体数组的定义掌握结构体变量指针、结构体数组元素指针等基本概念掌握结构体指针的声明、初始化、赋值及引用了解共用体类型的定义、共用体变量的声明、赋值及使用了解枚举类型的定义、枚举类型变量的声明、赋值及使用理解typedef的功能,8.1 结构体,数组中各元素是属于同一个类型。若要将不同类型的数据组合成一个有机的整体,例如:姓名、年龄、性别、成绩组合为一个组合项,C用结构体来建立这种数据结构。,8.1.1 结构体类型,一个结构体类型可以由若干个被称为成员(或域)的成分组成。每个成员具有自身的名字和数据类型,同一结构中的成员名不能相同。
2、例如一个学生的信息,它包括以下5项:(1)学号:用5位数字表示,长整型;(2)姓名:用汉语拼音表示,最多20个字符;(3)性别:用M或F表示,分别表示男或女;(4)生日:如19881015,表示年月日;(5)地址:用字符数组表示,最多30个字符。,8.1.2 结构体类型的声明,一个结构体类型的一般形式为:struct 结构体名 类型名1 成员名1;类型名2 成员名2;类型名n 成员名n;,例如:struct stu long int num;/*学号*/char name20;/*姓名*/char sex;/*性别*/unsigned long birthday;/*生日*/char addr
3、30;/*地址*/;,说明:,(1)结构体声明描述了结构体的组织形式,但在编译时并不为它分配存储空间。(2)结构体的成员可以是简单变量、数组、指针、结构体或共用体等。(3)结构体不可嵌套定义,但可以嵌套使用,例如:struct date int day;char month4;int year;struct student long int num;char name20;char sex;struct date birthday;/*结构体成员是另一种结构类型,结构体在此嵌套*/char*addr;,嵌套结构体student的逻辑结构,(4)结构体声明可以在函数内部,也可以在函数外部。(5)
4、定义结构体类型时,注意不能遗漏最后的分号。,8.1.3 结构体变量,一、结构体变量的定义可以采取以下三种方法定义结构体类型变量。1在声明结构体类型的同时定义变量。例如:struct student long int num;char name20;char sex;int age;float score;s1,s2,s3;,声明结构体类型的同时定义结构体变量的一般形式为:struct 结构体名 类型名1 成员名1;类型名2 成员名2;类型名n 成员名n;变量名,变量名,变量名m;特点:定义一次结构体变量之后,在该定义之后的任何位置仍可用该结构体类型来定义其它结构体变量。,2直接定义结构类型变量
5、例如:struct long int num;char name20;char sex;int age;float score;stu1,stu2,stu3;,直接定义结构体变量的一般形式为:struct 类型名1 成员名1;类型名2 成员名2;类型名n 成员名n;变量名,变量名,变量名m;特点:由于在struct后不出现结构体名,故不便于在源程序的其他地方定义该类型的新变量。,3先声明结构体类型再定义变量名例如:struct student long int num;char name20;char sex;int age;float score;struct student stu1,st
6、u2,stu3;,一般形式为:struct 结构体名 类型名1 成员名1;类型名2 成员名2;类型名n 成员名n;struct 结构体名 变量名,变量名,变量名m;特点:在该定义之后的任何位置,不仅可用该结构体类型来定义其他结构体变量,而且可把其结构体声明部分作为文件存放起来,这样就可借助于include命令把它复制到任何源文件中,用以定义同类型的其它结构体变量。,注意:,(1)定义一定要在结构体声明之后或与结构体声明同时进行,对尚未声明的结构体类型,不能用它来定义结构体变量。(2)存储空间分配是按照其对应的各成员项的定义顺序进行的。(3)同一结构类型的每个结构体变量,存储空间的大小都相同,是
7、各成员项所占空间之和。例如:sizeof(stu1)的值为31;sizeof(struct student)的值为31;sizeof(float)的值为4。(4)结构体变量中的成员可以单独使用,地位与一般变量相同。(5)结构体变量一般不用register型。,二、结构体变量的初始化,struct student long int num;char name20;char sex;char addr20;stu1,stu2=89031,Lilin,M,123 Beijing Road;/*结构体变量stu2初始化*/,三、结构体变量的引用,形式:结构体变量名成员名#includevoid mai
8、n()struct student long int num;char name20;char sex;char addr20;stu1,stu2=89031,Lilin,M,123 Beijing Road;/*结构体变量stu2初始化*/printf(NO.:%ldnname:%snsex:%cnaddress:%sn,stu2.num,stu2.name,stu2.sex,stu2.addr);stu1=stu2;/*两个相同类型的结构体变量之间可以进行赋值操作*/printf(NO.:%ldnname:%snsex:%cnaddress:%sn,stu1.num,stu1.name,s
9、tu1.sex,stu1.addr);,注意:(1)不能将一个结构体变量作为一个整体进行输入和输出。例:scanf(%ld%s%c%s,(4)如果成员本身又属一个结构体类型,则要逐级地找到最低的一级成员。只能对最低级的成员进行存取。,8.2 结构体数组,8.2.1 结构体数组的定义,1定义结构体类型后定义结构数组。例如:struct student long int num;char name20;char sex;int age;float score;struct student stu5;,2直接定义一个结构数组。例如:struct student long int num;char n
10、ame20;char sex;int age;float score;stu5;,或 struct long int num;char name20;char sex;int age;float score;stu5;,8.2.2 结构数组的初始化,格式:struct 结构体名 结构数组名元素个数=初始数据;struct student stu3=80101,Lilin,M,18,80102,Wanglan,F,19,80103,Zhangjun,F,20;struct student stu=80101,Lilin,M,18,80102,Wanglan,F,19,80103,Zhangjun
11、,F,20;,struct student long int num;char name20;char sex;int age;stu=80101,Lilin,M,18,80102,Wanglan,F,19,80103,Zhangjun,F,20;,8.2.3 结构数组元素的引用,形式:结构体数组名下标成员名例如stu0.num=80101;strcpy(stu0.name,Lilin);,例:统计全班男女生人数及1990年以后(含1990年)出生的人数。#include string.h#include stdio.hvoid main()struct stud/*定义一个结构stud,包含
12、3个成员*/char name20;/*姓名*/char sex;/*性别*/int year;/*出身年份*/;struct stud class100;/*定义一个结构数组class*/int m_num=0,f_num=0,total90=0,class_num,i;printf(Please enter class_num:);scanf(%d,for(i=0;i=1990)total90+;/*统计90以后出生的人数*/printf(n number of boy:%d,m_num);printf(n number of girl:%d,f_num);printf(n number
13、after of 1990:%d,total90);,测试数据与运行结果:输入:Please enter class_num:3Please enter name/sex/year:Zhanglin m 1988Please enter name/sex/year:Wangpin f 1990Please enter name/sex/year:Liutao M 1989输出:Zhanglin m 1988Wangpin f 1990Liutao M 1989number of boy:2number of girl:1number after of 1990:1,8.3 结构指针,8.3.1
14、指向结构体变量的指针形式:struct 结构体名*结构指针名;例:static struct student*p;结构指针在定义时也可以初始化。例:struct student long int num;char name20;char sex;int age;float score;stu1,*p=,用指针引用结构体成员的一般形式:(*结构指针名).成员名或结构指针名-成员名设有类型、变量声明及初始化如下:struct date int day;char month4;int year;birthday,*sp=则(*sp).day、(*sp).month、sp-day、sp-month均是
15、合法。其中(*sp).day和sp-day等效(*sp).month和sp-month等效。,例:#includestdio.h#includestring.hvoid main()struct stud char*num;char name20;float score;struct stud stu1,*sp;sp=,注意:(1)*sp两侧的括号不可省,因为成员运算符“.”优先于“*”运算符,*sp.num就等价于*(sp.num)了。(2)由于运算符“-”、“.”、“()”和“”的优先级最高,其结合性相同。例如:+sp-num等价于:+(sp-num)即成员值加1。(+sp)-num:先执
16、行sp=sp+1,再执行sp-num(注意sp的值已经改变)。sp+-num或(sp+)-num:先存取sp-num,再执行 sp=sp+1。sp-num+:先存取sp-num,再使成员值加1。,8.3.2 指向结构数组的指针,#includestruct student long int num;char name20;char sex;int age;stu3=80101,Lilin,M,18,80102,Yanglan,F,19,80103,Zhangjun,F,20;void main()struct student*p;/*p是指向struct student型数据的指针变量*/pr
17、intf(nNo.tNamettsextagen);for(p=stu;pnum,p-name,p-sex,p-age);运行结果:No Name sex age 80101 Lilin M 18 80102 Yanglan 19 80103 Zhangjun 20,8.3.3 结构体变量做函数参数,1用结构体变量的成员作参数。例如,用stu1.num或stu2.name作函数实参,将实参值传给形参,“值传递”方式。2用结构体变量作实参。采用“值传递”方式,将结构体变量所占的内存单元的内容全部顺序传递给形参。,例:有一个结构体变量stu1,内含学生学号、姓名、数学和英语两门课的成绩。要求在ma
18、in函数中赋值,在函数print中将它们打印输出。#include#includestruct student long int num;char name20;float math;float eng;,void main()void print(struct student);struct student stu1;stu1.num=80601;strcpy(stu1.name,Liling);stu1.math=80.5;stu1.eng=90;print(stu1);void print(struct student stu)printf(%ldn%sn%.1fn%.1fn,stu.n
19、um,stu.name,stu.math,stu.eng);,3.结构变量(或数组)的地址作为实参传递给形参例:将上例改用指向结构体变量的指针作实参。#include#include#define FORMAT%ldn%sn%.1fn%.1fnstruct student long int num;char name20;float math;float eng;void main()struct student stu1=80601,Liling,80.5,90,*sp=实质都一样即实参为stu1的起始地址*/,void print(struct student*p)/*形参类型修改了*/p
20、rintf(FORMAT,p-num,p-name,p-math,p-eng);/*用指针变量调用各成员之值*/printf(n);,stu1,numnamematheng,sp,p,结构体指针作函数参数,8.4 结构数组应用举例,例:候选人得票的统计。设有3个候选人,要选择其中的一人当班长。从键盘上输入得票的候选人的名字,输出最终的得票结果。#includestdio.h#includestring.hstruct personchar name10;int count;leader3=Chen,0,Yang,0,Zhou,0;void main()int i,j;char name20;/
21、*存放被选中候选人的姓名*/for(i=1;i=10;i+)scanf(%s,name);for(j=0;j3;j+)if(strcmp(name,leaderj.name)=0)leaderj.count+;printf(n);for(i=0;i3;i+)printf(%-6s:%2dn,leaderi.name,leaderi.count);,8.5 共用体,共用体是一种类似于结构体的构造型数据类型,它允许不同类型和不同长度的数据共享同一块存储空间,8.5.1 共用体类型定义及初始化,一、共用体的声明一般形式:union 共用体名 类型名1 成员名1;类型名2 成员名2;类型名n 成员名n
22、;共用体的声明只规定了一种组织形式,不分配存储空间。,二、共用体变量的定义1类型声明与变量定义分开。例如:union mydata int i;char ch;float f;union mydata data1,data2;2类型声明与变量定义合在一起。例如:union mydata int i;char ch;float f;data1,data2;,3类型声明与变量定义合在一起,但缺省共用体名。例如:union int i;char ch;float f;data1,data2;,三、共用体变量的引用,一般形式:共用体变量名.成员名或(*共用体指针名).成员名或 共用体指针名-成员名,#
23、includestdio.hunion mydata int i;char ch;float f;data1,*p=,8.5.2 使用共用体变量应注意的问题,(1)参与运算或操作的是共用体变量的某个成员,不能是共用体变量整体例如:printf(%d,data1);是错误的。应写成“printf(”%d“,data1.i);”或“printf(%c,data1.ch);”等。(2)同一个内存段可以用来存放几种不同类型的成员,但在每一瞬时只能存放其中一种,而不是同时存放几种。例如:data1.i=20;data1.ch=M;data1.f=80.5;在完成以上3个赋值运算以后,只有data1.f是
24、有效的,(3)共用体变量的地址和它的各成员的地址都是同一地址(4)不能在定义共用体变量时对它初始化,也不能对共用体变量名赋值。例如,下面这些都是不对的:union int i;char ch;float f;a=2,m,6.5;/*不能初始化*/a=2;/*不能对共用体变量赋值*/(5)不能把共用体变量作为函数参数,也不能使函数带回共用体变量,但可以使用指向共用体变量的指针(与结构体变量这种用法相仿)。,8.6 枚举,8.6.1 枚举类型的概念及其定义 枚举类型的概念 列举出所有可能的取值的一种数据结构。枚举类型的定义 enum枚举名枚举元素1,枚举元素2,枚举元素n;如:enum weekd
25、aysun,mon,tue,wed,thu,fri,sat;enum weekday weekend,workday;或:enum weekdaysun,mon,tue,wed,thu,fri,satworkday;或:enum sun,mon,tue,wed,thu,fri,satworkday;,枚举类型变量的赋值和使用(1)枚举值是常量,不是变量;sun=5;mon=2;sun=mon;均是错误的。(2)枚举类型是有序数据类型;如:weekday中,sun为0,mon为1,sat为6。再如:main()enum weekday sun,mon,tue,wed,thu,fri,sata,b
26、,c;a=sun;b=mon;c=tue;printf(“%d,%d,%d”,a,b,c);运行结果为:0,1,2,(3)可改变枚举元素的值;enum weekdaysun=7,mon=1,tue,wed,thu,fri,satworkday;则 tue=2,wed=3,.Sat=6。(4)枚举元素可比较;如默认时:monsun(5)只能将枚举值赋予枚举变量,不能把元素的数值赋予枚举变量 如:a=sun;b=mon;是正确的;而 a=0;b=1;是错误的。但 a=(enum weekday)2 或 b=(enum weekday)(5-3)是正确的。(6)枚举元素不是字符串常量,使用时不要加单
27、引号或双引号。,(7)由于C编译程序将枚举量作为整型数来处理,所以在程序中任何可使用常数的地方,都可以使用枚举常量符号名。如:enum colorred,green,yellow col;switch(col)case red:printf(“redn”);break;case green:printf(“greenn”),break;case yellow:printf(“yellown”),break;default:printf(“undefinedn”);break;(8)同一作用域内,枚举常量与变量必须互不相同。,8.7 用typedef为类型定义别名,typedef可完成为类型取别名 typedef的一般形式 typedef 类型名 新类型名;如:typedef float real;real a,f;再如:typedef char*pointer;pointer p,string=“This is a example.”;甚至还可用typedef为更为复杂的结构类型、联合类型、枚举类型规定一个别名等。,如:typedef struct tnode char*word;int count;struct tnode*left;struct tnode*right;treenode;treenode p;相当于:struct tnode p;,