递归调用参数交换
如下面这一段代码,运行时是A-->BB-->AA-->BB-->A ......等无线循环。但是我自己的理解是A-->BB-->AB-->AB-->A..........
我知道自己理解错了,但是他们到底是如何交换的呢?
#include<stdio.h>
void main()
{
void hanoi(char one,char two);
hanoi('A','B');
}
void hanoi(char one,char two)
{
void move(char x,char y);
move (one,two);
getchar();
hanoi(two,one);
}
void move(char x,char y)
{
printf("%c-->%c\n",x,y);
}
如下面这一段代码,运行时是A-->BB-->AA-->BB-->A ......等无线循环。
但是我自己的理解是A-->BB-->AB-->AB-->A..........
你的理解和代码运行没区别啊? 每调用一次hanoi都会交换实参,所以在move函数中打印的就是
A-->BB-->AA-->BB-->A ......等无线循环 那支笔和纸。画两行,分别写one和two,记下每次进hanio的one和two
one:ABA……
two:BAB……
就那样,自己模拟电脑的运行,自己去走一遍,走到哪写到哪,你就会清楚的认识到形参与实参的区别,表面传进move的顺序都是one,two但是one,two具体代表的是什么内容已经在前一步递归的时候互换了 {:10_257:}没有明白你想表达什么意思~ newu 发表于 2017-10-21 09:07
你的理解和代码运行没区别啊?
你运行了吗?计算机运行的结果是AB BA 一直交换,我的理解是开始是AB以后一直是 BA。很明显我的错了。 BngThea 发表于 2017-10-21 09:37
每调用一次hanoi都会交换实参,所以在move函数中打印的就是
A-->BB-->AA-->BB-->A ......等无线循环
我就是不懂他们为什么会一直交换? 丶忘却的年少o 发表于 2017-10-21 10:03
那支笔和纸。画两行,分别写one和two,记下每次进hanio的one和two
one:ABA……
two:BAB……
...
用调试明显看出来他们是在调换,但是我不理解,所以我才发帖问的。运行的是hanoi(two one)为什么会一直交换?two 不应该一直是A,one应该一直是B吗? 橙C 发表于 2017-10-21 10:24
没有明白你想表达什么意思~
运行的是hanoi(two one) 结果不应该是 two 是Aone 是B 吗?为什么每一次运行hanoi 。A和B 的值都会调换? 技术员 发表于 2017-10-21 19:35
用调试明显看出来他们是在调换,但是我不理解,所以我才发帖问的。运行的是hanoi(two one)为什么会一直交 ...
我当然知道调试能看到呀,但是自己脑子过一遍不是更清楚吗,思考的比看到的更深刻。
第一次进入hanoi的具体形参是什么?是不是hanoi(A, B),然后进入这个函数,递归了自己调用自己,那这个调用过程的参数是什么?hanoi(two,one)是这样吧,one是A,two是B,你要问为什么吗?你看下这个hanoi第一次调用时候传进来one,two这两个位置对应的分别是什么值。第二次调用就换了个位置,那代表的第二次函数的具体形参应该是hanoi(B,A)。
我只能说这种情况别调试,你自己把自己当电脑拿笔写一次,肯定比看调试来的明白。 丶忘却的年少o 发表于 2017-10-21 19:54
我当然知道调试能看到呀,但是自己脑子过一遍不是更清楚吗,思考的比看到的更深刻。
第一次进入hanoi的 ...
你这个说的我懂了,但是第三次是怎么变的呢? 技术员 发表于 2017-10-23 05:24
你这个说的我懂了,但是第三次是怎么变的呢?
就是因为one、two的值对调了呀,对调了!仔细看我上面的那段话,在第三行,多读几遍,就是那个时候对调的。不管第几次,原理都是一样,机器只会单纯的做你叫他做的。
把参数拿进来,打印,对调再给自己,拿进来,打印,对调……
#include <stdio.h>
void main()
{
void hannuota(int fangxiang ,int n);
int n;
scanf("%d",&n);
hannuota(1,n);
printf("\n");
}
void hannuota(int fangxiang,int n)
/*
fangxiang=1 表示移动方向为从A移到C
fangxiang=2 表示移动方向为从A移到B
fangxiang=3 表示移动方向为从B移到C
fangxiang=4 表示移动方向为从C移到B
fangxiang=5 表示移动方向为从B移到A
fangxiang=6 表示移动方向为从C移到A
hannuota(int fangxiang,int n)表示按照规定方向移动n个盘子
*/
{
if(n==1)
{
switch(fangxiang)
{
case 1:
printf("%3d:A->C",1); //表示把1号盘子从A移动到C
break;
case 2:
printf("%3d:A->B",1); //表示把1号盘子从A移动到B
break;
case 3:
printf("%3d:B->C",1); //表示把1号盘子从B移动到C
break;
case 4:
printf("%3d:C->B",1); //表示把1号盘子从C移动到B
break;
case 5:
printf("%3d:B->A",1); //表示把1号盘子从B移动到A
break;
case 6:
printf("%3d:C->A",1);//表示把1号盘子从C移动到A
}
}
else
{
switch(fangxiang)
{
case 1:
hannuota(2,n-1);
printf("%3d:A->C",n); //表示把n号盘子从A移动到C
hannuota(3,n-1);
break;
case 2:
hannuota(1,n-1);
printf("%3d:A->B",n); //表示把n号盘子从A移动到B
hannuota(4,n-1);
break;
case 3:
hannuota(5,n-1);
printf("%3d:B->C",n); //表示把n号盘子从B移动到C
hannuota(1,n-1);
break;
case 4:
hannuota(6,n-1);
printf("%3d:C->B",n); //表示把n号盘子从C移动到B
hannuota(2,n-1);
break;
case 5:
hannuota(3,n-1);
printf("%3d:B->A",n); //表示把n号盘子从B移动到A
hannuota(6,n-1);
break;
case 6:
hannuota(4,n-1);
printf("%3d:C->A",n); //表示把n号盘子从C移动到A
hannuota(5,n-1);
}
}
}
丶忘却的年少o 发表于 2017-10-23 08:55
就是因为one、two的值对调了呀,对调了!仔细看我上面的那段话,在第三行,多读几遍,就是那个时候对调的 ...
我把hanoi(two,one) 理解成hanoi( char one,char two)了。真是犯了低级错误!!感谢你的耐心回答。我已经完全明白了。 技术员 发表于 2017-10-25 12:14
我把hanoi(two,one) 理解成hanoi( char one,char two)了。真是犯了低级错误!!感谢你的耐心回答。我已经 ...
没关系,就是多拿笔,因为看着写着会觉得对不上然后会仔细看的
页:
[1]