void foo3(char *x)
{
if (!*x) return;
foo3(x+1);
printf("%c ",*x);
}
例如,如果x
指向数组ar[]="abc"
,为什么要打印"cba"
?如果它会不断重复输入该功能,直到if为真,然后返回,为什么还要打印。
它如何打印?
答案 0 :(得分:5)
如果调用foo3("hi")
,它所做的第一件事就是查看参数x
所指向的'h'。由于该值非零,因此调用foo3("i")
-表示它通过了字符串的其余部分的地址。
foo3("i")
查看'i',看到它为非零,然后调用foo3("")
-从技术上讲,它将空终止符的地址传递给原始字符串。
foo3("")
查看空终止符,然后返回。
foo3("i")
打印'i'并返回。
foo3("hi")
打印'h'。
该函数之所以起作用,是因为它在打印“当前字符”之前进行了 的递归调用,因此其余字符串将在其之前打印。
答案 1 :(得分:2)
调用堆栈看起来像这样(伪代码),应该显示出如何以及为什么打印“ cba”。
x是C样式的数组'a','b','c','\ 0'
call foo3(x)
call foo3(x+1)
call foo3(x+2)
call foo3(x+3)
return to foo3(x+2)
print(x+2) 'c'
return to foo3(x+1)
print(x+1) 'b'
return to foo3(x)
print(x) 'a'
return to calling program
答案 2 :(得分:0)
我们可以从中提取一般的经验法则:如果您先处理一些数据然后再进行递归,则您正在处理从前到后的数据。如果您再次出现然后处理一些数据,那么您正在从头到尾处理这些数据。如果倒转最后两行,您会看到此信息:
void foo3(char *x)
{
if (!*x) return;
printf("%c ", *x);
foo3(x + 1);
}
当我们现在处理一些数据然后重复出现时,数据按原始顺序显示。
答案 3 :(得分:0)
@cdlane有一点。这个带有两个printf的示例将帮助您了解重新存储的机制。
#include <stdio.h>
void foo3(char *x)
{
printf("%c=\n",*x);
if (*x=='\0') return;
foo3(x+1);
printf("%c ",*x);
}
int main(void)
{
foo3("abc");
return 0;
}