有人可以帮我理解下面代码中的递归吗?

时间:2016-09-11 21:23:17

标签: c recursion

我是递归的新手。有人可以帮助我理解递归在以下代码中的工作原理。任何帮助将不胜感激。

int f(int *p, int n)
{
    if (n <= 1) return 0;
    else return max(f(p+1,n-1),p[0]-p[1]);
}
int main()
{
   int a[] = {3,5,2,6,4};
   printf("%d", f(a,5));
}

具体来说,我不理解这一行中发生的递归:

max(f(p+1,n-1),p[0]-p[1]) 

2 个答案:

答案 0 :(得分:2)

函数f获取数组和该数组的大小,并递归地比较相邻值,最后返回相邻值之间的最大距离(数字,非绝对)。在您的情况下,该函数将返回3,表示52之间的最大距离为3。在这种情况下,26之间的差异为-4,因为未采用绝对值。

递归情况有点令人困惑,因为调用f(p+1,n-1)有两种算术。 p+1指针算术,而n-1是常规数值算术。 p+1只是将数组指针推进到下一个元素,而n-1正在递减数组大小,以便在没有更多元素可供比较时函数将结束。

基本情况表明,如果您已经检查了所有对,则最高距离为零。

已检测代码

检测以下代码,包括删除max()用法并选择简单的三元表达式来计算最大差异。在功能上,这应该与发布的内容相同,但在函数和printf中添加main()语句以查看这些地址的地址和值。它应该放大上面描述的内容。

#include <stdio.h>

int f(int *p, int n)
{
    // no sense in checking zero or one element.
    if (n <= 1)
        return 0; // actually, this should be INT_MIN, but whatever

    // print this call-frame for the values we're interested in
    printf("p = %p, n = %d, p[0] = %d, p[1] = %d\n",
           (const void*)p, n, p[0], p[1]);


    int lhs = f(p+1,n-1); // recurse here
    int rhs = p[0] - p[1];

    // return the maximum of the two values
    return (lhs < rhs) ? rhs : lhs;
}

int main()
{
    int a[] = {3,5,2,6,4};
    printf("%p %d", (const void*)a, f(a,5));
}

输出(注意:地址因系统而异)

p = 0x7fff5fbff970, n = 5, p[0] = 3, p[1] = 5
p = 0x7fff5fbff974, n = 4, p[0] = 5, p[1] = 2
p = 0x7fff5fbff978, n = 3, p[0] = 2, p[1] = 6
p = 0x7fff5fbff97c, n = 2, p[0] = 6, p[1] = 4
0x7fff5fbff970 3

请注意,最后一行显示a[]main()的基地址。函数的初始调用(顶行)显示相同的地址。请注意地址如何根据前面描述的指针算法进行调整。这与n的递减值一起使得每个递归调用看起来都是“更短”的序列。实际上它是相同的序列;只是从不同的位置开始,并且元素数量不同。

就是这样。

答案 1 :(得分:1)

如果我们将函数拆分为尽可能多的简单行并添加调试printf,则可能更容易看到事情:

#include <stdio.h>

int a[] = { 3, 5, 2, 6, 4 };
int level;

#define debug(_fmt...) \
    do { \
        for (int lvl = level << 1;  lvl > 0;  --lvl) \
            fputc(' ',stdout); \
        printf(_fmt); \
    } while (0)

static inline int
max(int x,int y)
{
    int ret;

    ret = (x > y) ? x : y;

    return ret;
}

int
f(int *p, int n)
{
    int pp;
    int val;
    int ret;

    debug("f: ENTER p=%p(%ld) n=%d level=%d\n",p,p - a,n,level);

    if (n <= 1)
        ret = 0;
    else {
        ++level;
        val = f(p + 1,n - 1);
        --level;

        pp = p[0] - p[1];
        debug("f: SUBVAL val=%d pp=%d\n",val,pp);
        ret = max(val,pp);
    }

    debug("f: EXIT ret=%d level=%d\n",ret,level);

    return ret;
}

int
main(void)
{
    printf("RESULT: %d\n", f(a, 5));
}

这是输出:

f: ENTER p=0x601050(0) n=5 level=0
  f: ENTER p=0x601054(1) n=4 level=1
    f: ENTER p=0x601058(2) n=3 level=2
      f: ENTER p=0x60105c(3) n=2 level=3
        f: ENTER p=0x601060(4) n=1 level=4
        f: EXIT ret=0 level=4
      f: SUBVAL val=0 pp=2
      f: EXIT ret=2 level=3
    f: SUBVAL val=2 pp=-4
    f: EXIT ret=2 level=2
  f: SUBVAL val=2 pp=3
  f: EXIT ret=3 level=1
f: SUBVAL val=3 pp=-2
f: EXIT ret=3 level=0
RESULT: 3