Writing a recursive function in C - c

I am studying how to program and have recently been working on a problem that calculates the total of 2 entered numbers from min to max. For example, if someone entered the numbers 4, 7. The calculation would be 4+5+6+7=22.
I've attempted what i think would be the definition of recSum but obviously it is wrong as I get a segmentation fault. What is wrong with my definition?
/* Define the recursive function */
int recSum (int x, int max)
{
int incrementalSum = 0;
if (x == max)
{
return x; /* Exit if summated lower to upper numbers */
}
else
{
return (x + recSum(x++, max)); /* My recursive call */
}
} /* End of function call */
*new code is shown above, sorry, i used the wrong code.

Your code has 3 important problems
The expression
incrementalSum = x + x++;
is undefined, read this for more information
Your function is not recursive, a recursive function calls it self until a condition happens where it should end.
Also, noting that I am not an irrational "don't ever use goto person", this is precisely why some people advice against using goto.

The reason your code doesn't work is this line:
return x + recSum(x++, max);
x++ increments x but returns the previous value, so in the recursive calls it never increments and you never reach the base case. Like an infinite loop. You have to replace x++ with ++x in order to give any result, even though it won't be correct. ++x is modifying x so it will alter the final sum of x + recSum. You'd better use:
return x + recSum(x + 1, max);
See What is the difference between ++i and i++?

It seems you mean the following
int recSum(int x, int max)
{
return max < x ? 0 : x + recSum( x + 1, max );
}
Or it would be even better to declare the return type of the function like long long int.
long long int recSum(int x, int max)
{
return max < x ? 0 : x + recSum( x + 1, max );
}
The function can be called like
printf( "%lld\n", recSum( 4, 7 ) );
As for your function then it exits in the first call
int recSum(int x, int max)
{
int incrementalSum = 0;
recCall: if (x < max)
return incrementalSum;
^^^^^^^^^^^^^^^^^^^^^
because usually it is called when x is less than max. So the function does not make sense. Moreover the function is not recursive because it does not call itself.

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

C recursion : return statement

I just started learning C and I faced the following problem:
in the first /recursive step/ I do not understand why we cannot simply return multiply(x, y)? Why do we need to add a value to y and only then return it?
The code is below.
Thank you!
#include <stdio.h>
unsigned int multiply(unsigned int x, unsigned int y)
{
if (x == 1)
{
/* Terminating case */
return y;
}
else if (x > 1)
{
/* Recursive step */
return y + multiply(x-1, y);
}
/* Catch scenario when x is zero */
return 0;
}
int main() {
printf("3 times 5 is %d", multiply(3, 5));
return 0;
}
If you return multiply(x, y), you will loop forever on the same call parameters. To have proper recursion, you have to reduce the problem to a simpler case. That simpler case is to reduce the multiplier by 1.
Recursion is simply doing the same operations with smaller inputs. Can we express multiplication of two numbers with smaller numbers ? Sure ! Finding the way to do this is finding a recursive definition of multiplication. First we will try to express x*y with a smaller x, like x-1.
From the simple fact that :
(x-1)*y = x*y - y
we find :
x*y=(x-1)*y + y
Remember that we will always have to find a stoping step, here we know that
0*y=0
and we're done. This gives us even a simpler form of a recursive mul function as the one given by #RobertEagle.
But let us take the thing further. x-1 is smaller than x, as y-1 is smaller than y. Exploring this fact gives us :
(x-1)*(y-1)=x*y-x-y+1
x*y = (x-1)*(y-1) + x + y - 1
This time the stopping step would be "if x or y is 0 then the result is 0". Translating this into code :
unsigned multiply(unsigned x, unsigned y)
{
if ( (x==0) || (y==0) )
return 0;
else
return x+y-1+multiply(x-1, y-1);
}
This sort of recursion is not quite efficient because we do not express the recursion with something really smaller. What if we try to halve one of the parameters ?
If x is even we can write :
x*y=2*(x/2)*y=(x/2)*(2*y)
If x is odd we can write :
x*y=(x-1+1)*y=(x-1)*y+y=((x-1)/2)*(2*y)+y
Multiplying (resp. dividing) by 2 can be achieved with left (resp. right) shifting :
unsigned multiply(unsigned x, unsigned y)
{
if (x==0)
return 0;
else if (x%2==0)
return multiply(x>>1, y<<1);
else
return y+multiply((x-1)>>1, y<<1);
}
This method will take less steps than the first one. The "more" you're getting smaller, the "more" you're getting faster, in general.
If you didn't add the value, it would simply return y as the final result of the top most recursive call.
X * Y = X, Y times
e.g. 4 * 5 = 4 + 4 + 4 + 4 + 4
This logic is expanding that evaluation, and just returning the last value would only evaluate to Y one time.
Every recursive function is made up of 2 elements:
The repetitive condition
The stopping condition
Without a stopping condition, the program would enter an infinite loop.
In this case, it would mean the program would continually call beyond x == 1.
Instead of stopping calling itself at x == 1, the program would also call multiply(-1,y), multiply(-2,y) ... to infinite.
Ultimately, you need to sum the y for x times. And to do this you need to return x times the value of y. And in this case, the repetitive condition adds y for x-1 times and for the stopping condition you only need one more time.
You also could have done it this way:
#include <stdio.h>
unsigned int multiply(unsigned int x, unsigned int y)
{
if (x == 0)
{
/* Terminating case */
return 0;
}
else if (x > 0)
{
/* Recursive step */
return y + multiply(x-1, y);
}
}
int main() {
printf("3 times 5 is %d", multiply(3, 5));
return 0;
}
Here you can see the repetitive is concerted with adding the y for exactly x times. Logically, the stopping condition would require to return 0, because we don't need to add anymore the y value. We already have added it for x times.

Can Recursion be named as a simple function call?

Please consider an Recursive function :
1) int calc(int num)
{
2) sum=sum+num;//sum is a global variable
3) num--;
4) if(num==0)
5) return sum;
6) calc(num);
}
It calculates the sum of an integer .
My teacher told me it's not recursion, but a simple function call, because you need to pass
num-- as an argument and return calc(num--) .
I was shocked, as I knew only one thing when a function call itself, its recursion.
She also gave the reason, that line no. 2 and 3 is stored extra in stack memory.
I have no idea what she was referring to.So after going through stack storage thingy:
Here, I noticed that the function arguments passed are in a recursive way, like n-- in my function.
So that they can be linked to the next function call.
For just this sake, can we term it a simple function call instead of recursion?
The teacher has something quite specific in mind even though what you presented is, technically, recursive. Another form which wouldn't depend upon the global would look something like this:
int calc(int num) // Assume this is valid for non-negative numbers
// In that case, type "unsigned int" would be more appropriate
{
if ( num < 0 )
return -1; // Consider this an error; won't happen in recursive case
if ( num == 0 )
return 0;
return num + calc(num-1);
}
You are correct, recursion is a function that calls itself. PERIOD. There are other points worth separately discussing about global variables, and other good programming practices, but whether you implement the decrement operator in the line of code where you call the function recursively or prior to that point, you are still making a recursive call.
It looks like you're trying to calculate, for a given num, the sum of 0 to num. The calc function really just needs one argument, num, and can then call a helper function calc_num which takes the current number and the running sum:
int calc( int num ) {
return calc_help( num, 0 );
}
Then, calc_help, given a current number, and the sum so far, checks whether num is less than or equal to zero. If it is, then the current running sum is the final sum and can be returned. Otherwise, a recursive call to calc_help is made. The current number for it will be one less than num (so that we're calling calc_help with successively smaller first arguments, getting closer and closer to the case where num <= 0), and the current sum will be sum plus the current number:
int calc_help ( int num, int sum ) {
return num <= 0 ? sum : calc_help( num-1, sum+num );
}
In a language (like Scheme) that performs tail call optimization, this is essentially the following loop. Some C/C++ compilers do perform tail call optimization (e.g., according to Tail recursion in gcc/g++, GCC will optimize tail calls when -O2 is specified), so this isn't entirely a moot point.
int calc( int num ) {
int sum = 0;
while ( num > 0 ) {
sum = sum+num;
num = num-1;
}
return sum;
}
or (if you want to be a bit more obscure):
int calc( int num ) {
int sum = 0;
for ( ; num <= 0; sum+=num, num-- );
return sum;
}
The more naïve recursive implementation that performs the addition of after the recursive call, i.e.,
int calc( int num ) {
return num <= 0 ? num : num + calc( num-1 );
}
can't be optimized in this way.

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;
}

