What is recursion really and explain the output of this program? [closed] - c

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I really can't understand this code. When a function calls itself what really happens? It is related to the concept of stack, I know, but still I can't solve these questions.
#include<stdio.h>
fun(int);
main()
{
int x=3;
fun(x);
}
fun(int a)
{
if(a<0)
{
fun(--a); // what happens when function calls itself
printf("%d",a);
fun(--a);
}
}
Please explain the sequence of events which occur during this.

In this case, calling fun() is like calling any other function. For example:
int main() {
int a = 0;
foo(a);
printf("main a = %d\n", a);
}
void foo(int a) {
a = 1;
bar(a);
printf("foo a = %d\n", a);
}
void bar(int a) {
a = 2;
printf("bar a = %d\n", a);
}
Your call sequence look like this:
main();
foo();
bar();
And your output will be this:
bar a = 2
foo a = 1
main a = 0
The arguments are passed by value, so a is copied and is actually a different variable in each function. The same happens with recursion.
main(); x = 3
fun(3); a = 3, so a > 0, nothing happens, return to main()
If you were to change the condition so fun() calls itself when a > 0 (read top-down)
main(); x = 3
fun(3); a = 3, a > 0 so --a = 2, fun(2)
fun(2); a = 2, a > 0 so --a = 1, fun(1)
fun(1); a = 1, a > 0 so --a = 0, fun(0)
fun(0); a = 0, so return to fun(1)
fun(1); printf("%d", a) displays 1, --a = 0, fun(0) /* same as fun(1) above */
fun(0); a = 0, so return to fun(1)
fun(1); nothing left to do so return to fun(2) /* same as fun(1) above */
fun(2); printf("%d", a) displays 2, --a = 1, fun(1)
fun(1); a = 1, a > 0 so --a = 0, fun(0) /* this is a new fun(1) */
fun(0); a = 0, so return to fun(1)
fun(1); printf("%d", a) displays 1, --a = 0, fun(0)
fun(0); a = 0, so return to fun(1)
fun(1); nothing left to do so return to fun(2)
fun(2); nothing left to do so return to fun(3)
fun(3); printf("%d", a) displays 3, --a = 2, fun(2) /* halfway point */
fun(2); a = 2, a > 0 so --a = 1, fun(1)
fun(1); a = 1, a > 0 so --a = 0, fun(0)
fun(0); a = 0, so return to fun(1)
fun(1); printf("%d", a) displays 1, --a = 0, fun(0)
fun(0); a = 0, so return to fun(1)
fun(1); nothing left to do so return to fun(2)
fun(2); printf("%d", a) displays 2, --a = 1, fun(1)
fun(1); a = 1, a > 0 so --a = 0, fun(0)
fun(0); a = 0, so return to fun(1)
fun(1); printf("%d", a) displays 1, --a = 0, fun(0)
fun(0); a = 0, so return to fun(1)
fun(1); nothing left to do so return to fun(2)
fun(2); nothing left to do so return to fun(3)
fun(3); nothing left to do so return to main()
And your output should be: 1213121 which reflects the tree structure of the calls:
3
/ \
/ \
2 2
/ \ / \
1 1 1 1

Function arguments are passed by value in C, which means temporary local variables are created each time the function is called. When a function is called recursively, a new set of variables is created each time. However, recursion doesn't necessarily save storage space, since somewhere a stack of the values being processed must be maintained.

Functions are merely code that resides somewhere in memory. Whenever you make a function call, the compiler translates that into an assembly code command for the platform that saves the address of the next command to be executed after the function call is complete as well as tell the processor where to literally "jump" in memory in order to read the next command to be executed.
Recursion works because you can easily tell the processor to "jump" back to the beginning of the function's code block in memory. The current function that you are calling from has a memory address just like any other function, and therefore there is no difference for the processor to jump to the beginning of the current function's code block in memory, or some other function's code block in memory.
The stack comes into play due to the fact that we need to save the return address for the command to execute after we complete the function call, as well as a location to store the current function's arguments and automatic variables. So as you make successive function calls, there is a call-stack that is created, with arguments as well as return addresses for any previously called functions higher-up on the stack if the stack is growing downwards. This is collectively called the "stack frame" for the function. When you return from a function, the current function's stack frame is popped off the bottom of the stack, and then the memory address for where the processor needs to jump back to after the function is complete is read and executed. In the case of recursion, this means that we simply jump back to a previous version of the same function, but in this case the automatic stack variables and arguments will be different after we return since we have returned back to a stack frame for a previous version of the function.

