首页计算机计算机软件C语言程序设计 09 第九章 结构体与共用体.pptx

09 第九章 结构体与共用体.pptx

页数:29页文件大小:342.1 KB来源: C语言程序设计ppt课件

本课件讲解C语言的结构体与共用体,先说明结构体的用途与类型定义方法,再介绍结构体变量的三种定义方式、引用规则与初始化,随后展开结构体数组的定义初始化与统计候选人选票实例,重点讲解指向结构体变量与结构体数组的指针及结构体指针作函数参数,最后介绍typedef定义类型的方法与嵌套用法。

第九章结构体与共用体导览页,列出结构体共用体与类型定义等要点
结构体用途页,用书目卡片与学生信息说明构造数据类型的必要性
结构体类型定义页,说明struct关键字与成员类型的一般形式
查看本课件的文字版(共 29 页,供检索与复制)

第1页:第九章结构体与共用体导览

第九章结构体与共用体章节封面,标示本章内容包括结构体、共用体、类型定义与 typedef。

第2页:结构体的用途

书目卡片(登录号、书名、作者名、分类号、出版单位、出版时间、价格)与学生信息(学号、姓名、年龄、性别、住址、电话、平均分)都是逻辑上相关但类型不同的数据。

结构体是一种构造数据类型,用途是把逻辑相关且数据类型不同的数据组合成一个整体,属于用户自定义数据类型,便于组织复杂数据、提高可读性、便于维护。

第3页:结构体类型的定义

struct [结构体名] { 类型标识符 成员名; 类型标识符 成员名; ……………. };
  • struct 是关键字,不能省略
  • 结构体名为合法标识符,可缺省形成无名结构体
  • 成员类型可以是基本型或构造型
  • 结构体类型定义只描述结构的组织形式

第4页:结构体类型定义示例

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

各成员分别占 2、20、1、4、30 字节。该定义了一种新的数据类型、描述了结构的组织形式,但没有定义任何变量,不分配内存。

第5页:结构体变量定义方式一

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

也可用宏替换:

#define STUDENT struct student STUDENT { ... }; STUDENT stu1, stu2;

为结构体变量分配存储空间,大小可用 sizeof(struct student) 求得。

第6页:结构体变量定义方式二

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

类型定义与变量定义合写,适用于只在本处使用的结构体。

第7页:结构体变量定义方式三

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

用无名结构体类型直接定义变量,由于没有类型名,这种方式只能使用一次。

第8页:结构体类型与变量的说明

说明

  • 结构体类型与结构体变量概念不同:类型不分配内存,变量分配内存;类型不能赋值、存取、运算,变量可以
  • 结构体类型可嵌套,成员可以是另一个结构体类型
  • 结构体成员名与程序中的变量名可相同,不会混淆
  • 结构体类型及变量的作用域与生存期遵循一般规则
struct date { int month; int day; int year; }; struct student { int num; char name[20]; struct date birthday; } stu;

第9页:结构体变量的引用

引用规则:结构体变量不能整体引用,只能引用其成员。成员(分量)运算符优先级 1,从左向右结合,引用方式为 结构体变量名.成员名。

stu1.num = 10; stu1.score = 85.5; stu1.score += stu2.score; stu1.age++; stu2 = stu1; printf("%d,%s,%c,%d,%f,%s\n", stu1); stu1 = {101,"Wan Lin",'M',19,87.5,"DaLian"}; 

结构体嵌套时逐级引用:stu1.birthday.month = 12;

第10页:结构体变量的初始化

struct student { int num; char name[20]; char gender; int age; char addr[30]; }; struct student stu1 = {112, "Wang Lin", 'M', 19, "200 Beijing Road"};

也可在定义类型的同时初始化,或用无名结构体定义时直接初始化,初值按成员顺序依次给出。

第11页:结构体数组的定义

struct student { int num; char name[20]; char sex; int age; }; struct student stu[2]; struct student { int num; char name[20]; char sex; int age; } stu[2]; struct { int num; char name[20]; char gender; int age; } stu[2];

stu[0]、stu[1] 各含 num、name、gender、age 成员,在内存中连续存放。

第12页:结构体数组的初始化

 struct student stu[] = {100,"Wang Lin",'M',20, 101,"Li Gang",'M',19, 110,"Liu Yan",'F',19}; struct student stu[] = {{100,"Wang Lin",'M',20}, {101,"Li Gang",'M',19}, {110,"Liu Yan",'F',19}};

全部初始化时数组维数可以省略。

第13页:结构体数组的引用

引用方式:结构体数组名[下标].成员名

struct student { int num; char name[20]; char sex; int age; } stu[3]; stu[1].age++; strcpy(stu[0].name, "ZhaoDa");

第14页:统计候选人选票

struct candidate { char name[20]; int count; } leader[3] = {"Li",0, "Zhang",0, "Wang",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 (i = 0; i < 3; i++) printf("%5s:%d\n", leader[i].name, leader[i].count); }

成员 name 与 count 分别存放候选人姓名和票数,初始均为 0。

第15页:指向结构体变量的指针

定义形式:struct 结构体名 *结构体指针名;,如 struct student *p;,存放结构体变量的起始地址。

struct student { int num; char name[20]; char sex; int age; } stu; struct student *p = &stu;

第16页:用结构体指针引用成员

引用成员形式

  • 结构体指针名->成员名,指向运算符优先级 1,从左向右结合
  • (*结构体指针名).成员名,与上式等价
  • 结构体变量名.成员名
