why is my variable storing value from previous recursion runs? - c

the first image is of the Program with regular recursion format, I am returning values for both cases but self call to the function is made only when the argument is a natural number. The result is as expected
in the second program, however, I am not returning any value for natural numbers, the only return case is when the argument is 0.
Ideally, (taking 5 as the input) recursion will happen till num value equals 0. First with
sum = 5 + add(5-1);
sum = 4 + add(4-1);
sum = 3 + add(3-1);
sum = 2 + add(2-1);
sum = 1 + add(1-1);
At this stage, the function will return 0 as flow moves to else block,and value of sum for that loop is 0.
Now, with 0 being returned we rise one step up and 0 will take place of add(1-1) in the line
sum = num + add(num-1);
it should look like
sum = 1 + 0;
the function add(num) should terminate now, after assigning 1 to variable sum.
Two main questions.
No value should rise up for sum = 2 + add(2-1), as in the previous step no value is returned. for add(1), after getting value from add(0), summation of 1 and returned value is stored in variable sum and then exits out of function body.
Every time recursion occurs new variable sum is declared and initiated to 0, so, I don't see why the computer is storing the values of the sum from previous calls to the function, when instead it should start a fresh new variable sum.
to me, after completion of code, the value of variable sum in add() should be 1.
Please someone, if you can make sense of this code. Let me know. Much appreciated
P.s: you can try this on any online C compiler as well. Here is the code:
#include <stdlib.h>
#include <stdio.h>
int add(int num);
int main(){
int number,sum;
printf("enter a number of your choice: ");
scanf("%d",&number);
sum = add(number);
printf("SUM = %d",sum);
}
int add(int num){
int sum = 0;
if(num != 0)
sum = num + add(num-1);
else
return sum;
}

sum = add(number);
Using the return value of a function that flowed off the end without explicitly returning a value is undefined behavior. UB means anything is allowed to happen, including giving you the (false) illusion that a variable is "storing value from previous recursion runs". Quoting from C11 6.9.1/12:
If the } that terminates a function is reached, and the value of the function call is used by the caller, the behavior is undefined.

A function declared to return an int must always return a value (i.e. an int value). Your code doesn't.
int add(int num){
int sum = 0;
if(num != 0)
// If the execution gets in here
sum = num + add(num-1);
else
return sum;
// it will continue here (when the recursion ends).
// And here it is WITHOUT a returned value - that's bad.
}
You probably want:
int add(int num){
int sum = 0;
if(num != 0)
sum = num + add(num-1);
return sum;
}
or
int add(int num){
if(num != 0)
return num + add(num-1);
else
return sum;
}
or (more clear and secure):
int add(int num){
if(num <= 0)
{
return 0;
}
return num + add(num-1);
}

Related

recursive Function, to find even or odd digits inside given number

Basically, its printing only one instance when it happens, and i don't understand why, maybe has something to do with the code reseting every time and starting the variable at 0 again, and i got another question if someone can help me with, i have to return both values when its odd and even, like how many digits are even and odd at the same time, i'm having a little trouble figuring out how to do it
#include <stdio.h>
int digits(int n)
// function that checks if the given value is odd or even, and then add
// + 1 if it's even, or odd, it's supposed to return the value of the quantity
// of digits of the number given by the main function
{
int r;
int odd = 0;
int even = 0;
r = n % 10;
if (r % 2 == 0) // check if given number is even
{
even = even + 1;
}
if (r % 2 != 0) // check if its odd
{
odd = odd + 1;
}
if (n != 0) {
digits(n / 10); // supposed to reset function if n!=0 dividing
// it by 10
}
if (n == 0) { return odd; }
}
int
main() // main function that sends a number to the recursive function
{
int n;
printf("type number in:\n ");
scanf("%d", &n);
printf("%d\n", digits(n));
}
odd and even variables are local in your code, so they are initialized by zero every time.
I think they should be declared at caller of the recursive function, or be declared as global variables.
#include <stdio.h>
void digits(int n, int *even, int *odd)//function
{
int r;
r = n % 10;
if (r % 2 == 0)//check if given number is even
{
*even = *even + 1;
}
else //otherwise, its odd
{
*odd = *odd + 1;
}
n /= 10;
if (n != 0)
{
digits(n, even, odd);//supposed to reset function if n!=0 dividing it by 10
}
}
int main()
{
int n, even = 0, odd = 0;
printf("type number in:\n ");
scanf("%d", &n);
digits(n, &even, &odd);
printf("even: %d\n", even);
printf("odd: %d\n", odd);
return 0;
}
Maybe I found the problem you are facing. You you initialized you odd and even variable as zero. every time you call the function it redeclares their value to zero again. You can use pointer caller or use those as your global variable so that every time they don't repeat their initial values again.
Implementing a function that counts the number of odd and even digits in a number, is not to be done using recursive. That is simply a wrong design choice.
But I assume that it's part of your assignment to use recursion so ... okay.
You want a function that can return two values. Well, in C you can't!! C only allows one return value. So you need another approach. The typical solution is to pass pointers to variables where the result is to be stored.
Here is the code:
void count_odd_even(const int n, int *even, int *odd)
{
if (n == 0) return;
if (((n % 10) % 2) == 1)
{
*odd += 1;
}
else
{
*even += 1;
}
count_odd_even(n/10, even, odd);
}
And call it like
int odd = 0;
int even = 0;
count_odd_even(1234567, &even, &odd);