Related

Recursive Function with two calls

Here I've a code about recursion from geeksforgeeks.com
#include<stdio.h>
void fun(int x)
{
if(x > 0)
{
fun(--x);
printf("%d\t", x);
fun(--x);
}
}
int main()
{
int a = 4;
fun(a);
return 0;
}
I am really getting lost myself, I cannot understand working principle of this function. As far as I know, firstly the recursive each call of the function are stored in stack and is being started popping after base case reached. However, I cannot understand how it works after the printf function which the second call. Can anyone please explain me? I'm very pleased, if so.
Thanks in advance for your lovely contributions.
The x variable in fun(x) is local, and first call is x-1, second is x-2
Consider the simplest case
fun(1)
Results in fun(0) and fun(-1) being called
fun(2)
Results in fun(1) and fun(0) being called, and since 1 is > 0, fun(1) will also invoke fun(0) and fun(-1) before fun(2) calls fun(0)
Here's a partial call stack, indented according to which function is calling
fun(4)
fun(3)
fun(2)
fun(1)
fun(0)
print
fun(-1)
print
fun(0)
fun(1)
fun(0)
print
fun(-1)
print
fun(0)
fun(2)
...
The detail below illustrates the call depth using indents and shows calls to fun and printf to illustrate the execution sequence and print output:
Line 15: fun(4) --> depth 1
Line 6: x=3, fun(3) --> depth 2
Line 6: x=2, fun(2) --> depth 3
Line 6: x=1, fun(1) --> depth 4
Line 6: x=0, fun(0) --> depth 5, do nothing & return
Line 7: printf --> "0"
Line 8: x=-1, fun(-1) --> depth 5, do nothing & return
Return --> depth 3
Line 7: printf --> "1"
Line 8: x=0, fun(0) --> depth 4, do nothing & return
Return --> depth 2
Line 7: printf --> "2"
Line 8: x=1, fun(1) --> depth 3
Line 6: x=0, fun(0) --> depth 4, do nothing & return
Line 7: printf --> "0"
Line 8: x=-1, fun(-1) --> depth 4, do nothing & return
Return --> depth 2
Line 7: printf --> "3"
Line 8: x=2, fun(2) --> depth 2
Line 6: x=1, fun(1) --> depth 3
Line 6: x=0, fun(0) --> depth 4, do nothing & return
Line 7: printf --> "0"
Line 8: x=-1, fun(-1) --> depth 4, do nothing & return
Return --> depth 2
Line 7: printf --> "1"
Line 8: x=0, fun(0) --> depth 3, do nothing & return
Return --> depth 1
Return --> depth 0
First of all, I recommend you to read a book about recursion, for example the books of Rozsa Peter or Daniel Friedman (The little schemer) or better take some first year course/mooc of introduction. After that you can study more advanced stuff.
You have this code:
void fun(int x)
{
if(x > 0)
{
fun(--x);
printf("%d\t", x);
fun(--x);
}
}
Suppose you call fun(4).
In this case you have a sigma-recursive operator (also called primitive recursion). The recursion needs some limit cases. In this case it is a simple linear recursion with only the case "counter reaches null value" (the same as in the definition of arithmetics of Peano).
If it reaches 0, it finished. Otherwise, it calls itself with the counted decremented by 1 toward the limit case and stacks 2 more calls:
printf("%d\t", x);
fun(--x);
The last call is in tail position, so it does nothing, it modified a local variable that is not used any longer. So your function reduces to this:
void fun(int x)
{
if(x > 0)
{
fun(--x);
printf("%d\t", x);
}
}
As the other answers say, this function will stack some calls and I do not reproduce any more the stack that is present in the other answers.
Practically,
it calls itself for f(4),
then f(3),
then f(2),
then f(1),
then f(0) is the limit case,
then it returns to the stacked printf from f(1), and PRINTS 1,
then it returns to the stacked printf from f(2), and PRINTS 2,
then it returns to the stacked printf from f(3), and PRINTS 3,
then it returns to the stacked printf from f(4), and PRINTS 4.

Recursive function descending output

