第 11 章 结构体与共用体

61
第 11 第 第第 第第第第 体体 第第第第第

Upload: skyler

Post on 15-Jan-2016

133 views

Category:

Documents


0 download

DESCRIPTION

第 11 章 结构体与共用体. 信息管理系. 第 11 章 结构体与共用体. 11.1 结构体类型的定义与引用 11.2 链表的知识 11.3 共用体类型的定义与引用 11.4 枚举类型与自定义类型的定义. 结构体类型的定义. 在程序中,如需要存储一组性质相关、而类型不同的数据时,就可以使用结构体类型。 结构类型定义的一般形式: struct 结构类型名 { 成员类型 1 成员名 1 ; 成员类型 2 成员名 2 ; …… 成员类型 n 成员名 n ; };. 说明: - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 第 11 章  结构体与共用体

第 11 章 结构体与共用体

信息管理系

Page 2: 第 11 章  结构体与共用体

第 11 章 结构体与共用体

11.1 结构体类型的定义与引用 11.2 链表的知识 11.3 共用体类型的定义与引用 11.4 枚举类型与自定义类型的定义

Page 3: 第 11 章  结构体与共用体

结构体类型的定义

在程序中,如需要存储一组性质相关、而类型不同的数据时,就可以使用结构体类型。

结构类型定义的一般形式:struct 结构类型名{

成员类型 1 成员名 1 ; 成员类型 2 成员名 2 ; ……

成员类型 n 成员名 n ;};

说明:1 struct 是结构类型定义的保

留字,必须原样照写;2 结构类型名应符合标识符

的规定,在以后的结构变量声明中可以被引用;

3 大括号内是由结构成员组成的结构体,每个成员的数据类型可以是基本类型,也可以是构造类型。

4 不要漏掉分号。

Page 4: 第 11 章  结构体与共用体

结构体类型的定义

例:一个学生的个人信息包括学号( int )、姓名 (char) 、性别 (char) 、年龄 (int) 、成绩 (float) 、家庭住址 (char)等,因为这些数据是紧密联系的,所以我们需要将这些不同类型的数据组合成一个有机的整体,以便于引用和处理。我们可声明如下的结构体类型以满足我们的要求:struct student{ int num ; char name[20] ; char sex ; int age ; float score ; char addr[30] ;} ;

这样我们就指定了一个结构体类型,相当于一个模型(相当于 int,char 等),但其中并无具体的数据,为了能够在程序中使用这种类型的数据,应当定义结构体类型的变量,并在其中存放具体数据。

Page 5: 第 11 章  结构体与共用体

结构体类型变量的定义

先声明结构体类型再定义变量名 struct 结构体类型名 变量名;

在声明类型的同时定义变量 struct 结构体类型名 { 结构体成员列表; } 变量表;

直接定义结构体类型变量 struct { 结构体成员列表; } 变量表;

Page 6: 第 11 章  结构体与共用体

结构体类型变量的定义

要定义前面我们讨论的关于学生情况的结构体类型变量 stu1 、 stu2 ,我们可用如下的三种方法来定义:

1 struct student { int num ; char name[20] ; char sex ; int age ; float score ; char addr[30] ; } ;

struct student stu1,stu2;

2 struct student { int num ; char name[20] ; char sex ; int age ; float score ; char addr[30] ; } stu1,stu2;

3 struct studentstudent { int num ; char name[20] ; char sex ; int age ; float score ; char addr[30] ; } stu1,stu2;

Page 7: 第 11 章  结构体与共用体

结构体类型变量的初始化(赋值)

和其他类型变量一样,对结构体变量可以在定义时指定初始值。

例:struct student { int num ; char name[20] ; char sex ; int age ; float score ; char addr[30] ; } stu={205 ,” Li Lin”,’M’,86.5,”123 Beijing Road”};

注意:

在进行结构变量的初始化时,数据与其对应的结构成员的类型要一一对应。

Page 8: 第 11 章  结构体与共用体

结构体类型变量的引用

在定义了结构体变量以后,当然可以引用这个变量,但应遵循以下规则:

不能将一个结构体变量作为一个整体进行输入和输出。例如已定义结构体变量 stu 且已赋初值:不能这样引用: printf(“%d,%s,%c,%d,%f,%s\n”,stu);

