版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1
C语言程序设计任务式教程(微课版)
VisualC++模块6组合数据类型任务1结构体任务2共用体任务3枚举3计算机工程学院模块6组合数据类型任务1结构体学习目标掌握结构体类型的说明、结构体变量的定义及初始化方法、掌握结构体变量成员的引用、结构体数组的使用、领会存储动态分配和释放。4计算机工程学院6.1.1案例讲解案例1学生信息的描述1.问题描述
假定一个学生的信息包括学号,姓名,成绩,在数据处理中,我们通常把一个学生信息作为整体,编程构造一个学生信息类型,并实现其输入,输出。2.编程分析
(1)C语言中的结构体类型可以将不同类型的信息组织成一个整体,构造出一种新的类型,这里我们可以构造学生类型,学生是我们处理信息的基本单位。5计算机工程学院
(2)新构造的类型没有对应的输入,输出格式控制符,需要把学生类型包含的各个成员分别输出,可以定义函数来实现学生信息的输入和输出。3.编写源程序#include<stdio.h>structstudent{ intnumber; charname[10]; floatscore;};6计算机工程学院voidprintStu(structstudent*p);
structstudentinputStu();voidmain(){
structstudentstu1;
printf("请输入一个学生的信息(学号姓名成绩)\n");
stu1=inputStu();
printf("结构体变量中的内容是:\n");
printStu(&stu1);}voidprintStu(structstudent*p)7计算机工程学院{printf("%d%s%f\n",p->number,p->name,p->score);}structstudentinputStu(){ structstudentstu;scanf("%d%s%f",&stu.number,,&stu.score); returnstu;
}8计算机工程学院4.程序运行结果图6-1案例1运行结果9计算机工程学院5.归纳分析
(1)结构体类型定义在函数外面,它的使用范围是全局的,以便所有的函数都可以使用。(2)stu1是结构体变量,它的类型是structstudent,stu1包含3个成员:学号,姓名,成绩,变量占用的存储空间大小sizeof(stu1)=sizeof(number)+sizeof(name)+sizeof(score),若要表示这个学生的成绩是90分,可以写成:stu1.score=90,“.”在这里是一个运算符。
10计算机工程学院(3)程序中还用到了结构体指针:structstudent*p,并且这个指针作为函数的参数,根据参数的传递,p=&stu1,使用指针操作结构体变量中的成员有两种写法:p->score或(*p).score,它们的值与stu1.score相等。11计算机工程学院案例2职工信息的查询1.问题描述有6个职工的信息,其中每个职工信息包括编号、姓名、工资,请找到工资最高的职工并输出其信息。2.编程分析
(1)把编号,姓名,工资组合成一个整体,作为新的数据类型,用这个类型定义长度为6的数组,再利用数组中查找最大值的算法来解决问题。12计算机工程学院
(2)伪代码如下:定义结构体:职工
voidmain(){定义结构体数组用于保存6个职工信息;定义变量i用于控制循环次数;定义变量k记录工资最高的职工;循环输入6个职工的信息;设k的初值为0(从第0位职工开始找);循环变量i=1;循环比较大小:13计算机工程学院
{如果第i个职工的工资>第k个职工的工资
k=i;
}输出第k个(即工资最高的)职工的信息;
}3.编写源程序#include<stdio.h>
structworker{intnumber;
14计算机工程学院charname[20];floatpay;};voidmain(){
structworkerw[6];inti,k;printf("输入6个员工信息\n");printf("编号姓名工资\n");for(i=0;i<6;i++){15计算机工程学院scanf("%d%s%f",&w[i].number,w[i].name,&w[i].pay);}k=0;i=1;while(i<6)
{
if(w[i].pay>w[k].pay)k=i;i++;
}
printf("工资最高的人员信息是:\n");
printf("%d\t%s\t%f\n",w[k].number,w[k].name,w[k].pay);}16计算机工程学院4.程序运行结果图6-2案例2运行结果17计算机工程学院5.归纳分析结构体类型的名称是structworker,用结构体类型来定义结构体变量或结构体数组。w是长度为6的数组,存放6个员工的信息,那么第一个员工就是w[0],第六个员工就是w[5],第一个员工的工资表示为:w[0].pay,第一个员工的姓名是:w[0].name;输入或输出第i个员工的信息时不能对w[i]整体进行操作,用格式控制符%d对应w[i].number,%s对应w[i].name,%f对应w[i].pay,因为number是int型的,name是字符串,pay是float型数据。18计算机工程学院查找最大值时第k个员工就是工资最高的人员,如果有人的工资比第k个员工还高,那么更新最高纪录k,这使得k始终是工资高的员工的下标。19计算机工程学院6.1.2基础理论
在前面学习的各种数据类型包括数组在内,都只能存放同类型的数据。而在日常的数据处理中,我们经常需要将若干不同类型的数据组合起来,作为一个整体进行处理。例如一个学生的数据信息有:学号、姓名、性别、成绩、家庭住址等,这些信息分别具有整型、字符型、实型等不同的类型。20计算机工程学院
C语言提供的结构体(structure)或称之为“结构”类型,就可将这些不同类型的信息组织成一个整体。
“结构体”是由若干“成员”(数据信息)组成的一种构造类型。每一个成员可以是一个基本数据类型或者又是一个构造类型,结构体就是一种“构造”而成的数据类型。21计算机工程学院1.结构体类型的定义结构体类型定义的一般形式:
struct<结构体名>{<成员表列>};其中struct是定义结构体类型的关键字,<结构体名>由用户根据标识符的命名规则进行命名,成员表列由结构体中各个成员组成。例如:22计算机工程学院
structstudent{longnum;/*学生的学号*/charname[20];/*学生的名字*/charsex;/*性别*/floatscore;/*成绩*/};在这个结构体定义中,结构体名为student,该结构体由4个成员组成。第一个成员num为整型变量;第二个成员name为字符数组;第三个成员sex为字符变量;第四个成员score为实型变量。这四个成员组成的成员表列就是结构体structstudent的成员信息。23计算机工程学院定义结构体时的注意事项:
(1)结构体名字符合标识符的规则,尽量取有实际意义的标识符。(2)注意大括号外的分号,不能少。(3)结构体成员可以是任何的基本数据类型变量,也可以是数组、指针类型的变量,还允许是其它类型的结构体变量。例如:24计算机工程学院structdata{intyear;/*年*/intmonth;/*月*/intday;/*日*/};structstudent{longnum;/*学生的学号*/charname[20];/*学生的名字*/charsex;/*性别*/
structdatabirthday;floatscore;/*成绩*/};25计算机工程学院
在structstudent这个结构体中又包含了birthday这个结构体变量,形成了结构体的嵌套定义形式。2.结构体变量的说明和其它类型的变量一样,结构体类型的变量也须先说明。结构体变量的说明有四种方法:
(1)先定义结构体类型,再说明结构体变量。一般形式为:
struct结构体名变量名表列;例如:26计算机工程学院
structstudent/*定义结构体类型*/{longnum;
charname[20];
charsex;
floatscore;};
structstudentstudent1,student2;/*说明结构体变量*/在本例中说明了两个structstudent类型的结构体变量student1,student2。变量名之间用逗号隔开。注意在定义结构体时,系统没有为其分配内存空间,只有在进行具体的变量说明时才为变27计算机工程学院
量分配内存空间。即在本例中系统不为结构体structstudent分配内存空间,只为变量student1和student2分配空间。如图6-3所示:
student1:
student2:图6-3结构体变量
(2)在定义结构体的同时说明结构体变量。一般形式为:2003001LiPingM91.52003001ZhaoQiangF89.028计算机工程学院
struct结构体名{成员表列}变量名表列;
例如:structstudent{longnum;
charname[20];
charsex;
floatscore;}student1,student2;29计算机工程学院(3)利用无名结构说明结构体变量。一般形式为:
struct{
成员表列;}变量名表列;例如:struct{longnum;charname[20];charsex;floatscore;}student1,student2;30计算机工程学院这种方法同样说明了两个结构体变量student1和student2,但在程序的其他地方(例如在函数内部)不可以使用这种结构体来说明其它的变量,因此这种方法使用的比较少。
(4)利用重命名类型(typedef)说明结构体在C语言中允许用户自己定义类型说明符,即利用类型定义符typedef为数据类型取“别名”。一般形式为:
typedef已定义的类型标识符新标识符;作用:利用新标识符代替原来已定义的类型标识符。31计算机工程学院例如:typedefintINTEGER;
typedeffloatREAL;分别用INTEGER和REAL代替系统中已存在的int和float类型,就可以利用它们说明新的变量。例如:INTEGERa,b;
REALc,d;下面利用typedef说明结构体,例如:32计算机工程学院先定义新类型名:typedefstruct{
longnum;
charname[20];
charsex;
floatscore;}STUD;说明新的结构体变量:STUDstudent1,student2;关于typedef需要注意的是它不是创建新的类型,只是为标识符取一个别名,使以后的使用更加灵活方便。33计算机工程学院3.结构体的引用与初始化结构体被说明后就可以在程序中引用它,对结构体变量的使用是通过对其成员的引用来实现的。引用结构体变量的常用方式是利用“.”(成员分量)运算符,一般形式为:
<结构体变量名>.<成员名>例如下列语句:student1.num=2003001;strcpy(,"LiPing");/*不能用="LiPing";*/student1.sex=’M’;student1.score=91.5;34计算机工程学院通过成员的引用,完成了对结构体变量student1的赋值。如果结构体成员又是一个结构体,需要利用若干个“.”,一级一级地找到最低层的成员,对其进行操作。例如:
student1.birthday.year=2003;结构体变量和其它变量一样,可以在定义的时候给它赋初始值,即初始化。和前面四种形式对应它们的初始化情况如下:
第一种形式的初始化:35计算机工程学院structstudent{longnum;charname[20];charsex;floatscore;};structstudentstudent1={2003001,"LiPing",’M’,91.5};第二种形式的初始化:
structstudent{longnum;36计算机工程学院charname[20];
charsex;
floatscore;}student1={2003001,"LiPing",’M’,91.5};第三种形式的初始化:struct{longnum;
charname[20];
charsex;
floatscore;}student1={2003001,"LiPing",’M’,91.5};37计算机工程学院第四种形式的初始化:typedefstruct{longnum;
charname[20];
charsex;
floatscore;}STUD;STUDstudent1={2003001,"LiPing",’M’,91.5};
38计算机工程学院4.结构体数组在前面的学习中知道相同的数据类型可以存放在一个数组中,同样多个属于同一类型结构体的数据信息也可以存放在同一个数组中,构成结构体数组。例如,利用以前定义的结构体类型说明结构体数组:
structstudentstu[3];在本例中定义了一个数组stu,由3个struct
student类型的数组元素组成。对于结构体数组的初始化和以前的结构体及数组的初始化的方法类似,结构体数组初始化的基本形式为:39计算机工程学院定义的结构体数组={初值表列};例如:structstudentstu[3]={{2003001,"Liguohua",’M’,89.5},{2003002,"Zhangpiang",’F’,90},{2003003,"Liujun",’M’,87}};当对全部元素作初始化赋值时,也可不给出数组长度。40计算机工程学院
5.结构体指针在前面学习了不同用途的指针,如指向数组的指针、指向指针数组的指针和指向函数的指针等,对于结构体数据同样也可以使用指针。把这种指向结构体的指针称为结构体指针。结构体指针和前面学习的指针在特性上完全相象,指针变量也可以指向结构体数组。指针变量的值是结构体变量的起始地址。指向结构体变量的指针的一般形式: <结构体类型名>*<指针变量名>;(1)指向结构体变量的指针(2)指向结构体数组的指针(3)结构体指针作为函数参数
定义指向结构体变量的指针
typedefstructstudent{charname[20];intage;ints1,s2;}SD;
SDx,stu,*p;
p=&stu;成员的引用格式(1)结构体变量名.成员名stu.name例:scanf(“%s”,);scanf(“%d”,&x.age);x.s1=89;x.s2=78;gets(stu.name);(*p).age=21;scanf(“%d”,&p->s1);p->s2=90;(2)(*指针变量名).成员名(*p).age(3)指针变量名->成员名p->s1赋值语句p=&student;
指针变量p指向结构体变量student引用结构体中的成员变量:
(*p).成员名
或
p->成员名相当于student.成员名pstudent对结构体数组及其元素可以用指针来指向例如:
structstruct_name{charname[10];intnum;floatscore;};/*定义结构体类型标识符*/structstruct_namestd[30],*p;指向结构体数组的指针900390赵明879002王建899001李红结构体数组stdstd[0]std[1]std[2]p赋值语句p=std;/*p指向一个结构体数组std*//*指针变量p存放的是数组std的首地址*/引用:p->name;p->num;p->score;赵明909003879002王建899001李红结构体数组stdstd[0]std[1]std[2]思考:赋值语句p=std+1;和p++;
分别代表指针p指向哪里?p->name;p->num;p->score;代表的信息发生了什么变化?pp#include<stdio.h>structstudent{intnum;charname[20];charsex;intage;};/*指向结构体类型的数组的初始化*/structstudentstu[3]={{10101,"LiLin",'M',18},{10102,"ZhangFun",'M',19},{10104,"WangMin",'F',20}};voidmain(){structstudent*p;/*指向结构体类型的指针变量*/printf("NO\tName\t\t\tSex\tAge\n");for(p=stu;p<stu+3;p++)/*循环地址*/{printf("%5d\t%-20s%4c%8d\n",p->num,p->name,p->sex,p->age);//printf("%5d\t%-20s%4c%8d\n",(*p).num,(*p).name,(*p).sex,(*p).age);}}48计算机工程学院
6.动态空间管理*C语言为用户提供了一些内存管理函数,这些内存管理函数可以按需要动态地分配内存空间,
也可把不再使用的空间回收待用,为有效地利用内存资源提供了手段。常用的内存管理函数有以下两个:
(1)分配内存空间函数malloc
函数原型:void*malloc(unsignedintsize);作用:在内存的动态存储区中分配一块长度为size个字节的连续区域。函数的返回值为该区域的起始地址的指针。若分配不成功返回NULL。49计算机工程学院
调用形式:(<类型说明符>*)malloc(size)
<类型说明符>表示把该区域用于存放何种类型的数据,(<类型说明符>*)表示把返回值强制转换为该类型的指针。例如:#defineLENsizeof(structstudent)structstudent*p;p=(structstudent*)malloc(LEN);表示分配29个字节(structstudent类型的大小)的内存空间,并把函数的返回值强制转换为structstudent类型的指针后赋予指针变量p。50计算机工程学院(2)释放内存空间函数free函数原型:voidfree(void*block);作用:释放block所指向的一块内存空间,block是一个任意类型的指针变量,它指向被释放区域的首地址。被释放区应是由malloc函数所分配的区域。调用形式:
free(p);
/*p是指向被释放区域的指针*/注意使用这两个函数需要引用两个头文件“stdio.h”和“alloc.h”。51计算机工程学院6.1.3技能训练
【实验6.1.1】有一个结构体变量student,包含学号和3门课的成绩。要求编写一个输入函数进行赋值,并编写一个输出函数进行输出操作。【指导】
(1)编程分析
●结构体中的3个成绩可以定义成数组
●整个程序需要3个函数:输入函数,输出函数,主函数
●注意函数的参数是结构体变量52计算机工程学院(2)示例程序#include“stdio.h”typedefstructstudent{intnum;floatscore[3];}STUDENT;STUDENTindata(){STUDENTstu;scanf(“%d”,&stu.num);scanf(“%f%f%f”,&stu.score[0],&stu.score[1],&stu.score[2]);return(stu);}53计算机工程学院voidprint(STUDENTstud){printf(“学号=%d\n”,stud.num);printf(“成绩1=%f\n”,stud.score[0]);printf(“成绩2=%f\n”,stud.score[1]);printf(“成绩3=%f\n”,stud.score[2]);}voidmain(){STUDENTstud;printf(“请输入学号和3门成绩\n”);stud=indata();printf(“这个学生的信息是:\n”);”’print(stud);}54计算机工程学院(3)程序的执行结果如图6-4所示。图6-4运行结果
在此例中使用了结构体函数和使用结构体变量在函数间传递数据。在主函数中说明了结构体55计算机工程学院变量stud并通过调用结构体函数indata()进行赋值,并将stud作为函数实参调用print()函数输出数据。【实验6.1.2】根据学生的学号查找学生的信息(要求利用函数实现)。【指导】(1)编程分析
●先定义结构体数组,初始化n个学生的信息。
●输入学生的学号,输出查找到的结果在主函数中实现56计算机工程学院
●因此需定义查找函数,函数的参数是学号和数组,函数的返回值是找到的学生信息的地址。(2)示例程序#include"stdio.h"structstudent{longnum;charname[20];charsex;floatscore;
};57计算机工程学院
structstudentstud[]={{2003101,"Wangling",’M’,94},{2003102,"Liping",’F’,87},{2003103,"Zhengjiujuan",’F’,93},{0,"\0",’\0’,0}};structstudent*find(structstudent*p,longnumber);voidmain(){structstudent*p;longnumber;charch;do{58计算机工程学院printf("\n请输入学号:");scanf("%ld",&number);p=find(stud,number);if(p!=0){printf("学号姓名性别成绩:\n");printf("%-10ld%-16s%c%8.1f\n",p->num,p->name,p->sex,p->score);}elseprintf(“没有找到\n”);printf("\n请输入'Y'or'y'继续查找:");ch=getchar();59计算机工程学院}while(ch==’Y’||ch==’y’);}structstudent*find(structstudent*p,longnumber){while(p->num!=number&&p->num!=0) p++;if(p->num!=0)returnp;elsereturn0;}60计算机工程学院(3)程序的执行结果如图6-5所示。图6-5运行结果61计算机工程学院在此程序中,利用结构体类型的指针p指向structstudent类型数组stud[]的首地址,在调用find()函数时,必须使用结构体数组stud[]的起始地址stud作为实参,传给形参p,p指向stud(如图所示)。在find函数中利用p对其进行操作,查找到后,返回p。
62计算机工程学院
【实验6.1.3】计算学生的平均成绩和不及格的人数。【指导】
(1)编程分析●首先需定义学生类型的结构体,并定义结构体数组,保存学生的成绩信息。●假定数组的长度为N,则用for语句循环N次,累加出学生的总成绩,最后除以N得到平均成绩。●累加的同时判断这个成绩是否小于60,小则不及格人数加一。63计算机工程学院(2)伪代码定义结构体structstudent定义结构体数组并初始化数据voidmain(){定义变量:用于保存循环控制变量,不及格人数,总分,平均分循环:{累加求和
if(成绩<60)不及格人数++}输出结果}64计算机工程学院(3)示例程序
#include<stdio.h>structstudent{longnum;charname[20];charsex;floatscore;}stu[5]={{2003101,"Liping",’M’,45},{2003102,"Zhangping",’M’,62.5},{2003103,"Hefang",’F’,92.5},{2003104,"Chengling",’F’,87},{2003105,"Wangming",’M’,58},};65计算机工程学院voidmain(){inti,c=0;floatave,sum=0;for(i=0;i<5;i++){sum+=stu[i].score;if(stu[i].score<60)c+=1;}ave=sum/5;printf("平均成绩=%f\n不及格人数=%d\n",ave,c);}66计算机工程学院本例程序中定义了一个外部结构体数组stu,共5个元素,并作了初始化赋值。在main函数中用for语句逐个累加各元素的score,成员的和值存于sum之中,如score的值小于60(不及格)即计数器C加1,循环完毕后计算平均成绩,并输出平均分及不及格人数。(4)运行情况如下67计算机工程学院图6-6运行结果68计算机工程学院6.1.4拓展与练习1.定义一个结构体类型,成员包括:姓名、电子信箱和QQ号码。编写input函数输入5个成员的记录,并编写一个函数print打印输出这些数据.2.编写程序,由键盘输入某商场的各商品的商品名、价格、销售量,计算各商品的销售额,并输出销售额前10名的商品信息。3.a和b是按学号升序有序的结构体数组,结构体类型包括学号和成绩两个成员,把这两个数组合并成一个按学号升序有序的数组c。69计算机工程学院6.1.5编程规范与常见错误1.不能将结构变量作为一个整体进行输入和输出。例如:
printf("Number=%ld\nName=%s\nSex=%c\nScore=%.2f\n",student);是错误的,应该是:printf("Number=%ld\nName=%s\nSex=%c\nScore=%.2f\n",student.number,,student.sex,student.score);70计算机工程学院2.成员可以是任意类型,如果成员本身又属于一个结构体类型,要一级一级地找到最低一级的成员如:student结构体变量s1,访问学生的生日:s1.birthday.month,不能使用s1.birthday,因为birthday本身是一个结构体。结构体是一个类型,而不是变量,定义变量时关键字struct不能省略,如定义一个学生:structstudents1,通常用typedefstructstudentSTU,这时可以用STU来定义变量,如STUs1;71计算机工程学院任务2共用体学习目标
掌握共用体类型的说明、共用体变量的定义及初始化方法、掌握共用体变量成员的引用。72计算机工程学院6.2.1案例讲解1.问题描述:有一个unsignedlong型整数,分别将前2个字节和后2个字节作为两个unsignedshort型输出。2.编程分析
unsignedlong类型占用4个字节,取其中的两个字节需要定义unsignedshort型变量。
方法一:定义unsignedshort型指针p,则*p和*(p+1)是前2个字节和后2个字节。
方法二:定义两个unsignedshort变量,并与unsignedlong变量使用同一个地址空间,即定义共用体。73计算机工程学院3.编写源程序
#include<stdio.h>uniondata{unsignedlongul;unsignedshortua[2];};voidmain(){uniondataw;unsignedshorthighbyte,lowbyte;w.ul=0x12345678;highbyte=w.ua[1];lowbyte=w.ua[0];printf("整型变量的值是%lx\n",w.ul);printf("前两个字节是%x,后两个字节是%x\n",highbyte,lowbyte);}74计算机工程学院4.程序运行结果图6-7运行结果75计算机工程学院5.归纳分析
(1)程序中&u1和ua是相等的,u1和ua共用同一块存储空间,即sizeof(w)=4。(2)公用体与结构体的使用形式类似,但含义不同,如果把w定义成structdata,则sizeof(w)=4+2+2=8,它可以存储一个长整型数据“和”两个整型数据,现在w是uniondata,它可以存储一个长整型数据“或”两个整型数据,两者选一,因为它们共用一个存储空间。(3)printf语句中%lx是以16进制输出长整型。可以看到长整型中的高16位0x1234放在高的地址空间了,低16位放在低的地址空间里。76计算机工程学院6.2.2基础理论1.共用体类型的定义
有时需要使不同的数据使用共同的存储区域,在C语言中利用共用体类型(又称联合体)来实现。共用体也是一种构造数据类型,它的类型定义、变量说明和引用在形式上类似于结构体,二者本质区别是存储方式的不同。共用体的定义的一般形式:
union〈共用体名〉{
〈成员列表〉}变量列表;77计算机工程学院
例如,定义把一个整型变量、一个字符型变量、一个实型变量放在同一个地址开始的内存单元中。图6-8共用体存储示意图
整型变量i
字符变量ch
实型变量f78计算机工程学院
uniondata{inti;
charch;
floatf;};设内存单元地址为1200,则它们的分配示意如图6-8,三者需要的内存空间不一样,但都从1200单元开始分配,分配多大的空间呢?如果上例使用的是结构则内存为结构体分配:2+1+4=7字节的空间,但在共用体中因为每次只使用共用体中的一个变量,所以分配的空间长度是最长成员的长度,在本例中是4个字节,这就是共用体和结构体的本质区别。79计算机工程学院2.共用体变量的说明和引用和结构体的说明对应,共用体的变量说明有四种方式:
(1)union〈共用体名〉{〈成员列表〉}变量列表;例如:uniondata{inti;
charch;
floatf;}a,b,c;说明了三个共用体变量a、b和c。80计算机工程学院(2)union〈共用体名〉{〈成员列表〉};
union共用体名变量列表;例如:uniondata{inti;
charch;
floatf;};
uniondataa,b,c;81计算机工程学院(3)union
{〈成员列表〉}变量列表;(4)typedefunion
{〈成员列表〉}共用体类型名;
共用体类型名变量列表;82计算机工程学院例如:typedefunion{inti;charch;
floatf;}DATA;
DATAa,b,c;共用体变量的引用和结构体、数组一样,只能引用共用体变量的成员。例如前面定义的三个共用体变量a,b,c,可以这样引用:83计算机工程学院
a.i;/*引用共用体变量中的整型变量i*/
a.ch;/*引用共用体变量中的字符变量ch*/
a.f;/*引用共用体变量中的实型变量f*/共用体类型数据有如下的特点:
(1)共用体的内存段可以存放几种类型的数据,但一次只能存放一个类型成员,且共用体变量中的值是最后一次存放的成员的值,如:
a.i=1;
a.ch=‘a’;
a.f=1.5;84计算机工程学院
完成以上三个赋值语句后,共用体变量的值是1.5,而a.i=1和a.ch=´a´已无意义。(2)共用体变量不能初始化,例如:
uniondata
{inti;
charch;
floatf;
}
a={1,’a’,1.5};(3)可以使用共用体指针,同样可以用指针形式来使用共用体成员。例如:
85计算机工程学院定义指针变量p:
DATA*p;p=&a;
则可以用下面的方式使用共用体的成员:
p->i=1;
p->ch=‘a’;
p->f=1.5;C语言最初引入共用体的目的之一是为了节省内存空间,另一个目的是可以将一种类型的数据转换为另一种类型的数据使用。86计算机工程学院
6.2.3技能训练
【实验6.2.1】设有若干个人员的数据,其中有学生和教师。学生的数据包括:姓名,学码,性别,专业,班级。教师的数据包括:姓名,工号,性别,职业,职务。可以看出,学生和教师所包含的数据是不同的,现要求把他们放在同一表格中,见表6-1。如果“job”项为“s”(学生),则第五项为class(班级)。如果“job”项为“t”(教师),则第五项为position(职务)。87计算机工程学院表6-1人员结构表【指导】
(1)编程分析
●定义一个结构体解决此问题,不同的部分(class和position)可以定义成共用体,即一88计算机工程学院个结构体类型中包含一个共用体成员。
●程序中当job的值是‘s’时,使用共用体中的class成员,当job的值是‘t’时,使用position成员。(2)示例程序
struct{intnum;charname[10];charsex;89计算机工程学院charjob;union{intclass;charposition[10];}category;}person[2];voidmain(){intn,i;for(i=0;i<2;i++){90计算机工程学院scanf(“%d%s%c%c”,&person[i].num,person[i].name,&person[i].sex,&person[i].job);if(person[i].job==’s’)scanf(“%d”,&person[i].category.class);elseif(person[i].job==’t’)scanf(“%s”,person[i].category.position);elseprintf(“inputerror!”);printf(“\n”);printf(“No.Namesexjobclass/position\n”);for(i=0;i<2;i++){91计算机工程学院if(person[i].job==’s’)printf(“%-6d%-10s%-3c%-3c%-6d\n”,person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.class);elseprintf(“%-6d%-10s%-3c%-3c%-6s\n”,person[i].num,person[i].name,person[i].sex,person[i].job,person[i].category.position);}}}92计算机工程学院6.2.4拓展与练习
1.有以下定义和语句,则sizeof(a)的值是【】,而sizeof(a.share)的值是【】
structdate{intday;intmonth;intyear;union{intshare1floatshare2;}share;}a;93计算机工程学院2.整型在内存中占4个字节,请编写一个程序,将四个字符(char)拼成一个长整型(long)数据。编写一个函数将四个字节的内容作为一个long型数据输出。94计算机工程学院
6.2.5编程规范与常见错误
1.理解共用体的含义,某一时刻只有一个成员的数据是有效的。例如定义共用体:uniondata{inti;charch;
floatf;}a;那么执行语句a.i=500;a.ch=’a’;printf(“%d”,a.i);结果不是500。95计算机工程学院2.注意结构体与共用体的区别,假如有如下定义:
那么sizeof(a)=max(sizeof(i),sizeof(ch),sizeof(f))=4;sizeof(b)=sizeof(i)+sizeof(ch)+sizeof(f)=2+1+4=7;因为a中某一时刻只有一个数据所以4个字节足够了,而b中3个成员都占用空间,需要7个字节。uniondata{inti;charch;floatf;}a;structdata{inti;charch;floatf;}b;96计算机工程学院任务3枚举学习目标
领会枚举类型的作用,枚举类型变量的定义、使用。97计算机工程学院
6.3.1案例讲解
1.问题描述:一个口袋里有红、黄、蓝、白、黑五种颜色的球若干个,依次从口袋中取出三个球,问:三个球的颜色正好都不相同的情况有几种?输出所有可能的排列组合。2.编程分析设取出的球为i,j,k,根据题意i,j,k分别为5种颜色之一,并且i≠j≠k,可以用穷举法,一一测试,看哪组符合条件,就输出它。98计算机工程学院伪代码如下:定义五种颜色;voidmain(){定义颜色变量i,j,k;定义整数变量n累计总的次数;外循环:第一个球i从red到black中循环:第二个球j从red到black如果i与j颜色相同则不取当i与j不相同,进入内循环:99计算机工程学院第三个球k也有五种可能当k与i不同并且与j也不同时
{输出次数n;输出三个球的颜色;输出换行;
}最后输出方案总数n;}100计算机工程学院3.编写源程序#include<stdio.h>enumcolor{red,yellow,blue,white,black};voidprintcolor(enumcolork);voidmain(){enumcolori,j,k;intn;n=0;for(i=red;i<=black;i++)for(j=red;j<=black;j++)if(i!=j){101计算机工程学院for(k=red,k<=black;k++)if((k!=i)&&(k!=j)){n++;printf(“%-4d”,n);printcolor(i);printcolor(j);printcolor(k);printf(“\n”);}}102计算机工程学院printf(“\ntotal:%5d\n”,n);}voidprintcolor(enumcolork){switch(k){casered:printf(%-10s”,”red”);break;caseyellow:printf(“%-10s”,”yellow”);break;caseblue:printf(“%-10s”,”blue”);break;casewhite:printf("%-10s","white");break;caseblack:printf("%-10s","black");break;default:break;}}103计算机工程学院4.程序运行结果图6-9运行结果104计算机工程学院5.归纳分析
(1)因为颜色一共有五种,可以一一例举出来,可以定义成枚举类型(2)枚举常量与整数有对应关系,red是0,yellow是1,依此类推。因此i,j,k可以循环的加一,也可以比较大小。(3)如果直接输出i,j,k则只能输出对应的整数,如printf("%d",red)结果是0,因此用函数printcolor处理一下,i=red则输出printf("%-10s","red")。105计算机工程学院
6.3.2基础理论
如果一个变量只有几种可能的值,可以将所有的值列举出来,在C语言将这种结构定义为枚举类型。“枚举”就是将变量可能的值一一列举出来的含义。变量的值只能取列举出来的值之一。1.枚举类型的定义枚举类型定义的一般形式为:
enum〈枚举类型名〉{枚举值表};例如:enumweek{SUN,MON,TUES,WED,THUR,FRI,SAT};定义了一个week是枚举类型名,有7个数据(称为“枚举元素”或“枚举常量),但它的值106计算机工程学院是SUN到SAT之一,并不是7个值,列出的7个数据是它的取值范围。2.枚举变量的说明与使用枚举变量也可用不同的方式说明,即先定义后说明,同时定义说明或直接说明。枚举变量说明的三种方法:
(1)先定义枚举类型,然后说明枚举变量。例:enumcolour{red,green,blue,yellow,white};enumcolourchange,select;107计算机工程学院
(2)在定义枚举类型的同时,说明枚举变量。例:enumcolour{red,green,blue,yellow,white}change,select;
(3)直接定义枚举变量。例:enum{red,green,blue,yellow,white}change,select;说明:108计算机工程学院●枚举元素是常量。在C编译器中,按定义的顺序取值0、1、2、...。例change=green;
printf("%d",change);
输出整数1。●枚举元素是常量,不是变量,因此不能赋值。
red=0;colour=1;
但在定义枚举类型时,可以指定枚举常量的值,如:
enumcolour{red=1,green=2,blue,yellow,white};
109计算机工程学院
此时,red,green,blue,...的值从red的值顺序加1。如:yellow=4。
●枚举值可以作判断比较的条件,例如:
if(change==red)....
if(select>green)....
●整型与枚举类型是不同的数据类型,不能直接赋值,如:
enumweek{sun=7,mon=1,tue,wed,thu,fri,sat}workday;workday=1但可以通过强制类型转换赋值,如:workday=(enumweek)2;110计算机工程学院6.3.3技能训练
【实验6.3.1】设某月的第一天是Sunday,请给出其它的日期是星期几。【指导】(1)编程分析用标识符sun,mon,…,sat表示星期,这比用数字1,2,…,7来表示要清晰,所以使用枚举可以提高程序的可读性。定义枚举类型表示星期(week),假定一个月是30天,定义数组(weekday)保存每一天是星期几,数组的长度是31,0号元素不用,数组的类型是week,那么:weekday[1]=sunday,表示1号是星期天。111计算机工程学院枚举型与整型有对应关系,sunday+1就是monday,当到了周末satday(对应整数6),下一天就应该是sunday(对应整数0)。(2)示例程序
voidmain(){enumweek{sun,mon,tue,wed,thu,fri,sat}weekday[31],j;inti;j=sun;for(i=1;i<=30;i++)112计算机工程学院{weekday[i]=j;
j++;
if(j>sat)
j=sun;}for(i=1;i<=30;i++){
switch(weekday[i])
{
casesun:printf("%3dSunday",i);break;
casemon:printf("%3dMonday",i);break;
casetue:printf("%3dTuesday",i);break;
casewed:printf("%3dWednesday",i);break;
casethu:printf("%3dThursday",i);break;
casefri:printf("%3dFriday",i);break;
casesat:printf("%3dSaturday\n",i);break;}
}printf("\n");
}113计算机工程学院6.3.4拓展与练习1.假设有如下定义:enumdata{MIN,first=15,last=20,total,num=50,max=1000}请指出各个枚举常量的值2.以下对枚举类型名的定义中正确的是enuma={one,two,three
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年安徽中医药高等专科学校高职单招职业适应性考试备考题库有答案解析
- 2026年抚州职业技术学院单招综合素质笔试参考题库带答案解析
- 2026年湖南劳动人事职业学院单招综合素质考试模拟试题带答案解析
- 2026年湖南邮电职业技术学院单招综合素质笔试备考试题带答案解析
- 2026年贵州护理职业技术学院高职单招职业适应性测试参考题库有答案解析
- 2026年成都工贸职业技术学院高职单招职业适应性考试备考题库有答案解析
- 2026年安徽绿海商务职业学院高职单招职业适应性考试备考题库有答案解析
- 2026年广西农业职业技术大学高职单招职业适应性测试备考试题有答案解析
- 2026年福建艺术职业学院单招职业技能笔试备考试题带答案解析
- 2026年河北工艺美术职业学院单招综合素质考试备考题库带答案解析
- (2025)医院医疗质量安全管控与不良事件防范专项总结(3篇)
- 2026年江西制造职业技术学院单招职业适应性考试模拟测试卷附答案
- GJB1406A-2021产品质量保证大纲要求
- 水利电工程施工地质规程
- JJF 2019-2022 液体恒温试验设备温度性能测试规范
- DZ∕T 0153-2014 物化探工程测量规范(正式版)
- (高清版)TDT 1013-2013 土地整治项目验收规程
- 国家开放大学电大《计算机应用基础(本) 》 终结性考试试题答案(完整版)
- 《建筑基坑降水工程技术规程》DBT29-229-2014
- 2023年广东学业水平考试物理常考知识点
- 中外政治思想史-复习资料
评论
0/150
提交评论