在程序编辑区编写程序,给定程序功能是: 从键盘上输入若干个学生的成绩,统计出平均成绩,并输出低于平均分的学生成绩,用输入负数结束输入。
例如输入: 70 80 90 -1
输出: ave =80.00
--------OUTPUT-----------
70.0
程序有两个空(1)、(2)需要补充完整。并将程序调试出所需的结果。
注意:不要随意改动程序,不得增行或删行,也不得更改程序的结构!
#include
int main(void)
{
float x[100], sum = 0, ave, a;
int n = 0, i;
// 读入学生成绩
scanf("%f", &a);
while (a >= 0.0 && n < 100) {
x[n] = a; // 将读入的成绩存入数组 x 中
sum += a;
n++;
scanf("%f", &a);
}
// 判断是否有有效学生成绩
ave = sum / n;
printf("ave =%.2f\n", ave);
// 输出低于平均分的学生成绩
printf("-----------OUTPUT. --------\n");
for (i = 0; i < n; i++)
if (x[i] < ave)
printf("%.1f\n", x[i]);
return 0;
}
上面这段代码缺少了判断是否有有效学生成绩的部分。如果没有有效学生成绩,这个程序会输出一个错误的平均分(通常为一个很大的数),并且不会输出低于平均分的学生成绩。
因此,建议还是加上对有效学生成绩的判断。在计算平均分和输出低于平均分的学生成绩前,判断是否有有效学生成绩。如果没有,就输出一条提示信息;如果有,就按照题目要求进行计算和输出。
#include
int main(void)
{
float x[100], sum = 0, ave, a;
int n = 0, i;
// 读入学生成绩
scanf("%f", &a);
while (a >= 0.0 && n < 100) {
x[n] = a; // 将读入的成绩存入数组 x 中
sum += a;
n++;
scanf("%f", &a);
}
// 判断是否有有效学生成绩
if (n > 0) {
// 计算平均分,并输出
ave = sum / n;
printf("ave =%.2f\n", ave);
// 输出低于平均分的学生成绩
printf("-----------OUTPUT. --------\n");
for (i = 0; i < n; i++) {
if (x[i] < ave) {
printf("%.1f\n", x[i]);
}
}
} else {
printf("No scores entered.\n"); // 没有有效学生成绩
}
return 0;
}
在上面的代码中,首先判断 n 的值是否大于 0。如果大于 0,说明有有效学生成绩,就进行计算和输出;如果小于等于 0,说明没有有效学生成绩,就输出一条提示信息。
拓展
#include
#define MAX_NUM 100 // 最多可输入的学生数
int main()
{
float score[MAX_NUM], sum = 0, avg;
int i, count = 0;
printf("请输入学生成绩,以负数作为输入结束:\n");
// 读入学生成绩,并计算成绩总和和有效学生数
for (i = 0; i < MAX_NUM; i++) {
scanf("%f", &score[i]);
if (score[i] < 0) {
break; // 输入负数结束
}
sum += score[i];
count++;
}
// 计算平均分,并输出
avg = sum / count;
printf("ave =%.2f\n", avg);
// 输出低于平均分的学生成绩
printf("--------OUTPUT-----------\n");
for (i = 0; i < count; i++) {
if (score[i] < avg) {
printf("%.1f\n", score[i]);
}
}
return 0;
}
上述程序中,首先通过一个 for 循环读入学生成绩,当输入负数时结束循环。在循环过程中,累加学生成绩并计算有效学生数。
之后,根据成绩总和和有效学生数计算平均分,并使用 printf 函数输出平均分。
最后,再通过一个 for 循环输出低于平均分的学生成绩。
需要注意的是,由于输入的学生数不确定,因此需要定义一个数组来存储学生成绩。同时,为了确保程序的健壮性,也需要对输入的学生数进行限制,本例中限制最多可输入100个学生。
拓展完善
在读入学生成绩时,这个程序没有限制输入的有效数字范围。如果用户输入了非法的字符(如字母、符号等),程序会出现错误。如果需要对输入进行限制,可以使用标准库函数 scanf()
的返回值进行判断
#include
#define MAX_NUM 100 // 最多可输入的学生数
int main()
{
float score[MAX_NUM], sum = 0, avg;
int i, count = 0;
printf("请输入学生成绩,以负数作为输入结束:\n");
// 读入学生成绩,并计算成绩总和和有效学生数
for (i = 0; i < MAX_NUM; i++) {
if (scanf("%f", &score[i]) != 1 || score[i] < 0) {
break; // 输入非法或负数结束
}
sum += score[i];
count++;
}
// 如果没有有效学生成绩则直接退出
if (count == 0) {
printf("没有有效学生成绩。\n");
return 0;
}
// 计算平均分,并输出
avg = sum / count;
printf("ave =%.2f\n", avg);
// 输出低于平均分的学生成绩
printf("--------OUTPUT-----------\n");
for (i = 0; i < count; i++) {
if (score[i] < avg) {
printf("%.1f\n", score[i]);
}
}
return 0;
}
拓展完善2:如果用户输入了非法字符,我们需要通过清空标准输入缓冲区的方式来跳过该非法字符,然后继续读取下一个字符。这个过程可以使用 scanf()
函数的返回值和 getchar()
函数实现。
也就是:如果输入了非法字符,则跳过该非法字符,直到读取到换行符为止
#include
#define MAX_NUM 100 // 最多可输入的学生数
int main()
{
float score[MAX_NUM], sum = 0, avg;
int i, count = 0;
printf("请输入学生成绩,以负数作为输入结束:\n");
// 读入学生成绩,并计算成绩总和和有效学生数
for (i = 0; i < MAX_NUM; i++) {
if (scanf("%f", &score[i]) != 1) {
// 清空标准输入缓冲区并跳过非法字符
while (getchar() != '\n');
continue;
}
if (score[i] < 0) {
break; // 输入负数结束
}
sum += score[i];
count++;
}
// 如果没有有效学生成绩则直接退出
if (count == 0) {
printf("没有有效学生成绩。\n");
return 0;
}
// 计算平均分,并输出
avg = sum / count;
printf("ave =%.2f\n", avg);
// 输出低于平均分的学生成绩
printf("--------OUTPUT-----------\n");
for (i = 0; i < count; i++) {
if (score[i] < avg) {
printf("%.1f\n", score[i]);
}
}
return 0;
}
拓展完善3: 将清空标准输入缓冲区并跳过非法字符的代码改为了跳过空格。当读取到非法字符时,该循环会一直执行,直到读取到一个空格停止。也就是:如果读到非法字符,跳过非法字符,直到读取到空格为止
#include
#define MAX_NUM 100 // 最多可输入的学生数
int main()
{
float score[MAX_NUM], sum = 0, avg;
int i, count = 0;
printf("请输入学生成绩,以负数作为输入结束:\n");
// 读入学生成绩,并计算成绩总和和有效学生数
for (i = 0; i < MAX_NUM; i++) {
if (scanf("%f", &score[i]) != 1) {
// 清空标准输入缓冲区并跳过非法字符
while (getchar() != ' ');
continue;
}
if (score[i] < 0) {
break; // 输入负数结束
}
sum += score[i];
count++;
}
// 如果没有有效学生成绩则直接退出
if (count == 0) {
printf("没有有效学生成绩。\n");
return 0;
}
// 计算平均分,并输出
avg = sum / count;
printf("ave =%.2f\n", avg);
// 输出低于平均分的学生成绩
printf("--------OUTPUT-----------\n");
for (i = 0; i < count; i++) {
if (score[i] < avg) {
printf("%.1f\n", score[i]);
}
}
return 0;
}
拓展完善4:在遇到非法字符时,会输出提示信息并清空缓冲区,同时使用 i-- 将当前位置回退一个字符,保证程序能够重新读入输入。也就是在输入非法字符时,跳过非法字符,在输出低于平均分值,非法字符对应的值不输出
#include
#define MAX_NUM 100 // 最多可输入的学生数
int main()
{
float score[MAX_NUM], sum = 0, avg;
int i, count = 0;
printf("请输入学生成绩,以负数作为输入结束:\n");
// 读入学生成绩,并计算成绩总和和有效学生数
for (i = 0; i < MAX_NUM; i++) {
if (scanf("%f", &score[i]) != 1) {
printf("输入非法,已跳过该字符,请重新输入!\n");
// 清空标准输入缓冲区
while (getchar() != ' ');
i--; continue;
}
if (score[i] < 0) {
break; // 输入负数结束
}
sum += score[i];
count++;
}
// 如果没有有效学生成绩则直接退出
if (count == 0) {
printf("没有有效学生成绩。\n");
return 0;
}
// 计算平均分,并输出
avg = sum / count;
printf("ave =%.2f\n", avg);
// 输出低于平均分的学生成绩
printf("--------OUTPUT-----------\n");
for (i = 0; i < count; i++) {
if (score[i] < avg) {
printf("%.1f\n", score[i]);
}
}
return 0;
}
拓展5:加入了 while 循环来保证只有在输入合法数字(即 scanf() 的返回值为1)时才会退出循环。同时,处理非法输入时也加入了清空缓冲区的操作。
#include
#define MAX_NUM 100 // 最多可输入的学生数
int main()
{
float score[MAX_NUM], sum = 0, avg;
int i, count = 0;
char c; // 用于清空缓冲区
printf("请输入学生成绩,以负数作为输入结束:\n");
// 读入学生成绩,并计算成绩总和和有效学生数
for (i = 0; i < MAX_NUM; i++) {
while (scanf("%f", &score[i]) != 1) {
printf("输入非法,请输入一个数字!\n");
// 清空标准输入缓冲区,避免无限循环
while ((c = getchar()) != '\n' && c != EOF);
}
if (score[i] < 0) {
break; // 输入负数结束
}
sum += score[i];
count++;
}
// 如果没有有效学生成绩则直接退出
if (count == 0) {
printf("没有有效学生成绩。\n");
return 0;
}
// 计算平均分,并输出
avg = sum / count;
printf("平均分为:%.2f\n", avg);
// 输出低于平均分的学生成绩
printf("低于平均分的成绩为:\n");
for (i = 0; i < count; i++) {
if (score[i] < avg) {
printf("%.1f\n", score[i]);
}
}
return 0;
}
实际输入:70 80 70 80 90
实际输出:平均分:78.00
低于平均分的成绩:70.0 70.0