31
1 计计计计计计计 计计计 计计计计计计11.1 计计 11.2 计计计计 计计计计计计计 11.3 计计 计计计计计 11.4 计计 计计计计计计 11.5 计计 计计 11.6 计计计计 计计计计计计计 11.7 计计计计计计计 11.8 计计11.9 计计计计 11.10 计 typedef 计计计计计计 计 11 计 计计 计计计计 体体 计计计计计计 计计 计计计计计 计计 计计 计计

本章教学内容: 11 .1 概述 11 .2 定义结构体类型变量的方法 11 .3 结构体变量的引用 11 .4 结构体变量的初始化 11.5 结构体数组

  • Upload
    vartan

  • View
    117

  • Download
    0

Embed Size (px)

DESCRIPTION

第 11 章 结构体与共用体. 本章教学内容: 11 .1 概述 11 .2 定义结构体类型变量的方法 11 .3 结构体变量的引用 11 .4 结构体变量的初始化 11.5 结构体数组 11.6 指向结构体类型数据的指针 11.7 用指针处理链表 11.8 共用体 11.9 枚举类型 11.10 用 typedef 命名已有类型. 本章教学内容: 结构体定义与引用 结构体数组 链表. 11.1 概述. - PowerPoint PPT Presentation

Citation preview

Page 1: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

1计算机工程学院 伍俊明

本章教学内容:11.1 概述11.2 定义结构体类型变量的方法11.3 结构体变量的引用11.4 结构体变量的初始化11.5 结构体数组 11.6 指向结构体类型数据的指针 11.7 用指针处理链表 11.8 共用体 11.9 枚举类型 11.10 用 typedef 命名已有类型

第 11 章 结构体与共用体本章教学内容:

结构体定义与引用 结构体数组 链表

Page 2: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

2

11.1 概述许多情况下,需要将不同类型的数据组合成一个整体,如一个学生有学号、姓名、性别、年龄、地址等属性。

C 语言允许构造结构体类型,以处理这类数据,如:

计算机工程学院 伍俊明

100101 Li Fun M 18 87.5 Beijing Num name sex age score addr

结构体类型名

类型名 成员名或域名

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

Page 3: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

3

11.1 概述结构体类型定义的一般形式:

struct 结构体类型名 {

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

类型 n 成员名 n ; };

计算机工程学院 伍俊明

Page 4: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

4

11.2 定义结构体变量的方法定义结构体变量有三种方法

一、先声明结构体类型,再定义结构体变量例: struct student1, student2;

定义 student1 、 student2 两个变量后系统为它们分配存储单元,每个变量至少占用 59 字节空间( =2+20+1+2+4+30 )

需要注意,定义结构体类型与定义结构体变量是两个不同的概念,结构体类型好比整型 int ,而结构体变量好比是整型变量i 、 j 、 k 。本方法值得推荐:先定义结构体类型,再定义结构体变量。

计算机工程学院 伍俊明

student1

100101 ZhangXin M 19 90.5 Shanghai

100102 WangLi F 20 98 Beijing

student2

Page 5: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

5

11.2 定义结构体变量的方法二、在声明结构体类型的同时定义结构体变量

定义形式 struct 结构体类型名 {

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

类型 n 成员名 n ; } 结构体变量名列表;

这种“二合一”的方式也是很好的方法,也推荐使用。

计算机工程学院 伍俊明

例: struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; } student1, student2 ;

Page 6: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

6

11.2 定义结构体变量的方法三、直接定义结构体变量

定义形式 struct

{

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

类型 n 成员名 n ; } 结构体变量名列表;

说明:这种方法未定义类型名,以后无法再引用类型名,建议尽量不使用本方法。

例: struct { int num; char name[20]; char sex; int age; float score; char addr[30]; } student1, student2 ;

无类型名

Page 7: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

7

11.2 定义结构体变量的方法结构体成员也可以是结构体

struct date

{ int month;

int day;

int year;

};

计算机工程学院 伍俊明

birthday addr

num name sex age Month day year

struct { int num; char name[20]; char sex; int age; struct date birthday; char addr[30]; } student1, student2 ;

addr

Page 8: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

8

11.3 结构体变量的引用结构体变量的使用原则 结构体变量不能作为整体进行输入、输出Printf(“%d,%s,%c,%d,%f,%s\n”, student1); 结构体变量的成员可以视为所属类型的变量进行处理student1.score=student2.score;

sum=student1.score+student2.score; 如结构体变量的成员也是结构体类型的,需逐级地处理其

下层的各个成员student1.birthday.month=12;

scanf(“%d”, &student1.birthday.year);

stuent1.age++;

计算机工程学院 伍俊明

Page 9: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

9

11.4 结构体变量的初始化变量在定义时也可以初始化

