简体   繁体   English

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

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

Shortly, I need to know how this function works? 很快,我需要知道此功能的工作原理? What's go inside? 里面有什么? How is the passed string reversed? 传递的字符串如何反转?

Here is the code and thanks in advance. 这是代码,在此先感谢。

#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]);
    }
}

EDIT: As the commenters advised, I will explain what I'm not understanding more. 编辑:正如评论员的建议,我将解释我所不了解的内容。 The string is not reversed, but printed reversely, Ok fine. 字符串不是反向的,而是反向打印的,好的。 What is the mechanism used to do this? 执行此操作的机制是什么? what is the execution sequence? 执行顺序是什么?

The reason is that the code dictate it to do the rest of the string before processing outputting the current char. 原因是代码指示它在处理输出当前char之前先处理字符串的其余部分。 Imagine the string "on\\0" 想象一下字符串“ 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

Every identation here represents a nested call. 这里的每个标识都代表一个嵌套调用。 Thus at the base case you have 3 calls to rev going at the same time, each with different c . 因此,在基本情况下,您同时有3个调用rev进行调用,每个调用都有不同的c

Its important to know that c is unique for each invocation so that when a call to rev returns to a previous rev c has not changed in the callee. 重要的是要知道c对于每个调用都是唯一的,因此,当对rev的调用返回到先前的rev时,被叫rev c 不会改变 That makes it nothing special so in fact it works the same way as calling a different function each time that does the same. 这没什么特别的,因此实际上,它的作用方式与每次执行相同功能的调用不同函数的方式相同。 It resumes after the previous call has returned. 返回上一个呼叫后,它将恢复。

Actually this recursive function is not reversing the input string. 实际上,此递归函数不会反转输入字符串。 It is just printing it in reversed order. 它只是以相反的顺序打印。 The logic is simple- Suppose I am having string str[4] = "ABC" which is null terminated string in C. 逻辑很简单-假设我有字符串str [4] =“ ABC”,它是C中以null终止的字符串。

  • For first call to rev(str) - str[0] is 'A' which is not null --> call rev(str[1]) and print str[0] = 'A' 对于第一次调用rev(str)-str [0]为'A',它不为null->调用rev(str [1])并输出str [0] ='A'
  • For second call to rev() str[0] is 'B' which is not null --> call rev(str[1]) and print str[0] = 'B' 对于第二次调用rev()str [0]为'B',它不为空->调用rev(str [1])并输出str [0] ='B'
  • And so on till '\\0' is found. 依此类推,直到找到“ \\ 0”。

Now before returning from each function call it is printing str[0]- 现在,从每个函数调用返回之前,它正在打印str [0]-

  • So for '\\0' - It will simply return without printing anything. 因此,对于'\\ 0'-它将简单地返回而不打印任何内容。
  • For 'C', it will print 'C' 对于“ C”,它将打印“ C”
  • For 'B', it will print 'B' And so on. 对于“ B”,它将打印“ B”,依此类推。

So the string will be printed in reverse order. 因此,字符串将以相反的顺序打印。

As per your program, ** H eythere ** ,In rev function, 根据您的程序,** H ** **,在rev函数中,

  1. c[0] = H is checked as NULL or not ==> NO c [0] = H是否检查为NULL ==> NO
  2. Passing address &c[1] = "ey there" which starts from e to again to rev function. 从& e [1] =“ ey there”传递地址,该地址从e再次开始到rev函数。
  3. c[0] = e is checked as NULL or not ==> NO c [0] = e是否检查为NULL ==> NO
  4. Passing address &c[1] = "y there" which starts from y to again to rev function. 将地址&c [1] =“ y there” (从y再次开始)传递到rev函数。
  5. this logic continues till end. 这种逻辑一直持续到结束。
  6. c[0] = e is checked as NULL or not ==> NO c [0] = e是否检查为NULL ==> NO
  7. Passing address &c[1] = \\0 which is NULL character to be passed to rev function. 传递地址&c [1] = \\ 0 ,这是要传递给rev函数的NULL字符。
  8. once identified \\0 , rev function starts returning. 一旦确定\\ 0 ,rev函数就会开始返回。
  9. after rev function, we have putchar(c[0]) which prints latest value of c[0] as 'e' [as per point 6]. 在rev函数之后,我们有putchar(c [0])c [0]的最新值打印为'e'[根据第6点]。
  10. the print continues ereh T ye H 打印继续进行

To make the action of the function more clear rewrite it the following way 为了使函数的动作更清晰,请按以下方式重写它

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

So for the first call of the function the function stores the first character of the string in the variable c . 因此,对于函数的第一次调用,函数将字符串的第一个字符存储在变量c

Then the function is called the second time moving the pointer to the second character. 然后第二次调用该函数,将指针移动到第二个字符。 Again the function stores this character in its own (local) variable c . 同样,该函数将此字符存储在其自己的(局部)变量c

And so on until the terminating zero is encountered. 依此类推,直到遇到终止零为止。

Then each function invocation before passing the control to the calling invocation prints its character stored in the variable c and you get the reverse order of the characters of the string. 然后,在将控件传递给调用调用之前,每个函数调用都会打印存储在变量c中的字符,您将获得字符串字符的相反顺序。

As you have mentioned, it is a recursive function. 如前所述,它是一个递归函数。 So the execution goes like this 所以执行是这样的

From main(), rec() is called. 从main()中调用rec()。 The control now enters the rec() function. 控件现在进入rec()函数。 Where a condition check is made to detect the end of string. 进行条件检查以检测字符串的结尾。 Until the end of string is detected, else part gets executed. 直到检测到字符串的末尾,否则部分将被执行。

Now let us see what happens in else part. 现在让我们看看其他部分会发生什么。

else calls rec() again. else再次调用rec() Where the rec() is called again until the end of string is met. 再次调用rec()直到遇到字符串结尾。

so the call sequence goes like this-> 所以调用顺序如下:

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

So on end of the control from last rec() function last putchar() will be executed. 因此,在最后一个rec()函数的控制结束时,将执行最后一个putchar() Then on the last before on and goes on till the first rec() called from main() . 然后在最后一个之前,一直进行到从main()调用的第一个rec()为止。

main() -> rec(H) as it is not null -> it again calls rec(e) main() -> rec(H)因为它不为空->它再次调用rec(e)

Here the control has not came out of the first call to rec() . 在这里,控件不是来自对rec()的第一次调用。 So rec(H) looks like 所以rec(H)看起来像

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

it goes on like this 这样下去

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

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