Where will the value of n be stored after first call to factorial()?
When n=1 then return 1 is sent, why doesn't res becomes equal to 1 in main function?
#include<stdio.h>
int factorial(int n)
{
if(n<=1)
return 1;
else
return n*factorial(n-1);
}
int main()
{
int res =factorial(3);
printf("%d",res) ;
}
The run-time stack will have four functions in total: main(), factorial(3), factorial(2), and factorial(1). Each of these gets its own variable space. There are three instances of the variable n, one for each call to factorial.
When factorial(1) returns 1, that value isn't returned to main(), because main() is not what called it: factorial(2) called it. That instance performs the operation 2*1 and returns 2. The caller of that instance is factorial(3), which receives the 2, performs the operation 3*2, and returns a value of 6 to its caller, main().
Does that help clear it up? If not, I have two suggestions:
(1) Search this topic on StackOverflow and the internet in general; there are plenty of detailed walk-through examples of factorial.
(2) Insert print statements to trace the flow of data and execution. Within factorial, separate the computation and the return, so you can put a print in between:
catch = factorial(n-1)
result = n * catch
print n, catch, result
return result
Each time a function is called, its parameter and local variables are pushed onto the stack. In the case of a recursive function, there will be a set of the variables on the stack for each active invocation of the function.
In this example, the first call to factorial has n set to 3. Within the function, factorial is called again, this time with n set to 2. It calls itself one more time with n set to 1. In this last call, it returns a value of 1. This gets returned to the prior invocation where n is 2, which then returns 2 * 1 which is 2. This value is returned to the first invocation where n is 3 and returns 3*2 which is 6 back to main.
So the call stack looks like this:
main
|--> factorial(n==3)
|--> factorial(n==2)
|--> factorial(n==1)
return 1
return 2*1
return 3*2
print 6
n is not stored in the way of global or static variables - it's stored on the stack. Calling a function with arguments the arguments are being pushed on the stack.
See what's happening when your running your program:
factorial(3) gets called (in main)
As n is not equal or smaller to 1 factorial(2) is called and the result will be multiplied by n (is 3).
As n is not equal or smaller to 1 factorial(1) is called and the result will be multiplied by n (is 2).
As n is now equal or smaller to 1 the function returns 1
factorial(2) returns 1*2
factorial(3) returns 2*3
res will be 6
Related
We use a value n to perform recursion on. We save this value in a variable x. Then the variable x gets added to recursion as a return value. How exactly does this work?
I tried different approaches to check whether you use recursion first for x and then use x to add it to another recursion.
#include <stdio.h>
#include <stdlib.h>
int up(int n)
{
int x;
if(n == 0)
{
return 0;
}
else if(n == 1)
{
return 1;
}
else
{
x = up(n - 2);
return x + up(n - 1);
}
}
int main(void)
{
int n = 20;
int res;
res = up(n);
printf("Result %d\n", res);
return 0;
}
The result is 6765. Since it's a code from school the result should be fine. I just dont get why.
It sounds like you are having an issue grasping the concept of the function scope with recursion. It's generally easiest to think of recursion as a tree/stack.
Stack:
Let's say that n=5 for a simplistic example.
Up(5) is pushed onto the stack.
You then declare that x inside of this function scope is UP(3).
Now UP(3) is pushed onto the stack, and UP(5) is waiting for Up(3) to return.
Stack Order:
Up(3)
Up(5)
Now Up(3) declares x inside of this function to be UP(1) and patiently waits for Up(1) to return. Since x is declared inside of the function, they are local variables only accessible inside of the function that declared them. This means that the X inside of Up(3) is stored in a completely different location in memory as the X inside of Up(5). You will most definitely learn more about this when you research address-spaces and how local variables are stored and the like. But continuing forward!
Stack:
Up(1)
Up(3)
Up(5)
Up(1) returns 1, and thus we pop it off the stack! This means Up(3) can continue running.
Stack:
Up(3)
Up(5)
Up(3) now has x=1 (the return of Up(1) and wishes to return x+Up(2). In order to do that we push Up(2) onto the stack.
Stack:
Up(2)
Up(3)
Up(5)
Continuing this example, Up(2) will add Up(0) to the stack. Up(0) will return 0 so the x inside of the scope for Up(2) is set to 0. Up(2) will then add Up(1) to the stack, which will return 1. Up(2) will return (0+1). Now we can go back to Up(3) by popping Up(2) off the stack. Up(3) has x=1 and wishes to return (1+1). Popping Up(3) off the stack we are left with Up(5) on the stack. X is now set to 2 due to the return of Up(3). Now we add Up(4) to the stack, which adds Up(2),Up(0),Up(1),Up(3),Up(2),Up(0),Up(1) in that order Note(Many of these calls are popped off before new ones are added).
I recommend reading about global scope and function scope. Understanding these concepts are pretty crucial to the basics of understanding recursion. You can already see however that this type of recursion is pretty bruteforced and not optimized at all. For instance, you are calculating Up(2) multiple times for each recursive call created. This leads to a scalability issue when working with larger numbers, as you are repeating the same operation multiple times on the same number. This can be solved with a memoization array and a bit more logic for a smaller Big O runtime, but that may be a bit too far in detail for this question.
The argument bindings are unique for each call. That means that n in up(20) is never mixed with the n in up(19). Since it is not a reference the n - 1 is calculated and passed as a new value in a different place the the old so that when it returns the old n is what it always has been during the additional calls. Local variables are also only existing in the scope and thus every x is different too.
Since this function is pure, thus it's result is the sole product of the algorithm and the argument I think you should go from the base case and up...
The base cases:
up(0) => 0
up(1) => 1
The default cases:
up(2) => up(2-2) + up(2-1) => up(0) + up(1) => 0 + 1
Now I knew the results of 0 and 1 from the base cases up there and you can just replace it with the result. We can go further:
up(3) => up(3-2) + up(3-1) => 1 + 1 => 2
up(4) => up(4-2) + up(4-1) => 1 + 2 => 3
up(5) => up(5-2) + up(5-1) => 2 + 3 => 5
...
Interesting thing about this (Fibonacci) sequence is that if you have the two previous numbers you can generate the next. This makes this sequence an excellent candidate for either tail recursion or a iterative loop, both of which are far superior to the easier to read recursive version.
Here is how much the function could be simplified:
int Fib(int n)
{
return (n<2 ? n : Fib(n-1) + Fib(n-2));
}
This is simple C, not C++
I am getting the output ' 0,1,2,0'. Please someone help me how this function call is working. I have this doubt that after decrementing n, if statement will not execute as it will not be greater than 0. Thus there will be no output. But the result is something else.
#include <stdio.h>
void fun(int);
int main(void)
{
int a=3;
fun(a);
return 0;
}
void fun(int n)
{
if(n > 0)
{
fun(--n);
printf("%d,", n);
fun(--n);
}
}
You're calling fun() from within itself, both before and after the printf(). So you're going to see the printf from the deepest invocation of fun() first.
#ForceBru is absolutely right, you can - and, if you want to be a programmer, need to be able to - trace the code out in your head or on paper. Here's an example.
on the first invocation of fun(), as is 3. 3 > 0 so fun() is called again, with the _pre_decremented value ( so n is set to 2, and 2 is passed to fun().
The whole process happens again. 2 > 0 so --n or 1 is passed to fun.
In the 3rd invocation deep, n is 1. That's still greater than 0, so fun(--n) is run again, with n being predecremented to 0.
Now within the fourth invocation of fun(), n is finally 0. Nothing happens.
Third invocation, first fun() returns. Rember, this fun() invocation's n was 1, but it's been decremented to 0 by this time. 0 is printed. n is then decremented again ( to -1, it being a signed int) and fun(-1) is called, but since -1 > 0 is false, nothing happens. The third invocation returns.
The second invocation was passed 2 but has since decremented to 1. 1 is printed and then fun(--n) turns into fun(0) and the next fun() invcocation isfun(-1)and also does nothing. The second invocation offun()` returns.
Finally, the first invocation of fun(), the one from main, is executing agian. It started with 3, but decremented to 2. A 2 is printed. Then --n, or 1, is passed to fun() one last time. 1>0 so fun() is invoked again, and outputs--1or 0 just like it did the first time it was passed a 1. The first invocation's recursive calls tofun()then finish, and the program finishes, having output a0, 1, 2, 0`.
Do walk through that yourself on paper, as recursive functions can be pretty confusing. I didn't understand why you got that output myself until I walked through the code, and I've been programing in c for 20 years!
I have a hard time understanding the part of the code where the program is recalling on the recursion multiple times.
The output is 1233333. If I change the recursion line to just fun (++count;). the output is 123, which I understand the logic, but when you start calling on the recursion multiple times, I become lost.
#include <stdio.h>
int fun(int count) {
printf("%d\n", count);
if(count < 3) {
fun(fun(fun(++count)));
}
return count;
}
int main()
{
fun(1);
return 0;
}
First function calls 1 as the argument and 1 is printed
then it enters the if statement
The count gets incremented
fun(fun(fun(2)))
2 is printed and and enters if and
count is incremented to 3
fun(fun(fun(3))))
3 is printed.But this time it is doesn't enter the if instead 3 is returned
return(3)
and 3 is returned to the previous nested calls
fun(fun(3))
this happens 4 times
and hence the output
1233333
fun(fun(fun(++count)));
Is basically equivalent to:
int tmp = fun(++count);
tmp = fun(tmp);
fun(tmp);
Firstly fun(1) will be called
Print 1
Fun(fun(fun++1)=fun(fun(fun(2)))
So,
fun(2) will be called
Print 2
Fun(fun(fun(3)))
Fun(3) called
Print 3
If confition false
Return 3, now
Fun(fun(3))
Again print 3
Return 3 then
Fun(3)
Print 3
Return 3
And recursion return back to the position of fun(2)
Fun(fun(fun(2))) will be fun(fun(3) //because 3 is
returned
Fun(fun(3))
Print 3
Then return 3
Fun(3)
Print 3
And also return 3
So after all the things printed values will be
1 2 3 3 3 3 3
Calling a function like this is not really a recursion. You can say it nested function call. In your case, you are calling function fun() three times and passing the value returned by earlier call of function.
fun(fun(fun(++count)));
So, first fun() call will take a value ++count. Whereas the second fun() call will take the value returned by first call of function as parameter. Similarly, the third call will take a value returned by second call of fun() as parameter.
To understand things easily, you can consider following example
fun3(fun2(fun1(++count)));
In this example fun1() will take ++count as parameter. fun2() will take returned value by fun1() as parameter. Similarly, fun3() will take returned value by fun2() as parameter.
I hope this explains.
#include<stdio.h>
find(int x, int y)
{
return((x<y)?0:(x-y));
}
int main(void)
{
int a=find(5,find(5,4));
printf("%d",a);
return 0;
}
The above program gives output as 4. I ran with different values and learnt that the code snippet is to find minumum of two numbers. But, I can't seem to understand how it is working. Can someone explain it for me? I know how the ternary operator works, I didn't get the function call inside function call part.
int a=find(5,find(5,4));
find(5,4) returns 1
find(5,1) returns 4
First the find() function gets executed with 5 and 4 as its paramters. which will cause x<y condition to fail and returns x-y which is 5-4 =1
Later you have find(5,1) which again makes the x<y condition fail returning 5-1 which is 4
Try to break it.
See it this way.
when you say int a=find(5,find(5,4));
then the find function inside the find function i.e find(5,4) returns 1;
Now the resultant value makes it int a=find(5, 1);
And when find find(5,1); is called it returns 4 :)
What's there to "get"?
The function call is, like any other call, evaluated "inside out". All the argument values must be known before the call is made. So, the second argument is find(5,4), thus that call happens first. Then the value of that call is used as an argument in the second, outer, call.
To add to the previously given answers, it is always better to explicitly specify the return type of a function.
Change your find() function signature to
int find(int x, int y);
Next, regarding the function execution order, the flow is inside-out, means, the inner function will be executed first, the return value will be used to execute the outer call.
Diagramatically,
int a=find(5,find(5,4));
can be decomposed as
int a=find(5,find(5,4)); //consider step 1.0
| /*inner find() executes first, returns 1*/
V
int a=find(5, 1 /*result of find(5,4)*/); //consider step 1.1
| /*result of inner find() used for outer find()*/
V
int a=find(5, 1)); //consider step 1.2
| /*outer find() executes second, returns 4*/
V
int a= 4; //consider step 1.3
/* value 4 is assigned to a*/
int fact(int x)
{
if (x == 1)
return 1;
else
return (x * fact(x-1));
}
My question is how the variables are allotted on the stack during function call and if x = 5 - obviously the return would be 5 * fact(4), but how this 5 * fact(4) is pushed onto the stack how its value is resolved later i.e simple values (not variables) can be pushed and their values can be retrieved back, but how does the compiler treat fact(4).
Can anyone explain how exactly this recursion procedure is implemented by the compiler in detail?
Before 5 * fact(4) is returned fact(4) is called and evaluated on a new stack frame. When the call to fact(4) finishes, it places it's return value where the fact(5) stack frame can reach it (this may be the stack or in a register) and use it to calculate its own return value. So the order of finishing evaluation will be fact(1), fact(2), ..., fact(4), fact(5). Each placing their return values where the next one can retrieve it and use to calculate its own return value.