C语言程序设计课件第9章 结构体、共用体和枚举类型_第1页
C语言程序设计课件第9章 结构体、共用体和枚举类型_第2页
C语言程序设计课件第9章 结构体、共用体和枚举类型_第3页
C语言程序设计课件第9章 结构体、共用体和枚举类型_第4页
C语言程序设计课件第9章 结构体、共用体和枚举类型_第5页
已阅读5页,还剩54页未读 继续免费阅读

下载本文档

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

文档简介

第9章结构体、共用体和枚举类型本章主要内容:9.1结构体(重点)9.2链表(重点)9.3共用体9.4枚举类型(重点)9.5类型定义符typedef本章教学要求:掌握结构体类型的定义及应用熟悉链表的定义及使用方法

掌握枚举类型定义及在实际问题中的应用了解共用体及类型定义符的使用9.1结构体

本节主要介绍结构体类型的定义、结构体变量的定义与使用、结构体数组的定义与使用、结构体指针的定义与使用。9.1.1结构体类型的定义1.定义格式如下:struct结构体名{ 成员项列表;};第9章结构体、共用体和枚举类型9.1结构体9.1.1结构体类型的定义2.例如,可以这样定义与学生基本信息对应的结构体类型:structstudent{charnum[11]; /*学号*/charname[10]; /*姓名*/charsex; /*性别*/intage; /*年龄*/charnation; /*民族*/charaddr[20]; /*家庭住址*/};第9章结构体、共用体和枚举类型9.1结构体9.1.1结构体类型的定义3.注意①不要忘记写花括弧外的分号。②一个结构体类型有其专用的标志,它由两个标识符组成,其中第一个标识符为关键字struct,第二个标识符student为结构体名,由编程人员按照标识符的命名规则来指定。这两者联合起来组成一个“类型标识符”即“类型名”。③一个结构体类型是由若干个数据项组成,每一个数据项都必须属于一种已定义的类型,且各个数据项的类型可以不相同。每一个数据项称为一个结构体的成员,也称为“域”。比如在上面的定义中,name、sex、age等不是变量名而是结构体类型structstudent的成员名。在一个函数中,可以另外定义与结构体成员同名的变量名,它们代表不同的对象。第9章结构体、共用体和枚举类型9.1结构体9.1.1结构体类型的定义3.注意④结构体类型可以有无数种。因为结构体名可由程序设计人员自定,且结构体成员可千变万化,所以结构体类型不是只有一种,而可以有千千万万种,这一点也是与基本类型不同的。⑤定义一个结构体类型并不意味着系统将分配一段内存单元来存放各数据项成员。因为这只是定义类型而不是定义变量,只有在定义变量以后,计算机才会依据结构体成员的数据类型,在内存中取得一块连续的存储空间来存放这些成员。第9章结构体、共用体和枚举类型9.1结构体9.1.2结构体变量的定义与使用1.结构体变量的定义结构体在使用时,需要先定义结构体类型,然后再根据自定义的结构体类型去定义结构体变量。可以用以下三种方法定义一个结构体变量。(1)先定义结构体类型再定义该类型的变量。如上面已经定义了一个结构体类型structstudent,现在可以用它定义结构体变量。structstudentstu1,stu2;(2)定义一个结构体类型的同时定义该结构体类型的变量。一般格式如下:struct

结构体名{ 结构体成员列表;}变量名列表;第9章结构体、共用体和枚举类型structstudent{charnum[11];charname[10];charsex;intage;charnation;charaddr[20];}stu1,stu2;9.1结构体9.1.2结构体变量的定义与使用1.结构体变量的定义可以用以下三种方法定义一个结构体变量。(3)直接定义结构体类型的变量。一般格式如下:struct

