【问题标题】:Why won't it properly calculate an average of members?为什么它不能正确计算成员的平均值?
【发布时间】:2013-09-16 16:56:11
【问题描述】:

这是代码:

#include <stdio.h>

int group, regular_group, regular_members, shutdown, special_group,
    special_members;
float average_special, average_regular;
main()
{
  do
  {
    printf("How many members are in the group?\n");
    scanf("%d", &group);

    if (group >= 15)
    {
      regular_group = regular_group + 1;
      regular_members = regular_members + group;
      printf("Do you want to add another group? yes = 1, no = 0 \n");
      scanf("%d", &shutdown);
    }

    else
    {
      special_group = special_group + 1;
      special_members = special_members + group;
      printf("Do you want to add another group? yes = 1, no = 0 \n");
      scanf("%d", &shutdown);
    }
  }

  while (shutdown == 1);

  average_regular = regular_members / regular_group;
  average_special = special_members / special_group;

  printf("\nTotal regular members:\n%d\n", regular_members);
  printf("\nTotal special members:\n%d\n", special_members);

  printf("\nAverage regular members in a group:\n%f\n", average_regular);
  printf("\nAverage special members in a group:\n%f\n", average_special);
  fflush(stdin);
  getchar();

}

如果一个组大于 15,它自动成为一个常规组,但如果它小于它一个特殊组。我需要每个类别的成员总数。 成员总数工作正常。但我还需要一组两个类别的平均大小。但平均值始终为 0,000000。但是我找不到错误..请帮助我

非常感谢!

【问题讨论】:

  • 啊,这是一个翻译错误。我忘了从荷兰语>英语翻译。在我的原始代码中是一样的
  • 在这里工作,除了如果至少一次输入值 >15 和一次输入值 1<enter>1<enter>16<enter>0 输出16.00000&lt;cr/lf&gt;1.00000&lt;cr/lf&gt;
  • @alk 只需要除以零检查即可避免这种情况。
  • 顺便说一句:这是int main(void)
  • 为了帮助调试,将格式从%f 更改为%e 以查看average_regular 是否真的是0.000000。

标签: c average


【解决方案1】:

这是因为

  1. 您正在对两个整数进行除法regular_members/regular_group,除法后得到一个整数。如果分子将变得小于分母,那么您将得到0 结果。
  2. 您没有初始化变量regular_groupregular_membersspecial_groupspecial_membersaverage_specialaverage_regular

而不是使用

average_regular = regular_members/regular_group;
average_special = special_members/special_group;

试试这个

average_regular = (float)regular_members/regular_group;
average_special = (float)special_members/special_group;

同时删除fflush(stdin)。它将调用未定义的行为。
声明你的变量

int group, regular_group, regular_members, shutdown, special_group,
special_members;
float average_special, average_regular;

main函数内部

main()
{
     int group, regular_group, regular_members, shutdown, special_group, special_members;
     float average_special, average_regular;
     ....
     ....
}

别忘了初始化变量regular_groupregular_membersspecial_groupspecial_membersaverage_specialaverage_regular0


这是你的工作代码(经过一些修改)

#include <stdio.h>

int main()
{
    int group, regular_group = 0, regular_members = 0, shutdown, special_group = 0,
    special_members = 0;
    float average_special = 0, average_regular = 0;

  do
  {
        printf("How many members are in the group?\n");
        scanf("%d", &group);

        if (group >= 15)
        {
            regular_group = regular_group + 1;
            regular_members = regular_members + group;
            printf("Do you want to add another group? yes = 1, no = 0 \n");
            scanf("%d", &shutdown);
        }

        else
        {
            special_group = special_group + 1;
            special_members = special_members + group;
            printf("Do you want to add another group? yes = 1, no = 0 \n");
            scanf("%d", &shutdown);
       }
  } while (shutdown != 0);

if(regular_group != 0)              //to stop division by zero
    average_regular = (float)regular_members / regular_group;
if(special_group != 0)              //to stop division by zero  
    average_special = (float)special_members / special_group;

printf("\nTotal regular members:\n%d\n", regular_members);
printf("\nTotal special members:\n%d\n", special_members);

printf("\nAverage regular members in a group:\n%f\n", average_regular);
printf("\nAverage special members in a group:\n%f\n", average_special);

return 0;

}

【讨论】:

    【解决方案2】:

    这是因为您在整数之间进行除法。 此外,如果结果变量是浮点数,这不足以让操作按预期执行。

    你需要像这样使用类型转换:

    average_regular = (float)regular_members/(float)regular_group;
    average_special = (float)special_members/(float)special_group;
    

    实际上,只对每个操作的两个成员之一进行强制转换就足以将操作编译为浮点除法:

    average_regular = (float)regular_members/regular_group;
    average_special = (float)special_members/special_group;
    

    【讨论】:

    • 不,我仍然得到 0.00000 作为答案
    • 根据 C99,如果您在多个数字之间进行代数运算,所有涉及的数字都将向上转换为必要的类型以适应发生的运算。这两个操作中的第一个是两者中更好的,因为无论如何编译器都会在第二种情况下隐式转换分母。至少在第一种情况下,您的意图是明确显示的。至于海报,您能否向我们提供样本运行的输出?打印出所有的元素,等等?
    • 遗憾的是,我发现“正常”的期望在不同的构建环境中会产生不同的结果。我发现必须经常在 Windows 上使用 gcc 为嵌入式目标进行转换。最近的一课:寻找和证明abs() 在我的世界里行不通。
    【解决方案3】:

    您的代码没有问题。 唯一的问题是 Global virable 被初始化为 0 所以当你没有任何特殊或常规组时

    regular_group or special_group value will be 0.
    

    和任何除以 0 的 no 都会给出浮点异常。我希望你明白了。

    main() must return int .
    

    休息没有问题。

    【讨论】:

      【解决方案4】:

      除法regular_members/regular_group 产生一个整数结果,因此任何分数都变为 0。

      将其中一个变量转换为浮点数,除法将产生浮点数。

      average_regular = regular_members/(float)regular_group;
      

      与其他版本类似average_special

      -另外你的 main 声明不正确,应该至少是 int main( void )

      -fflush(stdin); 不是清除缓冲区的正确方法。这可能会导致未定义的行为。

      -你可能会在这里调用除零average_regular = regular_members / regular_group;

      【讨论】:

      • @svenweer 你可能做错了什么,修复后代码产生了一个浮动结果。
      猜你喜欢
      • 2022-06-28
      • 2020-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-05
      • 2020-07-09
      • 2019-09-06
      相关资源
      最近更新 更多