#include <stdio.h>main() { struct student { long int num; char name[20]; char sex; char addr[20]; } a={89031, "Li Lin", 'M', "123 Beijing Road"}; printf("NO.:%ld\nname:%s\nsex:%c\naddress:%s\n", a.num,a.name,a.sex,a.addr);}

计算机工程学院 伍俊明

运行结果:No. : 10101

name : LiLin

sex :Maddress : 123 Beijing Road

Page 10: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

10

11.5 结构体数组尽管结构体变量包含了若干成员,但结构体类型的数据也可作为数组元素,构成结构体数组。

11.5.1 定义结构体数组结构体数组定义与其它类型的数组定义方法相仿例:

计算机工程学院 伍俊明

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

Page 11: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

11

11.5 结构体数组11.5.2 结构体数组的初始化

结构体数组也可以象其它数组一样初始化。struct student{ int num; char name[20] ; char sex ; int age ; float score; char addr[30] ;} stu[2]= {{10101,″LiLin″,′M′,18,87.5,″103 BeijingRoad″}, {10102,″Zhang Fun″,′M′,19,99,″130 Shanghai Road″}} ;

数组初始化也可以采用下面形式: struct student stu[]={{…}, {…},…{…}};

计算机工程学院 伍俊明

Page 12: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

12

11.5 结构体数组11.5.3 结构体数组应用举例

例:对候选人得票进行统计。设有 3 个候选人,每次输入一人得票候选人名字,输出各人的得票结果。

计算机工程学院 伍俊明

#include <stdio.h>#include <strint.h>struct person{ char name[20]; int count;} leader[3]={"Li", 0, "Zhang", 0, "Fun", 0};

void main() { int i,j; char leader_name[20]; for (i=1;i<=10;i++) { scanf("%s", leader_name); for(j=0;j<3;j++) if(strcmp(leader_name,leader[j].name)==0) leader[j].count++; } /*for*/ printf("\n"); for(i=0;i<3;i++) printf("%5s:%d\n",leader[i].name, leader[i].count);} /*main*/

11-2.CPP

运行结果: Li↙

  Fun↙

  Zhang↙

  Zhang↙

  Fun↙  Li↙

  Fun↙

  Zhang↙

  Li↙

  Li : 4  Zhang : 3  Fun : 3

Page 13: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

13

11.6 指向结构体类型数据的指针指针也可以指向结构体类型的变量,以及结构数组中的元素。

11.6.1 指向结构体变量的指针指向结构体变量的指针的定义

struct 结构体类型 * 指针变量名列表;例: struct student stu_1, *p;结构体指针变量的使用

p=&stu_1; stud_1.num=89101;

strcpy(p->name, “Li Lin”); p->sex=‘M’; (*p).score=89.5; 结构体变量的访问方法 结构体变量 . 成员名 (* 结构体变量的指针 ). 成员名 结构体变量的指针 -> 成员名

计算机工程学院 伍俊明

#include <stdio.h>#include <strint.h>struct student{ long num; char name[20]; char sex; float score;}

11-3.CPP

89101

“Li Lin”

‘M’

89.5

p *p

Page 14: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

14

11.6 指向结构体类型数据的指针11.6.2 指向结构体数组元素的指针

结构体变量的指针也可以指向结构体数组中的元素,例 11.4#include <stdio.h>struct student{ int num; char name[20]; char sex; int age;};struct student stu[3]={{10101,"Li Lin",'M',18}, {10102,"Zhang Fun",'M',19},{10104,"Wang Min",'F',20}};

计算机工程学院 伍俊明

11-4.CPP

void main() { struct student*p; printf("No. Name sex age\n"); for (p=stu;p<stu+3;p++) printf("%5d %-20s %2c %4d\n", p->num, p->name, p->sex, p->age);}

10101

Li Lin

‘M’

18

p

10102

Zhang Fun

M

19

P’

10104

Wang Min

F

20

P’’

Stu[0]

Stu[1]

Stu[2]

Page 15: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

15

11.6 指向结构体类型数据的指针11.6.3 用结构体变量和指向结构体变量的指针作函数参数

将一个结构体变量的值传递给一个函数,有三种方法: 用结构体变量的成员作参数——传值 用结构体变量作实参——传值 用指向结构体变量(或数组)的指针作实参,将结构体变

量(或数组)的地址传给形参——传地址,推荐使用例 11.5 、 11.6 有一个结构体变量,内含学生学号、姓名和 3

门课程成绩,要求在 main 函数中赋值,在另一函数中输出。

计算机工程学院 伍俊明

11-5.CPP 11-6.CPP

对字符串变量或成员赋值,需要使用 strcpy 函数。

Page 16: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

16

11.7 用指针处理链表11.7.1 链表概述

