chap 9 结构 9.1 构建手机通讯录 9.2 结构变量 9.3 结构数组 9.4 结构指针
Post on 22-Dec-2015
392 views
TRANSCRIPT
本章要点 什么是结构?结构与数组有什么差别? 有几种结构的定义形式,它们之间有什么不同? 什么是结构的嵌套? 什么是结构变量和结构成员变量,如何引用结构成
员变量? 结构变量如何作为函数参数使用? 什么是结构数组,如何定义和使用结构数组? 什么是结构指针,它如何实现对结构分量的操作? 结构指针是如何作为函数的参数的?
9.1.1 程序解析-程序结构
程序结构主函数 main :程序的总体控制函数 new_friend :新建联系人功能函数 search_friend :查询联系人功能
main()
new_friend() search_friend()
程序解析-数据类型 / 变量 数据类型 / 变量
结构类型 struct friends_list :在程序首部定义,其中的成员分别代表联系人的基本信息
struct friends_list{
char name[10]; /* 姓名 */
int age; /* 年龄 */
char telephone[13]; /* 联系电话 */
};
结构数组 friends :每个元素就是一个结构变量,对应一个联系人
struct friends_list friends[50];
程序解析-全局变量 / 函数参数全局变量 Count :记录当前的联系人总数
函数 new_friend 和 search_friend 的参数之一是结构数组:
void new_friend(struct friends_list friends[ ] );
void search_friend(struct friends_list friends[ ], char *name);
结构数组名作为函数实参与普通数组名作函数参数一样,将数组首地址传递给函数形参
程序解析-源程序#include<stdio.h>#include<string.h>/* 手机通讯录结构定义 */struct friends_list{ char name[10]; /* 姓名 */ int age; /* 年龄 */ char telephone[13]; /* 联系电话 */}; int Count = 0; /* 全局变量记录当前联系人总数 */void new_friend(struct friends_list friends[ ] );void search_friend(struct friends_list friends[ ], char
*name);
源程序int main(void)
{ int choice; char name[10];
struct friends_list friends[50]; /* 包含 50 个人的通讯录 */
do{
printf(" 手机通讯录功能选项: 1: 新建 2: 查询 0: 退出 \n");
printf(" 请选择功能: "); scanf("%d", &choice);
switch(choice){
case 1:
new_friend(friends); break;
case 2:
printf(" 请输入要查找的联系人名 :"); scanf("%s", name);
search_friend(friends, name); break;
case 0: break;
}
}while(choice != 0);
printf(" 谢谢使用通讯录功能 !\n");
return 0;
}
源程序/* 新建联系人 */void new_friend(struct friends_list friends[ ]){ struct friends_list f; if(Count == 50){ printf(" 通讯录已满 !\n"); return; } printf(" 请输入新联系人的姓名 :"); scanf("%s", f.name); printf(" 请输入新联系人的年龄 :"); scanf("%d", &f.age); printf(" 请输入新联系人的联系电话 :"); scanf("%s", f.telephone); friends[Count] = f; Count++;}
源程序
/* 查询联系人 */void search_friend(struct friends_list friends[ ], char *name){ int i, flag = 0; if(Count == 0){ printf(" 通讯录是空的 !\n"); return; } for(i = 0; i < Count; i++) if(strcmp(name, friends[i].name) == 0){ /* 找到联系人 */ flag=1; break; } if(flag){ printf(" 姓名 : %s\t", friends[i].name); printf(" 年龄 : %d\t", friends[i].age); printf(" 电话 : %s\n", friends[i].telephone); } else printf(" 无此联系人 !");}
9.1.2 结构的概念与定义 使用结构来表示通讯录信息:
struct friends_list{
char name[10]; /* 姓名 */
int age; /* 年龄 */
char telephone[13]; /* 联系电话 */
};
结构:构造数据类型,把有内在联系的不同类型的数据统一成一个整体,使它们相互关联
结构又是变量的集合,可以单独使用其成员
结构的定义
结构类型定义的一般形式为: struct 结构名 {
类型名 结构成员名 1 ; 类型名 结构成员名 2 ; 类型名 结构成员名 n ; }; 结构的定义以分号结束,
被看作一条语句
关键字 struct 和它后面的结构名一起组成一个新的数据类型名
结构定义示例定义平面坐标结构:
struct point {
double x;
double y;
};
虽然 x 、 y 的类型相同,也可以用数组的方式表示,但采用结构体描述整体性更强,增加了程序的可读性,使程序更清晰。
9.1.3 结构的嵌套定义 在实际生活中,一个较大的实体可能由多个成员
构成,而这些成员中有些又有可能是由一些更小的成员构成的实体。
在手机通讯录中,增加“通信地址”
姓名 性别 年龄 通信地址 联系电话
电子邮箱城市 街道 门牌号 邮编
结构的嵌套定义
struct address{ char city[10]; char street[20]; int code; int zip;};
struct nest_friendslist { char name[10]; int age; struct address addr; char telephone[13]; } nest_friend;
在定义嵌套的结构类型时,必须先定义成员的结构类型,再定义主结构类型。
姓名 性别 年龄 通信地址 联系电话
电子邮箱城市 街道 门牌号 邮编
9.2.1 结构变量的定义和初始化三种定义结构变量的方式:
1. 单独定义先定义结构类型,再定义具有这种结构类型的变
量 struct friends_list{ char name[10]; /* 姓名 */ int age; /* 年龄 */ char telephone[13]; /* 联系电话 */}; struct friends_list friend1, friend2;
结构变量的定义2. 混合定义在定义结构体类型的同时定义结构体变量
struct friends_list{char name[10]; int age; char telephone[13]; } friend1, friend2;
3. 无类型名定义在定义结构体变量时省略结构体名
struct { char name[10]; int age; char telephone[13]; } friend1, friend2;
结构变量的初始化 struct friends_list friend1 = {
"Zhang", 26, "0571-85171880 "
} ;
name age telephone ↓ ↓ ↓
Zhang 26 0571-85271880
9.2.2 结构变量的使用1. 结构变量成员的引用
结构变量名 . 结构成员名
friend1.age = 26;
strcpy(friend1.name, "Zhang San");
nest_friend.addr.zip
例 9-2 计算实发工资
在一个职工工资管理系统中,工资项目包括编号、姓名、基本工资、奖金、保险、实发工资。
输入一个正整数 n ,再输入 n 个职工的前 5 项信息,计算并输出每位职工的实发工资。
实发工资 = 基本工资 + 奖金–保险。
例 9-2 源程序
#include<stdio.h>struct employee{ int num; char name[20]; float jbgz, jj, bx, sfgz;};int main(void){ int i, n; struct employee e; printf(" 请输入职工人数 n: "); scanf("%d", &n); for(i = 1; i <= n; i++){ printf(" 请输入第 %d 个职工的信息 : ", i); scanf("%d%s", &e.num, e.name); scanf("%f%f%f", &e.jbgz, &e.jj, &e.bx); e.sfgz = e.jbgz + e.jj - e.bx; printf(" 编号 :%d 姓名 :%s 实发工资 :%.2f\n", e.num, e.name, e.sfgz); } return 0;}
请输入职工人数 n: 1请输入第 1 个职工的信息: 102 Zhong 2200.5 800 85.2编号 :102 姓名 :Zhong 实发工资 :2915.30
结构变量的使用-整体赋值2. 结构变量的整体赋值
具有相同类型的结构变量可以直接赋值。将赋值符号右边结构变量的每一个成员的值都赋给了左边
结构变量中相应的成员。 struct friends_list {
char name[10];
int age;
char telephone[13];
} friend1 = {Zhang",26, “0571-85271880”}, friend2;
friend2 = friend1;
例 9-3 结构变量做为函数参数改写例 9-2 ,要求使用结构变量作为函数参数。
定义一个用于计算实发工资的函数: float count_sfgz(struct employee m) { return m.jbgz + m.jj - m.bx; } 再将主函数 main 中的语句: e.sfgz = e.jbgz + e.jj - e.bx; 改为: e.sfgz = count_sfgz(e);
一个结构变量只能表示一个实体的信息,如果有许多相同类型的实体,就需要使用结构数组。
结构数组是结构与数组的结合,与普通数组的不同之处在于每个数组元素都是一个结构类型的数据,包括各个成员项。
9.3 结构数组
结构数组的定义方法与结构变量相同 struct friends_list{
char name[10]; int age; char telephone[13]; } friends[10];
结构数组 friends ,它有 10 个数组元素,从friends[0] 到 friends[9] ,每个数组元素都是结构类型 struct friends_list
9.3 结构数组
结构数组的初始化 struct friends_list friends[10] = {
{ "zhang san", 26, "0571-85271880"},
{ "Li Si", 30, "13605732436"}
};
friends[9]
…………
1360573243630Li Sifriends[1]
0571-8527188026Zhang Sanfriends[0]
结构数组元素 结构数组元素的成员引用
结构体数组名 [下标 ] . 结构体成员名 使用方法与同类型的变量完全相同
friends[5].age = 26;
strcpy(friends[5].name,"Zhang San");
friends[4] = friends[1];
friends[9]
…………
1360573243630Li Sifriends[1]
0571-8527188026Zhang Sanfriends[0]
例 9-4 结构数组排序 输入并保存 10 个学生的信息,计算并输出平均分,再按照从高分到低分的顺序输出他们的信息。
#include <stdio.h>struct student{ int num; char name[20]; int score;}; struct student stud[10]; /* 定义结构数组 */
例 9-4 源程序int main(void)
{ int i, j, index, sum = 0; struct student temp; /* 输入 10 个学生的记录,并累加成绩 */ for(i = 0; i < 10; i++){ printf("No %d: ", i+1); scanf("%d%s%d", &stud[i].num, stud[i].name, &stud[i].score); sum = sum + stud[i].score; } /* 按照分数从低到高排序,使用选择排序法 */ for( i = 0; i < 9; ++i ){ index =i; for (j = i+1; j <10; j++ ) if (stud[j].score < stud[index].score) /* 比较成绩的大小 */ index = j; temp = stud[index];stud[index] = stud[i];stud[i] = temp; /*交换数组元素
*/ } /* 输出成绩 略 */ return 0;}
9.4.1 结构指针的概念 结构指针:指向结构类型变量的指针
例 9-1 定义的结构类型 struct friends_list
struct friends_list friend1 = {"zhang", 26, "88018445"};
struct friends_list *p;
p = &friend1;
88018445 26zhangp
结构指针的使用(1) 用 *p访问结构成员
(*p).age = 36;
(2) 用指向运算符“ ->”访问指针指向的结构成员。p->age = 36;
当 p = &friend1 时,以下三条语句相同: friend1.age = 36; (*p).age = 36; p->age = 36;
9.4.2 结构指针作为函数参数当结构指针作为函数的参数时,执行效率高,
可以完成比基本类型指针更为复杂的操作。例 9-5 输入 10 个学生的学号、姓名和成绩,
输出学生的成绩等级和不及格人数。 每个学生的记录包括学号、姓名、成绩和等级 要求定义和调用函数 set_grade根据学生成绩设置等级,
并统计不及格人数等级设置:
A : 85 - 100 ; B : 70 - 84 ; C : 60 - 69 ; D : 0 - 59
例 9-5 源程序#define N 10struct student{ int num; char name[20]; int score; char grade;};int main(void){ struct student stu[N], *ptr; ptr = stu; /* 输入 略 */ count = set_grade( ptr ); …}
int set_grade(struct student * p){ int i, n = 0; for(i = 0; i < N; i++, p++){ if(p->score >= 85) p->grade = 'A'; else if(p->score >= 70) p->grade = 'B'; else if(p->score >= 60) p->grade = 'C'; else{ p->grade = 'D'; n++; } } return n;}
调用 set_grade 返回主函数后,主函数中结构数组 stu 的元素的 grade 成员已经被
赋值