第10章自定义数据类型_第1页
第10章自定义数据类型_第2页
第10章自定义数据类型_第3页
第10章自定义数据类型_第4页
第10章自定义数据类型_第5页
已阅读5页,还剩100页未读 继续免费阅读

下载本文档

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

文档简介

第10章自定义数据类型盐城第10章自定义数据类型10.1自定义数据类型引入10.2结构体类型10.3共用体类型10.4枚举类型10.5类型定义符10.1自定义数据类型引入10.1.1问题与引例C语言提供了一些由系统已经定义好的基本数据类型,用户可以使用这些基本数据类型解决一般的问题,但这些同时处理的数据往往具有相同数据类型。思考:如果一组数据具有不同的数据类型,如何处理?10.1.1问题与引例【引例】建立一个学生登记表,并对学生的记录按指定的要求进行相应的处理。设在学生登记表包括:学号(整型或字符型)、姓名(字符型)、年龄(整型)、性别(字符型)、成绩(整型或实型)。要求:①建立学生登记表;②根据学号进行查找;③按成绩排序;④输出排序结果。问题分析:本例建立的学生登记表是一个经常使用的二维表,这个表格由若干行若干列构成,每一行是由不同数据类型的数据组成,显然每一行的数据不能用数组进行存储和处理,因此,需要用户定义一种新的数据类型来进行处理。10.1.1问题与引例10.1.2结构体的概念为了解决上述问题,C语言中可以采用自定义数据类型——“结构”或称为“结构体”,它相当于其它高级语言中的记录。用户自己建立由不同类型数据组成的组合型的数据结构,它称为结构体。结构体是由若干“成员”组成的,每一个成员可以是一个基本数据类型或者又是一个自定义数据类型。10.2结构体类型1.结构体类型的定义声明一个结构体类型的一般形式为:struct结构体名{

成员表列

};

由若干个成员组成,每个成员都是该结构体的一个组成部分。其形式为:类型说明符成员名;

类型说明符

成员名;10.2.1结构体类型及其变量的引用

10.2.1结构体类型及其变量的引用

1.结构体类型的定义structStudent{intnum;charname[20];charsex;floatscore;};定义了一个结构体类型structStudent,它包括num,name,sex,score等4个不同类型的成员结构体类型名和成员名遵循标识符命名规则注意:花括号后面的分号是不可少的。结构体定义之后,即可进行变量定义,凡说明为结构体student的变量都由上述4个成员组成。结构体是一种复杂的数据类型,是数目固定、类型不同的若干个有序变量或数组的集合。10.2.1结构体类型及其变量的引用

2.结构体类型变量的定义定义结构体变量有以下三种方法:(1)先定义结构体类型,再声明该类型变量例如:structstudent//结构体类型定义{intnum;charname[20];charsex;floatscore;};10.2.1结构体类型及其变量的引用

2.结构体类型变量的定义定义结构体变量有以下三种方法:(1)先定义结构体类型,再声明该类型变量结构体类型名结构体变量名

//结构体类型变量声明structStudentboy1,boy2;10.2.1结构体类型及其变量的引用

2.结构体类型变量的定义定义结构体变量有以下三种方法:(2)在定义结构体类型的同时声明结构体变量定义的一般形式为:struct结构体名{成员表列}变量名表列;例如:structstudent{intnum;charname[20];charsex;floatscore;}boy1,boy2;10.2.1结构体类型及其变量的引用

2.结构体类型变量的定义定义结构体变量有以下三种方法:(3)直接定义结构体变量定义的一般形式为:struct{成员表列}变量名表列;例如:struct{

intnum;charname[20];charsex;floatscore;}boy1,boy2;10.2.1结构体类型及其变量的引用

说明:(1)结构体类型并非只有一种,而是可以设计出许多种结构体类型,例如structTeacherstructWorkerstructDate等结构体类型各自包含不同的成员10.2.1结构体类型及其变量的引用

说明:(2)结构体成员也可以属于另一个结构体类型

structDate

{intmonth;

intday;intyear;

};

structStu

{intnum;charname[20];charsex;intage;

structDatebirthday;

charaddr[30];

};numnamesexagebirthdayaddrmonthdayyear10.2.1结构体类型及其变量的引用

