繁体   English   中英

如何实现此递归行以打印反向字符串?

[英]How does this recursion line implemented to print the string reversed?

很快,我需要知道此功能的工作原理? 里面有什么? 传递的字符串如何反转?

这是代码,在此先感谢。

#include <stdio.h>
void rev (const char* const);

int main()
{
    char str [] = "Hey There";
    rev(str);

    return 0;
}

void rev(const char* const c)
{
    if(c[0]=='\0')
        return ;
    else
    {
        rev( &c[1]);
        putchar(c[0]);
    }
}

编辑:正如评论员的建议,我将解释我所不了解的内容。 字符串不是反向的,而是反向打印的,好的。 执行此操作的机制是什么? 执行顺序是什么?

原因是代码指示它在处理输出当前char之前先处理字符串的其余部分。 想象一下字符串“ on \\ 0”

rev("on\0");
  ->rev("n\0");
    ->rev("\0");  
      <-return;   // hits base case
    putchar('n'); // resumes after recursive call
    <-return;     // invisible return at end of function
  putchar('o');   // resumes after recursive call
  <-return;       // invisible return at end of function

这里的每个标识都代表一个嵌套调用。 因此,在基本情况下,您同时有3个调用rev进行调用,每个调用都有不同的c

重要的是要知道c对于每个调用都是唯一的,因此,当对rev的调用返回到先前的rev时,被叫rev c 不会改变 这没什么特别的,因此实际上,它的作用方式与每次执行相同功能的调用不同函数的方式相同。 返回上一个呼叫后,它将恢复。

实际上,此递归函数不会反转输入字符串。 它只是以相反的顺序打印。 逻辑很简单-假设我有字符串str [4] =“ ABC”,它是C中以null终止的字符串。

  • 对于第一次调用rev(str)-str [0]为'A',它不为null->调用rev(str [1])并输出str [0] ='A'
  • 对于第二次调用rev()str [0]为'B',它不为空->调用rev(str [1])并输出str [0] ='B'
  • 依此类推,直到找到“ \\ 0”。

现在,从每个函数调用返回之前,它正在打印str [0]-

  • 因此,对于'\\ 0'-它将简单地返回而不打印任何内容。
  • 对于“ C”,它将打印“ C”
  • 对于“ B”,它将打印“ B”,依此类推。

因此,字符串将以相反的顺序打印。

根据您的程序,** H ** **,在rev函数中,

  1. c [0] = H是否检查为NULL ==> NO
  2. 从& e [1] =“ ey there”传递地址,该地址从e再次开始到rev函数。
  3. c [0] = e是否检查为NULL ==> NO
  4. 将地址&c [1] =“ y there” (从y再次开始)传递到rev函数。
  5. 这种逻辑一直持续到结束。
  6. c [0] = e是否检查为NULL ==> NO
  7. 传递地址&c [1] = \\ 0 ,这是要传递给rev函数的NULL字符。
  8. 一旦确定\\ 0 ,rev函数就会开始返回。
  9. 在rev函数之后,我们有putchar(c [0])c [0]的最新值打印为'e'[根据第6点]。
  10. 打印继续进行

为了使函数的动作更清晰,请按以下方式重写它

void rev( const char * const s )
{
    if ( s[0] != '\0' )
    {
        char c = s[0];
        rev( s + 1 );
        putchar( c );
    }
}

因此,对于函数的第一次调用,函数将字符串的第一个字符存储在变量c

然后第二次调用该函数,将指针移动到第二个字符。 同样,该函数将此字符存储在其自己的(局部)变量c

依此类推,直到遇到终止零为止。

然后,在将控件传递给调用调用之前,每个函数调用都会打印存储在变量c中的字符,您将获得字符串字符的相反顺序。

如前所述,它是一个递归函数。 所以执行是这样的

从main()中调用rec()。 控件现在进入rec()函数。 进行条件检查以检测字符串的结尾。 直到检测到字符串的末尾,否则部分将被执行。

现在让我们看看其他部分会发生什么。

else再次调用rec() 再次调用rec()直到遇到字符串结尾。

所以调用顺序如下:

main()-> rec()->rec(rec(rec(... until \0..) putchar()) putchar())putchar())

因此,在最后一个rec()函数的控制结束时,将执行最后一个putchar() 然后在最后一个之前,一直进行到从main()调用的第一个rec()为止。

main() -> rec(H)因为它不为空->它再次调用rec(e)

在这里,控件不是来自对rec()的第一次调用。 所以rec(H)看起来像

rec(H)
{
rec(e);
putchar(H);
}

这样下去

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM