2019-2020 学年 C 语言程序设计补考考题

题 目

一、编程(70 分)
  某个比赛,有 6 个选手参赛,有 8 个评委负责给各个选手打分。选手最终得分的计 算方法是去掉最高分数和最低分数,取剩余分数的平均值。6 个选手的信息包括名字和 8 个得分,用以下全局变量保存: char Names[6][16]; int Scores[6][8]; 请编程完成以下步骤(每个步骤需要附带30字以上的思路描述,然后再给出代码):

1、请编写一个函数 InputName,参数为一个字符数组(数组长度 16),无返回值。 函数功能是输入单个选手名字赋值给该字符串。(10 分)

2、请编写一个函数 InputScore,参数为单个选手的得分数组(数组长度 8),无返回 值。函数功能是输入该选手的 8 个得分并赋值给该数组。注意,得分数有效值 只能介于 60-100 之间,如果某个值无效,必须重新输入,直到所有得分有效为 止。(10 分)
3、请编写一个函数 InputNamesAndScores,无参数,无返回值。在该函数中需调用 InputScore 和 InputName,实现输入所有选手的名字和得分,并保存在上述全局 变量 Names 和 Scores 里。(10 分)
4、请编写函数 CalculateScore,参数为单个选手的得分数组,返回值为该选手最终 得分(去掉最高分数和最低分数后的平均值)。(10 分)
5、请编写函数 FindScore,调用以上相关的函数,参数为名字字符串,返回值为对 应的选手最终得分。(10 分)
6、请编写主函数,综合调用以上相关的函数,最终输出选手的排名,格式为“排名: 名字 分数”,参考如下:(10 分) 1: Zhangsan 95 2:Lisi 93 ……
7、在以上的步骤中,选手的名字和得分是独立的,请结合结构体知识,定义选手的结构体,定义全局结构体数组用于保存所有选手的姓名和得分(不再使用全局 变量 Names 和 Scores)。通过对结构体元素的操作,实现步骤 6 规定的功能。 (10 分)

  帮其他系的童鞋写写补考试卷,说实话对于非专业的学生来说还挺难的,循序渐进的基础题,不过写起来还是要花功夫的,话不多说,要是这份卷子和你的补考卷子一样,得小心雷同!

测试数据:

yi 100 100 100 100 100 100 100 100
san 90 90 90 90 90 90 90 90
si 70 70 70 70 70 70 70 70
er 95 95 95 95 95 95 95 95
liu 60 60 60 60 60 60 60 60
wu 65 65 65 65 65 65 65 65

代码示例:

#include<stdio.h> 
#include<string.h> 

char Names[6][16]; 
int Scores[6][8];

struct Node{
	char Name[16];
	int Score[8];
}Students[6];


void InputName(char Names[]);
void InputScore(int Score[]);
void InputNamesAndScores();
float CalculateScore(int Score[]);
float FindScore(char Name[]);


///*6.这题的难点就是在于名字和成绩的结合,要是单纯的排序成绩,那么名字就会匹配不上
//	所以这里排序的时候多用一个数组存储排名变化的情况,最后再根据这个数组判断变化
//	后成绩对应的名字*/ 
//int main(){
//	int i,j,rank[6],temp,score[6];
//	for(i = 0; i < 6; i++){
//		InputName(Names[i]);
//		InputScore(Scores[i]);
//		score[i] = CalculateScore(Scores[i]);
//		rank[i] = i;
//	}
//	
//	//冒泡排序 
//	for(i = 0; i < 5; i++){
//		for(j = 0; j < 5-i; j++){
//			if(score[j] < score[j+1]){
//				temp = score[j];
//				score[j] = score[j+1];
//				score[j+1] = temp;
//				
//				temp = rank[j];
//				rank[j] = rank[j+1];
//				rank[j+1] = temp; 
//			}
//		}
//	}
//	int cnt = 0;
//	while(cnt < 6){
//		for(i = 0; i < 6; i++){
//			if(rank[i] == cnt){
//				printf("%d: %s %.0f\n",cnt+1,Names[rank[cnt]],CalculateScore(Scores[rank[cnt]]));
//				cnt++;
//			}
//		}
//	}
//	
//}


/*7.用结构体表示的话就不用多余的数组来判断名字和成绩的关系了,
	只需要排序一次交换结构体就好了,不过当数据量大的时候不如用
	上面的方法,但是本题还是用结构体实现比较方便*/
int main(){
	int i,j,score[6],temp;
	struct Node temp2; 
	for(i = 0; i < 6; i++){
		InputName(Students[i].Name);
		InputScore(Students[i].Score);
		score[i] = CalculateScore(Students[i].Score);
	}
	
	//冒泡排序 
	for(i = 0; i < 5; i++){
		for(j = 0; j < 5-i; j++){
			if(score[j] < score[j+1]){
				temp2 = Students[j];
				Students[j] = Students[j+1];
				Students[j+1] = temp2;
				temp = score[j];
				score[j] = score[j+1];
				score[j+1] = temp;
			}
		}
	}
	for(i = 0; i < 6; i++){
		printf("%d: %s %.0f\n",i+1,Students[i].Name,CalculateScore(Students[i].Score));
	}
	
}


/*1.参数为字符数组,以char Names[]表示参数 
	输入单个选手名字赋值给该字符串,函数不需要循环直接一个scanf即可*/ 
void InputName(char Name[]){
	scanf("%s",Name);
} 

/*2.传入的是单个学生的多个成绩,所以参数是一个一维数组
	遇到非60-100之间的数要跳过输入,不计入成绩用if判断是否输入有效 
	用计数cnt判断输入了几个数以便结束和输入*/ 
void InputScore(int Score[]){
	int score,cnt = 0;//score表示分数,cnt用来计数 
	while(cnt < 8){
		scanf("%d",&score);//输入分数 
		if(score >= 60 && score <= 100){//当分数符合要求时输入 
			Score[cnt] = score;
			cnt++;
		}
	}
} 

/*3.这个函数用来调用前面1,2写好的函数,只要把学生的序号和成绩的序号一致的传递 
	进函数,然后外面套一个循环就好了*/
void InputNamesAndScores(){
	int i;
	for(i = 0; i < 6; i++){
		InputName(Names[i]);
		InputScore(Scores[i]);
	}
} 

/*4.传入一组学生的成绩计算平均值,这里最后输出的要求是除去最大值和
	最小值,然后再算平均值,定义两个存贮最大和最小的变量,在读入的环节
	添加判断,最后减去这两个数再除6就可以得到平均值了*/
float CalculateScore(int Score[]){
	int i,max = -1,min = 101,sum = 0;
	for(i = 0; i < 8; i++){
		sum += Score[i];
		if(Score[i] > max)
			max = Score[i];
		if(Score[i] < min)
			min = Score[i];
	}
	sum = (sum - min - max) ;
	return sum / 6.0;
} 

/*5.要通过学生的名字来判断他的分数,这里的难点就是判断学生是几号
	找打学生的号数就能找到对应的分数,用过调用string包下面的strcmp
	可以在学生里进行匹配,匹配失败返回-1*/
float FindScore(char Name[]){
	int i;
	for(i = 0; i < 6; i++){
		if(!strcmp(Name,Names[i])){
			break;
		}
	}
	if(i == 6)//没找到
		return -1;
	return CalculateScore(Scores[i]);
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值