链表是一种重要的动态数据结构,能够根据需要动态地分配和回收存储单元,适用于元素个数不明确或不固定的情形。

链表是通过指针将若干数据元素(也称结点)按一定原则连接起来的,如下图:

链表的结点:存放有用户数据,也有指向下一结点的指针,两类数据类型不一,因此,是一种结构体类型的。

链表的有一个“头指针”,存放第一个结点的地址,指向第一个结点。

链表中各个结点所使用的存储空间可以是不连续的。计算机工程学院 伍俊明

Page 17: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

17

11.7 用指针处理链表链表结点的定义

若 A 、 B 、 C 、 D 分别表示四个学生的学号和成绩,定义如下

struct student { int num; float score; struct student *next; /* 定义指向下一结点的指针域 */ }

计算机工程学院 伍俊明

Page 18: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

18

11.7 用指针处理链表11.7.2 简单链表的建立与输出

计算机工程学院 伍俊明

#include <stdio.h>#define NULL 0 struct student{ long num; float score; struct student *next; };void main() { struct student a, b, c, *head, *p; head=&a; a. num=99101; a.score=89.5; a.next=&b; b. num=99103; b.score=90; b.next=&c; c. num=99107; c.score=85; c.next=NULL; p=head; do {printf("%ld %5.1f\n",p->num,p->score); p=p->next; } while(p!=NULL);}

运行结果:1010189.5

1010390.0

1010785.0

Page 19: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

19

11.7 用指针处理链表11.7.3 处理动态链表所需的函数

malloc 函数 函数原型: 函数功能: 申请长度为 size连续存储区,返回其始址

calloc 函数 函数原型: 函数功能:为一维数组的元素分配 n 个长度为 size 的存

储空间,返回其始址free 函数

函数原型: 函数功能:释放指针 p 所指的动态存储区

计算机工程学院 伍俊明

void *malloc(unsigned int size)void *malloc(unsigned int size)

void *cvoid *calloc(unsigned n, unsigned size)alloc(unsigned n, unsigned size)

void free(void *p)void free(void *p)

Page 20: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

20

11.7 用指针处理链表11.7.4 建立动态链表#include <stdio.h>

#include <malloc.h>

#define NULL 0

#define LEN sizeof(struct student)

struct student

{ long num;

float score;

struct student *next;

};

int n;

计算机工程学院 伍俊明

struct student *creat() { struct student *head, *p1, *p2; n=0; p1=p2=( struct student*) malloc(LEN); scanf("%ld,%f",&p1->num,&p1->score); head=NULL; while(p1->num!=0) { n=n+1; if(n==1) head=p1; else p2->next=p1; p2=p1; p1=(struct student*)malloc(LEN); scanf("%ld,%f",&p1->num,&p1->score); } /*while*/ p2->next=NULL; return(head);}11-8.CPP

Page 21: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

21

11.7 用指针处理链表11.7.5 输出链表——依次输出各个结点中的数据void print(struct student *head) {

struct student *p;

printf("\nNow,These %d records are:\n",n);

p=head;

if (head!=NULL)

do {

printf("%ld %5.1f\n",p->num,p->score);

p=p->next; /* 指针后移一个结点 */

} while(p!=NULL);

}

计算机工程学院 伍俊明

Page 22: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

22

11.7 用指针处理链表

计算机工程学院 伍俊明

struct student *del(struct student *head,long num) { struct student *p1,*p2; if (head==NULL){printf("\nlist null!\n"); goto end;} p1=head; while(num!=p1->num && p1->next!=NULL) {p2=p1;p1=p1->next;} /*寻找待删除的元素 */ if(num==p1->num) { /*查找成功 */ if (p1==head) head=p1->next; /*待删除的结点是头结点 */ else p2->next=p1->next; printf("delete:%ld\n",num); n=n-1; } else printf(“%ld not been found!\n”,num); /*查找失败 */ end:return(head);}

11.7.6 对链表的删除操作——删除满足条件的结点

Page 23: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

23

11.7 用指针处理链表11.7.7 对链表的插入操作——将结点插入到链表中合适位置

在按学号从小到大排序的链表中插入新学员信息,保持有序

计算机工程学院 伍俊明

struct student *insert(struct student *head, struct student *stud) { struct student *p0,*p1,*p2; p1=head; p0=stud; if (head==NULL) {head=p0; p0->next=NULL;} /*新元素作为头结点 */ else { while((p0->num>p1->num) && (p1->next!=NULL)) {p2=p1; p1=p1->next;} /*while 语句用于找到合适的位置 */ if (p0->num<=p1->num) { /*新结点应该插入到链表的中间 */ if(head==p1) head=p0; else p2->next=p0; p0->next=p1;} else {p1->next=p0; p0->next=NULL;} /*新元素插入到链尾 */ } /*if (head)*/ n=n+1; return(head);}