{

结构体成员列表;}变量名列表;即不出现结构体名。但这种形式只是定义了结构体类型的变量,没有指定此结构体类型的名字,因此以后不能再用它来定义其它变量。第9章结构体、共用体和枚举类型struct{ charnum[11]; charname[10]; charsex; intage; charnation; charaddr[20];}stu1,stu2;9.1结构体9.1.2结构体变量的定义与使用1.结构体变量的定义说明:①类型与变量是不同的概念。对结构体变量来说,在定义时一般先定义一个结构体类型,然后定义该类型的变量。只能对变量赋值、存取或运算,而不能对一个类型赋值、存取或运算。在编译时只对变量分配存储空间,对类型是不分配空间的。②对于某个具体的结构体类型,成员的数量必须固定。③对结构体中的成员可以单独使用,它的作用与地位相当于普通变量。④结构体类型的成员也可以是一个结构体变量。第9章结构体、共用体和枚举类型9.1结构体9.1.2结构体变量的定义与使用2.结构体变量的初始化结构体类型的使用方法与数组相似,它的初始化需要以每个成员为基本单位,可以在定义变量的同时赋初值。例如:structstudent{charnum[11]; charname[10]; charsex;

intage; charnation; charaddr[20];};structstudentstu1={"20150101001","LiMing",'M',30,'H',"YingcaiRoad"};第9章结构体、共用体和枚举类型9.1结构体9.1.2结构体变量的定义与使用3.结构体变量的引用(1)引用结构体变量中的单个成员。一个结构体变量表示的是一个整体,比如一个学生的基本信息,但有时我们要访问的是其中的一个数据项成员,比如某个学生的姓名,访问结构体变量的某个数据项成员的形式为:

结构体变量.结构体成员名其中符号“.”称为成员运算符。第9章结构体、共用体和枚举类型structstudent{ charnum[11]; charname[10]; charsex; intage; charnation; charaddr[20];}stu1;strcpy(,"LiMing");stu1.age=19;9.1结构体9.1.2结构体变量的定义与使用3.结构体变量的引用(2)整体引用结构体变量。可以将一个结构体变量的值赋给另一个具有相同类型的结构体变量。例如:

structstudentstu1={"20150101001","LiMing",'M',30,'H',"YingcaiRoad"};

structstudentstu2; stu2=stu1;但是不允许用赋值语句将一组常量直接赋给一个结构体变量,如下面的用法是不正确的。

structstudentstu1; stu1={"20150101001","LiMing",'M',30,'H',"YingcaiRoad"};第9章结构体、共用体和枚举类型9.1结构体9.1.2结构体变量的定义与使用3.结构体变量的引用(3)结构体变量中成员的输入输出。C语言不允许把一个结构体变量作为一个整体进行输入或输出操作。例如下列语句是不合法的:

scanf("%d",&stu1);

printf("%d\n",stu1);

printf("%s,%s,%c,%d,%c,%s\n",stu1);因为在用printf和scanf函数时,必须指定输入输出格式,一个格式符对应一个变量,有明确的存储界限。而结构体变量包括若干个不同类型的数据项,所以,要输入或输出一个结构体类型变量,只能对其成员进行操作。第9章结构体、共用体和枚举类型9.1结构体9.1.2结构体变量的定义与使用3.结构体变量的引用(4)可以引用结构体变量其成员的地址,也可以引用结构体变量的地址。

前面已经提到,结构体变量所占内存大小是各成员所占内存大小之和,这是因为结构体变量在内存中存储时,各个成员按其定义的先后顺序存储在连续的一段存储空间。这段连续存储空间的首地址也就是该结构体变量的地址,它的各个成员也有各自的存储地址,可以引用这些地址。

scanf("%d",&stu1.age); /*输入stu1.age的值*/

printf("%o%o\n",&stu1,&stu1.age); /*输出stu1和stu1.age的地址*/第9章结构体、共用体和枚举类型9.1结构体9.1.3结构体数组的定义与使用一个结构体变量只能存放一个对象(如一个学生)的数据,如果要存放一所学校所有的学生数据就要用到数组,这就是结构体数组。结构体数组的每个数组元素都是一个结构体类型的变量。1.结构体数组的定义(1)先定义结构体类型再定义结构体数组。例如:structworker{

charname[20]; charsex;

intage; floatsalary;};structworkerw[50];第9章结构体、共用体和枚举类型9.1结构体9.1.3结构体数组的定义与使用1.结构体数组的定义(2)定义类型的同时定义数组。例如:structworker{ charname[20]; charsex;

intage; floatsalary;}w[50];第9章结构体、共用体和枚举类型9.1结构体9.1.3结构体数组的定义与使用1.结构体数组的定义(3)直接定义结构体数组。例如:struct

