【问题标题】:Bug in While-Loop Keeps Counting Beyond ConditionWhile-Loop 中的错误不断计数超出条件
【发布时间】:2018-05-18 01:21:22
【问题描述】:

为了学校,我要编写一个 C 程序,它需要一些现金并返回达到该金额所需的最少硬币数量。我不知道我做错了什么。我一直在调整和尝试各种不同的东西,但我似乎无法完全调试程序。

程序对某些输入给出了正确的答案,但夸大了许多输入所需的硬币数量。

这是我目前所拥有的。

#include <stdio.h>

int main()
{
    float cash;
    int n;
    int counter=0;
    int quarters=0;
    int dimes=0;
    int nickels=0;
    int pennies=0;

    for (;;)
    {
        printf("Enter change amount: ");
        scanf("%f",&cash);

        if (cash > 0)
        {
            break;
        }
    }

    n = cash * 100; 
    counter = 0;

    while (n > 0)
    {
        while (n >= 25)
        {
            counter ++;
            n = n - 25;
            quarters ++;
            printf("%i\n",n);
        }

        while (n >= 10 && n < 25)
        {
            counter ++;
            n = n - 10;
            dimes ++;
            printf("%i\n",n);
        }

        while (n >= 5 && n < 10)
        {
            counter ++;
            n = n - 1;
            nickels++;
            printf("%i\n",n);
        }

        while (n > 0 && n < 5)
        {
            counter ++;
            n = n - 1;
            pennies ++;
            printf("%i\n",n);
        }
    }
    printf("%d\n",counter + n);
    printf("%i quarters, %i dimes, %i nickels, %i pennies\n", 
                quarters, dimes, nickels, pennies); 

    return 0;
}

【问题讨论】:

  • 为什么使用 while 循环作为 if 语句?另外,你忘了格式化你的结束}
  • 你的镍币循环减少了 1 而不是 5。
  • 您可以使用 n 来查找所有硬币值,而不是所有的循环,例如“ Quarters = n / 25; n = n % 25;”对每个硬币都这样做。所以对于 136, Quarters = 136 / 25 是 5,n = 136 % 25 是 11。然后你就做剩下的了。
  • 从风格上讲,您不应该将递增或递减运算符与递增或递减的变量分开。你真的不需要在一角钱循环中使用&lt; 25 条件;在满足条件之前,您不会达到它。

标签: c while-loop counter nested-loops


【解决方案1】:

我有点惊讶他们希望您使用 break 来退出循环,因为您通常希望循环“自然地”结束(并且您通常会为 switch 语句保存中断)。像这样的东西应该可以工作,使用整数除法和模运算符(编辑说明:我使用两个整数而不是单个浮点数,因为后者不准确。如果更有知识的人想要展示如何使用浮点数,会有趣。):

#include <stdio.h>

int main() {
    int dollar, cent;

    int q = 0;
    int d = 0;
    int n = 0;
    int p = 0;

    int re;

    printf("Enter amount: ");
    scanf(" %d.%d", &dollar, &cent);

    q = dollar * 4;        
    re = cent;

    q = q + (re / 25);
    re = re % 25;

    d = re / 10;
    re = re % 10;

    n = re / 5;
    re = re % 5;

    p = re;

    printf("q %d d %d n %d p %d\n", q, d, n, p);

    return 0;
}

例如,如果给定秒数并希望从中找到 min:sec,则此方法也适用。如果给你 65 秒,那么分钟部分(即 1)是 65 / 60,而秒部分是除以 60 或 65 % 60(即 5)后的余数。

【讨论】:

  • 您还需要从美分中获取 25 美分(例如 75 美分 -> 3 美分)。
【解决方案2】:

这是一个更完整的答案,与您提供给我们的代码相吻合。我将循环更改为减法/乘法并修复了您将镍币视为便士的错误。你不再需要 counter 变量了,但我把它留在里面了。

#include <stdio.h>

int main()
{
    float cash;
    int n;
    int counter=0;
    int quarters=0;
    int dimes=0;
    int nickels=0;
    int pennies=0;

    for (;;)
    {
        printf("Enter change amount: ");
        scanf("%f",&cash);

        if (cash > 0)
        {
            break;
        }
    }

    n = cash * 100; 
    counter = 0;

    if (n > 0)
    {
        quarters = (int)floor(n / 25);
        n -= quarters*25;
        printf( "%i\n", n );

        dimes = (int)floor(n / 10);
        n -= dimes*10;
        printf("%i\n",n);

        nickels = (int)floor(n / 5);
        n -= nickels*5;
        printf("%i\n",n);

        pennies = n;
        printf("%i\n",n);
    }
    printf("%i quarters, %i dimes, %i nickels, %i pennies\n", 
                quarters, dimes, nickels, pennies); 

    return 0;
}

【讨论】:

    【解决方案3】:

    首先,尝试从抽象出如何处理一种硬币开始:

    int coinsNeeded( int amount, int coinAmount )
    {
        return (int) floor( amount / coinAmount );
    }
    

    然后,分别处理每个硬币:

    quarters = coinsNeeded( cash, 25 );
    cash -= (quarters * 25);
    

    只需对您要考虑的每种硬币类型重复此操作,然后在最后打印出信息。关于是否要使用浮点数存在一些分歧。浮点数确实存在舍入错误,您在使用货币时要避免这些错误。你真正需要的是一个定点数据类型,但我离题了。您可以按照自己的方式进行操作(乘以 100 并仅处理便士)。

    【讨论】:

      猜你喜欢
      • 2016-05-16
      • 2013-11-12
      • 2020-04-30
      • 2015-07-24
      • 2023-01-11
      • 1970-01-01
      • 1970-01-01
      • 2020-07-16
      • 1970-01-01
      相关资源
      最近更新 更多