只能对结构体变量中的各个成员分别进行输入和输出,引用结构体变量中成员的方式为:结构体变量名.成员名

 例如: stu.num 表示 stu 变量中的 num 成员,即学号项。可以作为一个普通的同类型变量进行操作,如: stu.num=205; scanf(“%d”,&stu.num); stu.age++

如果成员本身又是一个结构体类型,则要一级一级找到最低的一级成员,即只能对最低级的成员进行赋值或存取以及运算。

Page 9: 第 11 章  结构体与共用体

11.1.5 结 构 体 数 组

一个结构体变量中可以存放一组相关数据,如果要处理若干组相同结构的数据,显然应该用数组来实现。即是结构体数组。结构体数组存储的是一系列的结构体类型的数据。定义结构体数组(数组的各元素在内存中连续存放)和定义结构体变量的方法相似,只需说明其为数组即可。1 、 struct student { int num ; char name[20] ; char sex ; int age ; float score ; char addr[30] ; } struct student stu[5];

2 struct student { int num ; char name[20] ; char sex ; int age ; float score ; char addr[30] ; } stu[5];

3 struct studentstudent { int num ; char name[20] ; char sex ; int age ; float score ; char addr[30] ; } stu[5];

Page 10: 第 11 章  结构体与共用体

11. 结构体数组的初始化

1 、 struct student { int num ; char name[20] ; char sex ; int age ; float score ; char addr[30] ; } struct student stu[5]={{105,”Li Lin”,’M’,19,87.5,”103 Beijing Road”},{123,”Wang Min”,’F’,20,78,”101 Zhongshan Road”} ,{…} , {…} , {…}};

2 struct student { int num ; char name[20] ; char sex ; int age ; float score ; char addr[30] ; } stu[]= {{105,”Li Lin”,’M’,19,87.5,”103 Beijing Road”},{123,”Wang Min”,’F’,20,78,”101 Zhongshan Road”} ,{…} , {…} , {…}};

Page 11: 第 11 章  结构体与共用体

结构体数组的应用举例例 1 :设一个班有 30 名学生,读入学生的学号、姓名、性别、年龄、成绩等信息,并统计该班 20 岁以下同学的个数,算出该班的平均分。main( ){struct student {int num; char name[20]; char sex; int age; float score; }stu[30]; float sum, aver; int i, agenum; printf(“ 请依次输入学生的学号、姓名、性别、年龄、成绩。”);

for (i=0;i<30;i++)scanf(“%d%s%c%d%f ”,&stu[i].num, stu[i].name, &stu[i].sex, &stu[I].age, &stu[i].score);agenum=0; sum=0;for(i=0;i<30;i++){ sum=sum+stu[i].score; if stu[i].age<20 agenum++;}aver=sum/30;printf(“The number of age<20 is :%d \n The average score is:%f\n”,agenum, aver);}

Page 12: 第 11 章  结构体与共用体

结构体数组的应用练习练习 1 :设一个班有 30 名学生,读入学生的学号、姓名、性别、年龄、成绩等信息,并统计该班 20 岁以下男同学的个数。main( ){struct student {int num; char name[20]; char sex; int age; float score; }stu[30];int i, agenum; printf(“ 请依次输入学生的学号、姓名、性别、年龄、成绩”);

for (i=0;i<30;i++)scanf(“%d%s%c%d%f ”,&stu[i].num, stu[i].name, &stu[i].sex, &stu[i].age, &stu[i].score);agenum=0;for(i=0;i<30;i++){ if ( stu[i].age<20 && stu[i].sex = = ‘F’) agenum++;}printf(“The number of age<20 is :%d ”,agenum,);}

Page 13: 第 11 章  结构体与共用体

指向结构体类型数组的指针结构体类型指针的定义

Struct 结构体类型名 * 结构体指针变量

如:struct student { int num ; char name[20] ; char sex ; int age ; float score ; } struct student *p, stu[10], stu1;

P 可以指向一个 student 类型的结构体变量,也可以指向一个 student 类型的结构体数组或 student 类型结构体数组中的元素。

如: p=&stu1;

p=stu; p++;

p=&stu[2];

101 wang F 18 52 105 zhang M 20 92 110 Li F …p

p

Page 14: 第 11 章  结构体与共用体

指向结构体类型数组的指针如: p=&stu[1];

取值 20 的方法:

stu[1].age

(*p).age

P - > age

101 wang F 18 52 105 zhang M 20 92 110 Li F …

p

stu[5]

指向运算符

