我必须分析这段代码,而且我真的不明白它是如何打印出比“!”更多的内容的。
#include <stdio.h>
int f(int i, int *v, char* p){
int x;
if(strlen(p)>0){
x=f(++i,v,++p);
printf("%c", *(--p)-*(v+(--i)));
}else
printf("! ");
return x;
}
int main(){
int v[4]={3,1,2,4}, a=3124;
char k[5]="HOGF";
char *p=k;
a=f(0,v,p);
return 0;
}
预期输出是
!贝恩
为什么函数不停止在“!”?
答案 0 :(得分:1)
f 返回的值是不确定的,因为它是未初始化变量 x 的“值”,但从未真正使用过该值。
Why doesn't the function stop at " ! "
因为代码在字符串“ HOGF”中进行处理直至到达结尾的空字符,并且在这种情况下,strlen
为0(显然不是>0
,所以打印了“!”,则递归)呼叫被“弹出”以产生其他字符的印记。
详细信息:
strlen(p)>0
为假,因此打印“!” --
取消 p 和的递归调用参数中的++
i ,因此 p 指向F,而 i 的值3,v[3]
为4,因此打印字符'F'-4为'B '--
取消 p 和的递归调用参数中的++
i ,因此 p 指向G,而 i 值2,v[2]
为2,因此打印字符'G'-2为'E '--
取消 p 和的递归调用参数中的++
i ,因此 p 指向O,而 i 值1,v[1]
为1,因此打印字符'O'-1为'N '--
取消 p 和的递归调用参数中的++
i ,因此 p 指向H,而 i 的值为0,v[0]
为3,因此打印字符'H'-3为'E '因此程序将打印! BENE
答案 1 :(得分:0)
(strlen(p)>0)
此时满足此条件,因为p引用“ HOGF”且其长度大于0。因此,如果执行if块而不是else块
现在,在if块中,x=f(++i,v,++p)
被执行,这就是递归函数的调用。当您仍处于函数f的上下文中时,再次调用它。
这会将新的执行上下文添加到您的调用堆栈中,并且由于传递了++ p而不是“ HOGF”,因为指针增加了下一个地址“ OGF”被传递。
在遇到return语句之前,将一直添加到堆栈中。
也就是说,在主要功能之上叠加了5种不同的功能。除非上面的函数返回并弹出,否则下面的函数无法继续执行。
在这种情况下,“ OGF”->“ GF”->“ F”->“”是传递给函数的值,以便最顶层的函数接收一个空字符串作为其参数
此时,当将空字符串作为参数传递给f函数时,(strlen(p)>0)
的值将为false,并且else块将首次执行。因此,在输出中首先打印“!” 。
您问为什么执行不会在这里停止。
因为我们已经建立了函数f的堆栈,并且在打印“!”之后函数才结束,直到返回为止。遇到return语句时。这将弹出堆栈中最上面的f函数,并返回最上面的f函数的'x'值。
x的值将是垃圾值,因为x是未初始化的变量。
x=f(++i,v,++p);
表示来自最顶部f函数的x的值将作为值传递给执行栈中位于其下方的f函数中的x。在这种情况下,该函数仍然具有printf("%c", *(--p)-*(v+(--i)))
和要执行的return语句。
*(--p)-*(v+(--i))
负责从“ HOGF”中的字符中减去并打印“ BENE”,
例如--p
返回指向'F'的指针,而--i
将i减至3,因此
'F'-v [3]变为'F'-4,即'B'
打印“ B”后,该函数将“ x”的值返回到执行堆栈中的下一个函数。类似地,还会打印'E','N','E',最后该函数将'x'的值返回给最初调用函数'f'的主函数。