【问题标题】:Why is this program running when input is 1?为什么这个程序在输入为 1 时运行?
【发布时间】:2016-02-25 19:09:37
【问题描述】:

我写了一个 C 程序,使用递归函数求一个数的阶乘,代码如下:

//program to find factorial of a number using a recursive function
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
int factorial(int a);
int main()
{
    int num, fact;
    printf("Enter a number: ");
    scanf("%d", &num);
    if(num<=0)
    {
        printf("The number cannot be zero/negative.");
        exit(1);
    }
    fact=factorial(num);
    printf("The factorial of the entered number is: %d", fact);
    getch();
    return 0;
}
int factorial(int a)
{
    while(a>1)
    return a*factorial(--a);
}

在“while”循环中的上述代码中,如果输入“a”>1,那么它应该执行,但是当我编译程序(使用 Dev C++ v.5.4.2)并将输入作为 1 时,我得到阶乘为 1。该程序是所需问题的解决方案,但我需要知道后台实际发生的情况......

提前谢谢你

【问题讨论】:

  • 当您调用factorial(1); 时,它不会返回任何内容,并且对fact 的访问会导致未定义的行为
  • 你已经有了递归。 while 是不必要的,如上所述,会导致问题。
  • @BlueMoon “未定义的行为”是什么意思?但是当我输入 1 时,我得到的阶乘为 1,这是正确的答案,为什么会这样......
  • 太糟糕了...在factorial() 中,如果a&gt;1 使用递减是未定义的行为,如果a&lt;=1 是未定义的行为,因为不执行`return 语句...跨度>
  • 我的意思是this。看似获得预期结果也是其中的一部分。

标签: c loops recursion


【解决方案1】:
int factorial(int a)
{
    while(a>1)
    return a*factorial(--a);
}

如果while 循环中的条件不成立,则此函数不会return 执行任何操作。因此,调用 undefined behavior (也许给你正确的输出)。

你应该处理那个案子-

int factorial(int a)
{
   if(a==1)return 1;
   //while(a>1)               // you use recursion then why using loop 
   return a*factorial(a-1);
}

【讨论】:

  • 我建议return a*factorial(a-1);,因为afactorial(--a)之间没有序列点。
  • @RSahu 是的,做出改变谢谢! :-) 。由于a 被递减,输出也出错了。
【解决方案2】:

a &lt;= 1 的情况下,您的函数没有返回语句,即使它需要一个。这意味着您有一个会引发未定义行为的错误:任何事情都可能发生,包括:“似乎工作正常”、“奇怪的输出”、程序崩溃等。

一个半体面的编译器会警告你这一点。例如启用警告的 GCC:

警告:控制到达非空函数[-Wreturn-type]|

【讨论】:

  • 那个警告是关于a*factorial(--a);,而不是关于缺少的return
  • @RSahu 哦,对,单行上有多个未定义的行为。这很让人佩服!原来我只是粘贴了错误的错误。谢谢,已经解决了:)
【解决方案3】:

这是未定义的行为。

N1256 6.9.1 函数定义

12 如果到达终止函数的},并且函数调用的值被 调用者,行为未定义。

要了解在这种特定情况下实际发生的情况,请让您的编译器输出汇编代码并读取它,或者将调试器用作 OllyDbg。

【讨论】:

    【解决方案4】:

    您的编译器似乎允许省略返回值。发生的情况是您的“阶乘”函数不会执行 while() 循环,并且在 while 循环之后没有 return 语句,因此返回值将是未定义的。

    int factorial(int a)
    {
        while (a>1) // a is 1 so this will be false, and the loop will not execute
            return a*factorial(--a);
        return 1; // this value will be returned
    }
    

    另外,我建议您查看此代码(在我看来,这就像一个学校练习)。目前,虽然它可以正常工作,但代码与有经验的程序员实现它的方式不同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-12-06
      • 2018-05-17
      • 2021-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多