第十一章结构体

  • 格式: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;