页数:29页文件大小:342.1 KB来源: C语言程序设计ppt课件
本课件讲解C语言的结构体与共用体,先说明结构体的用途与类型定义方法,再介绍结构体变量的三种定义方式、引用规则与初始化,随后展开结构体数组的定义初始化与统计候选人选票实例,重点讲解指向结构体变量与结构体数组的指针及结构体指针作函数参数,最后介绍typedef定义类型的方法与嵌套用法。
第九章结构体与共用体章节封面,标示本章内容包括结构体、共用体、类型定义与 typedef。
书目卡片(登录号、书名、作者名、分类号、出版单位、出版时间、价格)与学生信息(学号、姓名、年龄、性别、住址、电话、平均分)都是逻辑上相关但类型不同的数据。
结构体是一种构造数据类型,用途是把逻辑相关且数据类型不同的数据组合成一个整体,属于用户自定义数据类型,便于组织复杂数据、提高可读性、便于维护。
struct [结构体名] { 类型标识符 成员名; 类型标识符 成员名; ……………. };struct student { int num; char name[20]; char gender; int age; float score; char addr[30]; };各成员分别占 2、20、1、4、30 字节。该定义了一种新的数据类型、描述了结构的组织形式,但没有定义任何变量,不分配内存。
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) 求得。
struct student { int num; char name[20]; char gender; int age; float score; char addr[30]; } stu1, stu2;类型定义与变量定义合写,适用于只在本处使用的结构体。
struct { int num; char name[20]; char gender; int age; float score; char addr[30]; } stu1, stu2;用无名结构体类型直接定义变量,由于没有类型名,这种方式只能使用一次。
说明
struct date { int month; int day; int year; }; struct student { int num; char name[20]; struct date birthday; } stu;引用规则:结构体变量不能整体引用,只能引用其成员。成员(分量)运算符优先级 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;
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"};也可在定义类型的同时初始化,或用无名结构体定义时直接初始化,初值按成员顺序依次给出。
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 成员,在内存中连续存放。
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}};全部初始化时数组维数可以省略。
引用方式:结构体数组名[下标].成员名
struct student { int num; char name[20]; char sex; int age; } stu[3]; stu[1].age++; strcpy(stu[0].name, "ZhaoDa");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。
定义形式:struct 结构体名 *结构体指针名;,如 struct student *p;,存放结构体变量的起始地址。
struct student { int num; char name[20]; char sex; int age; } stu; struct student *p = &stu;引用成员形式
结构体指针名->成员名,指向运算符优先级 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; 等价。
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 首地址起逐个后移,指向结构体数组的各元素。
用结构体作函数参数有三种方式:
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。
形参 parm 是实参 arg 的副本,func 中改为 18、5、90 后回到 main 再次输出,arg 仍为 27、3、30,说明结构体变量作参数是多值传递,形参改变不影响实参。
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); }func 中通过 parm->a 等修改的是 main 中 arg 的成员,返回后输出 18 5 90,说明结构体指针作参数是地址传递,可双向传递数据。
#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; } }要求:计算并输出每个学生三门课平均成绩、每门课程平均成绩、平均成绩最高的学生记录,并按平均成绩从高到低输出成绩单。
类型定义形式:typedef type name;
typedef int INTEGER; typedef float REAL; | 对比项 | define | typedef |
|---|---|---|
| 处理时机 | 预编译时处理 | 编译时处理 |
| 处理方式 | 简单字符置换 | 为已有类型命名 |
typedef 没有创造新数据类型,是定义类型而不是定义变量。
typedef 定义类型步骤
int i;int INTEGER;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];
char *str; char *STRING; typedef char *STRING; STRING p, s[10]; 等价于 char *p, *s[10];,即 p 为字符指针,s 为含 10 个字符指针的数组。
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 为指向该结构体的指针。
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;。
本章小结
下载地址:{{downurl}}
{{{a}}}
{{#b}}{{{b}}}
{{/b}} {{/title}} {{#nolog}}登陆注册
{{/nolog}} {{#djsx}}点我刷新
{{/djsx}} {{#gocz}} {{/gocz}} {{#ffqr}} {{/ffqr}}