项目1 
错误代码:
/**
*Copyright @2018,优快云学院
*All rights reserved.
*文件名称:main.c
*作 者:袁生
*完成日期:2018年1月20日
*版 本 号:v1.0
*问题描述:求1+2^2+3^3+4^4+5^5+6^6
*/
#include <stdio.h>
int main()
{
int i=1,n,tn=1,sn=0;
scanf("%d",&n);
//简化循环
while(i<=n)
{
tn*=n; //tn=n^n
sn+=tn; //sn=∑tn=∑n^n
printf("n=%d tn=%d sn=%d\n",i,tn,sn);
i++;
}
return 0;
}
错误输出:
正解代码:
/**
*Copyright @2018,优快云学院
*All rights reserved.
*文件名称:main.c
*作 者:袁生
*完成日期:2018年1月19日
*版 本 号:v1.0
*问题描述:求1+2^2+3^3+4^4+5^5+6^6
*/
#include <stdio.h>
int main()
{
int i=1,j=1,n,tn=1,sn=0;
scanf("%d",&n);
while (i<=n)
{
j=1;
tn=1;
while (j<=i)
{
tn*=i;
j++;
}
sn+=tn;
printf("n=%d tn=%d sn=%d\n",j-1,tn,sn);
i++;
}
return 0;
}
正解输出:
小结
错误原因是对内循环分析不到位,明显sn=sn+ti
而ti是不能直接用i来做循环变量的,否则得不到ti=i^i
结果,比如
while(i<=n)
{
tn*=n; //tn=t(n-1)*n,即tn=k^n(k=n且k不变),并不是求tn=i^i(i在变)
sn+=tn; //sn=∑tn=∑n^n
printf("n=%d tn=%d sn=%d\n",i,tn,sn);
i++;
}
要注意tn=∑k^n=k+k^2+k^3+...+k^n
(底数k不变,循环可合并)与tn=∑n^n=1+2^2+3^3+...+n^n
(底数n在变,循环不可合并)的区别。
项目2 大奖赛计分
要举办青年歌手大奖赛,请你设计一个程序,计算歌手成绩
输入
评委人数judgeNum
歌手人数singerNum
每名评委对每位歌手的打分mark(小数:0-10分)
输出
每位歌手的成绩
打分规则
每位评委对每位歌手给出一个分数,去掉一个最高分和一个最低分,余下分数的平均值作为选手的最后得分。
错误代码:
/**
*Copyright @2018,优快云学院
*All rights reserved.
*文件名称:main.c
*作 者:袁生
*完成日期:2018年1月19日
*版 本 号:v1.0
*问题描述:大奖赛计分:
*要举办青年歌手大奖赛,请你设计一个程序,计算歌手成绩输入
*评委人数judgeNum
*歌手人数singerNum
*每名评委对每位歌手的打分mark(小数:0-10分)
*输出:
*每位歌手的成绩
*打分规则:
*每位评委对每位歌手给出一个分数,去掉一个最高分和一个最低分,余下分数的平均值作为选手的最后得分。
*/
#include <stdio.h>
int main()
{
int i=1,j=1,n,jn;
float mark,max=0,min=10,sum=0,av;
printf("输入歌手人数n和裁判人数jn:\n");
scanf("%d %d",&n,&jn);
while(i<=n)
{
printf("裁判打分:");
while (j<=jn)
{
scanf("%f",&mark);
if (mark<0||mark>10)
continue;
if (max<mark)
max=mark;
if (min>mark)
min=mark;
sum+=mark;
j++;
}
printf("最高分:%.2f 最低分:%.2f",max,min);
sum=sum-max-min;
jn=jn-2;
av=sum/jn;
printf("第 %d 位歌手得分:%.2f",jn,av);
i++;
}
return 0;
}
错误输出:
错因分析:
1. 初始化位置错误;
2. jn值产生变化;
代码常规写法:
/**
*Copyright @2018,优快云学院
*All rights reserved.
*文件名称:main.c
*作 者:袁生
*完成日期:2018年1月19日
*版 本 号:v1.1
*问题描述:大奖赛计分:
*要举办青年歌手大奖赛,请你设计一个程序,计算歌手成绩输入
*评委人数judgeNum
*歌手人数singerNum
*每名评委对每位歌手的打分mark(小数:0-10分)
*输出:
*每位歌手的成绩
*打分规则:
*每位评委对每位歌手给出一个分数,去掉一个最高分和一个最低分,余下分数的平均值作为选手的最后得分。
*/
#include <stdio.h>
int main()
{
int i,j,n,jn;
float mark,max,min,sum,av;
printf("输入歌手人数n和裁判人数jn:\n");
scanf("%d %d",&n,&jn);
i=1;
while(i<=n)
{
printf("裁判打分:");
j=1,max=0,min=10,sum=0;
while (j<=jn)
{
scanf("%f",&mark);
if (mark<0||mark>10)
continue;
if (max<mark)
max=mark;
if (min>mark)
min=mark;
sum+=mark;
j++;
}
printf("最高分:%.2f 最低分:%.2f\n",max,min);
sum=sum-max-min;
j=j-3;
av=sum/j;
printf("第 %d 位歌手得分:%.2f\n",i,av);
i++;
}
return 0;
}
输出:
小结
注意在循环之前将相关变量在正确位置初始化。输入数据注意不要输多,否则会影响后续结果,可以考虑一下如何防止输分数时数据个数输多的问题。下面就用清空scanf多于缓存来解决这个问题(清空缓存相关链接:C语言清空缓冲区,C语言清空输入缓冲区的N种方法对比):
完整版代码(还是错误的,囧,择日想办法解决):
/**
*Copyright @2018,优快云学院
*All rights reserved.
*文件名称:main.c
*作 者:袁生
*完成日期:2018年1月22日
*版 本 号:v1.2
*问题描述:大奖赛计分:
*要举办青年歌手大奖赛,请你设计一个程序,计算歌手成绩输入
*评委人数judgeNum
*歌手人数singerNum
*每名评委对每位歌手的打分mark(小数:0-10分)
*输出:
*每位歌手的成绩
*打分规则:
*每位评委对每位歌手给出一个分数,去掉一个最高分和一个最低分,余下分数的平均值作为选手的最后得分。
*/
#include <stdio.h>
int main()
{
int i,j,n,jn;
int k; //用来清空输入的多余分数数据
float mark,max,min,sum,av;
printf("输入歌手人数n和裁判人数jn:\n");
scanf("%d %d",&n,&jn);
i=1;
while(i<=n)
{
printf("裁判打分:");
j=1,max=0,min=10,sum=0;
while (j<=jn)
{
scanf("%f",&mark);
if (mark<0||mark>10)
continue;
if (max<mark)
max=mark;
if (min>mark)
min=mark;
sum+=mark;
j++;
}
//不停地使用getchar()获取缓冲中字符,直到获取的k是“\n”或文件结尾符EOF为止
while ((k=getchar())!=EOF||k!='\n');
printf("最高分:%.2f 最低分:%.2f\n",max,min);
sum=sum-max-min;
j=j-3;
av=sum/j;
printf("第 %d 位歌手得分:%.2f\n",i,av);
i++;
}
return 0;
}
错因分析:
清除缓存语句貌似死循环了。待续。。
更新:清除缓存语句有误应将循环条件中的“或”运算(||)改为“与”运算(&&),即
while ((k=getchar())!=EOF && k!='\n');
。
结果展示(第1、2名歌手时多输一组裁判数据):