如何在递归函数中实现运行变量

时间:2016-11-09 09:02:24

标签: c recursion printf function-call

目前我正在编写一个程序,在这个程序中我需要一个变量count,每次调用该函数时它都会递增。在我的例子中,我有一个递归函数,想知道程序执行了多少迭代。

我通过计算数字的阶乘来简化代码。

我的第一种方法不起作用,最后会收到警告信息:

#include <stdio.h>

int factorial(unsigned int i, int *count)
{
   *count += 1;
   if(i <= 1)
   {
     return 1;
   }
   return i * factorial(i - 1, &count);
}  

int  main()
{
   int i = 10;
   int count = 0;
   printf("%d Iterations, Factorial of %d is %d\n", count, i, factorial(i, &count));
   return 0;
}


warning: passing argument 2 of ‘factorial’ from incompatible pointer type

我的第二种方法也不起作用,但也没有任何警告信息。

#include <stdio.h>

int factorial(unsigned int i, int count)
{
   count += 1;
   if(i <= 1)
   {
     return 1;
   }
   return i * factorial(i - 1, count);
}   

int  main()
{
   int i = 10;
   int count = 0;
   printf("%d Iterations, Factorial of %d is %d\n", count, i, factorial(i, count));
   return 0;
}

如何让它运行?有任何想法吗?我使用Ubuntu和gcc。

4 个答案:

答案 0 :(得分:1)

正如其他解决方案所暗示的那样,不需要静态变量。以下是正确的:

int factorial(unsigned int i, int *count)
{
   *count += 1;
   if(i <= 1)
   {
     return 1;
   }
   return i * factorial(i - 1, count);
}   

int main(void)
{
   int i = 10;
   int count = 0;
   printf("%d Iterations, Factorial of %d is %d\n", count, i, factorial(i, &count));
   return 0;
}

一个注意事项:由于printf语句中的参数评估顺序无法保证,据我所知,count调用中printf的值可能为零(它在调用阶乘之前传递)或者可能是10(在调用阶乘之后的值)。因此,main最好写成:

int main(void)
{
   int i = 10;
   int count = 0;
   int fact= factorial(i, &count);
   printf("%d Iterations, Factorial of %d is %d\n", count, i, fact);
   return 0;
}
  6.5.2.2函数调用:10函数指示符的评估顺序,实际参数和实际参数中的子表达式是未指定的,但在实际调用之前有一个序列点。

答案 1 :(得分:0)

在您的第一个案例中,factorial()函数count的类型为int *。因此,在递归调用函数时(在return语句中),不要传递count的地址,只需传递count本身。

也就是说,因为count要在factorial()的函数调用中进行修改,所以不要传递它们(变量和修改变量的函数调用)相同的参数列表,因为作为参数列表传递的元素中没有序列点,因此您最终会调用undefined behavior

答案 2 :(得分:0)

在factorial函数本身内将count变量声明为static

    static int count = 0;

答案 3 :(得分:0)

有两种方法可以解决这个问题。

  1. 在递归函数中声明一个静态变量,以计算它被调用的次数。
  2. e.g。

    int factorial(unsigned int i, int *count)
    {
       static int count2;
       *count = ++count2;
       if(i <= 1)
       {
         return 1;
       }
       return i * factorial(i - 1, count);
    }
    
    int  main()
    {
       int i = 10;
       int count = 0, fact;
       fact = factorial(i, &count);
       printf("%d Iterations, Factorial of %d is %d\n", count, i, fact);
       return 0;
    }
    
    1. 将count作为指向整数的指针,然后可以在每个函数中更新以查找迭代次数。
    2. e.g。

      int factorial(unsigned int i, int *count)
      {
         (*count)++;
         // Remaining lines the same as first solution.
      }
      

      第二个解决方案只适用于某些特殊类型的递归函数,其中第一个函数调用第二个函数,第二个函数调用第三个函数,等等。例如,在递归的fibbonaci序列算法中,它不起作用。

      第一种解决方案更为通用,适用于所有条件。