How to "clean" static variables?

3

In C ++ static variables are very important. Let's suppose I want to make a factorial that uses recursion.

unsigned long long int RecursionFatorial(unsigned int fator)
{
    static long long int FatReturn;
    if(fator == 0)
    {
        unsigned long long int FatReturn_ = FatReturn;
        FatReturn = 0;
        return FatReturn_;
    }
    else
    {
        if(FatReturn == 0) FatReturn = 1;
        FatReturn *= fator;
        RecursionFatorial(fator - 1);
    }
}

The code runs and gives the expected result, but the code gets bigger: you have to create new variables (not static) to be able to reset variables that are static, check if the new one is zero to change the value (first call ) and causes unnecessary memory occupancy. How should we make good use of static variables and then clean them?

    
asked by anonymous 05.02.2014 / 17:25

2 answers

9

A static variable (declared within a method) will maintain its value between successive calls. If you do not want to keep the value between successive calls, why not just use local (non-static) variables? The recursive factorial could be implemented more simply (even without local or static variables):

unsigned long long int RecursionFatorial(unsigned int fator)
{    
    if(fator == 0)
    {
        return 1;        
    }
    else
    {
        return fator * RecursionFatorial(fator - 1);
    }
}
    
05.02.2014 / 17:37
5

If you need this, something is wrong with your design.

Static variables in functions should be used to store a global state , not a momentary state of the operation.

First, you do not need a state for a recursive function. You can use the return value directly:

unsigned long long fatorial(unsigned fator) {
    return fator == 0 ? 1 : fator * fatorial(fator-1);
}

Another common way is to use a parameter to save the state:

unsigned long long fatorial(unsigned fator, unsigned long long resultado = 1) {
    return fator == 0 ? resultado : fatorial(fator - 1, resultado * fator);
}

But if you insist on having a state, you can use an object. After all objects were made to have states:

struct Fatorial {
    unsigned long long resultado ;
    Fatorial() : resultado (1) {}
    unsigned long long calc(unsigned fator) {
        if (fator > 0) {
            resultado *= fator;
            calc(fator-1);
        }
        return resultado;
    }
}

Fatorial().calc(4) // 24

Note that this is a mess and is by far the ideal for a recursion.

Now answering the question in fact:

unsigned long long fatorial(unsigned fator, bool reset=true)
{
    static unsigned long long resultado;
    if (reset) resultado = 1;
    if (fator > 0) {
        resultado *= fator;
        fatorial(fator-1, false);
    }
    return resultado;
}
    
05.02.2014 / 17:47