3.结构体类型变量的引用在ANSIC中除了允许具有相同类型的结构变量相互赋值以外,一般对结构体变量的使用,包括赋值、输入、输出、运算等都是通过结构体变量的成员来实现的。结构体变量成员引用的一般形式:结构体变量名.成员名10.2.1结构体类型及其变量的引用

3.结构体类型变量的引用例如:boy1.num//第一个学生的学号boy2.sex//第二个学生的性别如果结构体变量成员本身又是一个结构体,则必须逐级找到最低级的成员才能使用。例如:boy1.birthday.month10.2.1结构体类型及其变量的引用

4.结构体类型变量的赋值---按成员逐个赋值结构体变量的赋值就是给各个成员赋值,可用输入语句或赋值语句来完成。//结构体成员赋值boy1.num=10001;="ZhangXin";10001ZhangXinM1990.5Shanghaiboy110.2.1结构体类型及其变量的引用

例如:把一个学生的信息(包括学号、姓名、性别、地址)放在一个结构体变量中,然后输出这个学生的信息。解题思路:自己建立一个结构体类型,包括有关学生信息的各成员用它定义结构体变量,同时赋以初值输出该结构体变量的各成员10.2.1结构体类型及其变量的引用

#include<stdio.h>voidmain(){structStudent{longintnum;charname[20];charsex;charaddr[20];}a={10101,"LiLin",’M’,"123BeijingRoad"};printf("NO.:%ld\nname:%s\nsex:%c\naddress:%s\n",

a.num,,a.sex,a.addr);}#include<stdio.h>voidmain(){structStudent{longintnum;charname[20];charsex;charaddr[20];}a={10101,"LiLin",’M’,"123BeijingRoad"};printf("NO.:%ld\nname:%s\nsex:%c\naddress:%s\n",a.num,,a.sex,a.addr);}#include<stdio.h>voidmain(){structStudent{longintnum;charname[20];charsex;charaddr[20];}a={10101,"LiLin",’M’,"123BeijingRoad"};……}a.num=10010;对printf("%s\n",a);不对#include<stdio.h>voidmain(){structStudent

{longintnum;charname[20];charsex;charaddr[20];}a={10101,”LiLin”,’M’,”123BeijingRoad”};……}b=a;对structStudentb;b.num++;对10.2.2结构体数组1.结构体数组定义数组的元素也可以是结构体类型的,因此可以构成结构体数组。结构体数组的每一个元素都是具有相同结构体类型的下标结构体变量。在实际应用中,经常用结构体数组来表示具有相同数据结构的一个群体。如:一个班级的学生档案、一个车间的职工信息等。10.2.2结构体数组1.结构体数组定义定义结构体数组的一般形式:struct结构体名{成员表列}数组名[常量表达式];1.结构体数组定义例如:structstudent{intnum;char*name;charsex;floatscore;}boy[5];定义了一个结构体数组boy,共有5个元素,boy[0]~boy[4]。每个数组元素都具有structstudent的结构体形式,对结构体数组可以进行初始化赋值。10.2.2结构体数组2.结构体数组的初始化结构体数组的初始化是在定义结构体数组时,在结构体数组的后面加上初值表列。一般形式如下:struct结构体名{成员表列}数组名[常量表达式]={初值表列};10.2.2结构体数组2.结构体数组初始化例如://定义结构体数组的同时初始化structstudent{intnum;char*name;charsex;floatscore;}boy[3]={{101,"Liping",'M',45},{102,"Zhangping",'M',62.5},{103,"Hefang",'F',92.5}};10.2.2结构体数组【例10.1】计算学生的平均成绩和不及格的人数。(1)算法分析本例先定义一个结构体数组boy,并初始化;然后将结构体数组中每一个元素的score成员的值求和,若小于60,则计数;最后求出平均成绩。10.2.2结构体数组(2)程序设计#include<stdio.h>structstudent{intnum;char*name;charsex;floatscore;}boy[5]={{101,"Liping",'M',45},{102,"Zhangping",'M',62.5},{103,"Hefang",'F',92.5},{104,"Chengling",'F',87},{105,"Wangming",'M',58}};10.2.2结构体数组主函数:voidmain(){inti,c=0;floatave,s=0;for(i=0;i<5;i++){s+=boy[i].score;//结构体数组元素的score成员求和