C Programming: Recursion

so I wrote this simple recursion program and am getting an error when I compile it with GCC
error: lvalue required as left
operand of assignment
Hopefully this isnt anything to serious, any insight is appreciated
THanks!
#include <stdio.h>
int factorial (int);
int main (void)
{
int i = 0;
int a = 0;
printf("Please enter an integer: ");
scanf("%d", &i);
a = factorial (i);
printf("\n\n%d factorial equals: %d \n", i, a);
return 0;
}
int factorial ( int n )
{
if ( n <= 0 )
return 0 ;
else
f(n) = f( n-1) + 2;
}
The following statement is not valid C:
f(n) = f( n-1) + 2;
(I assume this is the line on which you got the error; you didn't say.)
You might want to try the following:
return factorial(n-1) + 2;
but then the name factorial is misleading because that is not the correct formula for the factorial function.
Why are you writing this
f(n) = f( n-1) + 2;
I can't see any function named f().
This is not the correct formula for calculation factorial of any number. Look at Greg's provided link.
Change it to
int factorial (int n)
{
if (n==1||n==0)
return 1;
else
return n*factorial(n-1);
}
The error is with f(n) = f(n+1) in your factorial function. Anything with parenthesis is a function in c and a function cannot be assigned a value. You probably want n = factorial(n+1);
The assignment operator = needs a variable on the left hand side, to which the value on the right hand side is assigned to. You can't assign something to a function, which is what f(n) is according to C syntax. This is assigning a value to lines of code, which makes no sense. The only thing that makes sense on the left hand side of a function is something that can store a value.
Functions can go on the right hand side of the assignment though, as long as they return something (they are not type void).
To get the factorial right you need to think through it a little more... first of all remember that you want the last value to be 1, not zero. And all of the numbers in the factorial are multiplied.
replace f(n) = f( n-1) + 2; with
return n*factorial(n-1)
and yes, 0! is one so add
if(n==0) return 1;

Categories

Resources