配色: 字号:
第9章用户自己建立数据类型
2022-05-20 | 阅:  转:  |  分享 
  
9第章用户自己建立数据类型定义和使用结构体变量自己建立结构体类型struct结构体名{成员表列};C语言允许用户自己建立由不同类型数据组成
的组合型的数据结构,它称为结构体(structre)。在程序中建立一个结构体类型:结构体类型的名字是由一个关键字struct和结构
体名组合而成的。结构体名由用户指定,又称“结构体标记”(structuretag)。花括号内是该结构体所包括的子项,称为结构体
的成员(member)。对各成员都应进行类型声明,即“成员表列”(memberlist)也称为“域表”(fieldlist),
每一个成员是结构体中的一个域。成员名命名规则与变量名相同。numnamesexagescoreaddr10010LiFangM1
887.5BeijingstructStudent{ intnum;//学号为整型 charname[20]; //姓名为
字符串 charsex;//性别为字符型 intage;//年龄为整型 floatscore;//成绩为实型 char
addr[30]; //地址为字符串};//注意最后有一个分号类型名成员名;自己建立结构体类型(1)结构体类型并非只有
一种,而是可以设计出许多种结构体类型,各自包含不同的成员。(2)成员可以属于另一个结构体类型。numnamesexagebirt
hdayaddrmonthdayyearstructDate//声明一个结构体类型structDate{ intmont
h;//月 intday;//日 intyear;//年};structStudent//声明一个结构体类型struct
Student{intnum;charname[20];charsex;intage;structDatebirt
hday; //成员birthday属于structDate类型charaddr[30];};定义结构体类型变量先声明结
构体类型,再定义该类型的变量 2.在声明类型的同时定义变量 3.不指定类型名而直接定义结构体类型变量structStude
nt{ intnum; charname[20]; charsex; intage; floatscore; ch
araddr[30];}student1,student2;struct结构体名{ 成员表列}变量名表列;structSt
udent{ intnum;//学号为整型 charname[20]; //姓名为字符串 charsex;//性别为字
符型 intage;//年龄为整型 floatscore;//成绩为实型 charaddr[30]; //地址为字符串
};//注意最后有一个分号structStudentstudent1,student2; | |
|结构体类型名结构体变量名struct{ 成员表列}变量名表列;sutdent1:10001ZhangXinM1990
.5Shanghaistudent2:10002WangLiF2098Beijing定义结构体类型变量(1)结构体类型与结构
体变量是不同的概念,不要混淆。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时,对类型是不分配空间的,只对变
量分配空间。(2)结构体类型中的成员名可以与程序中的变量名相同,但二者不代表同一对象。(3)对结构体变量中的成员(即“域”),
可以单独使用,它的作用与地位相当于普通变量。结构体变量的初始化和引用【例9.1】把一个学生的信息(包括学号、姓名、性别、住址)放在
一个结构体变量中,然后输出这个学生的信息。#includeintmain(){ structStudent
//声明结构体类型structStudent { longintnum; //以下4行为结构体的成员 charnam
e[20]; charsex; charaddr[20]; }a={10101,"LiLin",''M'',"123Beiji
ngRoad"}; //定义结构体变量a并初始化 printf("NO.:%ld\nname:%s\nsex:%c\naddre
ss:%s\n",a.num,a.name,a.sex,a.addr); return0;}结构体变量的初始化和引用在定义结构体
变量时可以对它的成员初始化。初始化列表是用花括号括起来的一些常量,这些常量依次赋给结构体变量中的各成员。可以引用结构体变量中成员的
值,引用方式为“.”是成员运算符,它在所有的运算符中优先级最高,因此可以把student1.num作为一个整体来看待,相当于一个变
量。不能企图通过输出结构体变量名来达到输出结构体变量所有成员的值。只能对结构体变量中的各个成员分别进行输入和输出。结构体变量名.成
员名student1.num=10010;/已定义了student1为student类型的结构体变量,则student1.num
表示student1变量中的num成员,即student1的num(学号)成员/对结构体变量初始化,不是对结构体类型初始化注意p
rintf(″%s\n″,student1); //企图用结构体变量名输出所有成员的值结构体变量的初始化和引用(3)如果成员本
身又属一个结构体类型,则要用若干个成员运算符,一级一级地找到最低的一级的成员。只能对最低级的成员进行赋值或存取以及运算。(4)对
结构体变量的成员可以像普通变量一样进行各种运算(根据其类型决定可以进行的运算)。(5)同类的结构体变量可以互相赋值。(6)可
以引用结构体变量成员的地址,也可以引用结构体变量的地址(结构体变量的地址主要用作函数参数,传递结构体变量的地址)。但不能用以下语句
整体读入结构体变量。student1.num=10010; //结构体变量student1中的成员numstudent1.birt
hday.month=6; //结构体变量student1中的成员birthday中的成员monthstudent2.score=
student1.score; //赋值运算sum=student1.score+student2.score; //加法运算st
udent1.age++;//自加运算student1=student2; //假设student1和student2已定义为同
类型的结构体变量scanf(″%d,%s,%c,%d,%f,%s\n″,&student1);scanf(″%d″,&stude
nt1.num); //输入student1.num的值printf(″%o″,&student1); //输出结构体变量stud
ent1的起始地址结构体变量的初始化和引用【例9.2】输入两个学生的学号、姓名和成绩,输出成绩较高的学生的学号、姓名和成绩。#in
cludeintmain(){ structStudent //声明结构体类型structStuden
t { intnum; charname[20]; floatscore; }student1,student2; //定
义两个结构体变量student1,student2 scanf("%d%s%f",&student1.num,student1.
name,&student1.score); //输入学生1的数据 scanf("%d%s%f",&student2.num,st
udent2.name,&student2.score); //输入学生1的数据 printf("Thehigherscore
is:\n"); if(student1.score>student2.score) printf("%d%s%6.2f
\n",student1.num,student1.name,student1.score); elseif(student1.
scorent2.name,student2.score); else { printf("%d%s%6.2f\n",student
1.num,student1.name,student1.score); printf("%d%s%6.2f\n",stu
dent2.num,student2.name,student2.score); } return0;}使用结构体数组定义结构体
数组【例9.3】有3个候选人,每个选民只能投票选一人,要求编一个统计选票的程序,先后输入被选人的名字,最后输出各人得票结果。#in
clude#includestructPerson //声明结构体类型struct
Person{ charname[20]; //候选人姓名 intcount; //候选人得票数}leader[3]={
"Li",0,"Zhang",0,"Sun",0}; //定义结构体数组并初始化intmain(){ inti,j; char
leader_name[20]; //定义字符数组 for(i=1;i<=10;i++) { scanf("%s",lead
er_name); //输入所选的候选人姓名 for(j=0;j<3;j++) if(strcmp(leader_name,lea
der[j].name)==0)leader[j].count++; } printf("\nResult:\n"); for(
i=0;i<3;i++) printf("%5s:%d\n",leader[i].name,leader[i].count); r
eturn0;}namecountLi0Zhang0Sun0定义结构体数组(1)定义结构体数组一般形式是①②先声明一个结构体
类型,然后再用此类型定义结构体数组(2)对结构体数组初始化的形式是在定义数组的后面加上:structPerson{ cha
rname[20]; intcount;}leader[3];struct结构体名{成员表列}数组名[数组长度];str
uctPerson{ charname[20]; intcount;}structPersonleader[3]; //
leader是结构体数组名结构体类型数组名[数组长度];={初值表列};structPersonleader[3]={"L
i",0,"Zhang",0,"Sun",0};结构体数组的应用举例#includestructStuden
t //声明结构体类型structStudent{ intnum; charname[20]; floatscore;};
intmain(){ structStudentstu[5]={{10101,"Zhang",78},{10103,"Wa
ng",98.5},{10106,"Li",86}, {10108,"Ling",73.5},{10110,"Sun",100}}
;//定义结构体数组并初始化 structStudenttemp; //定义结构体变量temp,用作交换时的临时变量 co
nstintn=5;//定义常变量n inti,j,k; printf("Theorderis:\n"); for(i=
0;istu[k].sco
re) //进行成绩的比较 k=j; temp=stu[k];stu[k]=stu[i];stu[i]=temp; //st
u[k]和stu[i]元素互换 } for(i=0;i].num,stu[i].name,stu[i].score); printf("\n"); return0;}【例9.4】有n
个学生的信息(包括学号、姓名、成绩),要求按照成绩的高低顺序输出各学生的信息。结构体指针结构体指针所谓结构体指针就是指向结构体变量
的指针,一个结构体变量的起始地址就是这个结构体变量的指针。如果把一个结构体变量的起始地址存放在一个指针变量中,那么,这个指针变量就
指向该结构体变量。指向结构体变量的指针【例9.5】通过指向结构体变量的指针变量输出结构体变量中成员的信息。p10101LiLi
nM89.5#include#includeintmain(){ structStu
dent //声明结构体类型structStudent { longnum; charname[20]; charsex
; floatscore; }; structStudentstu_1; //定义structStudent类型的变量st
u_1 structStudentp; //定义指向structStudent类型数据的指针变量p p=&stu_
1; //p指向stu_1 stu_1.num=10101; //对结构体变量的成员赋值 strcpy(stu_1.nam
e,"LiLin"); //用字符串复制函数给stu_1.name赋值 stu_1.sex=''M''; stu_1.score=8
9.5; printf("No.:%ld\nname:%s\nsex:%c\nscore:%5.1f\n",stu_1.num,s
tu_1.name,stu_1.sex,stu_1.score); //输出结果 printf("\nNo.:%ld\nname
:%s\nsex:%c\nscore:%5.1f\n",(p).num,(p).name,(p).sex,(p).sco
re); return0;}如果p指向一个结构体变量stu,以下3种用法等价:①stu.成员名②(p).成员名③p-
>成员名stu.num(p).nump->num(p).num也可表示为p->num指向结构体数组的指针【例9.6】有3个学生
的信息,放在结构体数组中,要求输出全部学生的信息。#includestructStudent //声明结构
体类型structStudent{ intnum; charname[20]; charsex; intage;};st
ructStudentstu[3]={{10101,"LiLin",''M'',18},{10102,"ZhangFang",
''M'',19},{10104,"WangMin",''F'',20}};//定义结构体数组并初始化intmain(){ stru
ctStudentp; //定义指向structStudent结构体变量的指针变量 printf("No.Name
sexage\n"); for(p=stu;pc%4d\n",p->num,p->name,p->sex,p->age); //输出结果 return0;}p1010
1stu[0]LiLinM18p''10102stu[1]ZhangFangM19p''''10104stu[2]WangMinF
20用结构体变量和结构体变量的指针作函数参数将一个结构体变量的值传递给另一个函数,有3个方法:(1)用结构体变量的成员作参数
。例如,用stu[1].num或stu[2].name作函数实参,将实参值传给形参。用法和用普通变量作实参是一样的,属于“值传递”
方式。应当注意实参与形参的类型保持一致。(2)用结构体变量作实参。用结构体变量作实参时,采取的也是“值传递”的方式,将结构体变量
所占的内存单元的内容全部按顺序传递给形参,形参也必须是同类型的结构体变量。在函数调用期间形参也要占用内存单元。这种传递方式在空间和
时间上开销较大,如果结构体的规模很大时,开销是很可观的。此外,由于采用值传递方式,如果在执行被调用函数期间改变了形参(也是结构体变
量)的值,该值不能返回主调函数,这往往造成使用上的不便。因此一般较少用这种方法。(3)用指向结构体变量(或数组元素)的指针作实参
,将结构体变量(或数组元素)的地址传给形参。用结构体变量和结构体变量的指针作函数参数【例9.7】有n个结构体变量,内含学生学号、
姓名和3门课程的成绩。要求输出平均成绩最高的学生的信息(包括学号、姓名、3门课程成绩和平均成绩)。#includeh>#defineN3 //学生数为3structStudent //建立结构体类型structStudent{ in
tnum; //学号 charname[20]; //姓名 floatscore[3]; //3门课成绩 floata
ver; //平均成绩};intmain(){ voidinput(structStudentstu[]); //函数声
明 structStudentmax(structStudentstu[]); //函数声明 voidprint(str
uctStudentstu); //函数声明 structStudentstu[N],p=stu; //定义结构体数组和
指针 input(p); //调用input函数 print(max(p)); //调用print函数,以max函数的返回值作为
实参 return0;}voidinput(structStudentstu[]) //定义input函数{ inti
; printf("请输入各学生的信息:学号、姓名、三门课成绩:\n"); for(i=0;i%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; //求平均成绩 }}structStudent
max(structStudentstu[]) //定义max函数{ inti,m=0; //用m存放成绩最高的学生在数
组中的序号 for(i=0;istu[m].aver)m=i; //找出平均成绩最
高的学生在数组中的序号 returnstu[m]; //返回包含该生信息的结构体元素}voidprint(structSt
udentstud) //定义print函数{ printf("\n成绩最高的学生是:\n"); printf("学号:%d\
n姓名:%s\n三门课成绩:%5.1f,%5.1f,%5.1f\n平均成绩:%6.2f\n",stud.num,stud.nam
e,stud.score[0],stud.score[1],stud.score[2],stud.aver);}用指针处理链表什
么是链表链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。链表有一个“头指针”变量,图中以head表示,它存放一
个地址,该地址指向一个元素。链表中每一个元素称为“结点”,每个结点都应包括两个部分:(1)用户需要用的实际数据;(2)下一
个结点的地址。head指向第1个元素,第1个元素又指向第2个元素……直到最后一个元素,该元素不再指向其他元素,它称为“表尾”,它的
地址部分放一个“NULL”(表示“空地址”),链表到此结束。head12491356147510211249ABCD1356147
51021NULL什么是链表可以用结构体变量建立链表。一个结构体变量包含若干成员,这些成员可以是数值类型、字符类型、数组类型,也
可以是指针类型。用指针类型成员来存放下一个结点的地址。structStudent{ intnum; floatscore;
structStudentnext; //next是指针变量,指向结构体变量};num101011010310107sc
ore89.59085next上面只是定义了一个structStudent类型,并未实际分配存储空间,只有定义了变量才分配存储单
元。注意成员num和score用来存放结点中的有用数据(用户需要用到的数据)。next是指针类型的成员,它指向structStu
dent类型数据(就是next所在的结构体类型)建立简单的静态链表【例9.8】建立一个简单链表,它由3个学生数据的结点组成,要求输
出各结点中的数据。#includestructStudent //声明结构体类型structStudent
{ intnum; floatscore; structStudentnext;};intmain(){ struct
Studenta,b,c,head,p; //定义3个结构体变量a,b,c作为链表的结点 a.num=10101;a.sc
ore=89.5; //对结点a的num和score成员赋值 b.num=10103;b.score=90; //对结点b的
num和score成员赋值 c.num=10107;c.score=85; //对结点c的num和score成员赋值 head
=&a; //将结点a的起始地址赋给头指针head a.next=&b; //将结点b的起始地址赋给a结点的next成员 b.
next=&c; //将结点c的起始地址赋给a结点的next成员 c.next=NULL; //c结点的next成员不存放其他
结点地址 p=head; //使p指向a结点 do { printf("%ld%5.1f\n",p->num,p->score
); //输出p指向的结点的数据 p=p->next; //使p指向下一结点 }while(p!=NULL); //输出完c结
点后p的值为NULL,循环终止 return0;}num101011010310107score89.59085next建立简单
的动态链表【例9.9】写一函数建立一个有3名学生数据的单向动态链表。所谓建立动态链表是指在程序执行过程中从无到有地建立起一个链表,
即一个一个地开辟结点和输入各结点数据,并建立起前后相链的关系。开辟一个新结点,并使p1、p2指向它读入一个学生数据给p1所指的结点
head=NULL,n=0当读入的p1->num不是零n=n+1真假head=p1(把p1所指的结点作为第一个结点)p2->ne
xt=p1(把p1所指的结点连接到表尾)p2=p1(p2移到表尾)再开辟一个新结点,使p1指向它读入一个学生数据给p1所指结点表尾
结点的指针变量置NULLn等于1?建立简单的动态链表【例9.9】写一函数建立一个有3名学生数据的单向动态链表。p1p1headp1
p2headp2headp21010189.5(n=1)1010390(n=2)1010390(n=2)1010189.51010
189.5p1p1p1headheadhead1010785101078510103901010189.51010390(n=2)
10103901010189.51010189.5p2p2p2建立简单的动态链表【例9.9】写一函数建立一个有3名学生数据的单向动
态链表。p1p1headhead1010785001010785NULL00101039010103901010189.51010
189.5p2p2建立简单的动态链表【例9.9】写一函数建立一个有3名学生数据的单向动态链表。#include
#include#defineLENsizeof(structStudent)structStude
nt{ longnum; floatscore; structStudentnext;};intn; //n为全局变量
,本文件模块中各函数均可使用它structStudentcreat(void)//定义函数。此函数返回一个指向链表头的指针{
structStudenthead; structStudentp1,p2; n=0; p1=p2=(struct
Student)malloc(LEN);//开辟一个新单元 scanf("%ld,%f",&p1->num,&p1->s
core); //输入第1个学生的学号和成绩 head=NULL; while(p1->num!=0) { n=n+1; if(n
==1)head=p1; elsep2->next=p1; p2=p1; p1=(structStudent)malloc
(LEN); //开辟动态存储区,把起始地址赋给p1 scanf("%ld,%f",&p1->num,&p1->score);
//输入其他学生的学号和成绩 } p2->next=NULL; return(head);}intmain(){ struct
Studentpt; pt=creat(); //函数返回链表第一个结点的地址 printf("\nnum:%ld\ns
core:%5.1f\n",pt->num,pt->score); //输出第1个结点的成员值 return0;};输出链表【例
9.10】编写一个输出链表的函数print。#include#include#defin
eLENsizeof(structStudent)structStudent //声明结构体类型structStud
ent{ longnum; floatscore; structStudentnext;};intn; //全局变量
nvoidprint(structStudenthead) //定义print函数{ structStudentp;
//在函数中定义structStudent类型的变量p printf("\nNow,These%drecordsare:
\n",n); p=head; //使p指向第1个结点 if(head!=NULL) //若不是空表 do { printf(
"%ld%5.1f\n",p->num,p->score); //输出一个结点中的学号与成绩 p=p->next; //p指向
下一个结点 }while(p!=NULL); //当p不是"空地址"}p=head,使p指向第1个结点真假输出p所指向的结点p指
向下一个结点当p指向的不是表尾p指向的不是尾结点组合【例9.7】和【例9.9】#include#includ
e#defineLENsizeof(structStudent)structStudent{ lon
gnum; floatscore; structStudentnext;};intn;structStudent
creat() //建立链表的函数{ structStudenthead; structStudentp1,p2
; n=0; p1=p2=(structStudent)malloc(LEN); scanf("%ld,%f",&p1->n
um,&p1->score); head=NULL; while(p1->num!=0) { n=n+1; if(n==1)he
ad=p1; elsep2->next=p1; p2=p1; p1=(structStudent)malloc(LEN);
scanf("%ld,%f",&p1->num,&p1->score); } p2->next=NULL; return(hea
d);}voidprint(structStudenthead) //输出链表的函数{ structStudent
p; printf("\nNow,These%drecordsare:\n",n); p=head; if(head!=NU
LL) do { printf("%ld%5.1f\n",p->num,p->score); p=p->next; }while
(p!=NULL);}intmain(){ structStudenthead; head=creat(); //调用cr
eat函数,返回第1个结点的起始地址 print(head); //调用print函数 return0;}共用体类型什么是共
用体类型使几个不同类型的变量共享同一段内存的结构,称为“共用体”类型的结构。1000地址union //没有定义共用体类型名{
inti; charch; floatf;}a,b,c;union共用体名{ 成员表列}变量表列;短整型变量i字符型变
量ch实型变量funionData{ inti; //表示不同类型的变量i,ch,f可以存放到同一段存储单元中 charch
; floatf;}a,b,c;//在声明类型同时定义变量“共用体”与“结构体”的定义形式相似。但它们的含义是不同的。结构体变
量所占内存长度是各成员占的内存长度之和。每个成员分别占有其自己的内存单元。而共用体变量所占的内存长度等于最长的成员的长度。几个成员
共用一个内存区。unionData//声明共用体类型{ inti; charch; floatf;};unionDat
aa,b,c; //用共用体类型定义变量引用共用体变量的方式只有先定义了共用体变量才能引用它,但应注意,不能引用共用体变量,而只
能引用共用体变量中的成员。a.i //引用共用体变量中的整型变量ia.ch //引用共用体变量中的字符变量cha.f //引
用共用体变量中的实型变量fprintf(″%d″,a);printf(″%d″,a.i);共用体类型数据的特点同一个内存段可以
用来存放几种不同类型的成员,但在每一瞬时只能存放其中一个成员,而不是同时存放几个。(2)可以对共用体变量初始化,但初始化表中只能
有一个常量。(3)共用体变量中起作用的成员是最后一次被赋值的成员,在对共用体变量中的一个成员赋值后,原有变量存储单元中的值就被取
代。(4)共用体变量的地址和它的各成员的地址都是同一地址。(5)不能对共用体变量名赋值,也不能企图引用变量名来得到一个值。C
99允许同类型的共用体变量互相赋值。(6)C99允许用共用体变量作为函数参数。(7)共用体类型可以出现在结构体类型定义中,也
可以定义共用体数组。反之,结构体也可以出现在共用体类型定义中,数组也可以作为共用体的成员。unionDate{ inti; c
harch; floatf;}a;a.i=97;printf(″%d″,a.i); //输出整数97printf(″%c″,
a.ch); //输出字符′a′printf(″%f″,a.f); //输出实数0.000000unionDataa={1,''
a'',1.5};a=1;//不能对共用体变量赋值,赋给谁?m=a;//企图引用共用体变量名以得到一个值赋给整型变量mb=a;
//a和b是同类型的共用体变量,合法共用体类型数据的特点【例9.10】有若干个人员的数据,其中有学生和教师。学生的数据中包括:
姓名、号码、性别、职业、班级。教师的数据包括:姓名、号码、性别、职业、职务。要求用同一个表格来处理。numnamesexjobc
lass(班)position(职务)101Lifs501102Wangmtprof循环n次读入号码、姓名、性别、职业真假读入cl
ass真假读入position输出“输入错”循环n次真假输出:号码、姓名、性别、职业、班级输出:号码、姓名、性别、职业、职务职业j
ob等于''s''?job等于''t''?job等于''s''?共用体类型数据的特点【例9.10】有若干个人员的数据,其中有学生和教师。学生的
数据中包括:姓名、号码、性别、职业、班级。教师的数据包括:姓名、号码、性别、职业、职务。要求用同一个表格来处理。#includ
estruct //声明无名结构体类型{ intnum; //成员num(编号) charname[1
0]; //成员name(姓名) charsex; //成员sex(性别) charjob; //成员job(职业) u
nion //声明无名共用体类型 { intclas; //成员clas(班级) charposition[10]; /
/成员position(职务) }category; //成员category是共用体变量}person[2]; //定义结
构体数组person,有两个元素intmain(){ inti; for(i=0;i<2;i++) { printf("ple
aseenterthedataofperson:\n"); scanf("%d%s%c%c",&person[i]
.num,person[i].name,&person[i].sex,&person[i].job); //输入前4项 if(p
erson[i].job==''s'') scanf("%d",&person[i].category.clas);//如是学生,输入
班级 elseif(person[i].job==''t'') scanf("%s",person[i].category.posi
tion);//如是教师,输入职务 else printf("Inputerror!");//如job不是''s''和''t'',显示“
输入错误” } printf("\n"); printf("No.namesexjobclass/position\n");
for(i=0;i<2;i++) { if(person[i].job==''s'')//若是学生 printf("%-6d%-10
s%-4c%-4c%-10d\n",person[i].num,person[i].name,person[i].sex,pers
on[i].job,person[i].category.clas); else//若是教师 printf("%-6d%-10s%
-4c%-4c%-10s\n",person[i].num,person[i].name,person[i].sex,perso
n[i].job,person[i].category.position); } return0;}使用枚举类型使用枚举类型en
um[枚举名]{枚举元素列表}enumWeekday{sun,mon,tue,wed,thu,fri,sat};如果一个变量只
有几种可能的值,则可以定义为枚举(enumeration)类型,所谓“枚举”就是指把可能的值一一列举出来,变量的值只限于列举出来的
值的范围内。声明枚举类型用enum开头。花括号中的sun,mon,…,sat称为枚举元素或枚举常量。也可以不声明有名字的枚举类型,
而直接定义枚举变量:C编译对枚举类型的枚举元素按常量处理,故称枚举常量。不要因为它们是标识符(有名字)而把它们看作变量,不能对它们
赋值。每一个枚举元素都代表一个整数,C语言编译按定义时的顺序默认它们的值为0,1,2,3,4,5…。也可以在定义枚举类型时显式地指
定枚举元素的数值。枚举元素可以用来作判断比较。枚举元素的比较规则是按其在初始化时指定的整数来进行比较的。enumWeekday
workday,weekend;枚举类型枚举变量enum{sun,mon,tue,wed,thu,fri,sat}workd
ay,weekend;使用枚举类型#includeintmain(){ enumColor{red,ye
llow,blue,white,black}; //声明枚举类型enumColor enumColori,j,k,pri;
//定义枚举变量i,j,k,pri intn,loop; n=0; for(i=red;i<=black;i++) //外
循环使i的值从red变到black for(j=red;j<=black;j++) //中循环使j的值从red变到black i
f(i!=j) //如果二球不同色 { for(k=red;k<=black;k++) //內循环使k的值从red变到blac
k if((k!=i)&&(k!=j)) //如果3球不同色 { n=n+1; //符合条件的次数加1 printf("
%-4d",n); //输出当前是第几个符合条件的组合 for(loop=1;loop<=3;loop++) //先后对3个球
分别处理 { switch(loop) //loop的值从1变到3 { case1:pri=i;break; //loop
的值为1时,把第1球的颜色赋给pri case2:pri=j;break; //loop的值为2时,把第2球的颜色赋给pri
case3:pri=k;break; //loop的值为3时,把第3球的颜色赋给pri default:break; } s
witch(pri)//根据球的颜色输出相应的文字 { casered:printf("%-10s","red");break
; //pri的值等于枚举常量red时输出"red" caseyellow:printf("%-10s","yellow")
;break; //pri的值等于枚举常量yellow时输出"yellow" caseblue:printf("%-10s",
"blue");break; //pri的值等于枚举常量blue时输出"blue" casewhite:printf("%-
10s","white");break; //pri的值等于枚举常量white时输出"white" caseblack:pri
ntf("%-10s","black");break; //pri的值等于枚举常量black时输出"black" default
:break; } } printf("\n"); } } printf("\ntotal:%5d\n",n); return0
;}【例9.12】口袋中有红、黄、蓝、白、黑5种颜色的球若干个。每次从口袋中先后取出3个球,问得到3种不同颜色的球的可能取法,输出
每种排列的情况。用typedef声明新类型名用typedef声明新类型名1.简单地用一个新的类型名代替原有的类型名2.命名一
个简单的类型名代替复杂的类型表示方法①命名一个新的类型名代表结构体类型 ②命名一个新的类型名代表数组类型③命名一个新的类型名
代表指针类型 ④命名一个新的类型名代表指向函数的指针类型typedefintInteger; //指定用Integer为类型名
,作用与int相同typedeffloatReal; //指定用Real为类型名,作用与float相同typedefstru
ct{ intmonth; intday; intyear;}Date; //声明了一个新类型名Date,代表结构体类型
Datebirthday; //定义结构体类型变量birthday,不要写成structDatebirthday;Da
tep;//定义结构体指针变量p,指向此结构体类型数据typedefintNum[100]; //声明Num为整型数组类型名Numa;//定义a为整型数组名,它有100个元素typedefcharString; //声明String为字符指针类型Stringp,s[10];//定义p为字符指针变量,s为字符指针数组ypedefint(Pointer)(); //声明Pointer为指向函数的指针类型,该函数返回整型值Pointerp1,p2; //p1,p2为Pointer类型的指针变量①②③④用typedef声明新类型名声明一个新的类型名的方法是:①先按定义变量的方法写出定义体(如:inti;) ②将变量名换成新类型名(例如:将i换成Count)③在最前面加typedef(例如:typedefintCount) ④然后可以用新类型名去定义变量简单地说,就是按定义变量的方式把变量名换上新类型名,并在最前面加typedef,就声明了新类型名代表原来的类型。以定义上述的数组类型为例来说明:①先按定义数组变量形式书写:inta[100] ②将变量名a换成自己命名的类型名:intNum[100]③在前面加上typedef,得到typedefintNum[100] ④用来定义变量:Numa;相当于定义了:inta[100];同样,对字符指针类型,也是:①charp; //定义变量p的方式 ②charString; //用新类型名String取代变量名p③typedefcharString; //加typedef ④Stringp; //用新类型名String定义变量,相当charp;习惯上,常把用typedef声明的类型名的第1个字母用大写表示,以便与系统提供的标准类型标识符相区别。用typedef声明新类型名(1)typedef的方法实际上是为特定的类型指定了一个同义字(synonyms)。(2)用typedef只是对已经存在的类型指定一个新的类型名,而没有创造新的类型。(3)用tyoedef声明数组类型、指针类型,结构体类型、共用体类型、枚举类型等,使得编程更加方便。(4)typedef与#define表面实质不同的。#define是在预编译时处理的,它只能作简单的字符串替换,而typedef是在编译阶段处理的,且并非简单的字符串替换。(5)当不同源文件中用到同一类型数据(尤其是像数组、指针、结构体、共用体等类型数据)时,常用typedef声明一些数据类型。可以把所有的typedef名称声明单独放在一个头文件中,然后在需要用到它们的文件中用#include指令把它们包含到文件中。这样编程者就不需要在各文件中自己定义typedef名称了。(6)使用typedef名称有利于程序的通用与移植。有时程序会依赖于硬件特性,用typedef类型就便于移植。
献花(0)
+1
(本文系太好学原创)