Stacks and Recursion in C - c

#include <stdio.h>
void fun(int a) {
if (a > 0) {
fun(a / 10);
printf("%d", a % 10);
fun(a / 10);
}
}
int main() {
fun(12345);
return 0;
}
Here, as the function is calling itself at the start of the if block, shouldn't it print nothing, it will keep calling itself until the function argument becomes zero?
But instead, the output is 1213121412131215121312141213121

shouldn't it print nothing, it will keep calling itself until the
function argument becomes zero?
If I have understood correctly then you are right. The function will not output anything until a is equal to 0.
void fun(int a){
if(a > 0){
fun(a/10); // calls itself.
printf("%d",a % 10);
//...
Thus for this number 12345 the first output will be the most significant digit 1.
As the function calls itself twice
void fun(int a){
if(a > 0){
fun(a/10);
printf("%d",a % 10);
fun(a/10);
}
}
then for each digit of the number except the most significant digit the previous and next digits will be outputted twice on the left and on the right sides. For example
1 2 1
1 2 1 3 1 2 1
1 2 1 3 1 2 1 4 1 2 1 3 1 2 1
and so on.
I used embedded spaces for make the output more clear.

After the inner most function of the recursion has been finished (a>0) is evaluating to false it will execute the print statement and returns to the calling function.
The caller will print it's a%10 value and so on.
Not sure why you call fun(a/10) twice but this is why the output is printed twice.

Yuo do not need the second call
void fun(int a)
{
if(a)
{
fun(a/10);
printf("%d", a % 10);
}
}
https://godbolt.org/z/zWf64jjWe
Remember that it will not work for negative numbers.

The function attempts to print the decimal conversion of a but the second recursive call produces extra output.
The function will indeed produce no output for values below 10, which might not be the expected behavior. Without the second recursive call the output would be 1234.
You should use this instead:
void fun(int a) {
if (a >= 10)
fun(a / 10);
printf("%d", a % 10);
}
Note however that the above function only works for positive values.

You can implement this is 3 different ways:
Either make the recursive call before you start printing. If so the printing starts from the deepest level of recursion. This is very inefficient but ensures that you get the expected order 1,2,3... Generally, a recursive function that doesn't have the recursive call at the very end is an incorrect solution to any problem.
Or make the recursive calls after you print. This would lead to everything getting printed backwards as you've currently written the function. However, a recursive function with the call at the end, so-called "tail call", can sometimes get optimized into nearly as efficient code as a loop. You could probably do this here too, if you come up with a different algorithm.
Or you can implement it as a loop. Super-fast, super-readable, no risk of excessive stacking, no overhead. This is the correct solution in some 99% of all cases and the correct solution in 100% of all cases a beginner might be facing.

Related

How does this Decimal to Binary conversion program work?

I was looking for an easy program for the decimal to binary conversion and then, came across the following program using recursion.
void bin(unsigned n)
{
/* step 1 */
if (n > 1)
bin(n/2);
/* step 2 */
printf("%d", n % 2);
}
int main(void)
{
bin(4);
return 0;
}
The output of this program was 100 as expected. But, I'm unable to understand how does it show the output 100 because according to me, the output should be 1 (incorrect) instead of 100.
Here is my interpretation of steps of the bin function.
We will put 4 as an argument of bin first.
4 > 1, therefore, it will again call the bin function with the argument 2.
Now, 2 > 1, therefore, it will again call the bin function with the argument 1.
Since 1 is not greater than 1, we will go to step 2 and the compiler will print 1 (since 1%2=1) and hence, this program should print 1 only and not 100.
Can anyone please explain and guide me where I am wrong?
Perhaps the illustrated sequence will make it easier for you to understand:
bin(4)
bin(2)
bin(1)
printf("%d",1%2); // 1
printf("%d",2%2); // 0
printf("%d",4%2); // 0
You are on the right track,
We will put 4 as an argument of bin first.
bin(4): 4 > 1, therefore, it will again call the bin function with the argument 2. Function execution is not complete yet. Program will return here once the called function is executed
bin(2): Now, 2 > 1, therefore, it will again call the bin function with the argument 1. Function execution is not complete yet. Program will return here once the called function is executed
bin(1): Since 1 is not greater than 1, we will go to step 2 and the compiler will print 1 (since 1%2=1) and hence, this program should print "1". Fcuntion execution complete
bin(2): program now returns to the caller function and prints 0(since 2%2=0). function execution complete
bin(4): program now returns to the caller function and prints 0(since 2%2=0). function execution complete
Hence the ouput is '100'
Dividing an integer by 2 is the same as shifting it right one bit. So using recursion, it shifts the bits to the right until only 1 bit is left (the leftmost bit)
Then it prints this leftmost bit and returns. Upon return, there are still two bits, the leftmost and one-before-leftmost. With the % 2 it discards all leftmost bits and prints this one-before-leftmost. Now it returns and... etc.
This effectively prints the bits left-to-right.
With your logic:
somefunc();
someotherfunc();
When somefunc() is finished doing it's thing, someotherfunc() will not be executed since somefunc() was done.
What happens is that step 2 is done when the call to bin is done or not run at all and then step 2 is always done. Thus Every iteration of bin prints something and since it's after the recursion it does it from the deepest and and up making the printing in reverse order from the actual recursive path.
Every call to binhas it's own local variables so they don't interfere with each other. Thus when the call to bin from bin is done n is the same as before but the returning bin had a n that was half of the caller's n.

C program for calculating factorial

i have written a small function which calculates factorial for a number in C
as follows:
int factNnumbers(int n)
{
if(n == 1)
return 1;
else
return (n*factNnumbers(--n));
}
I call the function shown above as:
factNnumbers(takeInputN());
where the function to take the input (takeInputN) is defined as:
int takeInputN()
{
int n;
printf("\n\nHow many numbers ?? \n ");
scanf("%d", &n);
return n;
}
If I change one line in my factorial code as shown below , my program works perfectly. Otherwise with the above code it prints the factorial of the number input -1 (example if number input is 5, it will print the factorial of 4). Why is this happening?.
int factNnumbers(int n)
{
if(n != 1)
return (n * factNnumbers(--n));
}
The problem is that you're both reading and modifying n in the same expression:
n * factNumbers(--n)
The evaluation of the n argument to * and of the --n subexpression are unsequenced, which gives your code Undefined Behaviour.
The easiest solution (and also, IMO, more expressive), is to say n - 1 where you mean it:
n * factNumbers(n - 1)
Your "improved" code in the bottom of the question is actually even more wrong. There, you have a control path which will return an unspecified value: a clear no-no.
Note: This answer was written while the question still had a C++ tag, and uses C++ terminology. The end effect in C is the same, but the terminology might be different.
You are invoking undefined behaviour, that it works in one version is just an accident:
return (n*factNnumbers(--n));
Do you use n first and then decrement it or the other way around? I don't know and neither does the compiler, it's free to do either of them or format your hard drive. Just use n * f(n - 1).
Also, your "working" version does not return for the n==1 case, which is illegal.
There are two causes of undefined behavior in your code:
Whether n or --n in n * factNnumbers(--n) will be evaluated first is unspecified.See this. You want just n * factNnumbers(n - 1), why decrement? You're not using decremented n afterwards (at least you didn't want to).
You're not returning a value on all control paths, what's going to be returned on n == 1? An indeterminate value that will mess up the whole result.
the rule of decrement:
X = Y-- first passes the value of I to X and decrements after
X = --I first pass and decrements the value decremented X
for your case, you decrement the value of parameter passed as argument to the function factNnumbers. Therefore remedy this error, I invite you to put (n-1) instead of (--n).
I think it’s better to use the tgamma function from math.h for double precision calculations involving factorials (such as Poisson distribution etc.): tgamma(n+1) will give you factorial(n).
Factorial function is increasing very fast, and this will work also for values too big to fit an integer type.
When n<=1 (or == 1 in your code), the factorial function has to return 1. Futhermore the your --n in you code is false and sould be n-1 as:
function factorial(n)
{
if (n<=1)
return 1;
else
return n * factorial(n-1);
}

Recursion on Recursion in C

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.

difficulty in understanding successive recursive calls

I am trying to understand the following program in which successive recursion function calls are present, but getting confused while tracing how the tack gets loaded.
void func(char*); // function prototype
int main(){
func("123");
return 0;
}
void func(char a[]){
if(a[1]=='\0')
return;
func(a+1);
func(a+1);
printf("%c",a[1]);
}
the output for this is 3 3 2
would appreciate if someone could advise on this one...
does this kind of multiple recursive calls beneficial in any way or find application in specific problem areas..?
Just put yourself in the position of the CPU and step through line-by-line (or use a debugger to help with that task).
The first call is to
func("123")
this call does not satisfy the termination condition a[1] == '\0', so it calls
func("23");
The call to func("23") in turn calls
func("3")
which DOES satisfy the return condition. So, that call returns to the previous caller, func("23").
func("23") proceeds to make another call to func("3") due to the lines
func(a+1);
func(a+1);
Continue this process of executing the program in your mind, and write down what would be in each call to printf. That will explain your output.
UPDATE
Note that the call to printf() happens after the recursive calls, so e.g. a call to
func("123")
would proceed like
Enter func("123")
Termination condition not met
Call func("23")
Call func("23") again
Printf("3") (which is a[1])
Return
Debugging with breakpoints is one way to understand recursion. Another way is to draw the tree of recursive calls.
From the figure, In every level after level0, the printf statement occurs after every two nodes owing to these two lines of code:
func(a+1);
func(a+1);
In general, this becomes a perfect binary tree for any input string of length greater than 0. The total number of nodes is given by this formula:
2^(k+1) - 1 // k is the depth; here k = 2
Total number of printf statements executed can be obtained by this formula:
2^k - 1 // For k=2, there will be 3 printf statements each printing 3,3,2 respectively
the posted code is a rather poorly designed instance of recursion.
The following code has the correct 'tail' form of recursion.
It could be made even better by passing the reversed string back to main and let main print it.
It reverses the order of the string passed to func() by main()
Please, when asking about a runtime problem, post code the compiles, including the necessary #includes for header files so we are not guessing about which headers to include
#include <stdio.h>
void func(char*); // function prototype
int main(){
func("123");
return 0;
}
void func(char a[])
{
if(a[1]=='\0') // check for end of recursive sequence
{
printf( "%c", a[0] ); // last tail action
return;
}
func(a+1); // step+next recursion
printf( "%c", a[0] ); // tail action
return;
}
The recursion can be simply understood as follows.
For example:
Func(int a){
while(a>1)
return a * func(a-1);
}
Suppose a = 5.
What happens is that it returns 5 * func(4).
Now func(4) returns 4 * func(3) and it goes on like this.
Check out this example for use of recursion in fibonacci series.

How to understand a recursive function call for large inputs

The result of the following code is 0,1,2,0, I totally understand after writing explicitly every call. But I wonder whether there is an easier method to understand what the recursive function want to realize and find the result faster? I mean we can't write all the call if a=1000.
#include<stdio.h>
void fun(int);
typedef int (*pf) (int, int);
int proc(pf, int, int);
int main()
{
int a=3;
fun(a);
return 0;
}
void fun(int n)
{
if(n > 0)
{
fun(--n);
printf("%d,", n);
fun(--n);
}
}
Your question isn't "what does this do?" but "how do I understand recursive functions for large values?".
Recursion is a great tool for certain kinds of problems. If, for some reason, you ever had to print that sequence of numbers, the above code would be a good way to solve the problem. Recursion is also used in contexts where you have a recursive structure (like a tree or a list) or are dealing with recursive input, like parsers.
You might see the code for a recursive function and think "what does this do?" but it's more likely that the opposite will happen: you will find a problem that you need to solve by writing a program. With experience you will learn to see which problems require a recursive solution, and that's a skill you must develop as a programmer.
The principle of recursion is that you perform a [usually simple] function repeatedly. So to understand a recursive function you usually need to understand only one step, and how to repeat it.
With the above code you don't necessarily need to answer "what output does this code give" but instead "how does it work, and what process does the code follow". You can do both on paper. By stepping through the algorithm you can usually gain insight into what it does. One factor that complicates this example is that it isn't tail-call recursive. This means you must do more work to understand the program.
To 'understand' any program you don't necessarily need to be able to simulate it and calculate the output, and the same applies here.
All you need to do is add some debug statements to understand it a little better. This is the result of the if statements I added to track through it:
start program
before if, n is = 3
before fun call, n is = 3
before if, n is = 2
before fun call, n is = 2
before if, n is = 1
before fun call, n is = 1
before if, n is = 0
printing = 0
before if, n is = -1
after second fun call, n is = -1
printing = 1
before if, n is = 0
after second fun call, n is = 0
printing = 2
before if, n is = 1
before fun call, n is = 1
before if, n is = 0
printing = 0
before if, n is = -1
after second fun call, n is = -1
after second fun call, n is = 1
end program

Resources