How to fix program printing a 0 after the print statement executes in C?

This program tests Goldbach's Conjecture, printing a given even integer as the sum of two primes. After printing the first one, the given integer is to iterate by 2 , then find the sum of two primes for that integer. And so on until the program is interrupted by the user.
This problem is that the program prints a '0' after every executed print statement.
The code:
#include <stdio.h>
#include <math.h>
int GC(int goldsum); //function prototype
int main()
{
int goldsum;
printf("Enter an even integer greater than 5: ");
scanf("%d", &goldsum);
printf("%d\n", GC(goldsum));
goldsum = goldsum + 2;
printf("%d\n", GC(goldsum));
}
int GC(int goldsum) //function definition
{
int i, j; //prime addends
int div1, div2; //divisors
char prime1, prime2;
for (i=2 ;i<goldsum ;i++) //when number is less than goldsum, run this loop iterating by 1
{
prime1 = 1;
for (div1=2 ;div1<i ;div1++) //this loop determines if "i" is prime.
if (i % div1 == 0) //if yes, the prime number is stored in "i"
prime1 = 0;
if (prime1)
{
for (j=3; j<goldsum; j+=2) //when number is less than goldsum, run this loop iterating by 2
{
prime1 = 1;
for (div2=2; div2<j; div2++) //this loop determines if "j" is prime.
if(j % div2 == 0) //if yes, the prime number is stored in "j"
prime1 = 0;
if (prime1)
if (i + j == goldsum) //If i + j = goldsum, it prints the result.
{
printf("%d + %d = %d\n",i ,j , goldsum);
return 0;
}
}
}
}
return 0;
}
The output:
Enter an even integer greater than 5: 10
3 + 7 = 10
0
5 + 7 = 12
0
What I want it to look like:
Enter an even integer greater than 5: 10
3 + 7 = 10
5 + 7 = 12
use just GC(goldsum);
instead of printf("%d\n", GC(goldsum));
Maybe you misunderstood the return 0; we put in main(). Every function has to return the value we desire. In the case of main we want 0 because that means everything was OK. In the case of your function the return value should be what YOU want from it.
Edit: re-read the question and adding this: Since you don't want a return value from you function you should declare it as void and not have it in a printf() because all the printing you want is in your function.
Void functions do not return a value, so that is what you want.

the sum of divisor (other than itself)

Write a program that reads integer from the keyboard and, on the output, writes the sum of the divisors of n (other than itself).
I've created a method that finds the sum of divisor. Using the while statement I can have up to 10 integers entered by the user until EOF. In the while statement I had sum = the output of sum_divisor and print out sum.
If I enter 0 0 0 4 5 6 12 then the output should be 0 0 0 3 1 6 16.
The output I get is 0 0 0 3 4 10 26. How can I make it so that it doesn't add the sum_divisor to the previous sum?
#include <stdio.h>
int sum_divisor(int x);
int main()
{
int x;
int sum;
printf("Enter up to 10 positive integer ending with EOF:\n");
while((scanf("%d",&x)) != EOF){
sum = sum_divisor(x);
printf("%d ", sum);
}
return 0;
}
int sum_divisor(int x){
int i;
int sum;
if(x<= 0){
sum = 0;
}
else{
for(i=1;i<x;++i)
{
if(x%i==0)
sum += i;
}
}
return sum;
}
You should initialise sum to zero within your function. Otherwise, it will be set to some arbitrary value and the else block will have an arbitrary result.
In other words, change:
int sum;
into:
int sum = 0;
Of course, once you've done that, there's no need to explicitly do anything for the case where x is less than one. In addition, the initial if is superfluous since the for body won't execute when x is less than one, so you could get away with something like:
int sumDivisors (int x) {
int i, sum = 0;
for (i = 1 ; i < x; i++) {
if ((x % i) == 0) {
sum += i;
}
}
return sum;
}
As an aside, the values you're actually seeing without the initialisation are accumulating:
0 -> 0
0 -> 0
0 -> 0
3 -> 3
1 -> 4
6 -> 10
16 -> 26
This is almost certainly because each call to the function is reusing the same memory for the stack frame, including the variable sum, so sum is simply being added to each time (that the passed-in parameter is greater than one).
However, that's simply an artifact of the implementation, it's not guaranteed by the standard, which states quite clearly in C11 6.7.9 Initialization /10:
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.
In other words, don't rely on this.
And, as yet another aside, it's a mathematical given that, if a number n divides evenly by a, it also divides evenly by n/a. You can use this to your advantage to possibly make the code a little more efficient (though, as with all optimisations, you should measure, not guess).
Since you're discounting the number itself as a divisor, you have to treat the divisor 1 as a special case. You also have to treat perfect squares as a special case so that you don't add the square root twice.
The following code would be a good starting point for that:
int sumDivisors (int x) {
int i, sum;
// Always return zero for -inf..1 inclusive.
if (x < 2)
return 0;
// Otherwise, 1 is factor, search for others
// up to but NOT including sqrt(x).
for (i = 2, sum = 1 ; i * i < x; i++) {
if ((x % i) == 0) {
sum += i;
sum += x / i;
}
}
// Add in sqrt(x) ONCE for a perfect square.
if (i * i == x)
sum += i;
return sum;
}
When you call sum_divisor inside the while statement the same block of stack is being allocated, and therefore the sum variable is allocated in the same position on every call. At the first call the value is 0,(but not necessarily), the next time the value will be the one you calculated on the previous call.
int sum = 0; should fix it.
int sum_divisor(int x){
if(x <= 0) { // you do not need to even alocate space for i an sum if x < 1.
return 0;
}
int i = 1;
int sum = 0;
for(i=1;i<x;++i)
{
if(x%i==0)
sum += i;
}
return sum;
}