Page 24: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

24

11.7 用指针处理链表11.7.8 对链表的综合操作(将建立、输出、删除、插入)

计算机工程学院 伍俊明

void main() { struct student *head,*stu; long del_num;printf("input records:\n"); head=creat(); print (head); printf("\ninput the deleted number:"); scanf("%ld",&del_num); while (del_num!=0) { head=del(head,del_num); print (head); printf ("input the deleted number:"); scanf("%ld",&del_num);} printf("\ninput the inserted record:"); stu=(struct student *) malloc(LEN); scanf("%ld,%f",&stu->num,&stu->score); while(stu->num!=0){ head=insert(head,stu); printf("input the inserted record:");stu=(struct student *)malloc(LEN); scanf("%ld,%f",&stu->num,&stu->score); }}

Page 25: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

25

11.8 共用体一、共用体:将不同类型的变量存放在同一段存储单元中

定义形式:例: union data

{ int i;

char ch;

float f;

} a, b, c;

说明: 每个共用体变量占用 4 字节 每个变量只能存放其中一个成员 变量的内容为最后一次保存的值

计算机工程学院 伍俊明

union union 共用体类型名共用体类型名{ { 类型类型 1 1 成员成员 11 ;;……;类型;类型 n n 成成员员 nn ;;} } 变量名列表;变量名列表;

Page 26: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

26

11.8 共用体二、共用体变量的引用方式

举例: a.i, a.f, b.ch, c.f

三、共用体类型数据的特点不同类型的成员竞争使用同一存储区共用体变量只保存最后存入的值

例: a.i=1; a.ch=‘a’; a.f=1.5; 执行这三个语句后 a 中只有 f的值

共用体各成员的地址都相同: &a 、 &a.i 、 &a.ch 、 &a.f 相同共用体变量不能作为函数参数,函数返回值不许是共用体变量

,但可以返回指向共用体变量的指针共用体的成员可以是结构体类型的,结构体成员也可以是共用

体类型的计算机工程学院 伍俊明

共用体变量名共用体变量名 .. 成员名成员名

Page 27: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

27

11.8 共用体例 11.12 设有若干个人员的数据,其中有学生和教师。学生的数据中包括:姓名、号码、性别、职业、班级。教师的数据包括:姓名、号码、性别、职业、职务。可以看出,学生和教师所包含的数据是不同的。现要求把它们放在同一表格中。

计算机工程学院 伍俊明

11-12.CPP

Page 28: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

28

11.9 枚举类型枚举类型:将变量的值一一列举出来,每个值是标识符。枚举类型定义的一般形式:

例: enum weekday{sun,mon,tue,wed,thu,fri,sat}enum weekday{sun,mon,tue,wed,thu,fri,sat}

enum weekday workday, week_end;enum weekday workday, week_end;

workday=mon; week_end=sun;workday=mon; week_end=sun;

说明: 枚举值都是标识符,按常量来处理,不能对它赋值 每个枚举值都有一个编号,默认值从 0开始,依次增 1 ,

也可改变: enum weekday={sun=7, mon=1,tue,wed,thu,fri,sat} workday, week_end;

枚举值可依据其编号大小进行比较。计算机工程学院 伍俊明

enum enum 枚举类型名枚举类型名 {{标识符标识符 1,1, … , … , 标识符标识符 n}n}

Page 29: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

29

11.9 枚举类型例: 11.13 口袋中有红、黄、蓝、白、黑 5 种颜色的球若干个。每次从口袋中先后取出3个球,问得到 3 种不同色的球的可能取法,输出每种排列的情况。

计算机工程学院 伍俊明

11-13.CPP

Page 30: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

30

11.10 用 typedef 命名已有类型

C 语言允许用户用 typedef 为数据类型重新命名

例: typedef int INTEGER;

typedef struct {int month; int day; int year;}DATE;

INTEGER i, j; DATE birthday, *p;

例: typedef int NUM[100]; /* 声明 NUM 为整型数组类型 */

NUM n; /* 定义 n 为整型数组变量 */

例: typedef char *STRING;/*STRING 为字符指针类型 */

STRING p, s[10]; /*p 为指针变量, s 为指针数组 */

例: typedef int (*POINTER)(); /*POINTER 为函数指针类型 */

POINTER p1, p2; /*p1 、 p2 为 POINTER 类型的指针变量*/

计算机工程学院 伍俊明

typedef typedef 数据类型 类型名;数据类型 类型名;

Page 31: 本章教学内容: 11 .1  概述 11 .2  定义结构体类型变量的方法 11 .3  结构体变量的引用 11 .4  结构体变量的初始化 11.5   结构体数组

31

第 11 章 结构体与共用体作业 (P318) 11.2 11.3 11.5 11.9 11.11

计算机工程学院 伍俊明