{ charname[20]; charsex;

intage; floatsalary;}w[50];第9章结构体、共用体和枚举类型9.1结构体9.1.3结构体数组的定义与使用2.结构体数组的初始化结构体数组在定义时可以直接进行初始化。例如:structworker{ charname[20]; charsex;

intage; floatsalary;}w[50]={{"LiuGang",'M',30,5500},{"WangKe",'F',25,4000}};第9章结构体、共用体和枚举类型9.1结构体9.1.3结构体数组的定义与使用3.结构体数组的引用一个结构体数组的元素相当于一个结构体变量,所以前面关于结构体变量的使用方法对结构体数组元素同样适用。有关数组的用法同一般数组。例如,数组的输入可采用以下形式:for(i=0;i<50;i++)

scanf("%s,%c,%d,%f",w[i].name,&w[i].sex,&w[i].age,&w[i].salary);数组的输出:for(i=0;i<50;i++)

printf("%s,%c,%d,%f",w[i].name,w[i].sex,w[i].age,w[i].salary);第9章结构体、共用体和枚举类型9.1结构体9.1.3结构体数组的定义与使用【例9-1】员工档案信息的输入与输出。源程序:第9章结构体、共用体和枚举类型#include<stdio.h>#defineMAX3structworker{charname[20];charsex;intage;floatsalary;};intmain(){structworkerw[MAX];inti;for(i=0;i<MAX;i++){printf("Inputname:");scanf("%s",w[i].name);printf("Inputsex:");scanf("%c",&w[i].sex);printf("Inputage:");scanf("%d",&w[i].age);printf("Inputsalary:");scanf("%f",&w[i].salary);}printf("namesexagesalary\n");for(i=0;i<MAX;i++)printf("%-10s%-6c%-6d%-10.2f\n",w[i].name,w[i].sex,w[i].age,w[i].salary);return0;}程序运行结果:Inputname:LiuGang↙Inputsex:M↙Inputage:30↙Inputsalary:5600↙Inputname:WangKe↙Inputsex:F↙Inputage:25↙Inputsalary:4000↙Inputname:ChenPing↙Inputsex:F↙Inputage:30↙Inputsalary:5650↙name sexagesalaryLiuGang M305600.00WangKe F254000.00ChenPingF305650.009.1结构体9.1.4结构体指针的定义与使用一个结构体类型的数据在内存中占用一段连续的存储区域,可以定义一个指针变量来存储该存储区域的起始地址,这样的指针变量称为指向结构体类型的指针变量,简称结构体指针。1.结构体指针的定义(三种方式)定义结构体指针的方法和定义结构体变量的方法相同,也有三种方式:(1)先定义结构体类型再定义指向该类型的指针变量。如前面已定义过structworker类型,则可定义该类型的指针变量:structworker*p,*q;第9章结构体、共用体和枚举类型9.1结构体9.1.4结构体指针的定义与使用1.结构体指针的定义(三种方式)(2)定义类型的同时定义指针变量。例如:structworker{ charname[9]; charsex;

intage; floatsalary;}*p,*q;第9章结构体、共用体和枚举类型9.1结构体9.1.4结构体指针的定义与使用1.结构体指针的定义(三种方式)(3)直接定义指针变量。例如:struct

