1 / 27

第 9 章 结 构

第 9 章 结 构. 结构:一种数据类型. C 语言的数据类型. 整型 实型 字符型. 单精度型 双精度. 基本类型 构造类型 指针类型 空类型. 数组 结构 联合 枚举. 数据类型. §9.1 结构变量. 一般一个事物有多个特征 , 要用几个数据共同描述 例如 学生基本情况 : 学号、名字、性别、年龄、地址、成绩 日期 : 年、月、日、小时、分.

keran
Download Presentation

第 9 章 结 构

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. 第9章 结 构 结构:一种数据类型 C语言的数据类型 整型 实型 字符型 单精度型 双精度 基本类型 构造类型 指针类型 空类型 数组 结构 联合 枚举 数据类型

  2. §9.1 结构变量 一般一个事物有多个特征,要用几个数据共同描述 例如 学生基本情况: 学号、名字、性别、年龄、地址、成绩 日期: 年、月、日、小时、分 事物的各种特征可以用若干变量和数组描述,但不能反映这些特征数据相互联系。为了将描述一个物体的各分量集合一起,C语言提供结构类型数据来描述。 例如 每个学生有: 学号num、名字name[20]、成绩score 对某学生定义一个结构变量structent,则可表示为 strudent.num strudent.name strudent.score 定义类型 struct student_type {int num; char name[20]; int score; }; 定义变量 struct student_type student; 变量名 成员名 可见结构类型数据是各种数据的集合

  3. 9.1.1结构类型的定义 例如 定义一个关于学生基本情况的结构,其成员由学号、姓名、成绩组成: 结构类型的定义 格式 struct 结构类型名 {成员表列}; struct student {int num; char nane[20]; int score; }; 其中(1)结构类型名按标识符取名 (2)成员表列: 类型标识符1 成员名1; 类型标识符2 成员名2; …… 类型标识符n 成员名n; 定义struct student数据类型 又例 平面上的任意一点的结构 struct point {float x; float y; }; 注:结构的定义以分号结束。 定义struct point数据类型

  4. 9.1.2结构变量的定义和引用 1.结构变量的定义 (1)先定义结构类型再定义结构体变量 格式struct 结构类型名 变量1,变量2,... 例如 struct student {int num; char name[20]; int score; }; struct student student1,student2; 定义结构类型 定义结构变量 则内存分配 num name score student1 student2

  5. (2)定义结构类型时同时定义结构体变量 格式 struct 结构类型名 {成员表列}变量表列; (3)直接定义结构变量 格式 struct {成员表列}变量表列; 例如 struct {int num; char name[20]; int score; }student1,student2; 例如 struct student {int num; char name[20]; int score; }student1,student2; 注(1)类型与变量是不同的概念 类型声明变量 (2)成员名可以与程序中的变量名相同,两者不代表同一对象 如 int num; struct student student1,student2; num 与 student1.num、student2.num是不同量

  6. 2.结构类型变量的引用 形式 结构变量名.成员名 其中 . 是运算符,优先级为最高1级 表示访问某结构变量中的某成员,与简单变量和数组元素使用相同 如 struct {int num; char name[20]; int score; }stud1; 201 Zhang Hong 92 stud1.num=201; strcpy(stud1.name,"Zhang Hong"); stud1.score=92; scanf("%d %s %d", &stud1.num,stud1.name, &stud1.score); printf("%d %s %d", stud1.num,stud1.name, stud1.score);

  7. 例9-2 在工资管理系统中,工资项目有编号、姓名、基本工资、奖金、保险、实发工资。输入职工人数n,再输入每个职工的前5项信息,计算并输出实发工资。 其中,实发工资=基本工资+奖金–保险 #include<stdio.h> struct employee { int num; char name[20]; float jbgz, jj, bx, sfgz; }; void 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); } 请输入职工人数n: 1 请输入第1个职工的信息:102 Zhong 2200.5 800 85.2 编号:102 姓名:Zhong 实发工资:2915.30

  8. 3.结构体类型变量初始化 与变量、数组的初始化相似 例 struct student {int num; char name[20]; int score; }; struct student student1={201,"Zhang Hong",92}; main() { printf("%d %s %d\n", stud1.num,stud1.name, stud1.score); } 输出:201 Zhang Hong 92 注 按顺序将数据依次赋值于成员,数据类型与成员类型要一致

  9. 4.整体赋值 结构名1=结构名2; 如 student1=student2; 注赋值号"="的左右的结构类型要一致,所有的成员一一对应赋值 例 将结构变量stud1的值赋给结构变量stud2 。 #include <stdio.h> main() {static struct student {int num; char name[20]; int score; }stud1 ={201,"Zhang Hong",92}, stud2; stud2= stud1; printf("%d %s %d",stud2.num,stud2.name,stud2.score); } stud2= stud1; 等价与 stud2.num= stud1.num; strcpy(stud2.name, stud1.name); stud2.score= stud1.score; 输出 201 Zhang Hong 92

  10. 9.1.3结构的嵌套 结构可以嵌套,即结构的分量又是一个结构的变量 1.结构嵌套定义:用结构类型定义结构的分量 例如 struct date {int month; int day; int year; }; struct student {int num; char name[20]; int score; struct date birthday; }student1,student2; 或 struct student {int num; char name[20]; int score; struct {int month; int day; int year; }birthday; }student1,student2; 2.引用时,当结构的分量名又是结构名时,继续使用"."延伸 如 student1.birthday.year student2.birthday.day

  11. 若学生的信息构成如下图,请为其定义合适的数据类型 struct address {char city[20]; char street[20]; int number; }; struct student {int num; char name[20]; struct address addr; int score; }; void main() {struct student stud1={201,"Zhang Hong","Hangzhou","QS",11,92}; printf("%d\n",stud1.num); printf("%s\n",stud1.name ); printf("%s\n",stud1.addr.city); printf("%s\n",stud1.addr.street); printf("%d\n",stud1.addr.number); printf("%d\n",stud1.score); } 输出: 201 Zhang Hong Hangzhou QS 11 92

  12. 9.1.4结构变量作为函数的参数 形参为结构变量,实参要求同类型的结构变量。 虚实结合:将实参结构变量的成员一一对应赋值于形参的结构变量 #include<stdio.h> struct employee { int num; char name[20]; float jbgz, jj, bx, sfgz; }; 例9-3 改写例9-2。 float count_sfgz(struct employee m) {return m.jbgz+m.jj-m.bx; } void 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=count_sfgz(e); printf("编号:%d 姓名:%s实发工资:%.2f\n", e.num, e.name, e.sfgz); } 虚实结合: e.numm.num e.namem.name e.jbgzm.jbgz e.jjm.jj e.sfgzm.sfgz

  13. 9.2结构数组 9.2.1结构数组的定义和引用 结构数组用结构类型定义的数组 例如 struct student {int num; char name[20]; int score; }; struct student stud[10]; 或 struct {int num; char name[20]; int score; }stud[10]; 数组元素 stud[i]是一个数组元素(结构体变量),引用为 stud[i].num stud[i].score

  14. 9.2.2结构数组的初始化 例struct student {int num; char name[20]; int score; }; struct student stud[2]={201,"Zhang Hong",92,202,"Wang Fang",80}; 或 struct student stud[2]={{201,"Zhang Hong",92},{202,"Wang Fang",80}}; 每个{...}依次赋值于结构体数组元素 stud[0].num=201;stud[0].name="Zhang Hong";stud[0].score=92; stud[1].num=202;stud[1].name="Wang Fang";stud[1].score=80;

  15. 例9-4建立有10个学生的结构记录,输出平均分数,并从高到低输出成绩。例9-4建立有10个学生的结构记录,输出平均分数,并从高到低输出成绩。 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; } for(i=9;i>=0;i--) printf("%d%s%d",&stud[i].num,stud[i].name,&stud[i].score); } #include <stdio.h> struct student {int num; char name[20]; int score; }; struct student stud[10],temp; void main() {int i,sum=0; for(i=0;i<10;i++) { scanf("%d%s%d",&stud[i].num,stud[i].name,&stud[i].score); sum=sum+stud[i].score; } printf("aver=%d\n",sum/10);

  16. 9.4结构指针 结构变量指针结构变量的地址 指向结构变量的指针指针变量的值为结构变量的地址 1.定义结构指针变量 格式struct 结构体类型 *结构体指针变量名; 例struct student {int num; char name[20]; int score; }stud1={201,"Zhang Hong",92}; struct student *ptr; ptr=&stud1; &stud1 ptr

  17. 2.结构指针对结构分量访问 格式(*指针名).分量名 或 指针名->分量名 如 (*ptr).num (*ptr).name ptr->num ptr->name &stud1 p 例 #include <stdio.h> #include <string.h> main() {struct student {int num; char name[20]; int score; }; struct student stud1,*p; p=&stud1; stud1.num=201; strcpy(stud1.name,"Zhang Hong"); stud1.score=92; printf("%d %s %d\n", stud1.num,stud1.name,stud1.score); printf("%d %s %d\n", (*p).num, (*p).name, (*p).score); printf("%d %s %d\n", p->num, p->name, p->score);}

  18. 注(*指针名).分量名中的括号是不可少的,分量运算符"."的优先级高于"*" 的优先级 如 (*ptr).name 不能写成 *ptr.name 而是*(ptr.name) 例 对于以下的变量定义,表达式______不符合C语言语法。 struct node {int len; char *pk; } x = {2, "right"}, *p=&x; A、p->pk B、*x.pk C、*p->pk D、*p.pk 答案 D 不能用指向结构的指针直接指向结构体成员 如 struct student {int num; char name[20]; int score; }; struct student stud1,*p; int *q; p=&stud1.num; 不允许, 类型不一致 q=&stud1.num; 允许 结构变量虽然存储多数据,但结构的变量名仍不是地址值, 取地址必须&结构体变量名

  19. 3.指向结构数组的指针 指向结构数组的指针指针变量的值为结构数组元素的地址 p &stud[0] stud 例struct student {int num; char name[20]; char sex; int age;} struct student stud[3],*p; p=stud; p+1 &stud[1] p+2 &stud[2] 注p+i 是作地址运算 p的地址值+sizeof(struct student )*i

  20. 例 用结构指针求10个学生的平均分数。 #include <stdio.h> #include <string.h> void main() {struct student {int num; char name[20]; int score; }; struct student stud[10],*p; int i,sum=0; for(p=stud;p<=&stud[9];p++) {scanf("%d%s%d",&p->num,p->name,&p->score); sum=sum+p->score; } printf("aver=%d\n",sum/10); } p &stud[0] stu p+1 &stud[1] p+2 &stud[2]

  21. 4. 结构指针作为函数参数 形参是结构数组或结构指针,实参应是同类型的结构数组名或结构指针。虚实结合方式:地址传递 • 例9-5输入10个学生的学号、姓名和成绩,输出学生的成绩等级和不及格人数。 • 每个学生的记录包括学号、姓名、成绩和等级 • 要求定义和调用函数set_grade根据学生成绩设置等级,并统计不及格人数 • 等级设置: • A :85-100;B:70-84;C:60-69;D:0-59

  22. #define N 10 struct student{ int num; char name[20]; int score; char grade; }; void main() { 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; }

  23. 例9-1构建简单的手机通讯录 • 联系人的基本信息:姓名、年龄和联系电话 • 最多容纳50名联系人的信息 • 具有新建和查询功能 #include<stdio.h> #include<string.h> /*手机通讯录结构定义*/ struct friends_list{ char name[10]; /* 姓名 */ int age; /* 年龄 */ char telephone[13]; /* 联系电话 */ }; int count = 0; /* 全局变量记录当前联系人总数 */

  24. /*新建联系人*/ 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++; }

  25. /*查询联系人*/ 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("无此联系人!"); }

  26. void 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"); }

  27. 作业:第9章作业 下载http://www.ccea.zju.edu.cn/clearn/ 实验:第10次实验 10.71.5.8

More Related