void prikaz(int k, int n)
{
printf("%d\t",k);
if(k<n)
prikaz(k+1,n);
printf("%d\t",k);
}
prikaz(2,6);
I cant wrap my head around the output of this recursive loop, i can follow through till numbers start to descend but i dont understand why they descend.
The reason is because of the last line in the function, which prints the value of k after the recursive call has returned/finished. This will print the value as it was before the +1, i.e. the original value before the call.
However, it only does that part after all the recursive calls are complete.
Basically, when k<n is no longer true, then it will start to do the last printf call, then return to the previous function call and do that ones last printf (which will be the value of k before it was incremented) and it will repeat until all previous calls are complete.
It's quite hard to explain, you just need to step through it more carefully. Using a debugger would help greatly.
Maybe this helps explain it better:
// call 1 (k = 2)
// call 1 print 2
// call 2 (k = 3)
// call 2 print 3
// call 3 (k = 4)
// call 3 print 4
// call 4 (k = 5)
// call 4 print 5
// call 5 (k = 6)
// call 5 print 6
// k<n is false, so no more recursive calls.
// call 5 print 6
// call 4 print 5
// call 3 print 4
// call 2 print 3
// call 1 print 2

C function output

Can anyone tell me the reason of getting 0 1 2 0 as output of below program?
#include <stdio.h>
main() {
e(3);
}
void e(int n) {
if(n>0) {
e(--n);
printf("%d",n);
e(--n);
}
}
Output is 0 1 2 0
Here' the flow of execution after e(3) is called from main.
e(3)
e(2)
e(1)
e(0) ... return
n is now 0
print n. results in output 0
e(-1) ... return
n is now 1
print n. results in output 1
e(0) ... return
n is now 2
print n. results in output 2
e(1)
e(0) ... return
n is now 0
print n. results in output 0
e(-1) ... return
return
And you see the output
0 1 2 0
I'm assuming the following is what you want:
#include <stdio.h>
void e(int);
int main()
{
e(3);
return 0;
}
void e(int n)
{
if(n > 0) {
e(--n);
printf("%d", n);
e(--n);
}
}
This is an example of a recursive function - a function calling itself. Here, at each call the parameter is decremented and the function is again called until the condition n > 0 is not met. Then, the printf("%d", 0) happens. Now the second e(--n) will have no effect until n is at least 2, since the if condition cannot be passed with a value of n less than 1. Further printf()s happen in the reverse order of the call as the function calls are removed from the stack. When the value gets to 2, the second e(--n) gets a chance to make an effect thus printing 0.
You need to learn about recursion (if you still haven't) and then you can get a good picture of how things happen. Also, it will help you if learn more about how the stack is set up when a function is called, and later returned.
The 'flow' goes as follows:
main -> e(3)
e(3) -> IF(3>0)
{
// n is pre-decremented to 2
e(2) -> IF(2>0)
{
// n is pre-decremented to 1
e(1) -> IF(1>0)
{
// n is pre-decremented to 0
e(0) -> 0 is not > 0 so this call does nothing.
// n is still 0 in this function call so...
printf(0) <-- The first '0' in the output
// n is pre-decremented to -1
e(-1) -> -1 is not > 0) so this call does nothing.
}
// n is still 1 in this function call so...
printf(1) <-- The '1' in the output
// n is pre-decremented to 0
e(0) -> 0 is not > 0 so this call does nothing
}
// n is still 2 in this function call so...
printf(2) <-- The '2' in the output
// n is pre-decremented to 1
e(1) -> (1 is > 0)
{
// n is pre-decremented to 0
e(0) -> 0 is not > 0 so this call does nothing
// n is still 0 in this function call so...
printf(0) <-- The second '0' in the output
// n is pre-decremented to -1
e(-1) -> -1 is not > 0 so this call does nothing
}
}
It helps if you set the code out more clearly:
#include<stdio.h>
main()
{
e(3);
}
void e(int n)
{
if(n>0)
{
e(--n); // First recursion here, but with n=n-1 on entry to the call.
printf("%d",n); // outputs (original value of n) - 1.
e(--n); // Second recursion here, now with n=n-2 on entry to the call.
}
}
After denesting the code the reason for the results can be deduced in a single run in a debugger.
e() is recursive and called once before the print and once after. So before you hit your print statement you'll have to go through e again, and again, and again till it finally hits 0.
After that things start unlooping and you'll see prints popping up but it's still a big recursive mess because of the second call to e(n) in which n dips into the negative. I was rather grateful n was signed because if it was unsigned it would loop round to 2^32 and the program would get stuck in, pretty much, an infinite loop.
So yeah, TL;DR: run it through a debugger and learn from the FUBAR a recursion like this can cause.

