9.2.5 结构体和共用体综合实例——“梁山好汉的比武大会”
笔者大胆的做了一个假设,住在梁山的108个好汉因为他们的排名问题闹起了矛盾,主要是因为有的人的技艺已经有很大的提升,而有些人占着自己靠前的排名坐享其成。经过高层领导商议之后,决定举办一场比武大会,按照比武的成绩重新确立好汉们的排名,并且根据比武结果的等级来颁发奖品。
现在分配给您一个任务,编写程序将比武结果公布于众。具体来说,需要公布好汉的原有排名,再根据比武成绩公布现有排名,以及公布获奖情况,如果是前三甲,还要公布好汉详细的个人信息。其中,分数从1到108分,根据分数给与奖励,“一等奖”、“二等奖”、“三等奖”和“安慰奖”分别对应100-108,90-99,80-89,1-79。
【分析】:这个任务可以分为两个大的方面,一是好汉们信息的维护,主要是修改其排名,用结构体类型实现是一个很好的选择;二是对成绩和奖项的维护,用共用体类型实现较为合理。
下面给出比武信息公布的程序清单:
#include <stdio.h>
#include <string.h>
//结构体声明
struct hero
{
int number; //排名
int new_number; //新排名
char star_name[20]; //星名
char name[20]; //名称
char nickname[20]; //绰号
char position[20]; //职业
char weapon[20]; //使用武器
};
//定义表示108位好汉的结构体数组person和表示前三甲的结构体数组well
struct hero person[108];
struct hero well[3]={{1,-1,"天魁星","宋江","及时雨","总首领","无"},
{2,-1,"天罡星","卢俊义","玉麒麟","总督兵马副元帅","麒麟黄金矛"},
{3,-1,"天机星","吴用","智多星","机密军师","八门金锁阵"}};
//共用体声明
union mark
{
int score; //表示分数
char degree[10]; //表示奖项
};
//定义表示成绩和奖项的共用体result
union mark result;
//函数声明
void change_number(int);
void init_person(int);
void init_well(int);
void pf_well(void);
void get_cheer(int);
//主函数
void main()
{
int i;
for(i=0;i<108;i++)
{
init_person(i);
change_number(i);
if(person[i].new_number<=3)
{
init_well(i);
}
get_cheer(i);
}
pf_well();
}
/*
此函数用于改变排名
形参为person的下标
无返回值
*/
void change_number(int i)
{
printf("请输入%s比赛的成绩(1-108):/n",person[i].name);
scanf("%d",&result.score); //给表示成绩的变量赋值
person[i].new_number=109-result.score; //计算新的成绩
printf("比武后%s的排名是:%d/n",person[i].name,person[i].new_number);
}
/*
此函数用于初始化结构体数组person
形参为person的下标
无返回值
*/
void init_person(int i)
{
printf("请输入第%d位好汉的排名、星名、名字、绰号、职业、使用武器/n",i+1);
scanf("%d%s%s%s%s%s",
&person[i].number,person[i].star_name,person[i].name,
person[i].nickname,person[i].position,person[i].weapon);
printf("比武前%s的排名是:%d/n",person[i].name,person[i].number);
}
/*
此函数用于初始化结构体数组well
形参为person的下标
无返回值
*/
void init_well(int i)
{
int j;
j=person[i].new_number-1;
well[j]=person[i];
}
//此函数用于输出前三名
void pf_well(void)
{
int j;
printf("比赛的前三甲是:/n");
for(j=0;j<3;j++)
{
printf("第%d名的信息为(姓名、昵称、星名、职业、武器):/n",j+1);
puts(well[j].name);
puts(well[j].nickname);
puts(well[j].star_name);
puts(well[j].position);
puts(well[j].weapon);
}
}
/*
此函数用于输出奖项
形参为person的下标
无返回值
*/
void get_cheer(int i)
{
switch((person[i].new_number)/10)
{
//给共用体变量result的成员degree赋值
case 0:
strcpy(result.degree,"一等奖"); break;
case 1:
strcpy(result.degree,"二等奖"); break;
case 2:
strcpy(result.degree,"三等奖"); break;
default:
strcpy(result.degree,"安慰奖");
}
printf("%s在这次比武中获得:",person[i].name);
puts(result.degree);
}
此程序综合运用了结构体和共用体,比较好的实现了假设的梁山比武大会的公布排名和奖励的功能。因其比较简单,笔者不再对其进行解释,但此程序并不完善。笔者认为,此程序存在以下几点问题需要读者进行改进:
l 对好汉们信息的输入完全取决于用户,无法保证用于输入一些不合常理的值。
例如,如果用户对于好汉的成绩输入了相同的值,则好汉新的排名也将重复,这明显不合要求。
l 从整体结构上看,并没有使用第8章介绍过的预处理功能将程序分为若干个文件。
例如,结构体和共用体声明以及函数声明可以放在一个头文件中以供调用。
程序不能处理中文输入。
最新作品《C语言参悟之旅》全新上市,敬请关注!
官方网站:http://www.tqbooks.net/product/gb/product_detail.asp?catalogid=10&productid=1474
China-pub有售:http://www.china-pub.com/49980