void foo(int n, int sum)
{
int k = 0, j = 0;
if (n == 0) return;
k = n % 10;
j = n / 10;
sum = sum + k;
foo (j, sum);
printf ("%d,", k);
}
int main ()
{
int a = 2048, sum = 0;
foo (a, sum);
printf ("%d\n", sum);
getchar();
}
For me this should be 4,0,2,8,0
However, when i execute it, it gives me 2,0,4,8,0
As the code stands, the argument sum to foo is not really relevant since it is passed by value so the last statement in the main function printf ("%d\n", sum) will print 0 regardless of what happens inside foo. That's the last 0 you see in the output the program generates.
Now, the function foo itself accepts an argument n, performs integer division by 10, and recursively calls itself until n is zero. This in effect means that it will print the decimal digits of the input number which is what you see in the output...
It is called as recursive call to the function.
And internally Recursion run as a stack LAST IN FIRST OUT kind
Now in your case it is first printing the output of last call to foo function
Steps in which your program is executing are like this and result will go in stack
1 - 1 st call to foo value of k = 8
2 - 2 nd call to foo value of k = 4
3 - 3 rd call to foo value of k = 0
4 - 4 th call to foo value of k = 2
And as told earlier it will work like stack so the output of the program will be
2 0 4 8 and if you want 4,0,2,8,0 this as a output you need to write the logic accordingly :)
Yes, the output you are getting is absolutely right.
In main(),foo() is called with a=2048 and sum=0.
In foo() we have n=2048, then the if condition calculates values for k,i.e.,(n%10) and j,i.e.,(n/10) till n becomes equal to 0.
Now since there is a recursive call to foo() with j and sum as parameters, the value of k in each iteration gets pushed to a stack and is popped out when n==0 condition is satisfied.
So, if you trace out the program you get values of k=8,4,0,2 which is pushed to stack in the same sequence and thus while popping the elements we have 2,0,4,8.
Related
There is this Mario problem in the CS50 course and it's easy using the recursion method, except that when I try to add any arithmetic operation it shows (invalid operands to binary expression ('void' and 'int')). It's just for the sake of me to understand what I can do using recursion and what I can't; the problem is this line (sum(n-1)+n;)
Here is the code:
#include <cs50.h>
#include <stdio.h>
void sum(int n);
int main ()
{
int u = get_int("f");
sum (u);
}
void sum(int n)
{
if (n==0)
{
return;
}
sum(n-1)+n;
for(int i = 0 ; i < n; i++)
{
printf( "#");
}
printf("\n");
}
The error you are seeing is from this line:
sum(n-1)+n;
sum is a function that returns void, but you are trying to add it with an integer n.
I am not quite sure what that get_int("f") does, but I assume it's prompting to the user for an int input, and you are trying to sum from 0 to that number. Here is the solution:
int sum(int n) // Here is the critical change to your code, now it returns an int
{
if (n == 1) // Root case that will stop the recursion, otherwise, it's endless
return 1; // 1 = 1 + 0;
return sum(n-1) + n; // Recursion
}
Think about what we are trying to achieve here. We want to add from 0 to n, or to say from n to 0 downwards. If n is 3, it's going to be 3+2+1+0, and you'll notice that 3 is just n, and 2 is n - 1, 1 is (n - 1) - 1, etc. To visualize it:
before sum(3) could return anything, it calls sum(2) + 3;
before sum(2) could return anything, it calls sum(1) + 2;
1 is our root case, and there is no more calls, so sum(1) is going to return 1;
that 1 is returned to step 2, so sum(1) + 2 becomes 1 + 2, which is 3, and that is the value sum(2), and it returns its result to step 1, and step 1 becomes 3 + 3, which is 6, and the initial call to sum is then completed.
I hope that makes sense to you. Recursion is not an easy technique to master. Take your time, but you need to understand how function calls work in memory. Here is a video that illustrates how recursive calls in memory look like, Data Structures Using C++: Illustration of Recursive Function Calls (Call Stack).
It is because the return type of the function sum() is void.
You cannot add anything to void.
Anyway the result of the "addition" is thrown away, so you won't need addition.
This mean that sum ( n-1)+n; should be replaced with sum ( n-1);.
I usually program in java and recently watching some c codes.
I came up across this program and I don't know how this pointer thing is working.
I know pointer stores the address and all but couldn't make it through the program.
Please tell how is the output coming as 8 ?
#include <stdio.h>
int fun(int n, int * f_p) {
int t, f;
if (n <= 1) {
*f_p = 1;
return 1;
}
t = fun(n - 1, f_p);
f = t + *f_p;
*f_p = t;
return f;
}
int main() {
int x = 15;
printf("%d\n", fun(5, &x));
return 0;
}
What you have here is a recursive function that calculates the i-th element of a Fibonacci sequence (indexing from 0). Each recursive iteration returns two values: the i-th Fibonacci number and the (i-1)-th (previous) Fibonacci number. Since a function in C can only return one value (well, unless you use a struct as return type), the other value - the previous Fibonacci number - is returned to the caller through a pointer parameter f_p.
So, when you call fun(5, &x), the function will return 8, which is the 5-th Fibonacci number, and it will also place 5 into x, which is the previous (4-th) Fibonacci number.
Note that the initial value of x does not matter. That 15 does not play any role in this program. Apparently it is there as a red herring.
If you know what a Fibonacci sequence is, you know that the next element of the sequence is the sum of the two previous elements. This is why the function is written to "return" two elements of the sequence to the caller. You might not care about that previous value in the top-level caller (i.e in main), but the nested recursive calls do need it to calculate the next number. The rest is pretty straightforward.
Step by step:
fun gets called with a 5 and the x address
fun calls fun with a 4 and f_p, which is the x address
fun calls fun with a 3 and f_p, which is the x address
fun calls fun with a 2 and f_p, which is the x address
fun calls fun with a 1 and f_p, which is the x address
fun got called with a 1 so the if condition is true, puts a 1 in the variable pointed by f_p(x) and returns 1
this returned value is assigned to the t of the fun(2,f_p), f is f = t + *f_p which is 1+1 -> f=2;
the variable pointed by f_p is set to t so x=1, returns f so it returns 2
this returned value is assigned to the t of the fun(3,f_p), f is f = t + *f_p which is 2+1 -> f=3;
the variable pointed by f_p is set to t so x=2, returns f so it returns 3
this returned value is assigned to the t of the fun(4,f_p), f is f = t + *f_p which is 3+2 -> f=5;
the variable pointed by f_p is set to t so x=3, returns f so it returns 5
this returned value is assigned to the t of the fun(5,f_p)(the first call to fun), f is f = t + *f_p which is 5+3 -> f=8;
the variable pointed by f_p is set to t so x=5, returns f so it returns 8, which is what the printf prints
Another answer revealed this to calculate the fibonacci numbers using a useful technique for returning an extra value. I've rewritten the code in what I think is a much more understandable and maintainable manner. Hope this prevents people thinking you need to write terrible code to do something like this
#include <stdio.h>
int fib(int n) {
// This is used to return the previous fib value
// i.e. fib(n - 1)
int prevValRet;
return fibRec(n, &prevValRet);
}
// *prevValRet contains fib(n-2)
int fibRec(int n, int *prevValRet) {
// Termination case
if (n <= 1) {
// return fib(0) and fib(1) as 1
*prevValRet = 1;
return 1;
}
// Calculate fib(n-1)
int prevVal = fibRec(n - 1, prevValRet);
// Calculate fib(n) = fib(n-1) + fib(n-2)
int thisVal = prevVal + *prevValRet;
// Return fib(n-1) and fib(n)
*prevValRet = prevVal;
return thisVal;
}
int main() {
printf("%d\n", fib(5));
return 0;
}
As these things go, it's technically straightforward, but...stupid, in the sense that nobody should do things like this. It's a bad use of recursion and badly-written recursion, given the side effects.
The original call of fun(5, &x) isn't going to trip the condition. So, it'll recurse four times (5-1, 4-1, 3-1, 2-1). That's your base condition, which has the effect of setting the pointed-to location (the original x) to 1 and returning 1.
Then we unroll the four calls, each time adding the returned value to the thing at the pointer and changing the thing at the pointer to be that sum.
In simple English, you're doubling one three times.
Edit: As pointed out, I misread the code as assigning f to *f_p rather than t. That makes it a Fibonacci counter.
So, I have two questions.
Question 1) I find recursion difficult in C. And I have this one question, that I dont know how should I go about attempting it. I want to know its output, Please help me.
#include <stdio.h>
void fun (int);
int main (void)
{
int a;
a = 3;
fun(a);
printf("\n");
return 0;
}
void fun ( int n )
{
if ( n > 0 )
{
fun(--n);
printf("%d",n);
fun(--n);
}
}
How can I solve this recursion manually?
I know during recursion, the information is stored on stack. Therefore, I tried doing it by that way. Firstly, a will be decremented all the way upto 0. But then, it will exit out of the loop. So, when will it print the values?
Question 2) Also, I Wanted to know since the topic I am studying right now is functions. If I make a function and lets suppose it returns some value, then IS IT MANDATORY that I collect its value upon calling or I can call it without collecting its return value?
For eg: Let's say I made the function as,
int foo ( int a )
{
........
return b;
}
Now, if I call this function from inside main, then is it mandatory that I store the returned value in some variable?
You had 2 questions: the first one is what happens in your code:
To your question #1: Function fun(n) could be rewritten so that it is functionally equivalent but easier to understand, as:
void fun(n) {
if (n > 0) {
fun(n - 1);
printf("%d", n - 1);
fun(n - 2);
}
}
That is:
for fun(n)
if n > 0,
first call fun(n - 1)
then print the number n - 1
lastly call fun(n - 2)
Thus the following happens when unwinding the recursion:
fun(3) ->
fun(2) ->
fun(1) ->
fun(0) ->
n <= 0 -> exits
prints 0
fun(-1) ->
n <= 0 - exits
prints 1
fun(0) ->
n <= 0 - exits
prints 2
fun(1) ->
fun(0) ->
exits as n <= 0
prints 0
fun(-1) ->
exits as n <= 0
Execution goes from up to down sequentially - thus the output 0120 from the prints lines.
Question #2:
No, return value does not need to be stored in a variable. In fact, the printf you used returns an int, that tells the number of characters written, but you did not store that return value anywhere.
For no 1 - Get a note pad and a pencil.
Start off an write fun(3) - It is in Main.
You can now cross that out an instead write
if ( 3 > 0 )
{
fun(2);
printf("%d",2);
fun(1);
}
(applying the logic of --n)
Repeat with both of those fun. You can do the leg work on this one
Number 2 - You do not have to collect the return value from a function
I would like to answer your second question About storing the value returned by the called function.
The answer returned by the called function can be displayed in two ways..
No.1-You need not store it in any variable in the calling function and print it directly as follows:
#include<stdio.h>
#include<conio.h>
void main()
{
int a=10, b=9, add(int,int);
printf("Sum of %d and %d is : %d",a,b,add(a,b));
getch();
}
int add(int m,int n)
{
return(m+n);
}
Here,the function call has been written in the printf() function and hence the need of an extra variable has been eliminated
No.2-The other way and the code for the same-
#include<stdio.h>
#include<conio.h>
void main()
{
clrscr();
int a=10,b=9,c,add(int,int);
c=add(a,b);
printf("Sum of %d and %d is : %d",a,b,c);
getch();
}
int add(int m,int n)
{
return(m+n);
}
So,you do need a variable for the second method.Because there has to be something to catch the value thrown by the called function
I recently started reading Hacking: The Art of Exploitation by Jon Erickson. In the book he has the following function, which I will refer to as (A):
int factorial (int x) // .......... 1
{ // .......... 2
int i; // .......... 3
for (i = 1; i < x; i++) // .......... 4
x *= i; // .......... 5
return x; // .......... 6
} // .......... 7
This particular function is on pg. 17. Up until this function, I have understood everything he has described. To be fair, he has explained all of the elements within (A) in detail, with the exception of the return concept. However, I just don't see how (A) is suppose to describe the process of
x! = x * (x-1) * (x-2) * (x-3)
etc which I will refer to as (B). If someone could take the time to break this down in detail I would really appreciate it. Since I am asking for your help, I will go through the elements I believe I understand in order to potentially expose elements I believe I understand but actually do not but also to help you help me make the leap from how (A) is suppose to be a representation of (B).
Ok, so here is what I believe I understand.
In line 1, in (int x), x is being assigned the type integer. What I am less sure about is whether in factorial (int x), int x is being assigned the type factorial, or if even factorial is a type.
Line 3 is simple; i is being assigned the type integer.
Line 4 I am less confident on but I think I have a decent grasp of it. I'm assuming line 4 is a while-control structure with a counter. In the first segment, the counter is referred to as i and it's initial value is established as 1. I believe the second segment of line 4, i < x, dictates that while counter i is less than x, keep looping. The third segment, i++, communicates that for every valid loop/iteration of this "while a, then b" situation, you add 1 to i.
In line 5 I believe that x *= i is suppose to be shorthand for i * x but if I didn't know that this function is suppose to explain the process of calculating a factorial, I wouldn't be able to organically explain how lines 4 and 5 are suppose to interact.
'I humbly ask for your help. For any one who helps me get over this hump, I thank you in advance. '
I think the program given in the book is wrong. Theoretically, the for-loop will never terminate, as x is growing in every iteration, and much faster than i.
In practice, x will overflow after some time, thus terminating the loop.
Forget about why this calculates the factorial for a moment. First let's figure out what it does:
int factorial (int x) // .......... 1
{ // .......... 2
int i; // .......... 3
for (i = 1; i < x; i++) // .......... 4
x *= i; // .......... 5
return x; // .......... 6
} // .......... 7
Line 1:
Ignoring the part in the parenthesis for now, the line says int factorial (...) - that means this is a function called factorial and it has a type of int. The bit inside the parenthesis says int x - that means the function takes a parameter that will be called x and is of type int. A function can take multiple parameters separated by commas but this function takes only one.
Line 3:
We are creating a variable which we will call i of type int. The variable will only exist inside these curly braces so when the function is finished i will not exist any more.
Line 4:
This is indeed a looping control that uses the variable i created on line 3 to keep the count. At the start of the loop, the i=1 makes sure the count starts at 1. The i<x means it will keep looping as long as i is less than x. The i++ means each time the loop finishes the stuff in the curly braces the variable i will be incremented. The important part of this line is that the loops stops when i gets to x - which, as we will see, never happens.
Line 5:
The x*=i means the value of x will be updated by multiplying it by i. This will happen each time the loop iterates. So, for example, if x was equal to 5 the loop will make i equal to the values 1, 2, 3 and 4 (the numbers from 1 up but less than x) and the value of x will be updated by multiplying it by 1, 2, 3 and 4, making it larger and larger. But now that x is larger, the loop doesn't end here as expected - in fact, it contines looping making x larger and larger until the value of x no longer fits into an int. At that point, the program has undefined behaviour. Because compilers assume no one would want undefined behaviour, the program can do absolutely anything at that point including crashing or looping infinitely or even rewriting the whole program so it doesn't do any calculations at all.
Line 6:
We need to get that value of x back to the outside world and that is what the return command does - if the program gets to here the return statement gives the factorial function the value of x (which is the value of the factorial of 5 in the example we just used).
Then somewhere else in your program you might do this:
int f;
f = factorial(5);
Which will make the parameter called x have an initial value of 5 and will make f have the final value of the function.
So what does it return? Well, there is undefined behaviour so anything could happen - but because x gets larger and larger it definitely will NOT return the factorial. Anything could happen, but in my tests factorial(5) returns a huge negative number.
Try it online!
So how do we fix it? Well, as #JonathanLeffler said, we can't change the value of x so we need a new variable to hold the result. We will call that variable r:
int factorial (int x)
{
int r = 1;
for (int i = 1; i < x; i++)
r *= i;
return r;
}
So this program changes the value of r and doesn't change the value of x. So the loop works properly now. But it still doesn't calculate the factorial of the value passed in - if x is 5 it multiplies all the values up to but not including x.
Try it online!
So how do we fix it? The factorial has to include all the values including x, so this actually calculates the factorial:
int factorial (int x)
{
int r = 1;
for (int i = 1; i <= x; i++)
r *= i;
return r;
}
And this works as long as the value of x you pass in is small enough that the factorial can fit into a signed int.
Try it online!
You could get more range by using an unsigned long long but there is still a maximum value that can be calculated.
The program loops through integers 1 thru N-1. (Assume the input value is 'N')
Before loop starts, x=N.
After one iteration, x=N*1.
After 2 iterations, x=N*1*2.
After N-1 iterations, x=N*1*2*....(N-1).
Which is N factorial.
So N! is returned.
The fifth line is : x *= i;
You should understand here : x = x * i;
The loop will execute while i < x. Which means until reaches x - 1;
Knowing that i begins at 1 you will get this sum : x * 1 * 2 * 3 * ... * ( x - 1)
You can rearrange this so you get : 1 * 2 * 3 * ... * (x - 1) * x
I have a code which includes a recursive function. I have wasted a lot of time on recursion but I still couldn't get it really:
#include<stdio.h>
void count(int);
int main()
{
int x=10,z;
count(x);
}
void count(int m)
{
if(m>0)
count(m-1);
printf("%d",m);
}
When the 1st time count is called with argument as 10. it fulfills the condition and then here starts the recursive part. what happens really when a function calls itself? I don't get it. Please explain with reference to stacks.
While m is greater than 0, we call count. Here is a representation of the stack calls:
count (m = 10)
count (m = 9)
count (m = 8)
count (m = 7)
count (m = 6)
count (m = 5)
count (m = 4)
count (m = 3)
count (m = 2)
count (m = 1)
count (m = 0)
printf 0
printf 1
printf 2
printf 3
printf 4
printf 5
printf 6
printf 7
printf 8
printf 9
printf 10
next time it calls itself it has a smaller value
count(int m)
{
if(m>0)
count(m-1); // now it is calling the method "count" again, except m is one less
printf("%d",m);
}
So first it will call count with 10, then it will call it with 9, then 8, then 7..... all the way until this if statement isn't true:
if(m>0)
What might be confusing you is the if statement only applies to the next line (printf isn't part of the if statement)
so you have:
count(int m)
{
if(m>0)
{
count(m-1); // now it is calling the method "count" again, except m is one less
}
printf("%d",m);
}
So, the recursive calls will stop once m is not > 0, and then it will call the printf.
After it calls printf for when m is 0, then it will return from that 'count' call, (Back to where m was equal to 1), and then it will call the printf when m is 1, and then when m is 2, .....
So the output should be:
"0 1 2 3 4 5 6 7 8 9 10"
EDIT:
In terms of a stack:
This is what the stack is doing:
count(10) // push count(10)
->
count(9) // push count(9)
count (10)
->
...
->
count(0) // push count(0)
count(1)
count(2)
count(3)
count(4)
count(5)
count(6)
count(7)
count(8)
count(9)
count(10)
-> (and then it starts printing and popping the method off the stack)
// pop count(0), and printf(0)
count(1)
count(2)
count(3)
count(4)
count(5)
count(6)
count(7)
count(8)
count(9)
count(10)
->
// pop count(1), and printf(1)
count(2)
count(3)
count(4)
count(5)
count(6)
count(7)
count(8)
count(9)
count(10)
->
...
->
// pop count(9), and printf(9)
count(10)
->
// pop count(10), and printf(10)
When a function is called the return address (of the next code to execute) is stored on the stack along with its current arguments. Once the function finishes the address and arguments are popped so the cpu will know where to continue its code execution.
Let's write the addresses of the function (for the purpose of this example only)
count(int m)
{
(address = 100) if(m>0)
(address = 101) count(m-1); // now it is calling the method "count" again, except m is one less
(address = 102) printf("%d",m);
}
For m = 1:
The if is fullfield so we execute code at address 101 with m = 1. address 102 and m = 1 are pushed to the stack and the function is executed again from address 100 with m = 0. Since m = 0 we execute address 102 and printing 0 on console. The function ends and the last return address (102) and argument m = 1 are popped and the line at address 102 is executed printing 1 on the screen.
The function count is called with an integer argument of 10.
Since the function argument m which is 10 is greater than 0 the function count calls itself with an integer argument of m which is 10 minus 1 which equals 9.
Step 2 repeats with varying arguments (m-1) until m is not greater than 0 and which point the program prints the value of m.
The recursive function just modifies the parameter given to it and calls itself with that modified value until the desired result is returned (in this case m not being greater than 0).
Each number refers to the line number.
#include<stdio.h>
count(int);
main()
{
1int x=10,z;
2count(x);
}
count(int m)
{
3if(m>0)
4 count(m-1);
5printf("%d",m);
}
The execution happens like this(with x=3) -
line number|value of x
1 3
2 3
3 3
4 2
3 2
4 1
3 1
4 0
5 0
5 1
5 2
5 3
Numbers printed on the screen 0 1 2 3
If you want a more specific answer, then you have to look into how compilers work. But generally speaking the compiler will create machine code for the function that includes a preamble, in this code enough memory is allocated on the stack (by decrementing a stack pointer) that a copy of the functions variables can be placed on the stack (we can store the state of the function).
The function will have values stored in registers and memory and these must be stored on the stack for each (recursive) call, otherwise the new call will overwrite the precious data!. So very basically the machine code looks like this (pseudo code)
//store m on the stack
store m,stack_pntr+m_offset
//put input values in designated register
a0 = m
//allocate memory on the stack
stackPntr -= stack_size_of(count_vars)
//store return address in allocated register
//jump to the first instruction of count
.
.
By changing some data used for computation we can go back and read the same instructions again and get a different result. The abstraction of recursive function allows us to manipulate the data we want to change in a nice "call by value" way so that we don't overwrite it unintentionally.
This is done by the compiler when it stores the state of the calling function on the stack so we don't have to manually store it.