How Does This Recursive Function Operate in C++? [closed] - c++

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'd like to know how the 2nd output in the following code example is produced. How is the function able to count backwards after the if statement and recursive function call have ended?
void Recursion(int x)
{
if(x < 4) {
cout << x << " "; // 1st output: 1 2 3
Recursion(x + 1);
}
cout << x << " "; // 2nd output: 4 3 2 1
}
int main()
{
Recursion(1);
}

I'm going to interpret the question as "how can the function remember what it was doing when it returns?".
The C++ standard doesn't say (IIRC it's left to implementations to find a solution that works). In practice, though, the answer is "the stack".
In computer science generally, a stack is a last-in-first-out data structure. Push the sequence 1, 2 then 3 into a stack then do three pops and you get 3, 2 then 1.
In the early days, programming languages often didn't support recursive or re-entrant calls. Each function/procedure had a little block of memory it owned where it stored its parameters, local variables and which function to return to after completion. If you tried to call a function that was already running, that would mean storing two sets of local variables and two return addresses in the space for one, so that was an error.
However, one of the innovations in IIRC the Algol programming language was support for recursion. And at around the same time, "processor stacks" were becoming a thing.
A processor stack (among other things) allows you to use a different method for handling parameters, local variables and return addresses. You don't need a permanently allocated block for each function - you allocate a block (at the top of the stack) when you call the function. The location of the current "stack frame" is relative to the current "stack pointer". And this means you can have multiple stack frames for the same function on the stack at the same time.
So calling a function involves creating a new stack frame at the top of the stack, and adjusting the stack pointer to suit. And returning from a function involves discarding that stack frame and adjusting the stack pointer back, so the top stack frame is now the stack frame for the caller. That caller may or may not have been the same function - it doesn't matter because each call got it's own stack frame storing a separate set of parameters, local variables, a separate return address etc.
So just before the Recursion (3) call, the stack would look something like...
|-------------------+-------------------+
| Recursion Frame 1 | Recursion Frame 2 |
|---------------+---+---------------+---+
| ??? | X | ??? | X |
|---------------+---+---------------+---+
| ??? | 1 | ??? | 2 |
|---------------+---+---------------+---+
^
|
STACK
POINTER
The ??? represents "housekeeping" stuff like the return address.

Think about just the first call to Recursion.
The function is going to print a "1", then other stuff is going to happen, then it prints a "1" again.
So the output is going to be 1 ... 1
Now think about the second call to Recursion, its going to print a "2", then other stuff is going to happen, then it prints a "2" again.
So its output is 2 ... 2.
Stick those two together and you get 1 2 ... 2 1
And then just keep going.

You should try stepping through the code, executing it with pencil and paper (or a virtual scratch pad). Let's keep the function definition close:
void Recursion(int x)
{
1 if(x < 4) {
2 cout << x << " "; // 1st output: 1 2 3
3 Recursion(x + 1);
. }
.
4 cout << x << " "; // 2nd output: 4 3 2 1
5 return;
}
Now, let's call main:
call main
call Recursion(1) -> x := 1
(1) if (x < 4) -> true
(2) cout << x << " "; // with x == 1
(3) call Recursion(x + 1) -> x := 2
(1) if (x < 4) -> true
(2) cout << x << " "; // with x == 2
(3) call Recursion(x + 1) -> x := 3
(1) if (x < 4) -> true
(2) cout << x << " "; // with x == 3
(3) call Recursion(x + 1) -> x := 4
(1) if (x < 4) -> false
(4) cout << x << " "; // with x == 4
(5) end Recursion -> x:= 3
(4) cout << x << " "; // with x == 3
(5) end Recursion -> x:= 2
(4) cout << x << " "; // with x == 2
(5) end Recursion -> x:= 1
(4) cout << x << " "; // with x == 1
(5) end Recursion -> del x
end main
And now, you can just check what is outputed: cout << x << " "; is called successively with values: 1, 2, 3, 4, 3, 2, 1, yielding "1 2 3 4 3 2 1 ".