{ charname[20]; charsex;

intage; floatsalary;}*p,*q;第9章结构体、共用体和枚举类型9.1结构体9.1.4结构体指针的定义与使用2.结构体指针的使用(1)结构体指针的赋值与普通变量相同,结构体指针变量也必须先赋值才能使用。一个结构体指针变量可以用一个结构体变量的首地址赋值,也可以用结构体数组的某个元素的首地址赋值,例如:structworker{ charname[20]; charsex;

intage; floatsalary;};structworkerw1,w[50],*p,*q;p=&w1;q=w;或q=&w[0];第9章结构体、共用体和枚举类型注意:结构体指针只能指向一个结构体变量,不能指向结构体变量中的某一个成员,因为结构体指针和结构体成员的数据类型不一致。9.1结构体9.1.4结构体指针的定义与使用2.结构体指针的使用(2)利用结构体指针引用结构体变量的成员。

要访问结构体变量的一个成员,可以用运算符“.”(如w1.age)的形式。如果要用结构体指针来访问这个结构成员,也可以写成(*p).age的形式。除此之外,为了使用方便和直观,C语言又引入了指向运算符“->”,即:(*p).age也可以写成p->age的形式。这样,引用结构体变量成员可以有以下三种形式:①结构体变量名.成员名②(*结构体指针变量名).成员名③结构体指针变量名->成员名注意:①运算符“->”左侧只能是结构体指针变量。②在第二种形式中,“(*结构体指针变量名)”两边的括号不能省略,因为运算符.的优先级要高于指针运算符*。第9章结构体、共用体和枚举类型9.1结构体9.1.4结构体指针的定义与使用【例9-2】输入一个学生的学号、姓名、期中考试成绩和期末考试成绩,计算平均成绩并输出所有信息。分析:定义一个结构体类型的变量,用来存放学生的相关信息。在引用各成员时有三种方式。源程序:第9章结构体、共用体和枚举类型#include<stdio.h>structstudent{ charnum[12],name[18]; intfinal,midterm,aver;};voidmain(){ structstudent*p,stu1; p=&stu1; printf("Inputthenumnamemidtermfinal:"); scanf("%s%s%d%d",stu1.num,,&stu1.midterm,&stu1.final); (*p).aver=((*p).final+(*p).midterm)/2;

printf("num:%sname:%s\n",p->num,p->name);

printf("midtermscore:%dfinalscore:%daverscore:%d\n", p->midterm,p->final,p->aver);}程序运行结果:Inputthenumnamemidtermfinal:150203001LiLin88 92↙num:150203001name:LiLinmidtermscore:88finalscore:92averscore:909.2链表

链表是一种常见而又重要的数据结构。它是一种动态存储结构,根据需要开辟内存单元,其具体的理论和用法在《数据结构》课程中会详细介绍。本节主要介绍利用结构体变量和指针实现链表的方法。

所谓链表是指将若干个数据元素按一定的原则连接起来的表。链表中的每一个数据元素(可能包含多个成员项)称为一个“结点”。

链表的连接原则是:前一个结点“指向”下一个结点,只有通过前一个结点才能找到下一个结点。第9章结构体、共用体和枚举类型9.2链表9.2.1单链表的结构

在单链表中,每个结点由两个域组成:数据域用于存储数据;指针域用于存储后继结点的地址。第一个结点的地址存储在一个指针变量中,该指针变量称为“头指针”(如图9-1中的H);最后一个结点的指针域存储一个“NULL”值(NULL是头文件中定义的一个符号常量,值为0,专门用于设置指针无效或判断指针是否无效),即空指针,表示链表到此结束。这样,通过“头指针”沿着各个结点的指针域就可以找到链表中各个结点,如果不提供“头指针”,则整个链表无法访问。也正因为这种结构就如同一条铁链一样,一环扣一环,中间不能断开,所以称之为链表。第9章结构体、共用体和枚举类型9.2链表9.2.1单链表的结构链表中的结点结构可用结构体类型来实现。例如:structstudent{

intnumber;

structstudent*next;};其中number用来存放结点数据,next存放下一个结点的地址。第9章结构体、共用体和枚举类型9.2链表9.2.2链表的动态存储

在C语言中,链表中每个存储单元的开辟和释放都是动态存储函数实现的。

