递归功能,调用后命令

时间:2019-01-12 09:51:14

标签: c string recursion

我正在跟踪pdf来研究递归和字符串操作,但我偶然发现了这一点。.我通常对递归函数的表现(仍然不太好)有所了解,但无法弄清楚。这将反转字符串。好吧,把它打印反过来。

void reverse(const char *const sptr);

int main()
{

char sentence[80];
printf("Enter a line of text:\n");
gets(sentence);

printf("\nThe reversed version:\n");
reverse(sentence);
puts("");


return 0;
}

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

我不太了解putchar在这种情况下如何工作。谁能向我解释?我想这不仅仅用于putchar,在调用该函数后“写”另一个命令行时,该函数的行为如何?

4 个答案:

答案 0 :(得分:2)

与putchar无关,与递归无关。

假设您给它提供字符串"1234"-或称它为['1','2','3','4','\0'] 第一次调用反向函数,它的参数sptr指向['1','2','3','4','\0'];

执行到达递归调用以反转,并且这次使用偏移量1,因此参数变为['2','3','4','\0']

重复此过程,直到找到'\0',然后该函数返回到上一个调用方,该调用方打印最后一个字符,返回到上一个调用方,打印第二个字符,最后一个字符,依此类推,直到顶部反向到达呼叫并打印第一个字符,然后该呼叫存在。

也许打印一些其他调试信息将使其更容易理解。

#include <stdio.h>

void reverse(const char *const sptr);

int recursion_level;

int main()
{
recursion_level=0;
    char sentence[80]="1234";
    // printf("Enter a line of text:\n");
    // gets(sentence);

    printf("\nThe reversed version:\n");
    reverse(sentence);
    puts("");
    return 0;
}

void reverse(const char *const sptr)
{
        recursion_level++;
        printf("reverse entered, recursion level:%d , sptr:%s \n",recursion_level, sptr);
        if(sptr[0] == '\0')
        {   recursion_level--;
            return;
        }
        else{
            reverse(&sptr[1]);
            putchar(sptr[0]);
        }
        printf("\n  reverse exits, recursion level:%d , \n",recursion_level);
        recursion_level--;
}

哪个生成以下输出

The reversed version:                                                                                                                          
reverse entered, recursion level:1 , sptr:1234                                                                                                 
reverse entered, recursion level:2 , sptr:234                                                                                                  
reverse entered, recursion level:3 , sptr:34                                                                                                   
reverse entered, recursion level:4 , sptr:4                                                                                                    
reverse entered, recursion level:5 , sptr:                                                                                                     
4                                                                                                                                              
  reverse exits, recursion level:4 ,                                                                                                           
3                                                                                                                                              
  reverse exits, recursion level:3 ,                                                                                                           
2                                                                                                                                              
  reverse exits, recursion level:2 ,                                                                                                           
1                                                                                                                                              
  reverse exits, recursion level:1 ,  

答案 1 :(得分:1)

这是可行的,因为:

   reverse(&sptr[1]);
   putchar(sptr[0]);

您先调用下一个字符然后,然后打印第一个字符,因此

  • 第一个打印的字符将是最后一个
  • 然后您返回并在前一个之前写上一个
  • ...
  • 然后返回并打印第一个字符

&sptr[1]等效于sptr + 1,因此指向下一个字符的地址


如果您将线颠倒并执行此操作:

   putchar(sptr[0]);
   reverse(&sptr[1]);

您以初始顺序打印字符


不了解时,只需逐步将程序执行到调试器中即可

答案 2 :(得分:1)

这很简单。

您以字符串作为参数递归调用函数。每次调用时,字符串都短一个字符(当您将指针传递到字符串中的第二个char时。如果长度为零,则第一个返回出现。字符串的长度为1,并且它只是最后一个字符)打印该字符串(打印第一个字符时),然后返回到该字符串长度为2个字符的实例-打印该字符串时,第一个字符是末尾的第二个字符,然后返回长度为3个字符,您将再次打印第一个字符,并重复进行直到您以相反的顺序打印字符串中的所有字符。

您根本不需要else语句,就像满足条件一样,控件将永远不会到达该语句

void reverse(const char *const sptr)
{
    if(!sptr[0]) return;
    reverse(&sptr[1]);
    putchar(sptr[0]);
}

int main()
{
    reverse("Hello World");

    return 0;
}

您还可以添加检查参数是否为NULL

void reverse(const char *const sptr)
{
    if(!sptr && sptr[0] == '\0') return;
    reverse(&sptr[1]);
    putchar(sptr[0]);
}

答案 3 :(得分:1)

正如其他所有人所说,这很简单。

但是最好的解释是看一下如何在C代码中添加一些日志。

#include "pch.h"
#include <stdio.h>
#include <stdlib.h>

void reverse(const char *const sptr);
void openTraceFile();
void closeTraceFile();
void enterFunction();
void exitFunction();
void writeMessage(const char* s);

int main()
    {
    char sentence[80];
    printf("Enter a line of text:\n");
    //gets(sentence);
    fgets(sentence, 80, stdin);

    openTraceFile();

    printf("\nThe reversed version:\n");
    reverse(sentence);
    puts("");

    closeTraceFile();

    return 0;
    }

static FILE* logfile;
static int iNrSpaces = 0;

void reverse(const char *const sptr)
    {
    enterFunction();

    if (sptr[0] == '\0')
        {
        writeMessage("end of string");
        exitFunction();
        return;
        }

    reverse(&sptr[1]);

    putchar(sptr[0]);

    char s[80];
    sprintf(s,"putchar( %c )", sptr[0]);
    writeMessage(s);

    exitFunction();
    }

void openTraceFile()
    {
    logfile = fopen("reverse.log", "w");

    if (logfile == NULL)
        {
        printf("Error! Could not open file\n");
        exit(-1);
        }


void closeTraceFile()
    {
    fclose(logfile);
    }

void enterFunction()
    {
    writeMessage(">> reverse()");
    iNrSpaces += 4;
    writeMessage("{");
    }

void exitFunction()
    {
    writeMessage("}");
    iNrSpaces -= 4;
    }

void writeMessage(const char* s)
    {
    for (int i = 0; i < iNrSpaces; i++)
        {
        fputc(' ',logfile);
        }
    fprintf(logfile, s);
    fputc('\n', logfile);
    }

在输入“帮助”时执行该程序时,您将在reverse.log文件中获得以下几行。

>> reverse()
    {
    >> reverse()
        {
        >> reverse()
            {
            >> reverse()
                {
                >> reverse()
                    {
                    >> reverse()
                        {
                        end of string
                        }
                    putchar( \0 )
                    }
                putchar( p )
                }
            putchar( l )
            }
        putchar( e )
        }
    putchar( h )
    }

如果现在,您在不更改执行顺序的情况下提取putchar()调用,您将获得

putchar( p ); 
putchar( l ); 
putchar( e ); 
putchar( h ); 

那是反字符串!

我希望使用LOG进行的解释可以帮助您理解此问题。

小注释:\ 0字符在您的示例中优先返回!