Does it help if you look at this:
string RecursiveReturn(int x)
{
if(x >= 4) {
return to_string(x);
}
return to_string(x) + " " + RecursiveReturn(x+1) + " " + to_string(x);
}
int main()
{
cout << Recursion(1);
}
A recursive call is like any other function call... it is evaluated, and when it returns the calling function continues.

The stack depicts that when "1st output" is performed to stdout, the "2nd output" is inserted into stack("function stack").
When the function "recursion" returns to "main" function the unwinding or popping contents of stack happens. If you visulaise properly this is how it gives output.

Related

Squaring numbers in consecutive order 0-9

I am extremely new to the coding world. I just have a basic question regarding this function that squares integers from 0-9. I understand most of what's going on until I get to
std::cout << i << " " << square << "\n";
i = i + 1;
I'm not too sure how that ends up causing the output to square the results in order from 0-9. Can someone explain the reasoning behind this line of code? Here is the code for this function.
#include <iostream>
int main() {
int i = 0;
int square = 0;
while ( i <= 9) {
square = i*i;
std::cout << i << " " << square << "\n";
i = i + 1;
}
return 0;
}
This code:
std::cout << i << " " << square << "\n";
i = i + 1;
Doesn't square anything. It is merely outputting the current square that has already been calculated, and then increments i for the next loop iteration.
The actual squaring happens here:
square = i*i;
So, the code starts at i=0, calculates square=0*0 and displays it, then sets i=1, calculates square=1*1 and displays it, then sets i=2, calculates square=2*2 and displays it, and so on until i exceeds 9, then the loop stops.
Lets start from beginning and what is happening, I will ignore first several lines and start at:
int i = 0;
int square = 0;
You see when you say int i; your compiler says I need to allocate bucket of memory to hold value for i. When you say i = 0 zero is put into that memory bucket. That is what is happening for square as well.
Now to loop
while ( i <= 9 ) {
square = i*i;
std::cout << i << " " << square << "\n";
i = i + 1;
}
So, lets ignore
square = i*i;
std::cout << i << " " << square << "\n";
for now we will come to it later.
So
while ( i <= 9 ) {
i = i + 1;
}
goes into the loop and gets value from i's bucket, adds 1 and puts new value into the i's bucket. So in first loop it will be i = 0 + 1, put 1 into i bucket. Second, i = 1 + 1 put 2 in, third i = 2 + 1 put 3.
So lets go back to square and its bucket.
square = i*i;
So first time we go into the loop i = 0 and square = 0 * 0 so compiler puts 0 into square's memory bucket. Next time it hits square i has been incremented to 1 so square = 1 * 1, thus compiler puts 1 into the bucket. Third time i is 2 so square = 2 * 2, and compiler puts 4 into the bucket. And so on till it i <= 9. When i hits 10 loop is not executed.
In comments you have stated that you do not know the difference between a math equation and an assignment statement. You are not alone.
I will try to explain, as an addition to existing answers, to provide a different angle.
First, two examples of math equations:
x = 1 +1
y+1 = x*2
To illustrate their meaning, let me point our that you first can determine that x is 2 and in a second step that y is 3.
Now examples of assignment statements.
x = 1 +1;
y = x*2;
The minor difference is the ; at the end, tipping you off that it is a program code line.
Here the first one looks pretty much the same as the first equation example. But for a C compiler this is different. It is a command, requesting that the program, when executing this line, assigns the value 2 to the variable x.
The second assingment statement I made similar to the second equation example, but importantly different, because the left side of = is not an expression, not something to calculate. The equation-turned-statement
y +1 = x*2;
does not work, the compiler will complain that it cannot assign a value (no problem with doing a little calculation on the right side) to an expression. It cannot assign the value 4 to the expression y+1.
This helps with your problem, because you need to understand that both lines
i = i + 1;
square = i*i;
are statements which, when executed (and only then) cause a change to the value of the variable in that line.
Your program starts off with the value 0 in the variable i. At some point it executes the first of the statements above, causing the value of i to change from 0 to 1. Later, when the same line is executed again, the value of i changes from 1 to 2. So the values of i change, loop iteration by loop iteration, to 2,3,4,5,6,7,8,9
The second assignment line causes the value of square to become the value of i, whatever it is during that loop iteration and multiplied by itself. I.e. it gets to be 4,9,16,25,36....
Outputting the value of square each time in the loop gets you the squares.
Since you state that you basically understand loops, I just mention that the loop ends when i is not lower or equal to 9 any more.
Now from the other point of view.
If you try to solve the equation
i = i + 1
for i, you should hear your math teacher groaning.
You can subtract i from both sides and get
0 = 1
The solution is "Don't try.", it is not an equation.
std::cout << i << " " << square << "\n"; prints every
number i next to its square, which is previously computed
(square = i*i;).
i = i + 1; increments i to compute the next square. It stops when i reaches 10.
The output will look like this:
0 0
1 1
2 4
3 9
4 16
5 25
6 36
7 49
8 64
9 81
So we have a while loop here, which run while i <= 9. The square of any number i is i * i.
while(i <=9){ //check the condition and then enter the body
//body
}
But we need a condition to get out of the loop, otherwise our program will enter into an infinite loop.
To ensure, we will exit from the loop we increase the value of i by 1.
so at first when i = 0 square = 0 * 0 = 0,now we increase the value of i i.e now i becomes one which still satisfies the condition to stay inside the loop , again it will calculate square = 1 * 1 until and unless the value of i remains less than or equal to 9.
Once the condition fails, the execution comes out of the loop.

