#37 循环嵌套1

本文探讨了C语言中循环嵌套的应用,分别分析了项目1和项目2。项目1强调了内循环分析的重要性,错误代码由于使用了错误的循环变量导致结果不正确。项目2涉及青年歌手大奖赛的计分系统,要求计算歌手成绩,通过去除最高分和最低分取平均值。错误代码存在初始化位置错误和循环条件问题,同时提出了解决输入数据过多影响后续结果的方法,即清空输入缓冲区,并修正了清除缓存的语句。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目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名歌手时多输一组裁判数据):
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值