递归反转函数

时间:2013-08-07 16:43:34

标签: c++ function pointers recursion reverse

我想知道是否有人可以解释这个小代码片段是如何工作的。

void reverse(char *s)
{
   if(*s)
       reverse(s+1);
   else
       return;

   cout << *s;
}

当你在main中调用这个函数时,它应该打印出任何放入的字符串的反向(例如,hello会cout as olleh)但是我不明白如何。据我所知,if语句增加了s的值,直到它到达字符串的末尾,在字符串结束时打印出每个值。为什么不重新打印字符串。显然我错过了一些东西。 (对不起,我是C ++和递归函数的新手)

5 个答案:

答案 0 :(得分:3)

考虑"hello"字符串如何存储在内存中:假设其'h'字符的地址恰好是0xC000。然后字符串的其余部分将存储如下:

0xC000 'h'
0xC001 'e'
0xC002 'l'
0xC003 'l'
0xC004 'o'
0xC005 '\0'

现在考虑reverse的一系列调用:初始调用通过0xC000; reverse来自反向传递s+1的调用,因此下一级获得0xC001;下一个获得0xC002,依此类推。

请注意,每个级别调用下一个级别,直到看到'\0'的级别。在我们达到零之前,堆栈是“加载”的,如下所示:

reverse(0xC004) // the last invocation before we hit '\0'
reverse(0xC003)
reverse(0xC002)
reverse(0xC001)
reverse(0xC000) // the earliest invocation

现在,当顶部调用调用reverse(0xC005)时,*s的检查失败,函数立即返回而不打印任何内容。此时堆栈开始“展开”,打印其s参数指向的任何内容:

0xC004 -> prints 'o', then returns to the previous level
0xC003 -> prints 'l', then returns to the previous level
0xC002 -> prints 'l', then returns to the previous level
0xC001 -> prints 'e', then returns to the previous level
0xC000 -> prints 'h', then returns for good.

这就是打印原始"hello"字符串的反转方式。

答案 1 :(得分:3)

尝试可视化调用堆栈的构建方式。每次递归调用都会创建另一个堆栈帧,其副本s递增1。当退出条件发生时,堆栈开始展开,并为每个帧调用cout语句。由于LIFO原理,字符串反向打印。

enter image description here

答案 2 :(得分:2)

让我们考虑一个长度为3的字符串。reverse(i)是在字符串的第i个索引上调用的函数的缩写(技术上它是char指针+ i,但是这个解释需要更深入的理解)。

如果*s指向s\0指示字符串的结尾,reverse(0) calls reverse(1) calls reverse(2) calls reverse(3) end of string - return prints 2 prints 1 prints 0 返回false,这也是有用的,因此,在这种情况下,它会简单地返回。

以下是发生的事情:

{{1}}

答案 3 :(得分:1)

让我们看一个简单的例子,假设s =“the”

我们会:

rev(t) - &gt;增量指针

rev(h) - &gt;增量指针

rev(e) - &gt;增量指针

rev('\ 0')(这只会返回)

然后我们将回到rev(e)的主体中,这将打印e

然后回到rev(h),它会打印h

然后最后回到rev(t),这将打印t

按照那个顺序然后我们会:eht(“反向”)

答案 4 :(得分:0)

将函数编写为:

可能会更清楚
void reverse(const char *s)
{
   if(*s)
   {
     reverse(s+1);
     std::cout << *s;
   }
}

即在调用下一个(通过调用反向)

之后将打印每个非空字符

PD:如果你不修改给定的字符串,请使用“const char *”而不是“char *”。