What happens when we call a function after initial condition [duplicate]

I am currently programming some divide-conquer algorithms, where function recursions are used everywhere, but I have very vague idea or no idea how exactly it works, and that's why I post it here and hope you don't mind it's too basic.
For example, if we have the following code:
#include<iostream>
using namespace std;
void Recursion(int n)
{
cout << n << endl;
if(n > 0)
{
Recursion(n-1);
}
cout<<n<<endl;
}
int main()
{
Recursion(3);
return 0;
}
I tested Recursion(3) and the print out in the terminal is:
3
2
1
0
0
1
2
3
I can understand the concept of recursive call of the function but I don't understand the mechenism how it works. For example, what will they do after they can't call the function again? For example, here, I can understand it prints from 3 to 0 but why it also prints from 0 to 3 again? I heard it's because function recursion is stored in a stack for one recursion and when it reaches the "bottom" it also has to delete.
But anyway, I don't know about it. So, can anyone help me out and clearly tell me what happened here and the exact flow of function call?
Thanks for your help!
The key to understanding recursion is the concept of the call stack. The call stack consists of "frames". A stack frame contains a function's local variables and an invisible return address. The classic physical analogy is a stack of plates. When you make a function call a plate (stack frame) is added to the top of the stack. When you return from a function the top plate (stack frame) is removed. You can only use the plate (stack frame) that is on top.
Recursive functions work the same way as ordinary functions. They are a little tricky because you can have multiple instances of their local variables on the stack at a given time. However, like other functions the function only refers to the stack frame that is on the top of the stack.
To illustrate how this works let's walk through your program showing how the call stack grows and shrinks.
Let's start with the base case: 0. Recursion(0);
Enter main: The stack is empty: Bottom of stack->||<-Top of stack
Recursion(0); Enter Recursion the stack has grown: Bottom of stack->|0|<-Top of stack
cout << n << endl; The value of n is 0 so the output is "0"
if (n > 0). 0 is not greater than 0 so Recursion(-1) is not called.
cout << n << endl; The value of n is 0 so the output is "0"
Return to main() the stack is empty again: Bottom of stack->||<-Top of stack
The output would be
0
0
Simple enough, no recursion took place. Let's take the next step. Recursion(1);
Enter main: Bottom of stack->||<-The top of stack
Recursion(1); Enter Recursion: Bottom of stack->|1|<-Top of stack
cout << n << endl; The value of n is 1 so the output is "1"
if (n > 0). 1 is greater than 0 so Recursion(0); is called.
Enter Recursion: Bottom of stack->|1,0|<-Top of stack
cout << n << endl; The value of n in this stack frame is 0 so the output is "0"
if (n > 0). 0 is not greater than 0 so the function does not recurse.
cout << n << endl; The value of n is 0 so the output is "0"
Return to the first call to Recursion. Bottom of stack->|1|<-Top of stack
cout << n << endl; The value of n is 1 so the output is "1"
Output
1
0
0
1
Let's go through the execution one final time with n == 2
Enter main: Bottom->||<-Top
Recursion(2); Enter Recursion: Bottom->|2|<-Top
cout << n << endl; "2"
if (n > 0). 2 is greater than 0 so Recursion(1); is called.
Enter Recursion: Bottom->|2,1|<-Top
cout << n << endl; "1"
if (n > 0). 1 is greater than 0 so Recursion(0); is called.
Enter Recursion: Bottom->|2,1,0|<-Top
cout << n << endl; "0"
if (n > 0). 0 is not greater than 0 so the function does not recurse again.
cout << n << endl; "0"
Return. Bottom->|2,1|<-Top
cout << n << endl; "1"
Return. Bottom->|2|<-Top
cout << n << endl; "2"
Return to main(). Bottom->||<-Top
Output
2
1
0
0
1
2
You are right, I also find recursive functions difficult to understand. Here is what i do, if i see a recursive function: run all the code step by step in your mind. This advice may seem trivial, but most of the time it works for me. Let's look at your code:
You call Recursion() function with parameter 3. It prints n and n>0 that's why it calls Recursion(2) (note that we didn't return from the Recursion(3) call we are still in it and now we are also in Recursion(2). The same is for recursion(1) and 0. Now n>0 conditional is false. It prints 0. and we return from recursion(0) We print 1 and return from recursion(1) and it goes on the recursion(3)
Recursion(3)
Recursion(2)
Recursion(1)
Recursion(0)
return from Recursion(0)
return from Recursion(1)
return from Recursion(2)
return from Recursion(3)
A function calling itself is not different from a function calling another function: before proceeding it has to wait that the function it has called returns.
By the way, recursion might look elegant, but in general it's not the most efficient way of programming: it makes for example impossible to inline functions, so the overhead for context switch is guaranteed. There's always a more efficient way to obtain the same result of a recursive function. But for some problems a recursive implementation is more intuitive, and not slower in any significant way. The example you gave in the comments, merge sort, is a good one.
A couple of interesting discussion about this:
Way to go from recursion to iteration
Can every recursion be converted into iteration?
My final advice: do not go for recursive when the problem does not require this approach, for example when computing a factorial.
Sometimes it is easier to understand recursion by starting at the base case, that is, the one that does not recurse.
In your example, when n<=0, the call is resolved without more calls. Let's start by that.
If you call Recursion(0), the expected result is to print zero twice, one before and one after the if. The code inside the if does not execute.
Now, Recursion(1) does its first print of the value one, then calls Recursion(0) which in its turn prints 0 twice like before, then execution returns to Recursion(1), which prints 1 again, after the execution of Recursion(0). That is why you see 1 0 0 1.
The same applies to Recursion(2), which will wrap the result of Recursion(1) around twos.