if(boy[i].score<60)c+=1;//score成员小于60时,计数

}ave=s/5;printf("average=%f\ncount=%d\n",ave,c);}10.2.3结构体指针1.指向结构体变量的指针当用一个指针变量来指向一个结构体变量时,这个指针变量就称之为结构体指针变量。结构体指针变量中的值是所指向的结构体变量的首地址,通过结构体指针变量即可访问该结构体变量,类似于数组指针。定义结构体指针变量定义的一般形式:

struct结构体名*结构体指针变量名10.2.3结构体指针1.指向结构体变量的指针指向结构体对象的指针变量既可以指向结构体变量,也可以用来指向结构体数组中的元素。指针变量的基类型必须与结构体变量的类型相同。例如:structStudent*pt;10.2.3结构体指针【例10.2】结构体指针变量的使用。#include<stdio.h>structstudent{intnum;char*name;charsex;floatscore;}boy1={102,"Zhangping",'M',78.5},*p;voidmain(){p=&boy1;printf("Number=%d\nName=%s\n",boy1.num,);printf("Sex=%c\nScore=%f\n\n",boy1.sex,boy1.score);printf("Number=%d\nName=%s\n",(*p).num,(*p).name);printf("Sex=%c\nScore=%f\n\n",(*p).sex,(*p).score);printf("Number=%d\nName=%s\n",p->num,p->name);printf("Sex=%c\nScore=%f\n\n",p->sex,p->score);}2.用指针访问结构体变量成员访问结构体变量成员的一般形式:(*结构体指针变量).成员名或为:结构体指针变量->成员名(更灵活高效)例如:(*p).num或者:p->num注意:(*p)两侧的括号不可少。因为成员符“.”的优先级高于“*”。10.2.3结构体指针3.指向结构体数组的指针指针变量可以指向一个结构体数组,这时结构体指针变量的值是整个结构体数组首元素的首地址。

结构体指针变量也可以指向结构体数组中的一个元素,这时结构体指针变量的值是该结构体数组元素的首地址。10.2.3结构体指针【例10.3】用指针变量输出结构体数组。#include<stdio.h>structstudent{intnum;char*name;charsex;floatscore;}boy[5]={{101,"Zhouping",'M',45},{102,"Zhangping",'M',62.5},{103,"Lioufang",'F',92.5},{104,"Chengling",'F',87},{105,"Wangming",'M',58}};boy为外部结构体数组,整个源程序有效主函数:voidmain(){structstudent*ps;

printf("No\tName\t\t\tSex\tScore\t\n");for(ps=boy;ps<boy+5;ps++)

printf("%d\t%s\t\t%c\t%f\t\n",ps->num,ps->name,ps->sex,ps->score);}ps为指向结构体student类型的指针ps指向boy数组的第一个元素,然后进行循环说明:为了使用方便和直观,C语言允许把(*p).num用p->num来代替(*p).name等价于p->name如果p指向一个结构体变量stu,以下等价:①stu.成员名(如stu.num)②(*p).成员名(如(*p).num)p->成员名(如p->num)【例10.4】用结构体指针变量作为函数的参数求一组学生的平均成绩和不及格人数。(1)解决问题的几个主要步骤①结构体类型定义;②结构体类型数组定义及初始化;③定义结构体指针变量;④数据处理;⑤输出。(2)算法分析

先定义一个结构体数组boy,并初始化;然后再定义一个指向结构体数组的指针,使用指针将结构体数组中每一个元素的score成员的值求和,若小于60,则计数;最后求出平均成绩。(3)部分程序代码//结构体类型定义,结构体数组定义并赋值structstudent{intnum;char*name;charsex;floatscore;}boy[5]={{101,"Liping",'M',45},{102,"Zhangping",'M',62.5},{103,"Hefang",'F',92.5},{104,"Chengling",'F',87},{105,"Wangming",'M',58}};(3)部分程序代码//计算平均值的函数voidaverage(structstudent*ps){intc=0,i;floatave,s=0;for(i=0;i<5;i++,ps++){s+=ps->score;if(ps->score<60)c+=1;}printf("s=%f\n",s);ave=s/5;printf("average=%f\ncount=%d\n",ave,c);}10.2.4链表由前可知:

