Home > OS >  Reversing a number in C using Recursion
Reversing a number in C using Recursion

Time:02-02

When i write this code, It does the job but also prints some random stuff.

If my input is 32, it prints 23 followed a line of random numbers . example:

23 983748572819937482

I wanna know what these random numbers are and why they are being printed

#include <iostream>

using namespace std;

int reverse(int n) {
    if (n == 0) {
        cout << " ";
        return 0;
    }
    else {
        int lastdigit = n % 10;
        int firstdigit = n / 10;
        cout << lastdigit << reverse(firstdigit);
    }
}

int main() {
    int n;
    cin >> n;
    reverse(n);
}

CodePudding user response:

You should always compile with warnings enabled and as a beginner always have treat warnings as errors.

If you do that you would see that reverse doesn't return a value on all paths. As such when you do cout << reverse (firstdigit); you try to print what reverse returns and that is Undefined Behavior.

If you implement the function like this (by printing inside it) your function doesn't need to return a value. So this will work:


void reverse(int n) {
    if (n==0){
        cout << " ";
    }
    else {
    
     int lastdigit = n;
     int firstdigit = n/10;
     cout << lastdigit;

     reverse (firstdigit);
   }
}

However I don't think that is the intent of the exercise. I think your function should return the reversed number, not print it. So think about how you would modify the function to achieve this.

CodePudding user response:

As you're not capturing the return value, this function should be void, and can be used like this:

void reverse(int n) {
    if (n==0){
        cout << n
        return;
    }
    else {

        int lastdigit = n;
        int firstdigit = n/10;
        cout << lastdigit;
        if(firstdigit != 0) 
            reverse (firstdigit);
    }
}

Also the notation of "firstdigit" implies that its only the first digit, though its actually the rest of the number. I.E: 545/10 = 54

CodePudding user response:

I wanna know what these random numbers are and why they are being printed.

The weird numbers come from the second call to reverse: that call doesn't return anything, but cout << reverse(firstdigit) is still executed, leading to undefined consequences.

You can see it better if you annotate the code and print out whenever you enter and exit the reverse function:

[Demo]

#include <cstdint>  // intptr_t
#include <iostream>

using namespace std;

int reverse(int n) {
    std::cout << "\nCalling reverse(" << n << ") >>>\n";
    if (n == 0) {
        cout << " ";
        std::cout << "\n<<< Returning " << 0 << " from reverse(" << n << ")\n";
        return 0;
    }
    else {
        int lastdigit = n % 10;
        int firstdigit = n / 10;
        cout << lastdigit << reverse(firstdigit);
        std::cout << "\n<<< UB: callers might see a return value of " 
            << reinterpret_cast<std::intptr_t>(&cout) << " from reverse(" << n << ")\n";
    }
}

int main() {
    int n;
    cin >> n;
    reverse(n);
}

// Outputs:
//
//   Calling reverse(32) >>>
//   2
//   Calling reverse(3) >>>
//   3
//   Calling reverse(0) >>>
//    
//   <<< Returning 0 from reverse(0)
//   0
//   <<< UB: callers might see a return value of 4210816 from reverse(3)
//   4210816
//   <<< UB: callers might see a return value of 4210816 from reverse(32)

The traces show:

  • reverse(32)is called. cout << lastdigit prints 2 and then we call reverse(lastdigit).
  • reverse(3) is called. cout << lastdigit prints 3 and then we call reverse(lastdigit).
  • reverse(0) is called. cout << " " prints , and 0 is returned.
  • Now we are back to the reverse(3) call; we had printed out 3, and we print the int value returned from reverse(firstdigit), which is a 0. And we return from this call to reverse without a return statement. gcc warns us about this with warning: control reaches end of non-void function [-Wreturn-type].
  • Finally, we are back to the reverse(32) call; we had printed out 2, and we print the int value returned from reverse(firstdigit). Using a return value from a function declared to return a value and that didn't explicitly return it is undefined behaviour.

The caller to reverse(3) is getting whatever it is where the return value should be (e.g. EAX register). In this case, it happens to be the result of the last expression evaluated in the reverse(3) call, the value returned by operator<<, std::cout&.


One possible fix: change the reverse function so that it doesn't return anything and just print the numbers.

[Demo]

#include <iostream>  // cout

void reverse(int n) {
    if (n <= 9) {
        std::cout << n;
    }
    else {
        std::cout << n;
        reverse(n/10);
    }
}

int main() {
    for (int n : { 0, 5, 15, 125 })
    {
        reverse(n);
        std::cout << "\n";
    }
}
  •  Tags:  
  • Related