根据需要随时开辟存储单元,不再需要时又可随时释放,这样使得存储空间的利用比较合理。链表中各结点的地址在需要时向系统申请分配,系统会根据内存的当前情况,既可连续分配地址,也可跳跃式分配地址。第9章结构体、共用体和枚举类型9.2链表9.2.2链表的动态存储与动态存储有关的库函数1.malloc函数。函数原型为:void*malloc(unsignedintsize)其功能是在内存的动态存储区中分配一个长度为size的存储空间。函数返回值为分配域的起始地址,如果内存不足,则分配不成功,返回0(空指针)。2.calloc函数。函数原型为:void*calloc(unsignedintn,unsignedintsize)其功能是在内存的动态存储区中分配n个长度为size字节的存储空间。函数返回值为分配域的起始地址;如果分配不成功,则返回0。第9章结构体、共用体和枚举类型9.2链表9.2.2链表的动态存储与动态存储有关的库函数3.free函数。函数原型为:voidfree(void*ptr)其功能是将指针变量ptr

所指向的存储空间释放。ptr

是最近一次调用calloc函数或malloc函数时返回的地址。free函数没有返回值。4.realloc函数。函数原型为:void*realloc(void*ptr,unsignedintsize)其功能是将ptr所指向的存储空间(是原先用malloc函数分配的)的大小改为size个字节,即重新分配。可以使原来的分配区扩大也可缩小。它的函数返回值是一个指针,即新的存储区的首地址。说明:以上库函数包含在头文件stdlib.h(即standardlibrary)标准库头文件中。第9章结构体、共用体和枚举类型9.2链表9.2.3单链表的建立与输出1.单链表的建立建立单向链表的主要操作步骤如下:①定义链表中的结点结构;②读取数据;③生成新结点;④将数据存入结点的成员变量中;⑤将新结点的指针成员赋值为空,如果是空表,则将新结点连接到表头;如果是非空表,则把新结点连接到表尾。重复②~⑤的操作直到输入结束。第9章结构体、共用体和枚举类型9.2链表9.2.3单链表的建立与输出1.单链表的建立【例9-3】编写函数creatlist,建立一个整数的单向链表。要求:结点数据域的数值从键盘输入,以-1作为输入的结束标志,链表的起始地址由函数值返回。分析:设立三个指针:h、s和r,它们都指向结构体类型数据,其中h存放链表的起始地址,而s和r为工作指针:指针s用来指向新生成的结点,指针r总是指向链表中最后一个结点。每当把指针s所指的新开辟的结点连接到表尾后,指针r便移向这一新的表尾结点,这时又可用指针s去指向下一个新开辟的结点。链表最后一个结点的指针域中置'\0'(NULL值),作为单向链表的结束标志。n是结点个数。源程序:第9章结构体、共用体和枚举类型#include<stdlib.h>#include<stdio.h>#defineNULL0#defineLENsizeof(structstudent)structstudent/*定义结点类型*/{intdata;structstudent*next;};structstudent*creatlist()/*建立链表函数*/{structstudent*h,*s,*r;intx;printf("x=");scanf("%d",&x);/*输入第一个元素值*/if(x==-1){h=NULL;return(h);}h=r=(structstudent*)malloc(LEN);/*在内存中产生第一个结点空间*/r->data=x;printf("x=");scanf("%d",&x);/*输入第二个元素值*/while(x!=-1){s=(structstudent*)malloc(LEN);/*产生下一个结点空间*/s->data=x;r->next=s; /*s结点接到链尾*/r=s; /*r指向新的链尾*/printf("x=");scanf("%d",&x);/*输入下一个元素值*/}r->next=NULL;/*最后一个结点的指针域为空*/return(h);}9.2链表9.2.3单链表的建立与输出2.单链表的输出

