我很困惑,不知道这里发生了什么:
#include <iostream>
void recur();
int i = 1;
int main() {
recur();
}
void recur() {
std::cout << "\nvalue of i above while loop : " << i << std::endl;
while(i++ < 10) {
recur();
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
}
}
这是输出:
value of i above while loop : 1
value of i above while loop : 2
value of i above while loop : 3
value of i above while loop : 4
value of i above while loop : 5
value of i above while loop : 6
value of i above while loop : 7
value of i above while loop : 8
value of i above while loop : 9
value of i above while loop : 10
statement just after the recursive call to tester and here the value of i is :11
statement just after the recursive call to tester and here the value of i is :12
statement just after the recursive call to tester and here the value of i is :13
statement just after the recursive call to tester and here the value of i is :14
statement just after the recursive call to tester and here the value of i is :15
statement just after the recursive call to tester and here the value of i is :16
statement just after the recursive call to tester and here the value of i is :17
statement just after the recursive call to tester and here the value of i is :18
statement just after the recursive call to tester and here the value of i is :19
每次调用函数recur
时,它都会打印它的第一行,当值变为等于10时,循环中断。当我们离开循环时,while循环中的语句如何工作/打印?有人可以解释发生了什么吗?
让我验证
我在想什么?在每次调用函数recur
时,控件都会返回函数定义的开头。例如:
while(i++<10) {
recur();
//...
}
|
|
\ /
void recur() { // here i is 2
while(i++ < 10) {
recur();
//....
}
}
|
|
\ /
void recur() { // here i is 3
while(i++ < 10) {
recur();
//....
}
}
这是通话的方式吗?
答案 0 :(得分:3)
变量i继续递增,因为while条件必须再次执行以确保它为false,导致i递增,即使每次调用recur()都超过10。
如果您将i的增量放在条件之外,则结果将更符合您的预期。例如:
while (i < 10) {
i++;
// Do rest.
}
但是使用当前的代码,每次测试条件时,即使条件为假,我也会继续递增。
答案 1 :(得分:2)
你以一种相当奇怪的方式混合递归和迭代。
第一个recur()调用第二个,调用第三个,依此类推。每个增量i。当第十个嵌套函数调用将i递增到10时,它返回。然后第9个函数调用打印消息,再次递增i,退出循环并返回到第8个函数。
没有一个函数多次绕过while循环 - 因为当嵌套的recur()调用返回时,i总是至少为10。
你为什么要这样做?
答案 2 :(得分:1)
不,当recur()
返回时,您仍然在while
语句中,您必须在std::cout
之后执行recur()
。
void recur() {
std::cout << "\nvalue of i above while loop : " << i << std::endl;
while(i++ < 10) {
recur();
// <b>each time `recur()` returns, its return to here</b>
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
}
}
好的,我画了一个图表
while(i++<10) {
recur();
//... <---------return to here--
} |
|
void recur() { // here i is 2 |
while(i++ < 10) { |
recur(); |
//.... <-----return to here---- |
} | |
return; ------------------------------
} |
|
void recur() { // here i is 3 |
while(i++ < 10) { |
recur(); |
//.... |
} |
return; ----------------------------
}
答案 3 :(得分:1)
以下是您的计划流程:
value function stack depth
----- -------- -----------
i = 1 recur() 0
i = 1 print i 1
i = 1 i++ 1
i = 2 recur() 1
i = 2 print i 2
i = 2 i++ 2
i = 3 recur() 2
i = 3 print i 3
i = 3 i++ 3
i = 4 recur() 3
i = 4 print i 4
i = 4 i++ 4
i = 5 recur() 4
i = 5 print i 5
i = 5 i++ 5
i = 6 recur() 5
i = 6 print i 6
i = 6 i++ 6
i = 7 recur() 6
i = 7 print i 7
i = 7 i++ 7
i = 8 recur() 7
i = 8 print i 8
i = 8 i++ 8
i = 9 recur() 8
i = 9 print i 9
i = 9 i++ 9
i = 10 recur() 9
i = 10 print i 10
i = 10 i++ 10
i = 11 return 10
i = 11 print i 9
i = 11 i++ 9
i = 12 return 9
i = 12 print i 8
i = 12 i++ 8
i = 13 return 8
i = 13 print i 7
i = 13 i++ 7
i = 14 return 7
i = 14 print i 6
i = 14 i++ 6
i = 15 return 6
i = 15 print i 5
i = 15 i++ 5
i = 16 return 5
i = 16 print i 4
i = 16 i++ 4
i = 17 return 4
i = 17 print i 3
i = 17 i++ 3
i = 18 return 3
i = 18 print i 2
i = 18 i++ 2
i = 19 return 2
i = 19 print i 1
i = 19 i++ 1
i = 20 return 1
i = 20
答案 4 :(得分:0)
在最里面的recur调用中条件变为false后,它会跳出循环并正确返回。它返回到recur的第二个最里面的调用,它显示i
的值,然后返回到while循环的开头以再次检查条件。条件为(i++ < 10)
,因此它第二次递增i
(现在为11),看到它大于10,并返回第三个最里面的调用。第三个最里面的增量检查(i++ < 10)
,要求它在知道打开它的循环之前递增i
(到12)。等
基本上,每次通话都有一个循环。它一次只能打破一个。你想要:
void recur() {
std::cout << "\nvalue of i above while loop : " << i << std::endl;
i++; //here, outside the loop
while(i < 10) {
recur();
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
}
}
[编辑]
是的,当一个函数调用自身时,计算机将再次调用该函数,当内部函数返回时,它将返回到外部函数中的确切位置。基本上,就像任何其他函数调用一样。
答案 5 :(得分:0)
我认为解释它的最好方法是展示我如何重写函数以使其更具可读性。以下每个片段的输出都与原始代码相同(假设首次调用recur()时i == 1)
首先,让我们将postincrement运算符排除在条件之外,因为我觉得它很混乱。此代码是等效的:
void recur() {
std::cout << "\nvalue of i above while loop : " << i << std::endl;
while(i < 10){
i++;
recur();
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
}
i++;
}
注意最后有一个i ++。这是因为在原始代码中,我将在(i ++&lt; 10)条件下递增,即使条件不计算为true并且不进入循环。
接下来,您可以通过反复内联代码来“重新排列”重复。每当它的值发生变化时,我也会追踪i的值。
void recur() {
std::cout << "\nvalue of i above while loop : " << i << std::endl;
while(i < 10){
i++; //i == 2
std::cout << "\nvalue of i above while loop : " << i << std::endl;
while(i < 10){
i++; //i == 3
std::cout << "\nvalue of i above while loop : " << i << std::endl;
while(i < 10){
i++; //i ==4
std::cout << "\nvalue of i above while loop : " << i << std::endl;
while(i < 10){
i++; //i == 5
std::cout << "\nvalue of i above while loop : " << i << std::endl;
while(i < 10){
i++; //i == 6
std::cout << "\nvalue of i above while loop : " << i << std::endl;
while(i < 10){
i++; //i == 7
std::cout << "\nvalue of i above while loop : " << i << std::endl;
while(i < 10){
i++; //i == 8
std::cout << "\nvalue of i above while loop : " << i << std::endl;
while(i < 10){
i++; //i == 9
std::cout << "\nvalue of i above while loop : " << i << std::endl;
while(i < 10){
i++; //i == 10
std::cout << "\nvalue of i above while loop : " << i << std::endl;
while(i < 10){//this doesn't evaluate to true since i == 10
//we stop unrolling here because the interior of this loop won't be executed anyway
}
i++; // i == 11
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
}
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
}
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
}
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
}
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
}
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
}
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
}
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
}
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
}
i++;
}
注意每个while循环只执行一次 - 当第一次完成任何单个while循环时,i大于10,因此不会再次输入循环。考虑到这一点,我们可以完全摆脱这些问题,并为自己省去一些缩进。
void recur() {
std::cout << "\nvalue of i above while loop : " << i << std::endl;
i++; //i == 2
std::cout << "\nvalue of i above while loop : " << i << std::endl;
i++; //i == 3
std::cout << "\nvalue of i above while loop : " << i << std::endl;
i++; //i ==4
std::cout << "\nvalue of i above while loop : " << i << std::endl;
i++; //i == 5
std::cout << "\nvalue of i above while loop : " << i << std::endl;
i++; //i == 6
std::cout << "\nvalue of i above while loop : " << i << std::endl;
i++; //i == 7
std::cout << "\nvalue of i above while loop : " << i << std::endl;
i++; //i == 8
std::cout << "\nvalue of i above while loop : " << i << std::endl;
i++; //i == 9
std::cout << "\nvalue of i above while loop : " << i << std::endl;
i++; //i == 10
std::cout << "\nvalue of i above while loop : " << i << std::endl;
i++; // i == 11
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
i++;
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
i++;
}
也可以优化其中一些重复的陈述......
void recur(){
for(int x = 0; x < 10; x++){
std::cout << "\nvalue of i above while loop : " << i << std::endl;
i++;
}
for(int x = 0; x < 9; x++){
std::cout << "statement just after the recursive call to tester and here the value of i is :" << i << std::endl;
i++;
}
}
现在很明显看到第一个语句为i = 1到10打印自己,第二个从i = 11到19打印。