C compound conditional not working as expected (value mysteriously reassigned to other value) - possible gcc bug

I have a program that is stuck in a loop because of a possible bug in gcc. I have tested this on multiple versions of the compiler, and it seems to stick around. A mockup version of the bug is
#include <stdio.h>
#include <stdlib.h>
#define db printf("t=%d\n", t)
size_t t = 9;
int main(int argc, char** args) {
l: //label so we can repeat
t-(t^14) //works as expected if this line is changed to t-7, but t xor 14 = 7... this line is also executed ONCE
==2?db,t=1: //end of first conditional, next line starts the second
t==1?db,t=41: //buggy ONLY if t=40 or 41 on this and next line
t==41?db,t=0: //bug in this line (after this line executes, t = 1 no matter what)
t==0?exit(0): //terminates if not buggy
0;
goto l; //repeat
}
Please don't ask why I use this because it's for an obfuscated code contest, and I am using this particular method.
I would also like to know if this is even unexpected behavior, but I suspect it is.
Thanks
I re-wrote your expression with indenting and comments so that it can be traced.
t-(t^14)==2?
/*True */ db,t=1
/*else */ :
/*False*/ t==1?
/*True */ db,t=41
/*else */ :
/*False*/ t==41?
/*True */ db,t=0
/*else */ :
/*False*/ t==0?
/*True */ exit(0)
/*else */ :
/*False*/ 0;
Now a trace-through:
Pass #1
t = 9
t^14 = 7
t-7 == 9 - 7 == 2, therefore Condition 1 is True.
printf 9, t = 1, goto top.
Pass #2
t=1
t^14 = 15
t-15 = -14 != 2, therefore condition 1 is False.
Condition 2: t==1? TRUE,
printf 1, t = 41, goto top.
Pass #3
t = 41
t^14 = 39
41-39 = 2, therefore Condition 1 is true.
Printf 41, t = 1, goto top.
Because t is now back to value 1, we're back in the same scenario as Pass #2.
The cycle continually flips between Pass #2 and Pass #3. (t=1 and t=41).
An infinite loop is the proper outcome.
(You need to be a million times smarter before you honestly believe you found a compiler bug.)
The value of t printed alternates between 1 and 41, so when your program is unravelled it becomes quite obvious why exit(0) is never executed.
In the first iteration t==9 and t-(t^14)==2 so t becomes 1.
In the second iteration t==1 and t-(t^14)!=2 so t becomes 41.
In the third iteration t==41 and t-(t^14)==2 so t becomes 1.
Now repeat as second iteration.
#include <stdio.h>
#include <stdlib.h>
size_t t = 9;
int main(int argc, char** args) {
l: //label so we can repeat
if (t-(t^14) == 2) {
printf("t=%d\n", t);
t=1;
}
else if (t==1) {
printf("t=%d\n", t);
t=41;
}
else if (t==41) {
printf("t=%d\n", t);
t=0;
}
else if (t==0)
exit(0);
else
0;
goto l;
}

Recursive Confusion