数组在存储器中占用一段连续的存储空间,若要在数组中插入新的元素或要在数组中删除一个元素,都要移动大量数组元素。思考:有没有更好的数据结构来处理插入删除操作,且不需要移动元素呢?1.什么是链表链表是一种常见的重要的数据结构,它是动态地进行存储分配的一种结构使用链表可以方便实现元素的插入或删除链表必须利用指针变量才能实现10.2.4链表链表由若干个结点链接而成的,每个结点是一个结构体。在结点结构中第一个结点称为头结点,它存放有第一个结点的首地址。以后的每个结点都分为两个域:数据域、指针域。存放时,在第一个结点的指针域内存入第二个结点的首地址,在第二个结点的指针域内又存放第三个结点的首地址,如此下去直到最后一个结点。最后一个结点因无后继结点连接,其指针域可赋为0或NULL。这样一种连接方式,在数据结构中称为“链表”。10.2.4链表head12491249A135613561475B1475C10211021DNULL头指针各结点地址可以不连续各结点含有两个部分表尾由图看出,链表中的各元素在内存中不一定是连续存放的。链表的基本操作主要有:建立链表、结点的查找与输出、结点的插入、结点的删除等。下图是一种简单的链表结构10.2.4链表2.建立与输出静态单向链表建立简单静态链表的主要步骤:(1)定义一个结构体类型,其成员由具体问题决定。(2)将第一个结点的起始地址赋给头指针,第二个结点的起始地址赋给第一个结点的指针域,第三个结点的起始地址赋给第二个结点的指针域,……(3)将最后一个结点的指针域赋予NULL。10.2.4链表2.建立与输出静态单向链表【例10.5】

建立一个如图所示的简单链表,它由3个学生数据的结点组成,要求输出各结点中的数据。1010189.510103901010785a结点b结点c结点numscorenext10.2.4链表解题思路:1010189.510103901010785a结点b结点c结点numscorenextheadhead=&a;a.next=&b;b.next=&c;NULLc.next=NULL;10.2.4链表定义结点:#include<stdio.h> structStudent{intnum;floatscore;

structStudent*next;//结构体指针};voidmain()//主函数{structStudenta,b,c,*head,*p;a.num=10101;a.score=89.5;b.num=10103;b.score=90;c.num=10107;c.score=85;//分别初始化head=&a;a.next=&b;//结点连接b.next=&c;c.next=NULL;p=head;//p指向头结点

do{printf(”%ld%5.1f\n”,p->num,p->score);p=p->next; }while(p!=NULL);//依次输出每个结点的值}

p=head;do{printf(”%ld%5.1f\n”,p->num,p->score);p=p->next; }while(p!=NULL);}1010189.510103901010785a结点b结点c结点numscorenextheadNULLp相当于p=&b;

p=head;do{printf(”%ld%5.1f\n”,p->num,p->score);p=p->next; }while(p!=NULL);}1010189.510103901010785a结点b结点c结点numscorenextheadNULLp相当于p=&b;

p=head;do{printf(”%ld%5.1f\n”,p->num,p->score);p=p->next; }while(p!=NULL);}1010189.510103901010785a结点b结点c结点numscorenextheadNULLp相当于p=&c;

p=head;do{printf(”%ld%5.1f\n”,p->num,p->score);p=p->next; }while(p!=NULL);}1010189.510103901010785a结点b结点c结点numscorenextheadNULLp相当于p=&c;

p=head;do{printf(”%ld%5.1f\n”,p->num,p->score);p=p->next; }while(p!=NULL);}1010189.510103901010785a结点b结点c结点numscorenextheadNULLp相当于p=NULL;静态链表3.建立与输出动态单向链表

