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.
Related
can someone explain me this code?
I cant understand why printed value is 8 in this code
can someone explain it to me
#include <stdio.h>
int f(int i){
switch (i){
case 0 :
return 0;
case 1:
case 2:
return 1;
default:
return f(i-2)+f(i-1);
}
}
void main(void) {
printf("%d", f(6));
}
Maybe you just need to step through the code in a debug run, but this is why you have f(6)=8
step1: f(6)
step2: f(6-2) +f(6-1)
step3: f(4-2)+f(4-1) +f(5-2) +f(5-1)
step4: f(2) +f(3-2)+f(3-1)+f(3-2)+f(3-1)+f(4-2)+f(4-1)
step5: 1 +1 +1 +1 +1 +1 +f(3-2)+f(3-1)
step6: 1 +1 +1 +1 +1 +1 +1 +1
final: 8
This is a recursive function to implement the Fibonacci sequence
Lets consider a simpler scenario (in order to shorten response length) of if we were to call the function with argument of 4 : f(4)
Stepping through it we find:
Called f(4)
Hit default case statement to call f(2) + f(3)
The f(2) call will hit the case statement for 2 and return 1
The f(3) call will hit the default case statement and call f(1) + f(2)
Both f(1) and f(2) will hit their respective case statements and return 1
We now know the f(3) call returns f(1) + f(2) = 1 + 1 = 2
We now know the f(4) call returns f(2) + f(3) = 1 + 2 = 3
I would recommend the same process to see why a call of f(5) would return 5. And then using the fact that f(4) = 3 and f(5) = 5, you can understand why f(6) = f(4) + f(5) = 8.
This is a recursive implementation the Fibonacci sequence, where each number is the sum of the two preceding numbers.
The switch statement works as follows:
If i is 0, return 0
If i is 1 or 2, return 1
Otherwise, return the sum of f(i-2) and f(i-1) - this eventually boils down to the two base cases above.
This is a recursive function which contains a switch case. Generally, in a Switch case, you need a statement breaker like break or return so that only that specific case executes correctly. Since in your code case 1 and case 2 return to same value ie 1 your code breaks down as a sum of 8 1s and final sum is 8.
I'm solving a factorial problem where the function takes a number and returns the factorial of that number.
The problem I'm running into is that the code works but I don't know why. There are no loops to call it back after the code is executed and I'm not even sure where the current value is being stored.If I am correct the I assume the function is re-running every time it hit the return and it is running with a value of n-1 so one number less than the previous time it ran, however, I still do not see how the value is getting stored to multiple each number by the current value. Even if I log the current value of n after every run all I get is the numbers 10 down to one. I would think the current value would change to the multiplied value.
Again this code works perfectly I just need to understand why.
function factorial(n) {
if (n === 0) {
return 1;
}
console.log(n);
return n * factorial(n - 1);
}
factorial(10);
What you have here is a recursive function - a function which calls itself. You also need to keep in mind the "scope" of the variables in the function.
The scope of the parameter "n" is local to the function. Every time the function is called, the new variable is created. The scope of each variable is the function execution.
1: function factorial(n) {
2: if (n === 0) {
3: return 1;
4: }
5: console.log(n);
6: return n * factorial(n - 1);
7: }
Example:
Parameter Value = 0
Hence, n = 0
Execute factorial(0)
1. line 1: variable n = 0
2. line 2: check if n = 0
3. line 3: return 1
Example:
Parameter Value = 2
Hence, n = 2
Execute factorial(2)
1. line 1: variable n = 2 (scope = execution #A)
2. line 5: console log n = 2
3. line 6: return 2 * factorial(2-1) // Function calls itself
4. line 1: variable n = 1 (scope = execution #B)
5. line 5: console log n = 1
6. line 6: return 1 * factorial(1-1) // Function calls itself
7. line 1: variable n = 0 (scope = execution #C)
8. line 3: return 1 // #C returns 1
9. return 1 * 1 // #B returns 1 * 1 (from #C)
10. return 2 * 1 // #A returns 2 * 1 (from #B)
I am trying to essentially pipe a .txt ascii file into a program. My program needs to be able read the lines upon lines of ascii code and then output what it reads into a file. At which point i will compare the file I just filled with ascii to another file which has the correct output of the file already using the diff command. I am really new to C (it's my third week, with once a week lab instruction time with my prof), and I feel I'm quite close to figuring this out, but i feel the nesting of my loops is off.
The three files I'm dealing with:
encoded_picture.txt
decoded_picture.txt
ascii_cat.txt
eg (encoded_picture.txt) Using less
29: 1. 1 4. 36: 1. 1 4. 3 2. 1: 1. 5 1. 1: 1. 8: -1?
30: 2. 39: 1. 1 3. 3 4. 7 1. 6: 2. 1: -1?
12: 1. 58: 6. 2 2. 9 1. 6: 2. 1: -1?
12: 2. 57: 1. 1 3. 1 3. 11 1. 8: -1?
12: 3 1. 55: 2. 2 1. 1 2. 12 1. 8: -1?
12: 1. 3 1. 53: 1. 1 1. 1 4. 13 1. 8: -1?
12: 1. 5 51: 8. 15 8: -1?
13: 1. 1 2. 2 1. 49: 7. 5 2. 9 8: -1?
14: 2 2. 2 1. 48: 6. 6 3. 2 1. 5 8: -1?
14: 1. 2 2. 3 1. 45: 6. 8 3. 1 2. 4 8: -1?
15: 1. 1 3. 3 1. 44: 5. 7 2. 1 6. 2 1. 8: -1?
16: 1 4. 4 1. 41: 5. 5 6. 1 5. 2 1. 8: -1?
16: 6. 5 1. 38: 6. 3 8. 1 5. 2 1. 8: -1?
17: 6. 5 2. 35: 6. 3 9. 1 5. 2 1. 8: -1?
17: 7. 6 2. 32: 6. 5 8. 1 5. 2 1. 8: -1?
18: 7. 7 1. 30: 6. 5 7. 1: 1. 1 3. 1 1. 2 1. 8: -1?
eg. (decoded_picture.txt)
::::::::::::::::::::::::::::::.. .....:::::::::::::::::::::::::::::::::::::.. ..... ...::.. ..::..:::::::::
:::::::::::::::::::::::::::::::...::::::::::::::::::::::::::::::::::::::::.. .... ..... ..:::::::...::
:::::::::::::..:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::....... ... ..:::::::...::
:::::::::::::...::::::::::::::::::::::::::::::::::::::::::::::::::::::::::.. .... .... ..:::::::::
::::::::::::: ..::::::::::::::::::::::::::::::::::::::::::::::::::::::::... .. ... ..:::::::::
:::::::::::::.. ..::::::::::::::::::::::::::::::::::::::::::::::::::::::.. .. ..... ..:::::::::
:::::::::::::.. ::::::::::::::::::::::::::::::::::::::::::::::::::::......... :::::::::
::::::::::::::.. ... ..::::::::::::::::::::::::::::::::::::::::::::::::::........ ... :::::::::
::::::::::::::: ... ..:::::::::::::::::::::::::::::::::::::::::::::::::....... .... .. :::::::::
:::::::::::::::.. ... ..::::::::::::::::::::::::::::::::::::::::::::::....... .... ... :::::::::
::::::::::::::::.. .... ..:::::::::::::::::::::::::::::::::::::::::::::...... ... ....... ..:::::::::
::::::::::::::::: ..... ..::::::::::::::::::::::::::::::::::::::::::...... ....... ...... ..:::::::::
:::::::::::::::::....... ..:::::::::::::::::::::::::::::::::::::::....... ......... ...... ..:::::::::
::::::::::::::::::....... ...::::::::::::::::::::::::::::::::::::....... .......... ...... ..:::::::::
::::::::::::::::::........ ...:::::::::::::::::::::::::::::::::....... ......... ...... ..:::::::::
:::::::::::::::::::........ ..:::::::::::::::::::::::::::::::....... ........::.. .... .. ..:::::::::
:::::::::::::::::::.......... ..::::::::::::oooo:::::::ooo:::ooo:::...... .........::: .. .. ..:::::::::
::::::::::::::::::::......... ...::::::oooooOO&&OOooooOOooOOOOOOOOoo::..... ..........::.. .. ..:::::::::
::::::::::::::::::::..::::..::..... ...::::ooOO&&OOO&&&&OOOO&&&&&&&OOOOOooo::.. ...........::.. ..::..::..::::::
:::::::::::::::::::::::::::..::.... ....::oooOO&&&&&&&&&&&&&&&&OOOOooo::oo:: ....:::........ ..:::::..:::::
:::::::::::::::::::::::::::::::... ::::oooOO&&&&OO&&&&&&&&&&&&OOOOOoo::... ...:::::::..... ..:::::::..:::
:::::::::::::::::::::::::::::::::....::oooOOOO&&&&OO&&&&&&OO&&&&&OO&&OOOOooo::::.. ........::::.... ..::::::::..::
::::::::::::::::::::::::::oooo::::::ooooOOOO&&&&OOOOO&&&&&OO&&&&OOO&&&OOOoooooo:::.. .... .......:::... ::..::::::..::..
:::::::::::::::::::::::ooo:::::::::oooOOOOOO&&&&OOOOO&&&&&OO&&&&OOOO&&OOOOOoooo:::..:::.. ....::... .. ..:::...:::::..::
:::::::::::::::::::::ooo::::::::ooooOOoooOOOO&&&&&OOOOO&&&&&&&OO&&OOooOOOOOOOOOooo::ooo..... ... ..::.....:::....
:::::::::::::::::::::ooo::::::oo::ooOOOOOOOO&&OO&&OOOOoooOO&&&&OO&&OOO&&OOooOOOOOOOOOooooo:::::........... .....::.......
:::::::::::::::::::::oo::..::...::ooOOOOO&&&OO&&OO&&OO&&OOOOOOO&&&&OOOOOOOoooOOOOOOOOOOOoo::ooo::::... ..... ..::...........
:::::::::::::::::::::::....::oooOO&&&&&&&&OO&&OOOOOOoooOOOOOooOOOOOOooooOOOOOOOOOOoooooo::..... .. ..::......:::....
::::::::::::::::::::::...:::ooOOOO&&&&&&OOOOOOOOOOoooOOOOOooooOOoooooooOOOOOOOOOOoooooo:::.... .. ....::..::::::::
::::::::::::::::::::::....::OOO&&&&&&&&OOOOOOOOOoooo&&OOOoooooooooooooooOOooooOOOOoooooo::.... .... ...::....::::::::
:::::::::::::::::::::... ..::oo&&&&&&&OOOOOooOOOoooooooOOOOooooooo:::oooooooooooOOOOooOOoooo:::::.. ..::::...::::::::
::::::::::::::::::::::....::ooOO&&&&OOOOOOOooOOooooooooooOOoo::oo:::oo:::ooooooooooooOOoooOOoooooooo.. ..::::::..:::::::
::::::::::::::::::::::....::OOO&&&OOOOOOooOOoooo::ooooo::ooOOoooo:::::::::oooo::ooooooOOOOOOooooooo.. ..:::::...:::::::
::::::::::::::::::::::.. ...ooOOOOOOOoooooo::::oooo::..ooOOoooo::..:::::::::::oooooooOOOOOOOoooo::.. :::::::..:::::::
:::::::::::::::::::::::...::OOOOooooooooo:::..::ooo:::..::OOooo:::..:::::...:::::oooooooooOOooooooo::.. ..:::::::::::::..
:::::::::::::::::::::::::ooOOOoooooo:::ooo::...::oo::::..ooOOooo::....:::....::::::::ooooooooooooo:::.. ..::::::::.....:::
::::::::::::::::::::::::oooooooooo:::::....:::::...ooooo.....::::....::::..:::oooooooooooooo::.. ..::::::::::::oo:::
::::::::::::::::::::::::oooo:::ooooo::::.....:::::..::ooooOO::........ ...::...:::ooooooooooooo::.. ..::::::::ooo::oo::::
:::::::::::::::::::::::oooo:::::::::::.. :::::..::OO:::OO::........ .....:::::oooooooooooo:: ..::::::::oo::::::oo
::::::::::::::::::::::oooo::::::::::::.. ....::...OOoo:::OOoo..::.... .....:::::::::oooooooo::.. :::::::::oo::::::oo
:::::::::::::::::::ooooooo:::..::::::..::..........::OOoo:::OOO::..... ......:::::::::::oooooo::.. :::..:::...::::::...::
:::::::::::oo::::::::oooooo::....::..::oo:: ..........ooOOooooOOO:: ... .....:::::::..::::ooooooo::.. ..::..:::...::::::.. ..
::::::::::oooo::::::oooOOOOoo....:::..::oo.. :::......::OOOoooOO&&OO:: ....:::::.....::oooooooo::.. ...:::...:::::.....
::::::::ooooo:::::::ooOOOOoo::....:::..ooo.. ::&&oo.....::OOOooOO&&&OO:: ........ ...:::ooooooo::.. ....::...::..::::::..
::::::ooooooo::::::ooOOOOOoo::....::...:::.. ::&&oo.....::OO&&OO&&&&OO.. .. ..oo:: ... ..::::oooooo::......::...:::ooo::::..
::::::ooooo:::::::OOOOOOOoo::::..::: ... ..oo&&:::....::OO&&&&&OOoo.. ... ..::: .... ..::::ooooo:::::...ooo::ooo:::.....
:::::ooooo:::::::ooOOOOOOOoo:::::::..... ::&&OO..::.. ..::OO&&&&OOoo::.. .... ..::...........:::ooooooo::oo:::ooo:::........
::::ooooo:::::::ooOOOOOOOOOoo:::..:::.. ....::oo.......OO&&&&&OOoo::.. ..::.. .............::::oooooooooo::...........
:::oooooooooo::oooOOOOOOOOOoo::........ ......::...::oo&&&&&&OOO::.. ....::: ... ...........:::ooooooooo::...... .....
:::oooOOooooo::::ooOOOOOOOOOOoo::......:::...:::...::...ooOO&&&&&&OOOoo::.. ....::::.. ... ...........:::::ooooooo:::...... ......
::oooooo::::...::OOOOOOOOOOOoo::......:::::........ooOO&&&&OOOOOoo::.. .....::..... ..........::::::oooooo:::..... .......
ESC
At this point in the command line i would compile and then:
./a.out < encoded_picture.txt > decoded_picture.txt
And then to compare to see if it work:
diff decoded_picture.txt ascii_cat.txt
At this point i know that if diff displays an output, I've done it wrong.
Any help would be appreciated (actual program part3_file.c).
int length;
int i;
// loop until the end of input sentinel is seen
while (1)
{
// get the first element in the line
scanf("%d%c", &length, &character);
if(length == -1)
{
break;
}
else
{
// is it the sentinel? if so, then break out of the loop
// reconstruct a line, as per part 2
while ( length != -1 )
{
for( i = 0; i<= length; i++)
{
printf("%c", character);
}
scanf("%d%c", &length, &character);
}
printf("\n");
}
}
return 0;
If I understand your question and you want to read encoded_picture.txt from stdin and then based on each encoded pair 'lc' (that's l as in length and c as in character) output l number of characters c to stdout until length is -1 where a '\n' is output, then you are on the right track. However your loop logic is a bit strange.
You can use your scanf format string "%d%c". However, you always, always want to check the return of scanf to validate the expected number of conversions took place. For example, to read each pair until end of file is encountered you can do something like the following:
while (scanf ("%d%c", &l, &c) == 2) {
Your next task, to repeatedly output the specified number of characters, you can simply do:
for (int i = 0; i < l; i++)
printf ("%c", c);
(if l == -1 the loop will not execute anyway, also note: the loop is i < l for l characters, where i <= l would result in l+1 chars)
Your final task is to control the output of the newline in the event l == -1,
if (l == -1)
putchar ('\n');
Putting it together, you could do something like:
#include <stdio.h>
int main (void) {
int l;
char c;
while (scanf ("%d%c", &l, &c) == 2) {
for (int i = 0; i < l; i++)
printf ("%c", c);
if (l == -1)
putchar ('\n');
}
return 0;
}
Example Use/Output
Based on the encoded_picture.txt text you provided, that would result in something like the following (that looks like the start of Ratchet's ears):
$ ./bin/decodpic <dat/encpic.txt
:::::::::::::::::::::::::::::. ....::::::::::::::::::::::::::::::::::::. .... ..:. .:.::::::::
::::::::::::::::::::::::::::::..:::::::::::::::::::::::::::::::::::::::. ... .... .::::::..:
::::::::::::.::::::::::::::::::::::::::::::::::::::::::::::::::::::::::...... .. .::::::..:
::::::::::::..:::::::::::::::::::::::::::::::::::::::::::::::::::::::::. ... ... .::::::::
:::::::::::: .:::::::::::::::::::::::::::::::::::::::::::::::::::::::.. . .. .::::::::
::::::::::::. .:::::::::::::::::::::::::::::::::::::::::::::::::::::. . .... .::::::::
::::::::::::. :::::::::::::::::::::::::::::::::::::::::::::::::::........ ::::::::
:::::::::::::. .. .:::::::::::::::::::::::::::::::::::::::::::::::::....... .. ::::::::
:::::::::::::: .. .::::::::::::::::::::::::::::::::::::::::::::::::...... ... . ::::::::
::::::::::::::. .. .:::::::::::::::::::::::::::::::::::::::::::::...... ... .. ::::::::
:::::::::::::::. ... .::::::::::::::::::::::::::::::::::::::::::::..... .. ...... .::::::::
:::::::::::::::: .... .:::::::::::::::::::::::::::::::::::::::::..... ...... ..... .::::::::
::::::::::::::::...... .::::::::::::::::::::::::::::::::::::::...... ........ ..... .::::::::
:::::::::::::::::...... ..:::::::::::::::::::::::::::::::::::...... ......... ..... .::::::::
:::::::::::::::::....... ..::::::::::::::::::::::::::::::::...... ........ ..... .::::::::
::::::::::::::::::....... .::::::::::::::::::::::::::::::...... .......:. ... . .::::::::
Look things over and let me know if I misunderstood or if you have questions.
Writing Output WITHOUT a final POSIX line-end
While this is improper, the decoded_picture.txt does not contain a POSIX line-end. If you run the first version of my code, and then use diff -uNb decoded_picture.txt the_output.txt you find the only difference is my code properly includes a POSIX line-end (e.g. '\n') after the final line written. You can dupe the code into not writing a POSIX line-end by setting a toggle to only write the newline if characters were previously written in that line. That effectively prevent a final newline. You can do that as follows:
#include <stdio.h>
int main (void) {
int l, flag = 1;
char c;
while (scanf ("%d%c", &l, &c) == 2) {
for (int i = 0; i < l; i++)
printf ("%c", c);
if (l == -1) {
if (flag) {
putchar ('\n');
flag = 0;
}
}
else
flag = 1;
}
return 0;
}
Result
Then testing the code and output, you find the following:
$ gcc -Wall -Wextra -pedantic -std=gnu11 -Ofast -o bin/decodpic2 decodpic2.c
$ ./bin/decodpic2 <dat/encoded_picture.txt > dat/decode2.txt
$ diff -uNb dat/decoded_picture.txt dat/decode2.txt
(no output, the files match :)
While there is educational use in forcing a final write without a POSIX line-end -- do not do this is real life :)
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.
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.