在程序编辑区编写程序,给定程序功能是: 从键盘上输入若干个学生的成绩,统计出平均成绩,并输出低于平均分的学生成绩,用输入负数结束输入。

例如输入: 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  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