这段代码到底发生了什么?

时间:2012-09-04 14:19:36

标签: c function recursion

我有一个包含递归函数的代码。我浪费了大量的时间进行递归,但我仍然无法得到它:

#include<stdio.h>
void count(int);

int main()
{
    int x=10,z;
    count(x);
}

void count(int m)
{
    if(m>0)
        count(m-1);
    printf("%d",m);
}

当第一次使用参数10调用count时,它满足条件,然后启动递归部分。当函数调用自身时会发生什么?我不明白。请参考堆栈进行解释。

5 个答案:

答案 0 :(得分:31)

m大于0时,我们会调用count。这是堆栈调用的表示:

 count (m = 10)  
   count (m = 9)  
     count (m = 8)  
       count (m = 7)  
         count (m = 6)    
           count (m = 5)     
             count (m = 4)     
               count (m = 3)     
                 count (m = 2)     
                   count (m = 1)
                     count (m = 0)
                     printf 0
                   printf 1
                 printf 2
               printf 3
             printf 4
           printf 5
         printf 6
       printf 7
     printf 8
   printf 9
 printf 10

答案 1 :(得分:2)

下次它自己调用它的值会更小

count(int m)
{
 if(m>0)
 count(m-1); // now it is calling the method "count" again, except m is one less
 printf("%d",m);
}

所以首先它将调用count为10,然后它将调用9,然后是8,然后是7 .....直到这个if语句不是真的:

if(m>0)

你可能会感到困惑的是if语句只适用于下一行(printf不是if语句的一部分)

所以你有:

count(int m)
    {
     if(m>0)
     {
         count(m-1); // now it is calling the method "count" again, except m is one less
     }
     printf("%d",m);
    }

因此,一旦m不是>,递归调用就会停止。 0,然后它将调用printf。

当m为0时调用printf后,它将从'count'调用返回(返回m等于1),然后当m为1时调用printf,然后当m是2,.....

所以输出应该是:

"0 1 2 3 4 5 6 7 8 9 10"

编辑: 就堆栈而言:

这就是堆栈正在做的事情:

count(10) // push count(10)

- &GT;

count(9) // push count(9)
count (10)

- &GT;

...

- &GT;

count(0) // push count(0)
count(1)
count(2)
count(3)
count(4)
count(5)
count(6)
count(7)
count(8)
count(9)
count(10)

- &GT; (然后它开始打印并从堆栈中弹出方法)

// pop count(0), and printf(0)
count(1)
count(2)
count(3)
count(4)
count(5)
count(6)
count(7)
count(8)
count(9)
count(10)

- &GT;

// pop count(1), and printf(1)
count(2)
count(3)
count(4)
count(5)
count(6)
count(7)
count(8)
count(9)
count(10)

- &GT;

...

- &GT;

// pop count(9), and printf(9)
count(10)

- &GT;

// pop count(10), and printf(10)

答案 2 :(得分:0)

当调用函数时,返回地址(下一个要执行的代码)与其当前参数一起存储在堆栈中。一旦函数完成,弹出地址和参数,这样cpu就会知道继续执行代码的位置。

让我们写一下函数的地址(仅用于本例的目的)

count(int m)
{
(address = 100)  if(m>0)
(address = 101)     count(m-1); // now it is calling the method "count" again, except m is one less
(address = 102)  printf("%d",m);
}

对于m = 1:

if是完整字段,因此我们使用address 101m = 1执行代码。 address 102m = 1被推送到堆栈,并且address 100再次使用m = 0执行该功能。从m = 0开始,我们执行address 102并在控制台上打印0。函数结束,弹出最后一个返回address (102)和参数m = 1,并在屏幕上打印1执行address 102处的行。

答案 3 :(得分:0)

  1. 使用count的整数参数调用函数10
  2. 由于m的函数参数10大于0,函数count会调用自身,其整数参数为m,即10 1}}减去1等于9
  3. 第2步重复使用不同的参数(m-1),直到m不大于0以及程序打印m的值。
  4. 递归函数只修改给定的参数并使用该修改后的值调用自身,直到返回所需的结果(在这种情况下m不大于0)。

答案 4 :(得分:0)

每个数字都代表行号。

#include<stdio.h>
count(int);
main()
{
1int x=10,z;
2count(x);
}  
count(int m)
{
3if(m>0)
4   count(m-1);
5printf("%d",m);
}

执行就像这样(x = 3) -

行号| x的值

1 3

2 3

3 3

4 2

3 2

4 1

3 1

4 0

5 0

5 1

5 2

5 3

屏幕上打印的数字0 1 2 3