Hello everyone I had a tough time understanding recursive function calls and just when I thought I have understood them, I saw a question which made me realized that I am wrong
I am not able to understand the flow of the program
#include <stdio.h>
void fun(int n)
{
if(n>0)
{
fun(--n);
printf("%d\n",n);
fun(--n);
}
}
int main(void) {
int a;
a=3;
fun(a);
return 0;
}
This is the function call for your function when n = 3
f(3)
.f(2) [1]
..f(1) [1]
...f(0) [1]
...Print 0
...f(-1) [2]
..Print 1
..f(0) [2]
.Print 2
.f(1) [2]
..f(0) [1]
..Print 0
..f(-1)[2]
Where . represent the depth of stack and 1 and 2 specify whether its first recursive call from the loop or second.
Because
f(3)
becomes
f(2)
print 2
f(1)
which inturn becomes
f(1)
print 1
f(0)
print 2
f(0)
print 0
f(-1)
Which finally becomes
f(0)
print 0
f(-1)
print 1
f(0)
print 2
f(0)
print 0
f(-1)
Removing all the f(n) when n <= 0
print 0
print 1
print 2
print 0
Let's try to understand it with case n=2 and then you should be able to generalize.
fun (2):
What happens inside (flow):
1) n=2: if(n>0) is true and fun(--n) is called with n set to value 1 due to --; (see step below).
2) n=1: Now n=1: again if(n>0) is true and fun(--n) is called with n=0. See step below.
3) n=0: Now n=0; if(n>0) is false, so we return.
I think here is your confusion. From step 3 you are thrown back
at step 2 (not step 1). You are thrown actually in step 2 after fun(--n) call - so printf is called with value of n=0, due to decrement.
Then again in same place (after printf) fun(--n) is called with value n=-1 however, which will also exit - and eventually you will be thrown at the beginning.
I would draw a "call tree" to help visualize the program.
The function has those parts
decrement n, call, print, decrement n, call
now you can draw this:
0 -1
1->0, print 0, 0->-1, 0
2->1, print 1, 1->0, 1->0, .....
3->2, print 2, 2->1, .....
Start at the bottom left, and go up one line for each call. The program executes from left to right, and you can clearly see the order of the numbers printed.
Here is what happens (pseudocode):
n = 3
fun(3);
n = 2
fun(2); // first fun(--n)
n = 1
fun(1); // first fun(--n)
n = 0
fun(0); // first fun(--n)
return;
print 0
n = -1
fun(-1); // second fun(--n)
return;
return;
print 1
n = 0
fun(0); // second fun(--n)
return;
return;
print 2
n = 1
fun(1); // second fun(--n)
n = 0
fun(0); // first fun(--n)
return;
print 0
n = -1
fun(-1); // second fun(--n)
return;
return;
return;
return;
I believe the cause of confusion is your assumption that the same "n" is used by every call to the function fun(). In fact, that's not the case, since in the C language, argument are passed by value. That is, when fun(3) calls fun(2), a new n is created - specific to one instance of fun(2). Thus after the call to fun(3) within fun(2), the value of n is 2, not or -1.
You should therefore expect...
fun(1) to print 0
fun(2) to print 1
fun(3) to print 2
fun(1) (called from the second call to fun(2)) to print 0
and that's it.
The output of the program can be understood by iteratively expanding the function calls and removing the conditions; in a pseudocode-manner, this can be done as follows.
fun(3)
Can be expanded to the following.
if(3>0)
{
fun(2);
printf("%d\n",2);
fun(1);
}
In the follwing steps, the if condition is omitted if it will evaluate to false.
fun(1);
printf("%d\n",1);
fun(0);
printf("%d\n",2);
fun(0);
printf("%d\n",0);
fun(-1);
The calls to fun with non-positive arguments can be omitted as they will generate no output.
fun(1);
printf("%d\n",1);
printf("%d\n",2);
printf("%d\n",0);
Further expansion yields the following sequence.
fun(0);
printf("%d\n",0);
fun(-1);
printf("%d\n",1);
printf("%d\n",2);
printf("%d\n",0);
This can be again reduced to the following sequence.
printf("%d\n",0);
printf("%d\n",1);
printf("%d\n",2);
printf("%d\n",0);
So in total, the output will be as follows.
0
1
2
0
I hope this answers your question; however, it does not provide an intuitive way of describing the generated output.
To understand the recursive flow you can instrument your code with few printfs like below. This will show the sequence of flow of function using indentation.
#include <stdio.h>
void printSpace(int num)
{
while(num > 0)
{
printf(" ");
num--;
}
}
int NumSpace = 0;
void fun(int n)
{
printSpace(NumSpace);
printf("fun(%d)\n", n);
NumSpace += 4;
if(n>0)
{
fun(--n);
printSpace(NumSpace);
printf("%d\n",n);
fun(--n);
}
NumSpace -= 4;
}
int main(void) {
int a;
a=3;
fun(a);
return 0;
}
Result:
fun(3)
fun(2)
fun(1)
fun(0)
0
fun(-1)
1
fun(0)
2
fun(1)
fun(0)
0
fun(-1)
Hope this helps.

Resources