Confusing Fibonacci number program

Ok so I am having trouble understanding exactly how this program works:
#include <iostream>
using namespace std;
int getFibNumber(int fibIndex)
{
if(fibIndex < 2)
return fibIndex;
else
return getFibNumber(fibIndex - 1) + getFibNumber(fibIndex - 2);
}
int main(int argc, char** argv)
{
cout << "Enter 0-based index of desired Fibonacci number: ";
int index = 0;
cin >> index;
cout << "Fibonacci number is: " << getFibNumber(index) << endl;
return 0;
}
Specifically, what does "getFibNumber(...)" do when it reiterates(if that is the correct word)? I can't figure out what it does if the integer "fibIndex" that is passed in is greater than or equal to 2. Sorry to ask such a basic question, but I am really stumped by this and I feel like I'm missing something.
As everyone mentioned here, this is basically recursion.
Just to get a feel of how this program works, I have made the recursion tree with initial fibIndex as 5.
5 5 calls 4 and 3.
/ \
4 3 4 calls 3 and 2. 3 calls 2 and 1.
/ \ / \
3 2 2 1 1 is base case, returns 1.
/ \ / \ / \
2 1 1 0 1 0 2 is not base case. So calls 1 and 0.
/ \
1 0
This is called recursion. Instead of doing this with a loop it calls the function again, but with a different parameter. Eventually, the base condition will be true, and the function will return, causing the rest of the calls to return also. This can be a very powerful tool in the right situation.

