2

I'm trying to understand how recursion works in C. Can anyone give me an explanation of the control flow?

#include <stdio.h> /* printd: print n in decimal */ void printd(int n) { if (n < 0) { putchar('-'); n = -n; } if (n / 10) printd(n / 10); putchar(n % 10 + '0'); } int main() { printd(123); return 0; } 
5
  • 1
    Did you mean "recursion"? Commented Mar 30, 2011 at 22:43
  • 1
    Additionally, run it through a debugger and you'll see for yourself. Commented Mar 30, 2011 at 22:43
  • What exactly are you looking for? Assembly? Commented Mar 30, 2011 at 22:45
  • 4
    To understand recursion you must first understand recursion Commented Mar 30, 2011 at 22:47
  • 3
    To understand recursion, see related post. Commented Mar 30, 2011 at 23:25

7 Answers 7

18

The control flow looks like this (where -> is a function call)

main() └─> printd(123) ├─> printd(12) │ ├─> printd(1) │ │ └─> putchar('1') │ └─> putchar('2') └─> putchar('3') 
Sign up to request clarification or add additional context in comments.

2 Comments

@Carl: straight into the browser... the legacy of a youth partially misspent in 80x25 text mode.
shucks, I was hoping for a nifty code analysis tool to learn more about... ;-)
1
Call printd(123) (123 / 10) != 0, so Call printd(12) (12 / 10) != 0, so Call printd(1) (1 / 10) == 0, so Call putchar "1" Call putchar "2" Call putchar "3" return 0 (from main()) 

Comments

1

To understand recursion, you need to understand the storage model. Though there are several variations, basically "automatic" storage, the storage used to contain automatic variables, parameters, compiler temps, and call/return information, is arranged as a "stack". This is a storage structure starting at some location in process storage and "growing" either "up" (increasing addresses) or "down" (decreasing addresses) as procedures are called.

One might start out with a couple of variables:

00 -- Variable A -- 27 01 -- Variable B -- 45 

Then we decide to call procedure X, so we generate a parameter of A+B:

02 -- Parameter -- 72 

We need to save the location where we want control to return. Say instruction 104 is the call, so we'll make 105 the return address:

03 -- Return address -- 105 

We also need to save the size of the above "stack frame" -- four words, 5 with the frame size itself:

04 -- Frame size -- 5 

Now we begin executing in X. It needs a variable C:

05 -- Variable C -- 123 

And it needs to reference the parameter. But how does it do that? Well, on entry a stack pointer was set to point at the "bottom" of X's "stack frame". We could make the "bottom" be any of several places, but let's make it the first variable in X's frame.

05 -- Variable C -- 123 <=== (Stack frame pointer = 5) 

But we still need to reference the parameter. We know that "below" our frame (where the stack frame pointer is pointing) are (in decreasing address order) the frame size, return address, and then our parameter. So if we subtract 3 (for those 3 values) from 5 we get 2, which is the location of the parameter.

Note that at this point we don't really care if our frame pointer is 5 or 55555 -- we just subtract to reference parameters, add to reference our local variables. If we want to make a call we "stack" parameters, return address, and frame size, as we did with the first call. We could make call after call after call and just continue "pushing" stack frames.

To return we, load the frame size and the return address into registers. Subtract frame size from the stack frame pointer and put the return address into the instruction counter and we're back in the calling procedure.

Now this is an over-simplification, and there are numerous different ways to handle the stack frame pointer, parameter passing, and keeping track of frame size. But the basics apply regardless.

Comments

0

You have recursion in C (or any other programming language) by breaking a problem into 2 smaller problems.

Your example: print a number can be broken in these 2 parts

  1. print the first part if it exists
  2. print the last digit

To print "123", the simpler problems are then to print "12" (12 is 123 / 10) and to print "3".
To print "12", the simpler problems are then to print "1" (1 is 12 / 10) and to print "2".
To print "1", ... just print "1".

Comments

0
#include <stdio.h> #define putd(d) (printf("%d", d)) #define RECURSIVE void rprint(int n) { #ifndef RECURSIVE int i = n < 0 ? -n : n; for (; i / 10; i /= 10) putd(i % 10); putd(i % 10); if (n < 0) putchar('-'); /* Don't forget to reverse :D */ #else if (n < 0) { n = -n; putchar('-'); } int i = n / 10; if (i) rprint(i); putd(n % 10); #endif } int main() { rprint(-321); return 0; } 

Comments

0

Recursion works on stack i.e, first in last out.

Recursion is a process of calling itself with different parameters until a base condition is achieved. Stack overflow occurs when too many recursive calls are performed.

Comments

-1

Code:

main() {print f ("stat"); main(); print f ("end") ; } 

Code:

main() {int n, res; pf("enter n value"); sf("%d",&n); =fact(n); } int fact(int n) {int res; if(n==0) { res=1; } else { res = n*fact (n-1); } return res; } 

1 Comment

Please explain your implementation so that the user gets the correct answer to his question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.