所谓建立动态链表是指在程序执行过程中从无到有地建立起一个链表,即一个一个地开辟结点和输入各结点数据,并建立起前后相链的关系。10.2.4链表3.建立与输出动态单向链表(1)处理动态链表所需要的库函数①malloc()函数;②calloc()函数;③free()函数(2)建立动态单向链表的步骤①读取数据;②生成新结点;③将数据存入结点的成员变量中;④将新结点插入到链表中,重复上述操作直至输入结束。10.2.4链表4.在链表中插入结点对链表的插入是指将一个结点插入到已有的链表之中。在单向链表中插入结点,首先要确定插入的位置。插入结点在指针p所指的结点之前称为“前插”,插入结点在指针p所指的结点之后称为“后插”。10.2.4链表4.在链表中插入结点当进行前插操作时,需要3个工作指针:s指向新开辟的结点;用p指向插入的位置;q指向要插入的前趋结点。为了能做到正确插入,必须解决两个问题:怎样找到插入的位置;怎样实现插入。具体实现过程在后续课程数据结构中进一步研究10.2.4链表5.删除链表中的结点从一个动态链表中删去一个结点,并不是真正从内存中把它抹掉,而是把它从链表中分离开来,只要撤销原来的链接关系即可。为了删除单向链表中的某个结点,首先要找到待删除的结点的前趋结点(即当前要删除结点的前面一个结点),然后将此前趋结点的指针域去指向待删除结点的后继结点(即当前要删除结点的下一个结点),最后释放被删除结点所占的存储空间即可。10.2.4链表10.3共用体类型10.3.1共用体类型定义10.3.2共用体变量的定义10.3.3共用体变量中成员的引用10.3共用体类型10.3.1共用体类型定义共用体是用同一段存储空间存放不同类型的变量。使几个不同的变量共享同一段内存的结构,称为“共用体”类型的结构。10.3.1共用体类型定义

共用体的类型及其变量的定义和与结构体类型及其变量定义的方式基本相同。

不同的是结构体中变量中的成员各自占有不同的存储空间,而共用体的变量中的所有成员占有同一段存储空间。1000100110021003字符ch整型变量i实型变量f10.3.1共用体类型定义定义共用体类型的一般形式为:union共用体名{成员表列

};例如:unionData

{inti;

charch;

floatf;

};10.3.1共用体类型定义定义共用体类型变量的一般形式为:union共用体名{成员表列

}变量表列;例如:unionData

{inti;

charch;

floatf;

}a,b,c;unionData

{inti;charch;

floatf;

};unionDataa,b,c;10.3.2共用体变量的定义“共用体”与“结构体”的定义形式相似,但它们的含义是不同的。结构体变量所占内存长度是各成员占的内存长度之和,每个成员分别占有其自己的内存单元。而共用体变量所占的内存长度等于最长的成员的长度。10.3.2共用体变量的定义共用体变量中成员的引用方式共用体变量中每个成员的引用方式与结构体变量完全相同,可以使用下列3种形式之一:(1)共用体变量名.成员名。(2)指针变量名->成员名。(3)(*指针变量名).成员名。例如,前面定义了a,b,c为共用体变量,下面的引用方式是正确的:a.ia.cha.f10.3.3共用体变量中成员的引用2.共用体类型数据的特点

同一内存段可以用来存放几种不同类型的成员,但在每一瞬时只能存放其中一个成员,而不是同时存放几个。(2)可以对共用体变量初始化,但初始化表中只能有一个常量。(3)共用体变量中起作用的成员是最后一次被赋值的成员,在对共用体变量中的一个成员赋值后,原有变量存储单元中的值就取代。10.3.3共用体变量中成员的引用(4)共用体变量的地址和它的各成员的地址都是同一地址。(5)

不能对共用体变量名赋值,也不能企图引用变量名来得到一个值。(6)以前的C规定不能把共用体变量作为函数参数,但可以使用指向共用体变量的指针作函数参数。(7)共用体类型可以出现在结构体类型定义中,也可以定义共用体数组。反之,结构体也可以出现在共用体类型定义中,数组也可以作为共用体的成员。10.3.3共用体变量中成员的引用【例10.6】分析下列程序的运行结果。#include<stdio.h>uniondata{shortd[2];charch[4];};voidmain(){inti;uniondatada;for(i=0;i<4;i++) da.ch[i]=i;for(i=0;i<2;i++) printf("%8d",da.d[i]);printf("\n");}

【例10.7】有n个结构体变量,内含学生学号、姓名和3门课程的成绩。要求输出平均成绩最高的学生的信息(包括学号、姓名、3门课程成绩和平均成绩)。算法分析:本例中教师和学生信息的前4项是相同的,只有第5项不同。现要求采用一个表格处理,故可以定义一个结构体,前4个成员表示教师和学生信息的前4项,第5项用共用体处理。#include<stdio.h>#defineN3structStudent{intnum;charname[20];

