Question

I am from C background, and now I am learning OOP using C++

Below is a program that calculates factorial.

#include <iostream>

using namespace std;

void main ()
{
    char dummy;
    _int16 numb;
    cout << "Enter a number: ";
    cin >> numb;

    double facto(_int16);

    cout << "factorial = " <<facto(numb);
    cin >> dummy;
}

double facto( _int16 n )
{
    if ( n>1 )
        return ( n*facto(n-1) );
    else
        return 1;
}

The above code works fine.

But if I replace the return statement

    return ( n*facto(n-1) );  

with this

    return ( n*facto(n--) );

then it doesn't work. The n-- won't decrement n by 1. Why?

I am using Visual Studio 2012

Edit:Got it! thanks :)
*also, I would like to add to the answers below: using --n will cause the n to decrement before the statement is executed. So, due to pre-decrement, the expression will become (n-1)*facto(n-1) . That is why it is better not to use pre-decrement in this case *

Was it helpful?

Solution 2

EDIT:: The explanation below is only to shed light on the usage of Post and Pre-Decrement for OP's better understanding of them. The correct answer for OP's code is, n*facto(n - 1). @OP: You should not do any pre-drecrement in that part of your code because it will invoke Undefined Behavior due to unsequenced modification of variable n.

Pre And Post-Decrement:: You have to use pre-decrement (wiki-link) if you want to decrement the variable before the value is passed. On the other hand, a post-decrement evaluates the expression before the variable is decremented:

int n = 10, x;
x = --n;                // both are 9

and

int n = 10, x;
x = n--;                // x = 10, i = 9

Why not to use pre-decrement in your case?:: n*facto(n--) causes UB. Why?

The Standard in §5/4 says

Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression.

and

The prior value shall be accessed only to determine the value to be stored.

It means, that between two sequence points a variable must not be modified more than once and, if an object is written to within a full expression, any and all accesses to it within the same expression must be directly involved in the computation of the value to be written.

OTHER TIPS

Currently, by using n-- you are passing the original and therefore unmodified value of n into facto which is causing a loop.

You need to use n - 1 instead. It would, on the face of it, be tempting to use --n since that would decrement n and evaluate to the new (lower) value. But --n will give you undefined behaviour since you are pre-multiplying the function return value by n and since * is not a sequence point, the value of n is not well-defined.

(By the way, the behaviour in C would have been identical).

[Edit: acknowledge Mike Seymour on the undefined behaviour point].

return ( n*facto(n--) );

You are using the post decrement operator. What happens is, You pass the value of n to the function and then decrement it. That doesn't affect the value that is already passed to the function

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top