0

Does anyone know if a function is supposed to end after it returns something? I have my recursion function written below, but whenever it reaches the else statement and after it returns a value (steps),

it runs the "if (new_number % 2 == 1)" statement,

which does not make sense since the function should end when it reaches the else statement and should not repeat.

It works fine until it returns "steps" for the first time.

This is what happens after the first return: It doesn't even fully run the "if (new_number % 2 == 1)" statement, it just jumps to that line and decreases the value of "steps" and "input_steps" by 1. "new_number" and "number" just get completely random values

Then it returns "steps", then it jumps to "if (new_number % 2 == 1)" statement and decreases the value of "steps" and "input_steps" by 1. "new_number" and "number" just get completely random values again.

It repeats that cycle until "new_steps" and "steps" equal 0, then it returns 0 (because "steps" = 0) and ends the function.

Does anyone know why it does this????

Here is my code:

int step_recursion(int number, int input_steps)
{
    int new_number = number;
    int steps = input_steps;

    if (new_number != 1)
    {
        if (new_number % 2 == 0)
        {
            if (new_number != 1)
            {
                step_recursion(new_number / 2, steps + 1);
            }
        }
        if ((new_number % 2) == 1)
        {
            if (new_number != 1)
            {
                step_recursion(new_number * 3 + 1, steps + 1);
            }
        }
    }

    return steps;
}

I was expecting the function to end after returning "steps," but for some reason it doesn't. I already described the problem fully so go read that.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 3
    1) There is no else statement in what you posted. 2) This is a recursive function, so there can be multiple instances in play an the same time. 3) Any instance of the function does end after returning something. It returns to it's caller & the caller continues execution. 4) The caller can be & frequently is a previous instance of the routine that hasn't returned yet. – Avi Berger Nov 16 '22 at 22:20
  • 2
    It is odd and probably wrong that this function discards the return value returned from recursive calls. Presuming the recursion terminates, a more efficient version of this code with the same functionality would be `int step_recursion(int number, int input_steps) { return steps; }` I doubt that's really what was intended. – Avi Berger Nov 16 '22 at 22:28
  • Why does it check `new_number != 1` multiple times? I guess the `if ((new_number % 2) == 1)` should be an `else` instead. – Bob__ Nov 16 '22 at 22:29
  • 1
    Recursive functions can be hard to understand. It helps to add a `depth` parameter to the function. Then print the function arguments (including `depth`) as the first line of the function. And print a message (including `depth`) just before returning from the function. For example, the first `printf` could be `printf("begin %d -- N=%d S=%d\n", depth, number, input__steps);` and the other could be `printf("end %d -- S=%d\n", depth, steps)`. The recursive calls would look like `step_recursion(depth+1, new_n...)`. – user3386109 Nov 16 '22 at 22:46

2 Answers2

4

As far as I can see you are trying to implement the famous "Collatz conjecture". Below is a working version...

int step_recursion(int number, int steps) {
   if (number == 1) {
      return steps;
   }

   if (number % 2 == 0) {
      return step_recursion(number / 2, steps + 1);
   } else {
      return step_recursion(number * 3 + 1, steps + 1);
   }

   return steps;
}
  • In your code you are checking twice if the number is not equal to 1. Its better if you have an "early return"
  • You don't return the value of the recursion calls, you are just calling the function
  • 1
    Indeed. This is the tail function, which you could refactor into `int collatz_tail(int number, int steps) /* ... */`, then you can create an `int collatz(int number) { return collatz_tail(number, 1); }` ... and that's how that's done. – autistic Nov 16 '22 at 22:55
0

Let's go inline for a moment, then we'll cover your question, which seems excessively verbose and difficult to digest (and I'll explain that when I come back to it). Note the comments I added to this excerpt of your code...

if (new_number % 2 == 0)
{
    if (new_number != 1)
    {
        // if your intent is to control flow such that execution doesn't continue beyond here, you'd surely want a `return` statement here...
        /* return step_recursion(new_number / 2, steps + 1); */
        step_recursion(new_number / 2, steps + 1);
    }
}
if ((new_number % 2) == 1)
{
    if (new_number != 1)
    {
        /* ditto here */
        step_recursion(new_number * 3 + 1, steps + 1);
    }
}

I already described the problem fully so go read that.

My issue with your question is that it's rather lengthy, full of erroneous premises (which are kind of questions disguised as erroneous statements of fact) and unnecessary (English) boilerplate, which ought to be asked as different questions. For example:

Which book are you reading that teaches you "the function should end when it reaches the else statement"? This is a fundamental misunderstanding of C. Just to be clear, the else statement doesn't cause a function to return.

It works fine until it returns "steps" for the first time.

In other words, "it works fine until it doesn't work", which is an entirely superfluous statement that we could attach to almost any question on this network. That doesn't add meaning, though, does it? Hopefully your future questions are easier to digest, with less of this meaningless fluff.

Does anyone know why it does this????

The absence of a full problem description isn't the only reason for closure; sometimes we close questions because they have multiple built-in questions... The answer to this question is yes, but that single word answer doesn't help you understand.

Does anyone know if a function is supposed to end after it returns something?

... and to be clear, asking if something is a different question to asking why something. The answer to this different question is also yes.

TLDR; take this with a pinch of salt, but when you come here you really need to think about what information you're asking for and how to ask for that exact information without asking other questions (or injecting invalid assertions) at the same time.

autistic
  • 1
  • 3
  • 35
  • 80