| | |
changing loops (for to while) and (recursive to for)
![]() |
Okay. Generally speaking, tail recursion (where the last thing to be executed is the recursive call) can be optimized to some kind of loop. Not necessarily a "for" loop. Here's a step by step process for doing it. We'll use the GCD example that lies in another thread. The greatest common divisor function, when defined recursively, looks like this:
Now, the recursive call, gcd(y, x % y), can be interpreted as "Go back to the beginning of the function, with the new values for x and y being y and x%y, respectively."
So now we code that manually:
And the recursion has now been replaced by a loop. Further optimization can be done. For instance, if you carefully assign in the right order, only one temporary parameter holder is necessary.
It's not hard to see that this could be written as a while loop, which runs until y == 0:
Sometimes, you can't easily get rid of the goto (and then it's not worth eliminating the goto. But if we're going to talk about what is readable programming or not, we might as well leave in the tail-recursion and trust the compiler to optimize it away).
Now you can try to figure out on your own how to convert a loop to recursive form. It is similar to the reverse of this process.
C Syntax (Toggle Plain Text)
int gcd(int x, int y) { if (y == 0) { return x; } return gcd(y, x % y); }
Now, the recursive call, gcd(y, x % y), can be interpreted as "Go back to the beginning of the function, with the new values for x and y being y and x%y, respectively."
So now we code that manually:
C Syntax (Toggle Plain Text)
int gcd(int x, int y) { top: /* A label, used by the goto. */ if (y == 0) { return x; } int param_1 = y; /* First assign to temporary variables */ int param_2 = x % y; int x = param_1; /* Then set your 'new' values for x and y. */ int y = param_2; goto top; /* Goto the top of the function. */ }
And the recursion has now been replaced by a loop. Further optimization can be done. For instance, if you carefully assign in the right order, only one temporary parameter holder is necessary.
C Syntax (Toggle Plain Text)
int gcd(int x, int y) { top: if (y == 0) { return x; } int tmp = x; x = y; y = tmp % y; goto top; }
It's not hard to see that this could be written as a while loop, which runs until y == 0:
C Syntax (Toggle Plain Text)
int gcd(int x, int y) { while (y) { int tmp = x; x = y; y = tmp % y; } return x; }
Sometimes, you can't easily get rid of the goto (and then it's not worth eliminating the goto. But if we're going to talk about what is readable programming or not, we might as well leave in the tail-recursion and trust the compiler to optimize it away).
Now you can try to figure out on your own how to convert a loop to recursive form. It is similar to the reverse of this process.
![]() |
Similar Threads
- Please Help (C++)
- Recursion II (C++)
- Loops in Python (Python)
- Recursive prime number f(x) (C)
Other Threads in the C Forum
- Previous Thread: converting to strings..
- Next Thread: locking folder
| Thread Tools | Search this Thread |
#include adobe ansi api array asterisks binarysearch changingto char character cm copyimagefile cprogramme creafecopyofanytypeoffileinc createcopyoffile csyntax database directory dynamic execv feet fgets file fork forloop frequency function getlasterror givemetehcodez global grade graphics gtkgcurlcompiling hacking hardware highest histogram i/o include incrementoperators infiniteloop input interest kernel keyboard kilometer license linked linkedlist linux linuxsegmentationfault list locate logical_drives looping loopinsideloop. lowest match matrix meter microsoft motherboard mqqueue mysql number odf opensource owf pattern pdf performance pointer posix probleminc process program programming radix recursion recv repetition research reversing scanf segmentationfault sequential shape socket socketprograming standard string systemcall threads turboc unix user voidmain() wab windows.h windowsapi






