Pointers in C with recursion - c

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.

Related

Why does this recursive sum function not work correctly?

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);.

what should be the output for below program?

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.

Factorial Function in C

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

Incorrect output from recursive function to compute sum of digits of a number

I was trying to write a function that would compute the sum of the digits of a number using recursion, but the output is incorrect. Here's the code:
/*Write a function to calculate sum of digits of a number using recursion*/
/*Author:Udit Gupta Date:10/08/2011*/
#include<stdio.h>
int sum (int);
int main () {
int n,s;
printf ("Enter the number:");
scanf ("%d",&n);
s = sum (n);
printf ("The sum of the digits of the number is %d",s);
}
int sum (int a) {
int f;
if (a == 0) {
return f;
}
f = (a% 10) + sum (a/10);
}
Here are some of the output values:
udit#udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
Enter the number:123
The sum of the digits of the number is 7
udit#udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
Enter the number:1234
The sum of the digits of the number is 2919930
udit#udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
Enter the number:123456
The sum of the digits of the number is 4620297
udit#udit-Dabba ~/Desktop/letusc/ch5/J $ ./a2.out
Enter the number:12345
The sum of the digits of the number is 15 /*Only this one seems correct*/
Can someone help me figure out why this isn't working correctly?
Let's look at this recursive function in more detail:
int sum (int a) {
int f;
if (a == 0)
return f;
f = (a% 10) + sum (a/10);
}
While you're on the right track and you have the right idea in general, your actual implementation is a bit buggy. For starters, let's look at these lines:
if (a == 0)
return f;
You have the right idea to terminate the recursion when a reaches zero, but the way you're doing it is a bit off. In particular, you're returning the value of the integer f, but you've never initialized it. This means that the return value is completely arbitrary. Instead of writing this, I think that you probably meant to write something closer to
if (a == 0)
return 0;
which correctly says "if the number is zero, the sum of its digits is zero."
Similarly, take a look at the last line of your function:
f = (a% 10) + sum (a/10);
Again, your intuition is spot-on: the sum of the digits of a number are given by the sum of its first digit and the sum of the rest of its digits. However, notice that while you're correctly computing the sum of the digits, you aren't correctly returning the sum of the digits. In fact, you don't return anything at all if you execute this code, so the return value from the function is unspecified, hence the garbage output. To fix this, consider rewriting the code like this:
return (a % 10) + sum (a / 10);
This actually says to hand back the value that you just generated right here, instead of storing it in a local variable that will be immediately cleaned up as soon as the function returns.
I believe that the reason you coded this function this way is that you're under the impression that the value of int f; is carried across the function calls. Unfortunately, it is not. When writing a recursive function, each instance of the function is completely independent of each other instance and local variables accessible in one recursive call are not accessible in other recursive calls. Consequently, even though each recursive call has its own variable int f, those variables are all completely independent of one another. The value isn't carried through them. If you want to communicate values across recursive functions, the best way to do it is by using the return value of the recursive calls, or (if you must) by passing a pointer to some value down through the recursion.
Hope this helps!
When a is 0, you are returning an uninitialized value (f was not initialized).
Change it to:
if (a == 0)
return 0;
You also forgot the return in the end of the function:
return (a% 10) + sum (a/10);
It is highly recommended that you always compile with the flag -Wall, which would warn you about those mistakes.
Your recursive function will calculate nothing it either returns an uninitialized int or nothing. You need to be returning the work you are doing in the function.
int sum (int a) {
if (a == 0) {
return 0;
}
return (a% 10) + sum(a/10);
}
return a == 0 ? 0 : ((a% 10) + sum (a/10));
You only return f is it is 0, but not if it isn't, which makes your return value undefined. I assume you want to do:
int sum (int a) {
int f;
if (a == 0)
return 0;
f = (a % 10) + sum (a / 10);
return f;
}

Is my looping solution cheat for this puzzle?

