最近在学习objective-c,教程中有一段代码没弄清楚,是关于递归的,我用截图的形式发上来,给大家看看
void singTheSong(int numberOfBottles)
{
if (numberOfBottles == 0) {
printf("there are simply no more bottles of beer on the wall.\n");
} else {
printf("%d bottles of beer on the wall. %d bottles of beer.\n",
numberOfBottles, numberOfBottles);
int oneFewer = numberOfBottles - 1;
printf("Take one dowm, pass it around, %d bottles of beer on the wall.\n",
oneFewer);
singTheSong(oneFewer);
printf("put a bottle in the recycling, %d empty bottles in the bin.\n",
numberOfBottles);
}
}
int main(int argc, const char * argv[])
{
singTheSong(99);
return 0;
}
它的输出结果是这样的:
99 bottles of beer on the wall. 99 bottles of beer.
Take one dowm, pass it around, 98 bottles of beer on the wall.
98 bottles of beer on the wall. 98 bottles of beer.
Take one dowm, pass it around, 97 bottles of beer on the wall.
97 bottles of beer on the wall. 97 bottles of beer.
Take one dowm, pass it around, 96 bottles of beer on the wall.
96 bottles of beer on the wall. 96 bottles of beer.
Take one dowm, pass it around, 95 bottles of beer on the wall.
......(中间重复的省略)
1 bottles of beer on the wall. 1 bottles of beer.
Take one dowm, pass it around, 0 bottles of beer on the wall.
there are simply no more bottles of beer on the wall.
put a bottle in the recycling, 1 empty bottles in the bin.
put a bottle in the recycling, 2 empty bottles in the bin.
......(中间重复的省略)
put a bottle in the recycling, 98 empty bottles in the bin.
put a bottle in the recycling, 99 empty bottles in the bin.
Program ended with exit code: 0
这段代码,我看不懂的地方是,它如何从numberOfBottles等于0的时候,又继续运行了
printf("put a bottle in the recyling, %d empty bottles in the bin.\n",
numberOfBottles);
这段代码呢?并且numberOfBottles一直在+1
请大家帮我解惑,谢谢了~
핵심은 다음과 같습니다. 함수 호출에는
压栈
연산이 있고 재귀 호출은回到
재귀 이전에 반환되고继续
재귀 이후에 코드를 실행한다는 점을 이해해야 합니다. 전화하세요.singTheSong(99);
를singTheSong(3);
로 바꾸고 말씀해주세요.入参为3, 下面两行打印
벽에 맥주 3병.
다우름 하나 가져가서 돌리고, 벽에 맥주 2병.
第一次递归调用singTheSong(2), 入参为2.
注意, 此时singTheSong(oneFewer); 之后的printf打印不会出现, 因为递归调用还没有返回;
后面你看到的 numberOfBottles一直在+1 现象的直接原因就在这.
벽에 맥주 2병.
다우름 하나 가져가서 돌리고, 벽에 맥주 1병.
第二次递归调用singTheSong(1), 入参为1
同样, singTheSong(oneFewer) 之后的printf打印不会出现;
벽에 맥주 1병.
다우름 하나 가져가서 돌리고, 벽에 맥주 0병.
第三次递归调用singTheSong(0), 入参为0, 直接打印下面一行, 并退出;
注意, 这里的退出是退回到第二次递归的栈. 并从singTheSong(oneFewer)之后的printf开始执行.
벽에 더 이상 맥주병이 없습니다.
因为第二次递归入参为1, 所以这里打印下面一行
第二次递归调用退回到 第一次 递归的栈继续执行
병은 재활용품 수거함에 넣고, 빈병 1개는 쓰레기통에 넣으세요.
因为第一次递归入参为2, 所以这里打印下面一行
第一次递归调用退回到最初的singTheSong(3)继续执行
한 병은 재활용품 수거함에 넣고, 빈 병 2개는 쓰레기통에 넣으세요.
最初的singTheSong(3)调用入参为3, 所以打印下面一行.
한 병은 재활용품 수거함에 넣고, 빈 병은 3개를 쓰레기통에 넣으세요.
실행 순서 문제,
으아악numberOfBottles
이 항상 +1인 상황은 없습니다singTheSong(99);
를singTheSong(98);
실행 시 호출해야 하는데 이때singTheSong(99);
의 실행이 끝나지 않았습니다이 코드는
singTheSong(0);
이 완료될 때까지 호출되지 않습니다.singTheSong(1);
메소드 본문의 하단printf
코드가 실행된 후 재귀적으로 2, 3, 4...99를 실행하기 시작합니다.