P->age++; (20)

++p->age; (21)

应用:用指针实现练习 1 :

Page 15: 第 11 章  结构体与共用体

指向结构体类型数据的指针判断下面的语句是否正确 ( 假定 struct student 已定义 )

struct student st[8],*p=st;

int *q=&st[5].num;

p=&st[5];p++;参见程序 D11_7.c :有一个结构体变量 stu ,内含学生姓名,学号,三门课成绩。要求在主函数种赋值,在另一个函数 print 中将数据打印出来。

Page 16: 第 11 章  结构体与共用体

根据 D11_7.c 回答问题:1 、结构体类型的定义可否放在主函数之内,为什么?2 、假定子函数中把 stu 的有关成员改变了值是否影响主函数中的 stu 的成员?3 、可否把 stu 做成全局变量而不用传递参数?4 、主函数中的 strcpy(stu.name,“Zhang Mary”); 可否换成 stu.name=“Zhang Mary”,为什么?3 、用结构体变量的指针做参数把 11_7.c 改为指针实现。见程序 D11_8.c

针对 D11_8.c 重新回答上面的 4 个问题,哪些答案发生了变化?为什么?这和前面的知识矛盾吗?

Page 17: 第 11 章  结构体与共用体

指向结构体数组的指针应用例 2 :设一个班有 30 名学生,读入学生的学号、姓名、性别、年龄、成绩等信息,并统计该班 20 岁以下男同学的个数。

main( ){struct student {int num; char name[20]; char sex; int age; float score; }stu[30] , *p;int i, agenum; printf(“ 请依次输入学生的学号、姓名、性别、年龄、成绩。”);

for (p=stu;p<stu+30;p++)scanf(“%d%s%c%d%f ”,&p->num, p->name, &p->sex, &p->age, &p->score);agenum=0; for(p=stu;p<stu+30;p++){ sum=sum+p->score; if p->age<20 agenum++;}printf(“The number of age<20 is :%d \n” ,agenum);}

Page 18: 第 11 章  结构体与共用体

结构体变量与结构体数组练习

作业 1 :定义一个结构体变量,包括年、月、日,计算该天在本年中是第几天?注意闰年问题。

作业 2 :输入两个复数,计算并输出他们的和及乘积,要求利用结构变量,返回结构数据类型的函数。

作业 3 :设有 5 名学生,读入学生的学号、性别、及 3 门课的成绩,输出这五个学生的信息并找出成绩最高的学生的学号。

作业 4 :利用结构体数组编程完成下列工作假定有三个候选人: Zhangsan,Lisi,Wangwu, 参加选举的人总共有 20人 ,编程统计这三个人各得票多少张。

Page 19: 第 11 章  结构体与共用体

链 表链表是一种常见的重要的数据结构。它是动态地存储分配的一种结构。

用数组存放数据时,必须事先定义固定的长度,如果事先难以确定数据的个数,则必须 把数组做的足够大,显然会造成内存的浪费。链表可以弥补这一缺点,即链表可以根据需要开辟存储空间。

如:

1249A

1356

B

1475

1249 1356 1475

C

1021

1021head

说明:1 、有一个头指针,可由指针变量实现;2 、表尾指针;3 、中间部分每个结点由两部分组成 由结构体类型变量实现

D

NULL

Page 20: 第 11 章  结构体与共用体

链 表

1249

52

Linda

90

Maryhead

定义结构体类型变量实现链表的结点:

struct student{float score; char name[10]; struct student *next; };struct student *head;

78

Tom

66

Jack

NULL

Page 21: 第 11 章  结构体与共用体

链表的常用函数

分配存储区函数: malloc( )Malloc(size);从内存中分配一个长度为 size个字节的连续存储区。释放存储区函数: free( )Free(*ptr);释放由指针 ptr所指向的存储区。分配 n个存储区函数: calloc( )Calloc(n, size);分配n个数据项的连续存储区,每个数据项大小为 size个字节。改变存储区大小函数: realloc( )Reslloc(*p,size);将指针 p所指向的存储区的大小改为 size个字节。

