关于c语言递归的一个问题
#include <stdio.h>int a(int n)
{
int p;
if(n==2)
{
return n;
}
else
{
a(n-1);
p=n*n;
}
}
int main(int argc, char const *argv[])
{
/* code */
printf("%d\n",a(5) );
return 0;
}
这个返回值是多少呢? 本帖最后由 jackz007 于 2019-3-8 21:22 编辑
楼主的函数 a() 存在重大问题,只有在 n == 2 时才有返回值,n == 5 的时候无返回值。在递归过程中,返回值没有得到任何利用,也无法影响最终结果,根本没有必要使用递归函数。 25,这种编译运行一下不就行了嘛
唉,好像不对吧 你在p = n*n后面加上printf("%d\n",p);
产生了新的数 暗pluto 发表于 2019-3-8 22:02
你在p = n*n后面加上printf("%d\n",p);
产生了新的数
我就想知道这个返回值为什么是25,我函数里面没有return p啊 jackz007 发表于 2019-3-8 21:16
楼主的函数 a() 存在重大问题,只有在 n == 2 时才有返回值,n == 5 的时候无返回值。在递归过程中, ...
我知道递归怎么用,上面的程序是我偶然发现的一个问题 暗pluto 发表于 2019-3-8 21:20
25,这种编译运行一下不就行了嘛
为什么是25呢?解释一下 lcl1026504480 发表于 2019-3-8 22:06
为什么是25呢?解释一下
有单步调试过没有 p又没随n变化 递归回来不是5*5吗 本帖最后由 暗pluto 于 2019-3-9 01:13 编辑
lcl1026504480 发表于 2019-3-8 22:06
为什么是25呢?解释一下
我单步调试了一下,发现非常有趣
大致的原因应该是这样的,你return n是没错,但是return n不代表终止递归,而是终止本层递归
所以你return后,会返回上一层的递归,而25正是最后退出递归的值,至于为什么n的值会被p所覆盖,这个我也不太清楚(如果清楚了请务必告诉我),修改正确后的代码如下
#include <stdio.h>
int flag = 0;
int a(int n)
{
int p;
if(n==2&&flag==0)
{
flag = 1;
return n;
}
else{
a(n-1);
return;
p = n*n;
}
}
int main(int argc, char const *argv[])
{
/* code */
printf("%d",a(5));
return 0;
}
lijialijialijia 发表于 2019-3-8 23:39
p又没随n变化 递归回来不是5*5吗
我return的是p吗?你有脑子吗? 暗pluto 发表于 2019-3-9 01:11
我单步调试了一下,发现非常有趣
大致的原因应该是这样的,你return n是没错,但是return n不代表终止 ...
我也不知道为什么会覆盖,这个估计只有反汇编才能知道了 lcl1026504480 发表于 2019-3-9 11:47
我也不知道为什么会覆盖,这个估计只有反汇编才能知道了
如果递归的下面的表达式或者语句不含有n,那么就是返回2,如果有关于n的操作,返回的就不是2.很奇怪 为什么不是2? Swarm 发表于 2019-3-9 11:56
为什么不是2?
不知道啊 #include <stdio.h>
int a(int n)
{
int p;
if(n==2)
{
return n;
}
else
{
a(2);
printf("abc%d\n",n*n );
}
}
int main(int argc, char const *argv[])
{
/* code */
printf("%d\n",a(5) );
return 0;
}
https://i0.hdslb.com/bfs/article/da7b04574ea194146b75594574e4826603d7eaf7.png
这个更迷 @小甲鱼 快来回答啊 本帖最后由 Croper 于 2019-3-9 14:16 编辑
部分反汇编的结果:
#include <stdio.h>
int a(int n)
{
int p;
if(n==2)
{
return n;
}
else
{
a(n-1);
p=n*n;
//这是最后一次使用eax寄存器的位置
//01101814mov eax,dword ptr //把n的值放入eax寄存器,此时eax=5
//01101817imul eax,dword ptr //eax寄存器的乘上n的值,此时eax=25
//0110181Bmov dword ptr ,eax //把eax寄存器的值放入p,此时p=25,eax=25;
}
}
int main(int argc, char const *argv[])
{
/* code */
printf("%d\n",a(5) );
//01101988push 5
//0110198Acall a (01101217h) //这是调用函数a,返回后eax=25
//0110198Fadd esp,4
//01101992push eax //把eax当做a()的返回值推入栈,此时eax=25
//01101993push offset string "%d\n" (01107B30h)
//01101998call _printf (0110104Bh) //调用printf,此时输出的值当然是25
//0110199Dadd esp,8
return 0;
} Croper 发表于 2019-3-9 14:15
部分反汇编的结果:
这个我也反汇编过,不过感觉其实挺迷的
页:
[1]