C-递归

时间:2020-02-23 14:32:00  来源:igfitidea点击:

在本教程中,我们将学习C编程语言中的递归。

当我们调用或者调用一个函数时,控制流将从调用函数移至被调用函数。
当被调用函数中的所有代码语句都执行完后,控制流程将返回到调用函数。

如果我们从main()函数中调用greetings()函数,则main函数是调用函数,greetings函数是被调用函数。

这是常规函数调用。
另一方面,递归是一种特殊情况。

当函数调用自身时会发生递归。

注意!如果没有提供终止条件,则递归将变成无限循环的函数调用,如无限循环。

具有终止条件的递归

如果我们有一个阻止函数调用自身的条件,则使用终止条件进行递归是一种情况。

递归最常见的例子之一就是阶乘问题。

因此,如果我们有一个数字说n,则其阶乘如下:

factorial of n
= n x (n - 1) x (n - 2) x ... x 1

示例:3的阶乘为6

Factorial of 3
= 3 x 2 x 1
= 6

查找数字阶乘的公式如下。

F(n) represents the Factorial function to find factorial of n.

F(n) = n x F(n - 1)  if n > 1
     = 1             if n = 1 or 0

在上面的公式中,只要条件n> 1为真或者有效,我们就通过递归调用函数F()并在每次调用中传递值n-1来计算n的阶乘。
当n的值为1或者0时,F(n)返回1。

析取程序

以下是用C语言编写的程序以查找阶乘3。

#include <stdio.h>

int factorial(int);

int main(void) {
  int
    num = 3,
    fact;

  fact = factorial(num);
  
  printf("Factorial of %d is %d\n", num, fact);
  return 0;
}

int factorial(int n) {
  int prod;
  if (n == 1 || n == 0)
    return 1;
  else
    prod = n * factorial(n - 1);
  return prod;
}
Factorial of 3 is 6

探索递归

为了理解流程,以下代码具有一些printf()语句以打印出控制流程。

#include <stdio.h>

int factorial(int);

//this will mark the function
int functionID = 1;

int main(void) {
  int
    num = 3,
    fact;
  
  printf("----------------- Inside main() function ---------------\n");
  
  printf("main(): About to call the factorial() function #%d.\n", functionID);

  fact = factorial(num);
  
  printf("----------------- Back to main() function ---------------\n");
  
  printf("main(): Back from factorial() function #%d. Value returned: %d\n", functionID, fact);
  
  printf("main(): Factorial of %d is %d\n", num, fact);
  return 0;
}

int factorial(int n) {
  int prod;
  
  printf("----------------- Inside factorial() function #%d ---------------\n", functionID);
  
  printf("factorial() #%d: Value of n passed: %d\n", functionID, n);
  
  if (n == 1 || n == 0) {
    printf("factorial() #%d: Inside if-block. Value of n is 1 so, about to return 1 back to factorial function #%d\n", functionID, (functionID - 1));
    return 1;
  }
  else {
    printf("factorial() #%d: Inside else-block. Value of n is %d\n", functionID, n);
    printf("factorial() #%d: About to make a recursive call to factorial() function #%d with value of n = n - 1 i.e., %d\n", functionID, (functionID + 1), (n -  1));
    //increase function id to assign to called function 
    functionID++;
    prod = n * factorial(n - 1);
    //decrease function id to assign to calling function
    functionID--;
    printf("----------------- Back to factorial() function #%d ---------------\n", functionID);
    printf("factorial() #%d: Inside else-block. Value returned from factorial(%d) = %d\n", functionID, (n - 1), prod/n);
    printf("factorial() #%d: Inside else-block. Value stored in prod = n * factorial(n - 1) = %d * factorial(%d) = %d * %d = %d\n", functionID, n, (n- 1), n, prod/n, prod);
  }
  if (functionID == 1) {
    printf("factorial() #%d: About to return the value of prod = %d back to main()\n", functionID, prod);
  } else {
    printf("factorial() #%d: About to return the value of prod = %d back to factorial() function #%d\n", functionID, prod, (functionID - 1));
  }
  return prod;
}
----------------- Inside main() function --------------
main(): About to call the factorial() function #1.
----------------- Inside factorial() function #1 --------------
factorial() #1: Value of n passed: 3
factorial() #1: Inside else-block. Value of n is 3
factorial() #1: About to make a recursive call to factorial() function #2 with value of n = n - 1 i.e., 2
----------------- Inside factorial() function #2 --------------
factorial() #2: Value of n passed: 2
factorial() #2: Inside else-block. Value of n is 2
factorial() #2: About to make a recursive call to factorial() function #3 with value of n = n - 1 i.e., 1
----------------- Inside factorial() function #3 --------------
factorial() #3: Value of n passed: 1
factorial() #3: Inside if-block. Value of n is 1 so, about to return 1 back to factorial function #2
----------------- Back to factorial() function #2 --------------
factorial() #2: Inside else-block. Value returned from factorial(1) = 1
factorial() #2: Inside else-block. Value stored in prod = n * factorial(n - 1) = 2 * factorial(1) = 2 * 1 = 2
factorial() #2: About to return the value of prod = 2 back to factorial() function #1
----------------- Back to factorial() function #1 --------------
factorial() #1: Inside else-block. Value returned from factorial(2) = 2
factorial() #1: Inside else-block. Value stored in prod = n * factorial(n - 1) = 3 * factorial(2) = 3 * 2 = 6
factorial() #1: About to return the value of prod = 6 back to main()
----------------- Back to main() function --------------
main(): Back from factorial() function #1. Value returned: 6
main(): Factorial of 3 is 6

没有终止条件的递归

在这种情况下,将没有终止条件来停止该函数本身。

在下面的示例中,我们有一个函数" happy()",该函数不断调用自身。

#include <stdio.h>

void happy(void);

int main(void) {
  happy();
  return 0;
}

void happy(void) {
  printf("Because I am happy...\n");
  happy();
}
Because I am happy...
Because I am happy...
Because I am happy...
Because I am happy...
Because I am happy...
Because....

通过按Ctrl + C强制终止程序的执行。