【问题标题】:C recursion code [duplicate]C递归代码[重复]
【发布时间】:2015-09-10 06:15:45
【问题描述】:

我在使用递归理解这段代码方面需要帮助。

    int power(int n1,int n2);
    int main()
    {
        int base, exp;
        printf("Enter base number: ");
        scanf("%d",&base);
        printf("Enter power number(positive integer): ");
        scanf("%d",&exp);
        printf("%d^%d = %d", base, exp, power(base, exp));
        return 0;
   }
   int power(int base,int exp)
   {
       if ( exp!=1 )
       return (base*power(base,exp-1));
   }

代码运行良好,但我不明白为什么当exp 为 1 时它仍然能够返回一个值,即使函数体中的条件评估为假,所以我认为它不应该返回任何东西。

例如,如果在main() 函数中调用该函数,并且我将51 的值分别分配给baseexp,我希望我不应该得到返回值,因为 exp1 并且我的函数仅在 exp !=1 时返回一些东西,而且函数体中没有 else 部分来涵盖 exp1 的情况。 我知道 C 在未指定返回值时返回垃圾值,但在这种情况下,它返回正确的答案,我对其进行了多次测试。例如,当我在主函数中使用base=7exp=1 调用它时,它返回7 作为我的答案,即使使用其他“基数”值,它也总是返回正确答案的基数。这正是我困惑的根源——当函数体的 IF 子句评估为假时,C 如何设法向我返回正确的答案...... 我想我在这里遗漏了一些东西。

【问题讨论】:

  • 您的代码调用未定义行为,因为当exp 为 1 时,您不会返回 int。该函数将从内存中返回“随机”、“垃圾”值。所以任何事情都可能是结果。
  • exp = 1时不返回,但如果在调用函数时抓到返回值,就会是内存中的垃圾值
  • 我知道 C 在未指定返回值时返回垃圾值,但在这种情况下,它返回正确答案,我测试了几次。例如,当我在主函数中使用 base = 7 和 exp =1 调用它时,它返回 7 作为我的答案,即使使用其他“base”值,它也总是返回正确答案的 base。这正是我困惑的根源 - 当函数体的 IF 子句评估为 false 时,C 如何设法向我返回正确答案......

标签: c function recursion return-value


【解决方案1】:

实际上你的函数是Undefined Behaviour,因为在exp == 1的情况下没有返回任何内容

返回给 main 函数的值是随机的。

【讨论】:

    【解决方案2】:

    编译器可能会在声明int power(int base,int exp)中警告您

    没有返回,在函数中返回非void

    因此,当您使用exp = 1 调用power() 时,您将获得undefined behavior

    请注意:如果exp 为负数,您的power() 将陷入递归陷阱

    【讨论】:

      【解决方案3】:

      在您的情况下,对于具有值 1exp,没有 return 语句。如果该调用的返回值在调用者函数中使用,则程序显示 UB。参见下面的注释

      也就是说,如果您调用power() 时使用exp 以外的值1,该问题也将成立,因为power() 最终将使用exp 调用自身作为1在某个时间点。

      最后,exp 是一个int,它可以接受一个负值并进入无限循环,只是通过无限递归造成堆栈溢出。


      注意:根据C11 标准,如果函数通过到达关闭} 而终止并使用返回值,则调用invoke undefined behaviour

      参考:章节 §6.9.1,第 12 段,

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

      【讨论】:

      • 我知道 C 在未指定返回值时返回垃圾值,但在这种情况下,它返回正确答案,我测试了几次。例如,当我在主函数中使用 base = 7 和 exp =1 调用它时,它返回 7 作为我的答案,即使使用其他“base”值,它也总是返回正确答案的 base。这正是我困惑的根源——当函数体的 IF 子句评估为 false 时,C 如何设法向我返回正确的答案......
      • @AyorindeKomolafe 好吧,未定义的行为是未定义的。它还包括“按预期”工作的情况。
      • 真的吗?我不知道。我想如果它是未定义的,每次我运行它时它可能会给我不同的答案,但它总是给我正确的答案。
      猜你喜欢
      • 2014-04-14
      • 1970-01-01
      • 2011-04-17
      • 2017-03-10
      • 1970-01-01
      • 1970-01-01
      • 2017-10-31
      • 2011-08-03
      相关资源
      最近更新 更多