【问题标题】:Why is my code not generating factorial after 9?为什么我的代码在 9 之后没有生成阶乘?
【发布时间】:2021-09-18 23:05:42
【问题描述】:

用 C 编写一个程序来计算从命令行传递的数字的阶乘。这 阶乘必须在一个名为 computeFact() 的单独函数中计算,该函数具有以下内容 原型: int computeFact(int,…);

#include <stdarg.h>
#include <stdio.h>
#include<stdlib.h>
int computeFact(int, ...);
int main(int argc, char *argv[]) 
{
  if (argc < 2) 
  {
    printf("Invalid!");
  } else {
    for (int i = 1; i < argc; i++)
    {
      int n = atoi(argv[i]);
      printf("Factorial of %d is %d\n", n, computeFact(n));
    }
  }
  printf("\n");./
  return 0;
}
int computeFact(int num, ...) 
{
  va_list valist;
  int fact = 1;

  va_start(valist, num);
  for (int i = 0; i < num; i++) 
  {
    int x=va_arg(valist, int);
    if(x==0)
      return 1;
    else
    {
    for(int j = 1; j <= x; j++)
       fact=fact*j;
    return fact;
    }
  }
  va_end(valist);
}

输出如下:

~$ ./1 1 2 3 4 5 6 7 8 9 10
Factorial of 1 is 1
Factorial of 2 is 2
Factorial of 3 is 6
Factorial of 4 is 24
Factorial of 5 is 120
Factorial of 6 is 720
Factorial of 7 is 5040
Factorial of 8 is 40320
Factorial of 9 is 362880
Factorial of 10 is 1

~$ ./1 0
Factorial of 0 is 1

~$ ./1 99
Factorial of 99 is 362880

~$ ./1 98
Factorial of 98 is 40320

~$ ./1 5
Factorial of 5 is 120

我认为将 string 转换为 int 时存在一些错误,因为只有两位数中的最后一位被用于计算阶乘,但我无法确定我的代码中究竟要纠正什么。 em>

【问题讨论】:

  • 有趣的是,这段代码完全有效(至少对于
  • Windows,GCC @kol
  • 很奇怪,你的赋值指定原型int computeFact(int, ...),在这个应用程序中相当没有意义。更奇怪的是您的代码有效!您正在获取不存在的额外参数:您的 factorial 函数理论上可以用多个参数调用,但实际上它永远不会,所以总是只有一个参数,num .然而不知何故,它起作用了——但纯粹是偶然的。 (奇怪的是,它也可以在我的机器上运行,并且适用于大于 9 的数字!)
  • 我在 Windows 10 上使用 MinGW64、TDM-GCC 测试了这段代码,有许多不同的设置,但它总是给我错误的阶乘值。这段代码适用于 OP 一定是一个罕见的巧合。

标签: c command-line-arguments variadic-functions


【解决方案1】:

您正在通过读取va_arg 不存在的参数来调用未定义的行为

在这种情况下,您似乎应该停止使用 va_* 宏,而只需使用参数 num

int computeFact(int num, ...) 
{
  int fact = 1;

  int x=num;
  if(x==0)
    return 1;
  else
  {
    for(int j = 1; j <= x; j++)
      fact=fact*j;
    return fact;
  }
}

还要注意int 的限制。 99! 将是 156 位十进制数字,它不适合典型的 int 范围(最多 2,147,483,647 = 2**31 - 1)。

【讨论】:

  • 虽然我完全同意 OP 不应该使用 va_* 宏,但你能解释一下为什么他们的代码适用于数字 未定义的行为使这项工作?
【解决方案2】:

试试下面的代码:

int computeFact(int num, ...) 
{
  int fact = 1;

  int x = num;
  if(x==0)
    return 1;
  else
  {
    for(int value = 1; value <= x; value++)
      fact=fact*value;
    return fact;
  }
}

【讨论】:

    猜你喜欢
    • 2015-04-13
    • 2022-01-23
    • 2021-02-14
    • 1970-01-01
    • 2020-06-08
    • 1970-01-01
    • 1970-01-01
    • 2020-10-29
    • 2015-02-22
    相关资源
    最近更新 更多