simple recursion tracing understanding stacks

I'm working on a fairly easy tracing exercise however I'm not completely understanding why the solution is what it is...
void f( int n) {
if (n>0) {
f(n-1)
cout << n << " ";
}
}
int main () {
f(5);
return 0;
}
the answer is 1 2 3 4 5, however I'm wondering how this is so, since everytime the function f is called it never gets to the cout line...I understand that there is a stacking system where the last function implemented is looked at, however until the factorial example where it returned a value to multiply to the previous n, I'm not understanding how this is similar. Please don't use the factorial example again, I do understand it, but I'm not udnerstanding how the cout is implemented here.. thank you for your help.
Consider the simple case of calling f(1). We pass the if test and make a recursive call to f(0). This call will return doing nothing and continue executing the body of f(1). The next statement is the call to std::cout << 1 << " ";:
// Substitute the parameter with the passed in argument n = 1
void f(1) {
if (1 > 0) {
f(0);
std::cout << 1 << " ";
}
}
You should now be able to handle the case of f(2), and in general f(n). Whenever you are stuck thinking about recursive programs, consider the base cases and then generalize. Write the code out by substituting the function parameters with actual arguments.
It does get to the output line, after the recursive call to f returns.
The important part here is the stopping condition:
if (n>0)
This makes the recursive call only happen if n is larger than zero. And as the recursive call is with the argument n - 1 it will be lower and lower until it's zero and no more calls will be made.
Lets trace it for you, since you are to lazy to do it yourself in a debugger (or on paper):
The first call from main is made. n == 5 and clearly larger than zero, so a recursive call is made with 5 - 1
In the second call, n == 4, still larger than zero so a call is made again with 4 - 1
In the third call, n == 3, still larger than zero so a call is made again with 3 - 1
In the fourth call, n == 2, still larger than zero so a call is made again with 2 - 1
In the fifth call, n == 1, still larger than zero so a call is made again with 1 - 1
In the sixth call, n == 0, which is not larger than zero, so no more calls are made and the function returns.
Returns to n == 1, and so 1 is printed and then the function returns
Returns to n == 2, and so 2 is printed and then the function returns
Returns to n == 3, and so 3 is printed and then the function returns
Returns to n == 4, and so 4 is printed and then the function returns
Returns to n == 5, and so 5 is printed and then the function returns to the main function
That is, this is how it should have worked if it compiled. Now it won't even get this far since you will have compiler errors (with the code as shown in your question).

How to understand function recursion precisely?