以上函数的原型在头文件 stdlib.h 中,使用前应做编译预处理。(#include <stdlib.h>)

Page 22: 第 11 章  结构体与共用体

建 立 链 表(结点添加法)

1、定义链表结点的结构类型,并测试该结构类型所占内存的字节数。

2、说明链表指针 head、 p、 h。其中 head为头指针,p为创建新结点的指针, h为指向链表尾结点的指针

3、创建第一个结点,将该结点的首地址分别附给头指针 head和尾指针 p。

4、循环创建第 n( 1<n<=26)个结点,让 h指向尾结点,让 p指向新创建的结点。

5、创建结束,令尾结点的指针为 NULL。

Page 23: 第 11 章  结构体与共用体

链表的建立

A Bhead

C ……

1 、 struct link {char ch; struct link *next; }; len=sizeof(struct link);

Z

NULL

Page 24: 第 11 章  结构体与共用体

链表的建立

A Bhead

1 、 struct link {char ch; struct link *next; }; len=sizeof(struct link);

p

C

h

2 、 struct link *head, *p, *h;

Page 25: 第 11 章  结构体与共用体

链表的建立

A Bhead

C ……

1 、 struct link {char ch; struct link *next; }; len=sizeof(struct link);

2 、 struct link *head, *p, *h;

3 、 p=(struct link *)malloc(len); scanf(“%c”, p->ch); h=p; head=p;

p

Z

NULL

Ah

head

Page 26: 第 11 章  结构体与共用体

链表的建立

A Bhead

C ……

1 、 struct link {char ch; struct link *next; }; len=sizeof(struct link);

2 、 struct link *head, *p, *h;

3 、 p=(struct link *)malloc(len); scanf(“%c”, p->ch); h=p; head=p;

Z

NULL

p

Ah

head

4 、 p=(struct link *)malloc(len); scanf(“%c”, p->ch); h->next=p; h=p;

p

B

h

Page 27: 第 11 章  结构体与共用体

链表的建立

A Bhead

C ……

1 、 struct link {char ch; struct link *next; }; len=sizeof(struct link);

2 、 struct link *head, *p, *h;

3 、 p=(struct link *)malloc(len); scanf(“%c”, p->ch); h=p; head=p;

A

Z

NULL

head

4 、 p=(struct link *)malloc(len); scanf(“%c”, p->ch); h->next=p; h=p;

p

B

h

5 、 h->next = NULL ;

…NULL

Z

Page 28: 第 11 章  结构体与共用体

链表的建立

A Bhead

C ……

#include<stdlib.h>Main( ){ struct link {char ch; struct link *next; }; len=sizeof(struct link); struct link *head, *p, *h; int I=‘A’ ; p=(struct link *)malloc(len); scanf(“%c”, p->ch); h=p; head=p;

while (I!=‘z’)

{p=(struct link *)malloc(len); scanf(“%c”, p->ch); h->next=p; h=p;

I++;}

h->next = NULL ;

}

Z

NULL

Page 29: 第 11 章  结构体与共用体

链表的输出

A Bhead

C ……

1 、必须要知道链表的第一个结点的地址;( head)2 、另设一个指针变量 p,令其指向 head 用来移动指针;3、若该链表不为空,则输出 p->ch ;4、移动指针:令 p指向 p->next ;5、重复以上操作,直至 p为 NULL (输出结束)。

p

Z

NULL

Page 30: 第 11 章  结构体与共用体

链表的输出

A Bhead

C ……

p

{ struct link {char ch; struct link *next; };Void print (struct link *head){struct link *p;

p = head; while (p!=NULL) {printf(“%c “, p->ch); p=p->next;} }

Z

NULL

p p p

A B C …… Y Z

Page 31: 第 11 章  结构体与共用体

链表的建立和输出练习

练习 3 :设有 10 名学生,读入学生的学号、性别、及 3 门课的成绩等信息,并输出该班学生信息。(用链表实现)

Page 32: 第 11 章  结构体与共用体

链表的删除

1 3head

4 7

NULL

如:若要删除值为 4 的结点,只要让值为 3 的结点指向值为 5 的结点,然后释放值为 4 的结点的空间即可。

即: p->next=q->next;

free(q);

1 3head

4

5

7

NULL

p q

5

Page 33: 第 11 章  结构体与共用体

链表的删除

例:设有一个链表:每个结点包括工号、工资(如下所示)。写一函数 del ,删除工号为 4 的结点 ( 设工号互不重复)。Struct worker{int num; int money; struct worker *next;}

While (p!=NULL && p->num!=4) {q=p; p=p->next;} if(p->=4) if (p==head) head=p->next; else {q->next=p->next; free(p); } else printf(“没找到” );Return(head);}