输出链表是指将链表各结点的数据依次输出。单向链表的输出的操作步骤如下:①找到链表中第一个元素的地址;②设一个指针变量并使它指向第一个结点,输出其值成员;③使指针变量向后移一个结点,即指到下一个结点,再输出其值成员。重复步骤③直到链表的尾结点。第9章结构体、共用体和枚举类型9.2链表9.2.3单链表的建立与输出2.单链表的输出【例9-4】写出输出链表的函数display。分析:设置一个指针变量p,先使它指向第一个结点在输出完第一个结点之后,通过语句p=p->next;使p指向第二个结点依次处理直到表尾。head为头指针,其值由实参传过来。源程序:第9章结构体、共用体和枚举类型voiddisplay(structstudent*head){structstudent*p;p=head;while(p!=NULL){printf("%d",p->data);p=p->next;/*指针指向下一个结点*/}}voidmain(){structstudent*head;head=creatlist();display(head);}9.2链表9.2.4单链表的插入与删除1.单链表的插入

单链表的插入是指在链表中适当位置(称为插入位置)添加一个新结点。插入位置可能处于链表头、链表尾或链表中某两个结点之间。【例9-5】在单链表的第i个数据元素之前插入一个数据元素x。分析:此问题要修改第i-1数据元素的指针域,使其指向插入结点而插入结点的指针域指向第i个数据元素因此,首先应找到第i-1个结点,而后再修改指针的操作源程序:第9章结构体、共用体和枚举类型intinsert(structstudent*L,inti,intx){structstudent*p,*s;intj;p=L;j=1;while(p!=NULL&&j<i-1)/*查找第i-1个数据元素*/{p=p->next;j++;}if(p==NULL)return(0); /*如没有查找返回0*/s=(structstudent*)malloc(LEN);s->data=x;s->next=p->next;p->next=s; /*修改相应指针域,实现插入*/return(1);}9.2链表9.2.4单链表的插入与删除2.单链表的删除

单链表的删除是指使单链表中的某个数据元素从链表中脱离。【例9-6】删除单链表L的第i个数据元素。分析:要修改第i-1个数据元素的指针域,使其指向第i+1个数据元素。要删除的第i个元素的值可通过指针参数带回主调函数。源程序:第9章结构体、共用体和枚举类型intdelete(structstudent*L,inti,int*s){structstudent*p,*q;intj;if(L==NULL){printf("Listempty!");return(0);}/*链表为空,删除第i个数据元素失败*/p=L;j=1;while(p->next!=NULL&&j<i-1){p=p->next;j++;}if(p->next==NULL)return(0);q=p->next;p->next=q->next;*s=q->data;free(q);return(1);}9.3共用体共用体又称联合体,它是C语言中提供的另一种构造类型,它是将几种不同类型的变量存放到同一段内存单元中。虽然这些不同类型的变量在内存中所占的字节数不同,但它们都从同一地址单元开始存放。共用体使用的是一种覆盖技术,即几个变量互相覆盖。共用体的定义方法及使用规则与结构体类型相似。第9章结构体、共用体和枚举类型9.3共用体9.3.1共用体类型和共用体变量的定义

共用体类型的定义与结构体类型的定义相似,只需要将关键字struct换成union即可。其一般格式为:union

共用体名{

类型名1共用体成员名1;

类型名2共用体成员名2; ……

类型名n共用体成员名n;};

union为关键字,共用体各成员可以是简单变量,也可以是数组、指针、结构体和共用体。第9章结构体、共用体和枚举类型9.3共用体9.3.1共用体类型和共用体变量的定义与结构体变量相似,共用体变量的定义也有三种形式。1.先定义共用体类型再定义该类型的变量。例如:uniondata{

inta; charb; floatc;};uniondatax1,x2;其中,data是共用体名,x1和x2为data类型的共用体变量。第9章结构体、共用体和枚举类型根据共用体的定义,共用体变量x1中的各个成员共占内存中同一段存储空间,即成员a、b、c都是从同一存储单元开始存放(假设地址为1000H),a为整型,占用2个字节,即1000H和1001H两个存储单元;b为字符型,占用1个字节,即1000H这个存储单元;c为实型,占4个字节,即1000H至1003H共四个存储单元。共用体变量x1实际占用的存储空间为其成员中所需存储单元的最大值。9.3共用体9.3.1共用体类型和共用体变量的定义与结构体变量相似,共用体变量的定义也有三种形式。2.定义一个共用体类型的同时定义该共用体类型的变量。例如:uniondata{

inta; charb; floatc;}x1,x2;第9章结构体、共用体和枚举类型9.3共用体9.3.1共用体类型和共用体变量的定义与结构体变量相似,共用体变量的定义也有三种形式。3.直接定义共用体类型的变量。例如:union{

inta; charb; floatc;}x1,x2;第9章结构体、共用体和枚举类型9.3共用体9.3.2共用体变量引用

