第十一章结构体
- 格式:doc
- 大小:55.50 KB
- 文档页数:7
第十一章 结构体与共用体
通过本章实验作业应达目标
1.掌握结构类型变量与数组的定义和使用。
2.掌握使用结构指针和结构变量名使用结构成员的方法。
3.掌握链表的基本概念和操作(选做)。
本章上交作业
程序11_1_1.c,11_2_1.c上传至211.64.135.121/casp。
实验一 结构体类型、共用体类型和枚举类型的定义
【预备知识】
C语言按常量处理枚举元素。枚举元素和枚举变量在内存中按整型(int)数据方式存储。定义枚举类型时,用户可指定枚举元素的值,未指定值的枚举元素依前面枚举元素的值顺序排列。多个枚举元素可取同一值。
共用体与结构体类型可以嵌套定义。
【实验目的】
理解并掌握结构体类型、共用体类型和枚举类型的概念和定义方法,测试这几种自定义类型变量所占内存空间的字节数,掌握各类变量的定义和引用。
【实验内容】
作业1.定义一个结构体类型,其成员包括:学号、姓名、性别(char型)、年龄、高数、计算机、物理、英语、总分、平均分。同时定义一个该类型的变量,保存一个学生信息:203212022 李明 f 21 87 96 92 85 。计算并保存该学生的总分与平均分。请以11_1_1.c命名本程序。
实验二 顺序表结构的数据管理程序(综合类)
【实验目的】
掌握使用结构体数组组织与管理数据的方法,掌握指向结构体变量的指针变量应用。
【实验内容】
作业1.以本章“实验一 结构体类型、共用体类型和枚举类型的定义”中的结构体类型定义一个结构体数组,编写函数input( )实现从键盘输入表11-1中数据给数组。
表11-1 用以创建结构体数组的原始数据
学号 姓名 性别 年龄 高数 计算机 物理 英语 总分 平均分
1001 Jack m 23 34 56 78 12
1002 Sam f 56 67 65 87 54
1003 Marry f 45 54 68 67 56
1004 David m 78 34 56 98 44
作业2.编写计算函数calculate(),给每个同学的总分和平均分填上数据。
作业3.编写查询函数seek(),通过键盘输入一个姓名,查询该同学的各种数据;若此同学不存在,则输出“NO FIND”。如:输入“Marry”,则输出1003号同学各项数据;输入“Machael”,则输出“No find”。
作业4.编写按总分排序程序sort(),根据每位学生的总分降序排列。 请以11_2_1.c命名本程序。(作业1、作业2是必做,作业3、作业4是选做)
【实验提示】
结构体类型在函数外定义,结构体数组在main()中定义。
三个函数都是对main()中定义的数组进行操作,因而函数的参数必须是指向结构体类型的指针,使用指针访问一维数组。
【讨论与思考】
扩充编写排序程序,能按任意字段排序。(怎样根据用户的键盘输入决定排序关键字?)
如果我们需要对表中的数据进行增删应怎样操作?体会使用数组组织数据的局限(增删不易,容量不能实现动态指定)。
实验三 链表的创建
【实验目的】
了解单链表的有关概念,学会创建一个单向链表,掌握链表遍历。
【实验内容】
作业1.建立一个链表,每个结点包括的成员为:学号、分数。用malloc()函数开辟新结点,键盘输入各结点数据,输入学号为0时表示结束。用creat()函数建立链表,用list()函数输出数据。请以11_3_1.c命名本程序。各结点数据如表11-2:
表11-2
学号 分数
200224 67
201334 78
201342 72
202121 98
202141 66
实验四 链表的插入与删除
【实验目的】
掌握链表的增删操作。
【实验内容】
作业1.在“实验二 链表的创建”基础上,新增加一个学生数据,按学号的顺序插入链表。新插入的学生号为201324。写一inse( )函数实现插入。请以11_4_1.c命名本程序。
作业2.写delete()函数,实现按学号删除一个学生数据。请以11_4_2.c命名本程序。
【讨论与思考】
删除操作依赖于查询操作,根据查询结果定位需要删除的结点,因而查询定位可以与删除分离开,编写独立的查询程序定位满足条件的结点。再者,删除条件能否是模糊条件?比如:学号的前三位表示专业代码,要求删除所有201专业的学生。编写模糊查询与删除程序。
实验五 环形链表的使用(综合类)
【预备知识】
如果将单向链表的首尾相连,便构成了环形链表,环形链表可认为是无头无尾的链表。环形链表依然是单向链表,只能单向遍历。
【实验目的】
深入理解链表这种数据结构,学会创建环形链表,学会对环形链表进行增删操作。
【实验内容】
作业1.n个人围成一圈,从第1个人开始循环报数,报m者退出圈子。最后留下的是原来的几号?使用链表。请以11_5_1.c命名本程序。
【实验提示】
这个问题我们在数组那一章便遇到过,采用数组方法也能解决此问题,但用数组来描述此问题总是不太形象方便。
想像一下n个人手拉手围成一圈,从1到m循环报数,报到m者松开双手退出圈子,退出者相邻的两人再将手握住;圈中每个人的属性数据是他们的初始编号。至此,我们很容易将问题与一个环形链表联系起来。
我们使用有n个结点的链表保存1-n这样一组顺序数字,对链表单向遍历,每访问到第m个结点便删除该结点,直到链表中只剩下一个结点为止。剩下结点的整型成员值就是问题的结果。想一想,如果判断一个环形链表只有一个结点?结点的next指针指向自身。
【讨论与思考】
如果使用单向链表解决此问题,与环形链表相比有何差异?
与前面使用数组解决此问题相比较,方法与算法有何不同?与数组这种结构相比较,链表有什么优势?
实验六 编写同学通讯录(开发类实验)
【实验目的】
学会链表的综合操作,并培养模块化程序设计思想。
【实验内容】
作业1.编写同学通讯录程序,可以创建、浏览、修改、查询、删除、添加新记录。请以11_6_1.c命名本程序。
【实验提示】
有关链表的创建、浏览、修改、查询、删除、添加前面我们已分别熟悉与掌握,本实验我们要做的是将各个功能函数组合到一起完成综合操作。
在主函数中提出程序的主要功能模块(如何设置界面?)。图11-1是一个样例,可供参考:
图11-1 同学通讯录的功能界面
其后还应提供选择界面,接收用户对菜单的选择,然后根据接收的信息进行功能调用。这一部分请自行设计。
良好的人机交互界面是一个软件生命力的重要部分,创建新表、浏览当前表、增删与查询操作的人机交互界面可在小组中讨论确定。界面的开发是难点,刚开始进行时可先使用文本界面进行I/O操作。通讯录系统的功能还应包含容错处理过程等。
链表排序可以有几种算法,不改变链表结点顺序结构,通过交换改变结点数据是一种方法;不改变结点数据,改变链表结点结构顺序是另一种方法,这种方法将重新组织现有结点形成一个新链表。这两种方法都改变链表的物理结构,也称物理排序。物理排序后链表很难回到原来的顺序。
同学通讯录程序的详细分析放在文件类操作那一章中,请同学查阅最后一个开发性实验。
【讨论与思考】
物理排序改变了链表结构或链表数据,失去了原来的数据组织顺序。如果我们不希望改变链表的物理数据结构,但是在用户要求进行排序时又能按排序要求顺序操作相应的数据,则对数据表要进行索引排序。索引排序不改变数据表原有的物理结构,而是创建一个新的索引链表,新索引链表只包含排序关键字的值(比如按姓名排序,则只包含原表中各姓名值)和原表的结节编号,且新索引链表按排序关键字排好顺序。对原表的访问是通过索引表来进行的,这样既能实现排序又不破坏原表结构。请同学们自行查阅资料,编写索引排序程序。
习题
1. 下面程序的运行结果是___________.
main()
{
struct cmplx{int x;
int y;
}cnum[2]={1,3,2,7};
printf("%d\n",cnum[0].y/cnum[0].x*cnum[1].x);
}
a)0 b)1 c)3 d)6
2. 以下对结构体变量stu1中成员age的非法引用是________.
struct student
{int age;
int num;
}stu1,*p;
p=&stu1;
a)stu1.age b)student.age
c)p->age d)(*p).age
3. 以下scanf函数调用语句中对结构体变量成员的不正确引用是________.
struct pupil
{char name[20];
int age;
int sex; }pup[5],*p;
p=pup;
a)scanf("%s",pup[0].name);
b)scanf("%d",&pup[0].age);
c)scanf("%d",&(p->sex));
d)scanf("%d",p->age);
4. 以下程序的运行结果是________.
struct n{
int x;
char c;
};
main()
{struct n a={10,'x'};
func(a);
printf("%d,%c",a.x,a.c);
}
func(struct n b)
{
b.x=20;
b.c='y';
}
5. 若有定义:
struct num
{int a;
int b;
float f;
}n={1,3,5.0};
struct num *pn=&n;
则表达式pn->b/n.a*++pn->b的值是________,表达式(*pn).a+pn->f的值是________.
6. 以下程序的运行结果是________.
struct ks
{int a;
int *b;
}s[4],*p;
main()
{
int n=1;
printf("\n");
for(i=0;i<4;i++)
{
s[i].a=n;