floatscore[3];floataver;};4个成员输入前3个成员值三门课程的平均成绩voidmain(){voidinput(structStudentstu[]);structStudentmax(structStudentstu[]);voidprint(structStudentstu);structStudentstu[N],*p=stu;input(p);print(max(p));}voidinput(structStudentstu[]){inti;printf("请输入各学生的信息:

学号、姓名、三门课成绩:\n");for(i=0;i<N;i++){scanf("%d%s%f%f%f",&stu[i].num,stu[i].name,&stu[i].score[0],&stu[i].score[1],&stu[i].score[2]);

stu[i].aver=(stu[i].score[0]+stu[i].score[1]+stu[i].score[2])/3.0;}}stu[0]stu[1]stu[2]stu10101Li78899888.33voidinput(structStudentstu[]){inti;printf("请输入各学生的信息:

学号、姓名、三门课成绩:\n");for(i=0;i<N;i++){scanf("%d%s%f%f%f",&stu[i].num,stu[i].name,&stu[i].score[0],&stu[i].score[1],&stu[i].score[2]);

stu[i].aver=(stu[i].score[0]+stu[i].score[1]+stu[i].score[2])/3.0;}}stu[0]stu[1]stu[2]stu10101Li78899888.3310103Wang98.5876984.83voidinput(structStudentstu[]){inti;printf("请输入各学生的信息:

学号、姓名、三门课成绩:\n");for(i=0;i<N;i++){scanf("%d%s%f%f%f",&stu[i].num,stu[i].name,&stu[i].score[0],&stu[i].score[1],&stu[i].score[2]);

stu[i].aver=(stu[i].score[0]+stu[i].score[1]+stu[i].score[2])/3.0;}}stu[0]stu[1]stu[2]stu10101Li78899888.3310103Wang98.5876984.8310106Sun8876.58984.5structStudentmax(structStudentstu[]){inti,m=0;for(i=0;i<N;i++)if(stu[i].aver>stu[m].aver)m=i;returnstu[m];}

stu[0]stu[1]stu[2]stu10101Li78899888.3310103Wang98.5876984.8310106Sun8876.58984.5最大返回voidprint(structStudentstud){printf("\n成绩最高的学生是:\n"); printf("学号:%d\n姓名:%s\n

三门课成绩:%5.1f,%5.1f,%5.1f\n

平均成绩:%6.2f\n”,stud.num,,stud.score[0],stud.score[1],stud.score[2],stud.aver);}stud10101Li78899888.3310103Wang98.5876984.8310106Sun8876.58984.5numnamescoreaverstu[0]stu[1]stu[2]以上3个函数的调用,情况各不相同:调用input函数时,实参是指针变量,形参是结构体数组,传递的是结构体元素的地址,函数无返回值。调用max函数时,实参是指针变量,形参是结构体数组,传递的是结构体元素的地址,函数的返回值是结构体类型数据。调用print函数时,实参是结构体变量,形参是结构体变量,传递的是结构体变量中各成员的值,函数无返回值。10.4枚举类型如果一个变量只有几种可能的值,则可以定义为枚举类型所谓“枚举”就是指把可能的值一一列举出来,变量的值只限于列举出来的值的范围内10.4.1枚举类型及其变量的定义1.枚举类型定义的一般形式enum