I am currently programming some divide-conquer algorithms, where function recursions are used everywhere, but I have very vague idea or no idea how exactly it works, and that's why I post it here and hope you don't mind it's too basic.
For example, if we have the following code:
#include<iostream>
using namespace std;
void Recursion(int n)
{
cout << n << endl;
if(n > 0)
{
Recursion(n-1);
}
cout<<n<<endl;
}
int main()
{
Recursion(3);
return 0;
}
I tested Recursion(3) and the print out in the terminal is:
3
2
1
0
0
1
2
3
I can understand the concept of recursive call of the function but I don't understand the mechenism how it works. For example, what will they do after they can't call the function again? For example, here, I can understand it prints from 3 to 0 but why it also prints from 0 to 3 again? I heard it's because function recursion is stored in a stack for one recursion and when it reaches the "bottom" it also has to delete.
But anyway, I don't know about it. So, can anyone help me out and clearly tell me what happened here and the exact flow of function call?
Thanks for your help!
The key to understanding recursion is the concept of the call stack. The call stack consists of "frames". A stack frame contains a function's local variables and an invisible return address. The classic physical analogy is a stack of plates. When you make a function call a plate (stack frame) is added to the top of the stack. When you return from a function the top plate (stack frame) is removed. You can only use the plate (stack frame) that is on top.
Recursive functions work the same way as ordinary functions. They are a little tricky because you can have multiple instances of their local variables on the stack at a given time. However, like other functions the function only refers to the stack frame that is on the top of the stack.
To illustrate how this works let's walk through your program showing how the call stack grows and shrinks.
Let's start with the base case: 0. Recursion(0);
Enter main: The stack is empty: Bottom of stack->||<-Top of stack
Recursion(0); Enter Recursion the stack has grown: Bottom of stack->|0|<-Top of stack
cout << n << endl; The value of n is 0 so the output is "0"
if (n > 0). 0 is not greater than 0 so Recursion(-1) is not called.
cout << n << endl; The value of n is 0 so the output is "0"
Return to main() the stack is empty again: Bottom of stack->||<-Top of stack
The output would be
0
0
Simple enough, no recursion took place. Let's take the next step. Recursion(1);
Enter main: Bottom of stack->||<-The top of stack
Recursion(1); Enter Recursion: Bottom of stack->|1|<-Top of stack
cout << n << endl; The value of n is 1 so the output is "1"
if (n > 0). 1 is greater than 0 so Recursion(0); is called.
Enter Recursion: Bottom of stack->|1,0|<-Top of stack
cout << n << endl; The value of n in this stack frame is 0 so the output is "0"
if (n > 0). 0 is not greater than 0 so the function does not recurse.
cout << n << endl; The value of n is 0 so the output is "0"
Return to the first call to Recursion. Bottom of stack->|1|<-Top of stack
cout << n << endl; The value of n is 1 so the output is "1"
Output
1
0
0
1
Let's go through the execution one final time with n == 2
Enter main: Bottom->||<-Top
Recursion(2); Enter Recursion: Bottom->|2|<-Top
cout << n << endl; "2"
if (n > 0). 2 is greater than 0 so Recursion(1); is called.
Enter Recursion: Bottom->|2,1|<-Top
cout << n << endl; "1"
if (n > 0). 1 is greater than 0 so Recursion(0); is called.
Enter Recursion: Bottom->|2,1,0|<-Top
cout << n << endl; "0"
if (n > 0). 0 is not greater than 0 so the function does not recurse again.
cout << n << endl; "0"
Return. Bottom->|2,1|<-Top
cout << n << endl; "1"
Return. Bottom->|2|<-Top
cout << n << endl; "2"
Return to main(). Bottom->||<-Top
Output
2
1
0
0
1
2
You are right, I also find recursive functions difficult to understand. Here is what i do, if i see a recursive function: run all the code step by step in your mind. This advice may seem trivial, but most of the time it works for me. Let's look at your code:
You call Recursion() function with parameter 3. It prints n and n>0 that's why it calls Recursion(2) (note that we didn't return from the Recursion(3) call we are still in it and now we are also in Recursion(2). The same is for recursion(1) and 0. Now n>0 conditional is false. It prints 0. and we return from recursion(0) We print 1 and return from recursion(1) and it goes on the recursion(3)
Recursion(3)
Recursion(2)
Recursion(1)
Recursion(0)
return from Recursion(0)
return from Recursion(1)
return from Recursion(2)
return from Recursion(3)
A function calling itself is not different from a function calling another function: before proceeding it has to wait that the function it has called returns.
By the way, recursion might look elegant, but in general it's not the most efficient way of programming: it makes for example impossible to inline functions, so the overhead for context switch is guaranteed. There's always a more efficient way to obtain the same result of a recursive function. But for some problems a recursive implementation is more intuitive, and not slower in any significant way. The example you gave in the comments, merge sort, is a good one.
A couple of interesting discussion about this:
Way to go from recursion to iteration
Can every recursion be converted into iteration?
My final advice: do not go for recursive when the problem does not require this approach, for example when computing a factorial.
Sometimes it is easier to understand recursion by starting at the base case, that is, the one that does not recurse.
In your example, when n<=0, the call is resolved without more calls. Let's start by that.
If you call Recursion(0), the expected result is to print zero twice, one before and one after the if. The code inside the if does not execute.
Now, Recursion(1) does its first print of the value one, then calls Recursion(0) which in its turn prints 0 twice like before, then execution returns to Recursion(1), which prints 1 again, after the execution of Recursion(0). That is why you see 1 0 0 1.
The same applies to Recursion(2), which will wrap the result of Recursion(1) around twos.