Struct shuju *del(struct worker *head){Struct worker *p,*q;If (head==null) goto end;P=head;

Page 34: 第 11 章  结构体与共用体

链表的删除练习设有一个链表:每个结点的值为一个整数 ( 如下所示)。写一函数 del ,删除值为 4 的倍数的结点。Struct sj{int val; struct sj *next;}

1 4head

3

p

7

NULL

Struct sj *del(struct sj *head){Struct sj *p,*q; Int I=0; If (head==null) goto end; P=head;

While (p!=NULL){if (p->val%4!=0) {q=p; p=q->next;} else if (p==head) {head=p->next; p=head;} else {q->next=p->next; free(p); p=q->next;} } Return(head); }

8

Page 35: 第 11 章  结构体与共用体

链表的插入

1 3head

7 11

NULL

如:若要在值为 3 的结点和值为 7 的结点中间插入一值为 5 的结点,需要:

1 、开辟一个空间,存入值为 5 的结点; h=(struct link *)malloc(len);

2 、让值为 3 的结点指向值为 5 的结点; p->next=h;

3 、让值为 5 的结点指向值为 7 的结点。 h->next=q;

Struct link {int val; struct link *next;}; len=sizeof(struct link);

p q

9

5

Page 36: 第 11 章  结构体与共用体

链表的插入

1 3head

7 11

NULL

如:若要在链表的最前端插入一值为 5 的结点,需要:

1 、开辟一个空间,存入值为 5 的结点; h=(struct link *)malloc(len);

2 、令指针 p 也指向链头,让 head 指针指向欲插入结点; p=head; head=h;

3 、让值为 5 的结点指向值为 7 的结点。 h->next=p;

Struct link {int val; struct link *next;}; len=sizeof(struct link);

p

9

5

Page 37: 第 11 章  结构体与共用体

链表的插入

1 3head

7 11

NULL

如:若要在链尾插入一值为 5 的结点,需要:

1 、开辟一个空间,存入值为 5 的结点; h=(struct link *)malloc(len);

2 、令指针 p 也指向链尾,让 p 指向欲插入结点; p->next = h;

3 、让新插入的结点的 next 为 NULL 。 h->next=NULL;

Struct link {int val; struct link *next;}; len=sizeof(struct link);

p

NULL

9

5

Page 38: 第 11 章  结构体与共用体

链表的操作练习

练习 1 :已有 a 、 b 两个链表,且它们的头指针分别为 head1 、head2 。每个链表中的结点包括学号、成绩(如下所示)。要求把两个链表按学号的升序合并。(设学号互不重复)

Struct student

{ int num;

float score;

struct student *next;

}

练习 2 :将一个链表按逆序排列,即链头当链尾,链尾当链头。

Page 39: 第 11 章  结构体与共用体

双向链表

head ^ a1 ^a2 a3 a4

p

^ b ^s

设要在结点 p的后面插入一个值为 b的结点 s,试写出指针的改变情况。

s->next=p->next;p->next->pre=s;

p->next=s;s->pre=p;

设结点结构如下: struct node{int val; struct node *next; struct node *pre;}

p->next

Page 40: 第 11 章  结构体与共用体

双向链表

head ^ a1 ^a2 a3 a4

p

设要删除结点 p试写出指针的改变情况。 p->pre->next=p->next;

p->next->pre=p->pre;free(p);

设结点结构如下: struct node{int val; struct node *next; struct node *pre;}

p->pre p->next

Page 41: 第 11 章  结构体与共用体

循环链表

head a1 a2 a3

循环链表有如下几个特点:

1 、在循环链表中增加一个头结点,使得循环链表对空表和非空表的操作实现了统一;2、循环链表最后一个结点的指针域不是空,而是指向头结点。3、判断循环链表是否为空的办法是看看头结点的后继结点是否还是头结点。4、在循环链表中,从任何一个结点出发,都可以访问到表中其他所有结点。

Page 42: 第 11 章  结构体与共用体

共用体类型的定义

在程序中,如需要存储一组性质相关、而类型不同的数据时,就可以使用结构体类型。

结构类型定义的一般形式:struct 结构类型名{

成员类型 1 成员名 1 ; 成员类型 2 成员名 2 ; ……

成员类型 n 成员名 n ;};

说明:1 struct 是结构类型定义的保

留字,必须原样照写;2 结构类型名应符合标识符

的规定,在以后的结构变量声明中可以被引用;

3 大括号内是由结构成员组成的结构体,每个成员的数据类型可以是基本类型,也可以是构造类型。

4 不要漏掉分号。

Page 43: 第 11 章  结构体与共用体

共用体变量的引用

引用方法:共用体变量名.成员名[ 使用说明 ] :1、共用体变量 不能进行初始化2、一个共用体变量占用的内存空间,取决于共用体成员中占用内存空间最大的成员。3、同一个共用体变量可以存储不同类型的成员,但每一时刻只能有一个成员起作用,其他成员不起作用。4 、共用体变量中起作用的成员是最后一次赋值的成员。在存储一个新的成员后,原有成员将失去作用。

Page 44: 第 11 章  结构体与共用体

共用体变量的类型特点

1 、同一时刻只有一个成员有意义,其它无意义

union da{int a;char ch;float f;}x;

如果有 x.a=65; 此时只有 x.a 有意义,但 x.ch 与 x.f 也有一个值,但没有任何实际意义。若再执行 x.f=90.78 ;则此时只有 x.f 有意义,但 x.ch 与 x.a 也有一个值,但无任何实际意义。

2 、共用体变量的地址和其成员的地址是相同的 &x,&x.a,&x.ch,&x.f 的值是一样的。3 、共用体变量在定义时不能赋初值

如: union da x={24,’A’,56.78}; 是错误的

Page 45: 第 11 章  结构体与共用体

共用体变量的类型特点

4 、共用体变量不能做函数参数,函数返回值也不能是共用体类型。但其指针可做函数参数和返回值,其成员也可做函数参数和返回值

Page 46: 第 11 章  结构体与共用体

共用体类型变量的应用• 参见课本 11.8.2• 例题 11.12

Page 47: 第 11 章  结构体与共用体

和结构体以及共用体类型一样,枚举类型也是用户自己根据需要创建的一种新的数据类型。如果一个变量,它只有有限的几种可能的取值,则这类变量就可以定义为枚举类型——因为这类变量的可能取值可以一一列举出来。例:判断下列哪种变量可以定义为枚举类型的变量?1 、表示性别的变量2 、表示年份的变量3 、表示月份的变量4 、表示星期几的变量

枚举类型

Page 48: 第 11 章  结构体与共用体

enum 枚举类型名 { 值 1, 值 2, 值 3,…… 值 n} ;

例如:命令 enum sex{male,female}; 定义了一种新的数据类型 enum sex ,这种类型的变量的值只有两种可能,要么是 male ,要么是 female 。

例如: enum weekday{sun,mon,tue,wed,thu,fri,sat}; 命令定义了另一种新的数据类型 enum weekday ,这种类型的变量的值只能是 sun,mon……sat 之一。

一、 枚举类型的定义格式

Page 49: 第 11 章  结构体与共用体

例:判断下面语句的对错

1 、 enum sex a,b,c;2 、 enum weekday workday;3 、 enum color{red,black,green}c1,c2;

上面的三条语句都对。 1 和 2 是先定义类型,再定义变量, 3 是在定义类型的同时定义变量

一、 枚举类型的定义格式

Page 50: 第 11 章  结构体与共用体

若用 enum weekday{sun,mon,tue,wed,thu,fri,sat}; 命令定义了另一种新的数据类型 enum weekday ,则 {} 里面的 sun,mon……sat 等被称为枚举常量或枚举元素。

使用它们必须注意以下事项:1 、默认情况下,枚举元素按照它们所在的位置,它们所代表的值分别是 0,1,2,3……

例如:若有 enum weekday x; x=tue; 则定义 x 为 enum weekday 类型的变量,且把 x 的值设为 tue ,则x 实质是得到了一个常量 2 。

二、 枚举元素和枚举常量

Page 51: 第 11 章  结构体与共用体

2 、在定义枚举类型时,也可以改变枚举元素的默认值。如下所示:enum weekday{sun=7,mon=1,tue,wed,thu,fri,sat}; 则各个枚举元素的值分别时 7,1,2,3,4,5,6

二、 枚举元素和枚举常量

3 、枚举变量和枚举元素可用来做判断比较若有 enum weekday{sun,mon,tue,wed,thu,fri,sat};则 enum weekday a=mon,b=sat; 是定义两个枚举类型的变量 a 和 b ,并给它们赋以初值。判断下面的代码的执行结果:if (a==mon) printf(“ 星期一” );else printf(“NO”);

if (b<a) printf(“b is less”);else printf(“a is less”);

Page 52: 第 11 章  结构体与共用体

4 、不能在定义之外改变枚举元素的值若在定义之外有 sun=0;mon=2 ;等类似的操作是错误的。5 、若 a 是 enum weekday 类型的枚举变量,则 a=(enum weekday)3 或 a= (enum weekday)(10-7) 都是相当于把枚举元素中序号为 3 的枚举元素送给 a 。

Page 53: 第 11 章  结构体与共用体

例:口袋中有红、黄、蓝、白、黑 5 种颜色的球若干个,每次从口袋中取出 3 个球,问得到不同颜色的球的可能取法有多少,打印出每种组合的三种颜色

分析:球的颜色只能是 5 种颜色中的一种,所以可以用枚举类型代表球的颜色。再分别定义三个变量 i,j,k 来代表取出的三个球当中的第一个、第二个、第三个球的颜色。很显然它们只能是 5 种颜色之一,且不能重复。定义一个变量 n 来累计合乎要求的取法,另外设一个字符数组,分别代表 5 种颜色的英文名称。

见课本 11.9 例题 11.13

见程序 D11-9.c 和 D11_10.c ,并比较两种方法的异同点

使用枚举类型举例

Page 54: 第 11 章  结构体与共用体

自定义类型在 C语言中,不但可以直接使用基本数据类型和构造类型,还可以使用 typedef 定义新的类型名代替已有的类型名。自定义类型的一般形式: typedef 原类型名 新类型名;

其中,原类型名可以是基本数据类型,也可以是构造类型名,新类型名应符合标识符的构成规则,习惯上采用大写字母表示。

例如 : typedef struct ymd {int year;

int month; int day; }DATE;

用 DATE 类型代替结构体类型 struct ymd ,因此,下面的定义是等价的:

DATE birth;

struct ymd birth;

Page 55: 第 11 章  结构体与共用体

自定义类型自定义类型使用说明:

1、 typedef只能定义类型名,不能直接定义变量名;

2、 typedef定义时并不产生新的数据类型,只是为原数据类型增加了一个“别名”,在变量说明时,新类型名与原类型名的作用完全一样。

3、 typedef定义也适用于数组;

4 、使用 typedef 语句,可以增强程序的可移植性,便于程序的修改。

Page 56: 第 11 章  结构体与共用体

1 、下列程序的输出结果是( 6 ) struct abc {int a,b,c;} main() {struct abc s[2]={{1,2,3},{4,5,6}}; int t; t=s[0].a+s[1].b; printf(“%d\n”,t); }2 、变量 a 所占内存字节数是( 6 ) union U {char st[4]; int i; long l; };

struct A {int c; union U u; }a;

Page 57: 第 11 章  结构体与共用体

3 、有如下定义:

struct person {char name[9]; int age;};

struct person class[10]={“John”,17,

“Paul”,19,

“Mary”,18,

“Adam”,16};

根据以上定义,能输出字母M 的语句是()。

printf(“%c\n”,class[2].name[0]);

Page 58: 第 11 章  结构体与共用体

4 、以下对结构体类型变量的定义中,不正确的是( C ) A ) typedef struct aa {int n; float m; }AA; AA td1;

B ) #define AA struct aa AA{int n; float m; } td1 ;

C ) struct {int n; float m; }aa; struct aa td1;

D ) struct {int n; float m; } td1;

Page 59: 第 11 章  结构体与共用体

5 、设有以下说明语句

struct ex

{int x;

float y;

char z;}example;

下面叙述中不正确的是( B )

A ) struct 是结构体类型的关键字

B ) example 是结构体类型名

C ) x, y, z都是结构体成员名

D ) struct ex 是结构体类型

Page 60: 第 11 章  结构体与共用体

6 、以下程序的输出结果是( 0 )

union myun

{struct

{int x,y,z;}u;

int k;}a;

main()

{a.u.x=4; a.u.y=5; a.u.z=6;

a.k=0;

printf(“%d”,a.u.x);

}

Page 61: 第 11 章  结构体与共用体

7 、以下程序用来输出结构体变量 ex 所占存储单元的字节数,请填空:

struct st

{char name[20];

double score;};

main()

{struct st ex;

printf(“ex size: %d”, sizeof( ));

}