使用递归函数vol2添加数字

时间:2013-11-18 11:06:27

标签: c function recursion user-defined-functions

asked前几天

     #include <stdio.h>

     int MyAdd(int);
     main ()
     {
          int i;
          int c = 0;
          c = MyAdd(5); 
          printf("%d\n", c);
     }

     int MyAdd(int a)
     {
          if(a > 0)
               return a + MyAdd(--a);
          else
               return 0;
     }

为什么这个结果是10而不是15,我得到了答案

  

当在表达式中使用时,副作用操作符会做出有趣的,意想不到的事情,因为你基本上受编译器的支配。

     

在这种情况下,您的编译器在第一个运算符之前评估+ MyAdd( - a)的第二个运算符。所以,在添加变量之前,你要减少变量。

理解它!我正在玩我的代码,我用--i替换i--,我的编译器没有得到任何错误,当我运行它时我得到了Segmentation fault (core dumped)我想知道为什么发生了这件事。

4 个答案:

答案 0 :(得分:2)

1)

“我遇到了分段错误(核心转储)”

在这段代码中,您会看到每次调用MyAdd函数时,都会向它传递一个较小的参数(因为--a):

#include <stdio.h>

     int MyAdd(int);
     main ()
     {
          int i;
          int c = 0;
          c = MyAdd(5); 
          printf("result: %d\n", c);
     }

     int MyAdd(int a)
     {
          int  res = 0;

          if(a > 0) {
            res += a + MyAdd(--a);
            printf("%d\n", res);
            return res;
          } 
          else
               return 0;
     }

输出:

0     // you pass 1 to your function and decrement the argument
1     // you pass 2
3     // you pass 3
6     // you pass 4
10    // you pass 5. Because you decrement the argument each time
      // you pass it to your function, this will return normal result.
result: 10

如果您将--a更改为a--,则始终会将5传递给MyAdd。 这将是无限循环,因为:(5 + (5 + (5 + (5 + ...。如你所见,5总是超过0,所以如果总是递归调用MyAdd函数...

所以返回值会增加并增加,直到发生溢出:

  

ISO C99标准规定整数溢出会导致“未定义”   行为“,意味着符合标准的编译器可以这样做   他们喜欢的任何东西都完全忽略了溢出到流产   该程序。大多数编译器似乎忽略了溢出,导致   存储意外或错误的结果。

2)

“为什么这个结果是10而不是15”

当您第一次致电MyAdd 时,最好考虑传递给您的功能的参数。 然后你会得到15而不是10

#include <stdio.h>

     int MyAdd(int);
     main ()
     {
          int i;
          int c = 0;
          c = MyAdd(5); 
          printf("result: %d\n", c);      
     }

     int MyAdd(int a)
     {
          int  res = a;    // here it is

          if(a > 0) {
            res +=  MyAdd(--a);
            printf("%d\n", res);
            return res;
          } 
          else
               return 0;
     }

答案 1 :(得分:1)

在执行函数调用之前, 要执行递减部分。如果你不这样做,你得到的只是(5 +(5 +(5 +(5 +(5 + ...),最终是堆栈溢出和随后的段错误。

答案 2 :(得分:1)

它是一个递归函数,只有当它返回到调用函数时才会发生递减。在这种情况下i--。因此i将始终为&gt; 5。

答案 3 :(得分:1)

坚持 - 之前变量递减值并返回它(因此你的函数每次传递得到一个较小的参数)。

坚持 - 之后变量返回当前值,然后递减(因此你的函数重复地将相同的值传递给它自己:值不会减少,直到调用返回为止,它不会因为它递归地出现同样的问题而获胜。

最后,你用自己的函数调用填充堆栈,程序崩溃(堆栈是程序知道的位置&#34;返回&#34;:它每次都将返回地址添加到堆栈中你输入一个函数,并在每次我们回来时删除地址。我们永远不会回来,所以最终我们用完了空间。)