枚举名{枚举值表};在枚举值表中应列出所有可能的值,这些值也称为枚举元素。例如:enumweekday{sun,mon,tue,wed,thu,fri,sat};该枚举名为weekday,枚举元素共有7个,即一周中的七天。凡被说明为weekday类型变量的取值只能是七天中的某一天。枚举元素10.4枚举类型2.枚举类型变量的定义如同结构体和共用体一样,枚举类型的变量也可用三种不同的方式进行定义。定义枚举类型变量的一般形式:enum枚举名{枚举值表}枚举类型变量表列;然后可以用此类型来定义变量enumWeekdayworkday,weekend;10.4.1枚举类型及其变量的定义(1)enum是关键字,标识枚举类型。(2)在定义时,花括号中的枚举元素是用户自己指定的标识符。例如:enumcolor{red,yellow,blue,white,black}c1,c2;(3)枚举元素的值是一些整数。一般从第一个名字开始,各名字分别代表0、1、2、3、4,但不能enumcolor{0,1,2,3,4};。(4)可以在定义时对枚举元素初始化enumcolor{red=3,yellow,blue,white=8,black};10.4.1枚举类型及其变量的定义1.枚举类型的使用规定(1)枚举值是常量,不是变量。不能在程序中用赋值语句再对它赋值。例如:对枚举weekday的元素再作以下赋值:sun=5;mon=2;sun=mon;都是错误的。10.4.2枚举类型变量的使用(2)枚举元素本身由系统定义了一个表示序号的数值,从0开始顺序定义为0,1,2,…。如在weekday中,sun值为0,mon值为1,…,sat值为6。2.枚举类型的使用说明(1)只能把枚举值赋给枚举类型的变量,不能把元素的数值直接赋予枚举变量。如果一定要把数值赋予枚举变量,则必须用强制类型转换。(2)枚举元素不是字符常量也不是字符串常量,使用时不要加单、双引号。10.4.2枚举类型变量的使用10.5类型定义符C语言不仅提供了丰富的数据类型,而且还允许由用户自己定义类型说明符,也就是说允许由用户为数据类型取“别名”——类型定义符typedef10.5.1类型定义符的形式1.类型定义符的一般形式typedef原类型名新类型名其中原类型名中含有定义部分,新类型名一般用大写表示。例如:typedefintINTEGER;typedeffloatREAL;10.5类型定义符1.typedef定义类型的方法先按定义变量的方法写出定义体

将变量名换成新类型名(3)在最前面加typedef(4)然后可以用新类型名去定义变量

typedefintINTEGER;typedeffloatREAL;inti,j;floata,b;

与INTEGERi,j;REALa,b;

等价10.5.2typedef定义类型类型定义符的使用举例:(1)命名一个新的类型名代表复杂结构体类型:

typedefstruct{intmonth;intday;intyear;}Date;Datebirthday,*p;等价于typedefstructbirthday,*p;(2)命名一个新的类型名代表数组类型typedefintNum[100];Numa;10.5.2typedef定义类型以定义上述的数组类型为例来说明:①先按定义数组变量形式书写:inta[100];②将变量名a换成自己命名的类型名:intNum[100];

③在前面加上typedef,得到typedefintNum[100];

用来定义变量:Numa;

相当于定义了:inta[100];10.5.2typedef定义类型对字符指针类型,也是:char*p;

char*String;typedefchar*String;Stringp;10.5.2typedef定义类型2.typedef定义类型的说明(1)用typedef可以声明各种类型名,但不能用来定义变量。

(2)用typedef只是对已经存在的类型指定一个新的类型名,而没有创造新的类型。(3)用typedef声明数组类型、指针类型,结构体类型、共用体类型、枚举类型等,使得编程更方便。(4)typedef与#define表面上有相似之处10.5.2typedef定义类型2.typedef定义类型的说明(5)当不同源文件中用到同一类型数据时,常用typedef声明一些数据类型。可以把所有的typedef名称声明单独放在一个头文件中,然后在需要用到它们的文件中用#include指令把它们包含到文件中。这样编程者就不需要在各文件中自己定义typedef名称了。(6)用typedef名称有利于程序的通用与移植。10.5.2typedef定义类型10.6自定义数据类型程序设计及实例【例10.11】建立一个三个结点的动态单向链表,存放学生的数据(设学生的数据包含学号和成绩两项)。解题思路:定义3个指针变量:head,p1和p2,它们都是用来指向structStudent类型数据structstudent//定义结构体student类型{longnum;floatscore;structstudent*next;};structStudent*head,*p1,*p2;解题思路:用malloc函数开辟第一个结点,并使p1和p2指向它p1#defineLENsizeof(structstudent)p1=p2=(structStudent*)malloc(LEN);p2解题思路:读入一个学生的数据给p1所指的第一个结点p1scanf("%ld,%f",&p1->num,&p1->score);p21010189.5解题思路:读入一个学生的数据给p1所指的第一个结点使head也指向新开辟的结点headp1p2scanf("%ld,%f",&p1->num,&p1->score);1010189.5解题思路:再开辟另一个结点并使p1指向它,接着输入该结点的数据headp1p21010189

温馨提示

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

评论

0/150

提交评论