1 / 31

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

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

vartan
Download Presentation

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

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第11章 结构体与共用体 • 本章教学内容: • 11.1 概述 • 11.2 定义结构体类型变量的方法 • 11.3 结构体变量的引用 • 11.4 结构体变量的初始化 • 11.5 结构体数组 • 11.6 指向结构体类型数据的指针 • 11.7 用指针处理链表 • 11.8 共用体 • 11.9 枚举类型 • 11.10 用typedef命名已有类型 • 本章教学内容: • 结构体定义与引用 • 结构体数组 • 链表 计算机工程学院 伍俊明

  2. 11.1 概述 • 许多情况下,需要将不同类型的数据组合成一个整体,如一个学生有学号、姓名、性别、年龄、地址等属性。 • C语言允许构造结构体类型,以处理这类数据,如: Numname sex age score addr 100101 Li Fun M 18 87.5 Beijing struct student { int num; char name[20]; char sex; int age; float score; char addr[30]; }; 结构体 类型名 类型名 成员名 或域名 计算机工程学院 伍俊明

  3. 11.1 概述 • 结构体类型定义的一般形式: struct 结构体类型名 { 类型1 成员名1; 类型2 成员名2; …… 类型n 成员名n; }; 计算机工程学院 伍俊明

  4. 100101 ZhangXin M 19 90.5 Shanghai 100102 WangLi F 20 98 Beijing 11.2 定义结构体变量的方法 • 定义结构体变量有三种方法 一、先声明结构体类型,再定义结构体变量 • 例:struct student1, student2; • 定义student1、student2两个变量后系统为它们分配存储单元,每个变量至少占用59字节空间(=2+20+1+2+4+30) • 需要注意,定义结构体类型与定义结构体变量是两个不同的概念,结构体类型好比整型int,而结构体变量好比是整型变量i、j、k。 • 本方法值得推荐:先定义结构体类型,再定义结构体变量。 student1 student2 计算机工程学院 伍俊明

  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 ; 计算机工程学院 伍俊明

  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 ; 无类型名

  7. birthday addr num name sex age Month day year 11.2 定义结构体变量的方法 • 结构体成员也可以是结构体 struct date { int month; int day; int year; }; struct { int num; char name[20]; char sex; int age; struct date birthday; char addr[30]; } student1, student2 ; addr 计算机工程学院 伍俊明

  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++; 计算机工程学院 伍俊明

  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:M address:123 Beijing Road 计算机工程学院 伍俊明

  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]; 计算机工程学院 伍俊明

  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[]={{…}, {…},…{…}}; 计算机工程学院 伍俊明

  12. 11.5 结构体数组 运行结果: Li↙ Fun↙ Zhang↙ Zhang↙ Fun↙ Li↙ Fun↙ Zhang↙ Li↙   Li:4   Zhang:3   Fun:3 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.5.3 结构体数组应用举例 • 例:对候选人得票进行统计。设有3个候选人,每次输入一人得票候选人名字,输出各人的得票结果。 #include <stdio.h> #include <strint.h> struct person { char name[20]; int count; } leader[3]={"Li", 0, "Zhang", 0, "Fun", 0}; 计算机工程学院 伍俊明

  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; } p *p 89101 “Li Lin” ‘M’ 89.5 计算机工程学院 伍俊明

  14. 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); } 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} }; p 10101 Li Lin Stu[0] ‘M’ 18 P’ 10102 Zhang Fun Stu[1] M 19 P’’ 10104 Wang Min Stu[2] F 计算机工程学院 伍俊明 20

  15. 11.6 指向结构体类型数据的指针 11.6.3 用结构体变量和指向结构体变量的指针作函数参数 • 将一个结构体变量的值传递给一个函数,有三种方法: • 用结构体变量的成员作参数——传值 • 用结构体变量作实参——传值 • 用指向结构体变量(或数组)的指针作实参,将结构体变量(或数组)的地址传给形参——传地址,推荐使用 • 例11.5、11.6 有一个结构体变量,内含学生学号、姓名和3门课程成绩,要求在main函数中赋值,在另一函数中输出。 对字符串变量或成员赋值,需要使用strcpy函数。 计算机工程学院 伍俊明

  16. 11.7 用指针处理链表 11.7.1 链表概述 • 链表是一种重要的动态数据结构,能够根据需要动态地分配和回收存储单元,适用于元素个数不明确或不固定的情形。 • 链表是通过指针将若干数据元素(也称结点)按一定原则连接起来的,如下图: • 链表的结点:存放有用户数据,也有指向下一结点的指针,两类数据类型不一,因此,是一种结构体类型的。 • 链表的有一个“头指针”,存放第一个结点的地址,指向第一个结点。 • 链表中各个结点所使用的存储空间可以是不连续的。 计算机工程学院 伍俊明

  17. 11.7 用指针处理链表 • 链表结点的定义 • 若A、B、C、D分别表示四个学生的学号和成绩,定义如下 struct student { int num; float score; struct student *next; /*定义指向下一结点的指针域*/ } 计算机工程学院 伍俊明

  18. 11.7 用指针处理链表 11.7.2 简单链表的建立与输出 运行结果: 1010189.5 1010390.0 1010785.0 #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); } 计算机工程学院 伍俊明

  19. 11.7 用指针处理链表 11.7.3 处理动态链表所需的函数 • malloc函数 • 函数原型: • 函数功能: 申请长度为size连续存储区,返回其始址 • calloc函数 • 函数原型: • 函数功能:为一维数组的元素分配n个长度为size的存储空间,返回其始址 • free函数 • 函数原型: • 函数功能:释放指针p所指的动态存储区 void *malloc(unsigned int size) void *calloc(unsigned n, unsigned size) void free(void *p) 计算机工程学院 伍俊明

  20. 11.7 用指针处理链表 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.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; 计算机工程学院 伍俊明

  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); } 计算机工程学院 伍俊明

  22. 11.7 用指针处理链表 11.7.6 对链表的删除操作——删除满足条件的结点 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); } 计算机工程学院 伍俊明

  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); } 计算机工程学院 伍俊明

  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); } } 计算机工程学院 伍俊明

  25. 11.8 共用体 一、共用体:将不同类型的变量存放在同一段存储单元中 • 定义形式: • 例:union data { int i; char ch; float f; } a, b, c; • 说明: • 每个共用体变量占用4字节 • 每个变量只能存放其中一个成员 • 变量的内容为最后一次保存的值 union 共用体类型名 { 类型1 成员1;…;类型n 成员n; } 变量名列表; 计算机工程学院 伍俊明

  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相同 • 共用体变量不能作为函数参数,函数返回值不许是共用体变量,但可以返回指向共用体变量的指针 • 共用体的成员可以是结构体类型的,结构体成员也可以是共用体类型的 共用体变量名.成员名 计算机工程学院 伍俊明

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

  28. 11.9 枚举类型 • 枚举类型:将变量的值一一列举出来,每个值是标识符。 • 枚举类型定义的一般形式: • 例:enum weekday{sun,mon,tue,wed,thu,fri,sat} enum weekday workday, week_end; workday=mon; week_end=sun; • 说明: • 枚举值都是标识符,按常量来处理,不能对它赋值 • 每个枚举值都有一个编号,默认值从0开始,依次增1,也可改变:enum weekday={sun=7, mon=1,tue,wed,thu,fri,sat} workday, week_end; • 枚举值可依据其编号大小进行比较。 enum 枚举类型名{标识符1,… , 标识符n} 计算机工程学院 伍俊明

  29. 11.9 枚举类型 • 例:11.13 口袋中有红、黄、蓝、白、黑5种颜色的球若干个。每次从口袋中先后取出3个球,问得到3种不同色的球的可能取法,输出每种排列的情况。 计算机工程学院 伍俊明

  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 数据类型 类型名; 计算机工程学院 伍俊明

  31. 第11章 结构体与共用体 • 作业(P318) • 11.2 • 11.3 • 11.5 • 11.9 • 11.11 计算机工程学院 伍俊明

More Related