我正在跟踪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,在调用该函数后“写”另一个命令行时,该函数的行为如何?
答案 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字符在您的示例中优先返回!