-2

I'm writing a program that prints out the first 10 natural numbers in recursion. First off, I'm putting a parameter "--num"

int natural_numbers(int num) {
    if (num > 1) // Base case
        natural_numbers(--num);
    printf("%d ", num);
}
Input: 10
Output: 1 1 2 3 4 5 6 7 8 9

And then I changed the parameter to "num - 1" and it prints out what I was expected.

int natural_numbers(int num) {
    if (num > 1) // Base case
        natural_numbers(num - 1);
    printf("%d ", num);
}
Input: 10
Output: 1 2 3 4 5 6 7 8 9 10

I have no idea why the first one ouput was wrong. I need some help.

Steffen Moritz
  • 7,277
  • 11
  • 36
  • 55

4 Answers4

1

num - 1 creates a new temporary int, as a copy of num, and subtracts 1 from that temporary int.

--num subtracts 1 from num itself.

Also, note that your function natural_numbers should be void. It now says int but you don't return anything so your program really has Undefined Behaviour.

You could use a debugger and step through your program to see when things go bad, or add some debugging prints. This is your original program with prints before and after the recursive call. The number before and after should be the same for the algorithm to work, and as you will see, they are not.

#include <iostream>
#include <string>

void natural_numbers(int num) {
    static size_t indent = 0;
    std::cout << std::string(indent, ' ') << "num before: " << num << "\n";
    if(num > 1) { // Base case
        ++indent;
        natural_numbers(--num);
        --indent;
    }
    std::cout << std::string(indent, ' ') << "num after: " << num << "\n";
}

int main() {
    natural_numbers(10);
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • Thanks, I get it, but why it prints number 1 twice and missing number 10? – Jack Nguyen Jul 07 '19 at 17:17
  • Since you change num before you print it, 10 can't be printed (if 10 is your original input number). 1 is printed for the same reason. When num==2 you change num and call natural_numbers which willl print 1, and when the call returns, you print 1 again. – Ted Lyngmo Jul 07 '19 at 17:17
1

In first part you change num value with pre-decrement -- operator. Your second code doesn't change num value (it pass temporary num - 1 value to function call).

So if you next printf num value it is different. In first code part it is decrement by one, and in second part it is original num value.

If you originaly call natural_numbers with num == 10, below you can track how its value change/not change in next lines.

                                  //      num (its value)
int natural_numbers(int num) {    //       10
    if (num > 1) // Base case     //       10
        natural_numbers(--num);   //       10 / and 9 (after execution)
    printf("%d ", num);           //        9
}

int natural_numbers(int num) {    //       10
    if (num > 1) // Base case     //       10
        natural_numbers(num - 1); //       10
    printf("%d ", num);           //       10
}

BartekPL
  • 2,290
  • 1
  • 17
  • 34
0

If you want to pass num - 1 to a function (as in fact you do here), the way to do that is to simply call natural_numbers(num - 1). Nothing fancy needed. It's no coincidence that's the way that works.

C's special ++ and -- operators do more -- significantly more -- than just add or subtract 1. They add or subtract 1, and they store the incremented or decremented variable back into the original location. So --num doesn't just subtract 1 from num, it stores the value num - 1 back into num. But that's not what you want here. You don't want to modify num, because on each recursive call, you want to print out the value of num you started with, not the decremented version you passed down into the recursion.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
-1

You think we would want to call that function by num 3

when you use --num its just like you are changing that entered number in the natural_function so

the local stack when natural_numbers(3) called is look like

// =========call natural_number(3)

natural_number(2) // --num (change num itself. its like num = num - 1 then pass it)

// But here in this local stack  block "num" becomes 2 

print 2 // <== here it prints 2 on the backward step

// ========= call natural_number(2)

natural_number(1) // --num (change num itself. its like num = num - 1 then pass it)

// But here in this local stack  block "num" becomes 1

print 1 // <== Here it prints 1 on the backward step

// ========= call natural_number(1)

print 1 // Here we go out of stack by printing 1  

Result: 1 1 2

Now if we would call that function with (num - 1) it means you dont want to change the "num" variable entering in own local stack block.

The local stack for (num - 1) will be like this:

// ========= call natural_number(3)

natural_number(2) // (num - 1) (num wont change. its like temp = num - 1 then pass temp to it)

print 3 // Here it prints 3 on the backward step

// ========= call natural_number(2)

natural_number(1) // (num - 1) (num wont change. its like temp = num - 1 then pass temp to it)

print 2 // <== Here it prints 2 on the backward step

// ========= call natural_number(1)

print 1 // Here we go out of stack by returning 1  

Result: 1 2 3
Ehsan Ahmadi
  • 1,382
  • 15
  • 16