Why am I getting correct output even though the code is logically incorrect

Following is the code for reducing a given number to a single digit by adding the digits of the number recursively.
For example if the input is 845 the output is 8. 8+4+5 = 17 -> 1+7 = 8 (output)
#include <stdio.h>
#define TRUE 1
int reduceToSingle(int numb);
int main()
{
int numb;
scanf("%d",&numb);
printf("Original = %d Single digit = %d\n", numb, reduceToSingle(numb));
return TRUE;
}
int reduceToSingle(int numb)
{
int sum = 0, digit = 0;
for (digit = numb % 10; numb != 0; numb = numb / 10)
{
digit = numb % 10;
sum += digit;
}
if (sum > 9)
reduceToSingle(sum);
else
return sum;
}
In the above code in the if (sum > 9) block I haven't returned the function value. I just called the function instead. Logically this function should give an incorrect value. But when I ran the above program in my system I got the correct sum of digits in output. I am unable to comprehend the logic behind this behaviour.
It's just undefined behavior and I'm sure you got a warning. It happens to work - tweak the compiler settings or change the compiler altogether and it won't anymore.
In this case I suspect eax isn't clobbered so you get the expected value, i.e. the last value returned by any of the calls. So when you call reduceToSingle, it will eventually reach return (when sum <= 9). From then on the value of eax will trickle down to the original caller.
This is what i got
815
Original = 815 Single digit = 2009291924
in your code reduceToSingle(numb) is not returning any value in the code so it is something like
printf("%d %d",12);
so a garbage value is printed for the other format specifier

Why does recursive function count downwards after peak?

with fear that I may overstep another question of mine (although this is a new problem alltogether) I still ask this question.
I have this code:
int blob_count(int y, int x, int gridCopy[][5], int sum){
//Local vars
int posX, posY;
//Find the position 1 behind and 1 above the starting point, and start the loop there
for(posX = -1;posX <=1; posX++){
for(posY = -1; posY <= 1; posY++){
if((y + posY) >= 0 && (x + posX) >= 0){
if((y + posY) <= 5 && (x + posX) <= 5){
if(gridCopy[posY+y][posX+x] == 1){
//Set the starting point to 0 (so it wont get calculated again)
gridCopy[posY+y][posX+x] = 0;
y = posY+y;
x = posX+x;
sum++;
blob_count(y, x, gridCopy, sum);
}
}
}
}
}
return sum;
}
The issue is that sum, which counts up 1, for each recursive run, returns the wrong value. By doing a print for each recursive run it gives the result:
sum = 1
sum = 2
sum = ...
sum = n
Which is great, however, by setting printing out the sum outside the for loop (right before return sum;) the opposite happens when it has peaked, so it does this:
sum = n
sum = ...
sum = 2
sum = 1
return sum; // = 1
Which is obviously wrong, as I want the total count, not the lowest. Have I got the return value the wrong place? I've tried putting it in right after the recursive call (inside the loop), to no avail.
Okay let's get rid of the extra bits and simplify your problem down to the essentials.
You have:
int blob_count(int sum)
{
sum++;
if (sum < 10)
blob_count(sum);
return sum;
}
If you add printf("sum==%d\n", sum) right before the return then it will be called first at the innermost recursion (where sum == 10), then it will return to the next level out where sum == 9, print that, return to sum == 8 and so on.
If you put it before the recursive call to blob_count(sum) then you'll print the values before you recurse down, so they start with sum==0, sum == 1 and so on.
If you want sumto be the deepest level your recursion got to, then you could either pass it back via the return value like this:
int blob_count(int sum)
{
sum++;
if (sum < 10)
sum = blob_count(sum);
return sum;
}
or you could pass it via a pointer so that the original variable gets modified:
void blob_count(int* sum)
{
*sum++;
if (*sum < 10)
blob_count(sum);
return;
}
The first one is probably the solution you are looking for.
What pmg said. For each recursive call, the current value of sum is copied and the copy is passed to the recursive call. If you want to modify objects in functions, you must pass a pointer to these objects instead of the object itself.

Resources