对于共用体变量,一般只引用它的成员,而不引用整个共用体变量。其成员引用的一般格式为:共用体变量名.成员名例如:x1.ax1.bx1.c也可以通过指向共用体变量的指针来引用其成员,例如:uniondatax,*p=&x;则以下也是合法的引用形式:(*p).ap->b第9章结构体、共用体和枚举类型9.3共用体9.3.2共用体变量引用

由于共用体变量的各个成员共用一段内存,这段内存在某一时刻只能用一个成员名来标识,也就是只有一个成员起作用,而不是各个成员并存。因此,共用体变量在使用时应注意以下几个方面:(1)不能在定义共用体变量时对它初始化。例如,以下初始化方式是非法的。 uniondata {

int

a;

charb;

floatc; }x1={10,’a’,7.8};第9章结构体、共用体和枚举类型9.3共用体9.3.2共用体变量引用(2)如果多次给共用体成员赋值,则最近一次赋值有效。例如:x1.a=10;x1.b=’a’;x1.c=7.8;最终,共用体变量x1中存放的有效值为7.8。前面所赋的值10被’a’覆盖,而’a’被7.8覆盖,所以此时不能再引用x1.a的值10和x1.b的值’a’。因此,共用体成员参加运算时,一定注意当前在共用体变量中究竟是哪个成员有效。(3)共用体变量的地址与其各个成员的地址相同。例如:&x1==&x1.a==&x1.b==&x1.c第9章结构体、共用体和枚举类型9.3共用体9.3.2共用体变量引用(4)C语言允许两个相同类型的共用体变量之间相互赋值。例如: uniondatax1,x2; x1.a=10; x2=x1;这样,x2中的内容与x1完全相同,也可以引用x1.a的值。但是,不能引用共用体变量名进行以下操作,例如以下用法是错误的。 x1=5; scanf("%d",&x1); printf("%d\n",x1);第9章结构体、共用体和枚举类型9.3共用体9.3.2共用体变量引用【例9-7】将下列数据说明为共用体类型,并进行赋值和显示。姓名

年龄

月收入WangLei 32 6000源程序:第9章结构体、共用体和枚举类型#include<stdio.h>voidmain(){unioninfo{char*name;intage;intincome;};unioninfolist;="WangLei";printf("%8s\n",);list.age=32;printf("%2dold\n",list.age);list.income=6000;printf("%4dyuan\n",list.income);}9.3共用体9.3.2共用体变量引用【例9-8】有一个教师与学生通用的表格,教师数据有姓名、性别、职业、教研室4项;学生的数据有姓名、性别、职业、班级4项。编程序实现数据的输入和输出。分析:教师的教研室可采用字符串表示,而学生的班级可以用整型的班级号来表示,它们的类型不同,但要共用表格的一列,所以该表格的第4项应采用共用体类型。源程序:第9章结构体、共用体和枚举类型#include<stdio.h>#defineN10voidmain(){struct{charname[10];charsex;charjob;union{intclas;charoffice[10];}depa;}person[N];