struct student { long int num; char name[20]; char sex; float score; } stu, *p; p = &stu; stu.num = 89101; strcpy(stu.name, "Li Lin"); p->sex = 'M'; p->score = 89.5;

(*p).num = 101; 与 p->num = 101; 等价。

第17页:指向结构体数组的指针

struct student { int num; char name[20]; char gender; int age; } stu[3] = {{10101,"Li Lin",'M',18}, {10102,"Zhang Fun",'M',19}, {10104,"Wang Min",'F',20}}; void main() { struct student *p; for (p = stu; p < stu+3; p++) printf("%d%s%c%d\n", p->num, p->name, p->gender, p->age); }

p 从 stu 首地址起逐个后移,指向结构体数组的各元素。

第18页:结构体指针作函数参数

用结构体作函数参数有三种方式:

  • 用结构体变量的成员作参数——值传递
  • 用结构体变量作参数——多值传递,效率低
  • 用指向结构体变量或数组的指针作参数——地址传递

第19页:结构体变量作函数参数

struct data { int a, b, c; }; void main() { void func(struct data); struct data arg; arg.a = 27; arg.b = 3; arg.c = arg.a + arg.b; printf("%d %d %d\n", arg.a, arg.b, arg.c); func(arg); printf("%d %d %d\n", arg.a, arg.b, arg.c); } void func(struct data parm) { printf("%d %d %d\n", parm.a, parm.b, parm.c); parm.a = 18; parm.b = 5; parm.c = parm.a * parm.b; printf("%d %d %d\n", parm.a, parm.b, parm.c); }

main 中先输出 27 3 30,func 中输出 27 3 30 与 18 5 90。

第20页:结构体变量作参数的结果

形参 parm 是实参 arg 的副本,func 中改为 18、5、90 后回到 main 再次输出,arg 仍为 27、3、30,说明结构体变量作参数是多值传递,形参改变不影响实参。

第21页:结构体指针作函数参数

struct data { int a, b, c; }; void main() { void func(struct data *); struct data arg; arg.a = 27; arg.b = 3; arg.c = arg.a + arg.b; printf("%d %d %d\n", arg.a, arg.b, arg.c); func(&arg); printf("%d %d %d\n", arg.a, arg.b, arg.c); } void func(struct data *parm) { printf("%d %d %d\n", parm->a, parm->b, parm->c); parm->a = 18; parm->b = 5; parm->c = parm->a * parm->b; printf("%d %d %d\n", parm->a, parm->b, parm->c); }

第22页:结构体指针作参数的结果

func 中通过 parm->a 等修改的是 main 中 arg 的成员,返回后输出 18 5 90,说明结构体指针作参数是地址传递,可双向传递数据。

第23页:成绩处理综合示例

#define N 4 #define M 3 struct student { long num; char name[20]; float score[M]; float average; }; void main() { int i, j; struct student s[N]; for (i = 0; i < N; i++) { scanf("%ld%s", &s[i].num, s[i].name); for (j = 0; j < M; j++) scanf("%f", &s[i].score[j]); } calstuave(s); calcourseave(s); find(s); sort(s); output(s); } void calstuave(struct student s[]) { int i, j; for (i = 0; i < N; i++) { s[i].average = 0; for (j = 0; j < M; j++) s[i].average += s[i].score[j]; s[i].average /= M; } }

要求:计算并输出每个学生三门课平均成绩、每门课程平均成绩、平均成绩最高的学生记录,并按平均成绩从高到低输出成绩单。

第24页:typedef类型定义

类型定义形式:typedef type name;

typedef int INTEGER; typedef float REAL; 
typedef 与 define 的区别
对比项definetypedef
处理时机预编译时处理编译时处理
处理方式简单字符置换为已有类型命名

typedef 没有创造新数据类型,是定义类型而不是定义变量。

第25页:typedef定义类型的步骤

typedef 定义类型步骤

  • 按定义变量方法先写出定义体,如 int i;
  • 将变量名换成新类型名,如 int INTEGER;
  • 最前面加 typedef,如 typedef int INTEGER;
  • 用新类型名定义变量,如 INTEGER i, j;

例:定义含 100 个整型元素的一维数组类型

int a[100]; → int ARRAY[100]; → typedef int ARRAY[100]; → ARRAY a, b, c;

等价于 int a[100], b[100], c[100];

第26页:typedef定义字符指针类型

char *str; char *STRING; typedef char *STRING; STRING p, s[10]; 

等价于 char *p, *s[10];,即 p 为字符指针,s 为含 10 个字符指针的数组。

第27页:typedef定义结构体类型

struct date { int month; int day; int year; } d; typedef struct date { int month; int day; int year; } DATE; DATE birthday, *p;

等价于 struct date { int month; int day; int year; } birthday, *p;,DATE 为结构体类型名,birthday 为变量,p 为指向该结构体的指针。

第28页:typedef定义类型的嵌套

typedef struct club { char name[20]; int size; int year; } GROUP; typedef GROUP *PG; PG pclub;

GROUP 为结构体类型,PG 为指向 GROUP 的指针类型,PG pclub; 等价于 GROUP *pclub;,也等价于 struct club *pclub;。

第29页:本章小结

本章小结

  • 结构体:结构体类型定义;结构体变量定义、引用与初始化;结构体数组定义、引用与初始化;结构体与指针
  • 共用体:共用体与结构体的异同
  • 用 typedef 定义类型:定义类型的方法与应用、与 define 的区别
顶部目录