This programming problem is #85 from a page of Microsoft interview questions. The complete problem description and my solution are posted below, but I wanted to ask my question first.
The rules say that you can loop for a fixed number of times. That is, if 'x' is a variable, you can loop over a block of code based on the value of 'x' at the time that you enter the loop. If 'x' changes during the loop, that won't change how many times you loop. Also, that is the only way to loop. You can't, for instance, loop until some condition is met.
In my solution to the problem, I have a loop which will be set to execute zero or more times. The problem is, in reality, it only ever executes 0 times or 1 time because the only statement in my loop is a return statement. So if we enter the loop, it only has a chance to run once. I am using this tactic instead of using an if-else block, because logical comparisons and if statements are not allowed. The rules don't explicitly say that you can't do this, but I am wondering if you would consider my solution invalid. I couldn't really figure out another way to do it.
So here are my questions:
Do you think my solution is invalid?
If so, did you think of another way to solve the problem?
Problem description:
85) You have an abstract computer, so just forget everything you know
about computers, this one only does what I'm about to tell you it
does. You can use as many variables as you need, there are no negative
numbers, all numbers are integers. You do not know the size of the
integers, they could be infinitely large, so you can't count on
truncating at any point. There are NO comparisons allowed, no if
statements or anything like that. There are only four operations you
can do on a variable.
You can set a variable to 0.
You can set a variable = another variable.
You can increment a variable (only by 1), and it's a post increment.
You can loop. So, if you were to say loop(v1) and v1 = 10, your loop would execute 10 times, but the value in v1 wouldn't change so
the first line in the loop can change value of v1 without changing the
number of times you loop.
You need to do 3 things.
Write a function that decrements by 1.
Write a function that subtracts one variable from another.
Write a function that divides one variable by another.
See if you can implement all 3 using at most 4 variables. Meaning, you're not making function calls now, you're making macros. And at
most you can have 4 variables. The restriction really only applies to
divide, the other 2 are easy to do with 4 vars or less. Division on
the other hand is dependent on the other 2 functions, so, if subtract
requires 3 variables, then divide only has 1 variable left unchanged
after a call to subtract. Basically, just make your function calls to
decrement and subtract so you pass your vars in by reference, and you
can't declare any new variables in a function, what you pass in is all
it gets.
My psuedocode solution (loop(x) means loop through this block of code x times):
// returns number - 1
int decrement(int number)
{
int previous = 0;
int i = 0;
loop(number)
{
previous = i;
i++;
}
return previous;
}
// returns number1 - number2
int subtract(int number1, int number2)
{
loop(number2)
{
number1= decrement(number1);
}
return number1;
}
//returns numerator/denominator
divide(int numerator, int denominator)
{
loop(subtract(numerator+1, denominator))
{
return (1 + divide(subtract(numerator, denominator), denominator));
}
return 0;
}
Here are C# methods that you can build and run. I had to make an artificial way for me to
satisfy the looping rules.
public int decrement(int num)
{
int previous = 0;
int LOOP = 0;
while (LOOP < num)
{
previous = LOOP;
LOOP++;
}
return previous;
}
public int subtract(int number1, int number2)
{
int LOOP = 0;
while (LOOP < number2)
{
number1 = decrement(number1);
LOOP++;
}
return number1;
}
public int divide(int numerator, int denominator)
{
int LOOP = 0;
while (LOOP < subtract(numerator+1, denominator))
{
return (1 + divide(subtract(numerator, denominator), denominator));
}
return 0;
}
Ok so the reason I think your answer might be invalid is because of how you use return. In fact I think just using the return is too much of an assumption. in a few places you use the return value of a function call as an extra variable. Now if the return statement is ok, then your answer is valid. The reason i think its not valid is because the problem hints at the fact that you need to think of these as macros, not function calls. Everything should be done by reference, you should change the variables and the return values are how you left those variables. Here is my solution:
int x, y, v, z;
//This function leaves x decremented by one and v equal to x
def decrement(x,v):
v=0;
loop(x):
x=v;
v++;
//this function leaves x decremented by y (x-y) and v equal to x
def subtract(x,y,v):
loop(y):
decrement(x,v);
//this function leaves x and z as the result of x divided by y, leaves y as is, and v as 0
//input of v and z dont matter, x should be greater than or equal to y or be 0, y should be greater than 0.
def divide(x,y,v,z):
z=0;
loop(x):
//these loops give us z+1 if x is >0 or leave z alone otherwise
loop(x):
z++;
decrement(x,v);
loop(x):
decrement(z,v)
//restore x
x++;
//reduce x by y until, when x is zero z will no longer increment
subtract(x,y,v);
//leave x as z so x is the result
x=z;

Resources