inti;for(i=0;i<N;i++){printf("\nInput%dperson:",i+1);printf("\nname:");gets(person[i].name);printf("\nsex:");person[i].sex=getchar();getchar();printf("\njob:");person[i].job=getchar();if(person[i].job=='s'){printf("\nclass:");scanf("%d",&person[i].depa.clas);}else{printf("\noffice:");scanf("%s",&person[i].depa.office);}getchar();} for(i=0;i<N;i++){if(person[i].job=='s')printf("%-10s%-3c%-3c%-10d\n",person[i].name,person[i].sex,person[i].job,person[i].depa.clas);elseprintf("%-10s%-3c%-3c%-10s\n",person[i].name,person[i].sex,person[i].job,person[i].depa.office);}}9.4枚举类型所谓“枚举”是指将变量的值一一列举出来,而变量的值只能列举出来的其中之一。如果一个变量的取值范围可以一一列举出来,则可以将其定义为枚举类型。枚举类型的引入也可以限制数据的取值。第9章结构体、共用体和枚举类型9.4枚举类型9.4.1枚举类型的定义

枚举类型也属于一种构造类型,定义枚举类型的一般格式为:

enum

枚举名{枚举元素表};

其中,enum是表示枚举类型的关键字;枚举名是用户定义的类型名;枚举元素是用户定义的有意义的标识符,即罗列出该枚举类型各种可能的、合法的取值。

与结构体变量、共用体变量相似,枚举变量的定义也有三种形式。1.先定义枚举类型再定义该类型的变量。例如:

enum

week{sun,mon,tue,wed,thu,fri,sat};

enum

weekd1,d2;

上面定义了d1,d2两个枚举变量,它们的只能取sun,…,sat这7个值之一。第9章结构体、共用体和枚举类型9.4枚举类型9.4.1枚举类型的定义与结构体变量、共用体变量相似,枚举变量的定义也有三种形式。2.定义一个枚举类型的同时定义该类型的变量。例如:

enum

week{sun,mon,tue,wed,thu,fri,sat}d1,d2;3.直接定义枚举类型的变量。例如:

enum

{sun,mon,tue,wed,thu,fri,sat}d1,d2;第9章结构体、共用体和枚举类型9.4枚举类型9.4.2枚举变量的使用

枚举变量的使用方式和普通变量一样,但枚举变量的取值范围只能是其枚举类型所列举的各个枚举元素。例如: d1=sun;d2=wed;都是合法的。但d1=sunday;则是非法的。第9章结构体、共用体和枚举类型9.4枚举类型9.4.2枚举变量的使用使用枚举类型应注意以下几个问题:(1)在定义枚举类型时,枚举元素的名字是程序设计者自己指定的例如:sun,mon等,命名规则与标识符相同。这些名字并无固定的含义,只是一个符号。在C编译中,对这些枚举元素按常量处理,也称枚举常量。它们不是变量,不能改变它们的值。(2)枚举常量的值是一些整数,C语言编译系统按定义时的顺序使它们的值为0,1,2,……。例如,在上面的定义中sun的值为0,而mon的值为1等等。这是系统自动赋给的,定义枚举类型时不能写成:

enum

weekday{0,1,2,3,4,5,6};枚举常量必须用标识符。

可以在定义类型时改变枚举元素的值,例如:

enum

weekday{sun=7,mon=1,tue,wed,thu,fri,sat};

定义sun值为7,mon值为1,以后顺序加1,tue值为2,sat值为6。第9章结构体、共用体和枚举类型9.4枚举类型9.4.2枚举变量的使用使用枚举类型应注意以下几个问题:(3)枚举常量的值可以赋给枚举变量,但不能将一个整数直接赋给枚举变量,例如:d2=wed;则d2的值就为3,且这个值可以输出。例如:printf("%d\n",d2);输出结果为3。但是d2=3;则是错误的,因为它们属于不同的类型。(4)枚举常量的值可以进行判断比较。例如: if(d1==sun)printf("ItisSunday!\n"); if(d2!=sun)printf("ItisnotSunday!\n");它们是按所代表的整数值进行比较的。

枚举类型变量的值是在该枚举类型中所列举的常量所代表的整数值范围内,因此枚举变量可以作为循环变量来控制循环。第9章结构体、共用体和枚举类型9.4枚举类型9.4.2枚举变量的使用【例9-9】已知今天是星期天,输入一个整数n,计算第n

温馨提示

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

评论

0/150

提交评论