66 - Variables locales static


Ver video

Hemos visto que cuando definimos una variable local su valor se pierde inmediatamente cuando finaliza la función.

En el lenguaje C podemos definir variables locales que no pierdan su valor entre llamadas mediante el modificador static.

Veamos con dos programas la diferencia entre definir una variable local y una variable local static:

Programa: programa211.c

#include<stdio.h>
#include<conio.h>

void imprimir()
{
    int x=0;
    x++;
    printf("%i ",x);
}


int main()
{
    imprimir();
    imprimir();
    imprimir();
    getch();
    return 0;
}

Como sabemos el resultado de ejecutar este programa es:

variable local en C

Cada vez que se llama a la función imprimir se define una variable local llamada x, se la inicializa con 0 y luego se la incrementa en uno y se imprime su valor.

Si queremos que la variable x no pierda su valor entre llamadas a la función imprimir se le antecede el modificador static:

Programa: programa212.c

#include<stdio.h>
#include<conio.h>

void imprimir()
{
    static int x=0;
    x++;
    printf("%i ",x);
}


int main()
{
    imprimir();
    imprimir();
    imprimir();
    getch();
    return 0;
}

Ejecutando este programa tenemos como resultado una salida:

variable local static en C

Cuando se define una variable local como static se reserva espacio para la misma antes de ser llamada a la función y se inicializa con el valor que le asignamos. Esto significa que la variable local x existe previo a llamar a la función.

El contenido de la variable local static solo se le puede modificar o consultar dentro de dicha función.

Es muy importante tener en cuenta que en cada llamada a la función imprimir no se esta definiendo una variable local x e inicializandola en cero, podemos decir que la línea:

    static int x=0;

se ejecuta antes de ser llamada la función. Cuando llamamos a la función se ejecutan las líneas:

    x++;
    printf("%i ",x);

Es decir que en cada llamada a la función imprimir se incrementa en uno la variable static x y se muestra su contenido.

Si bien este problema se puede resolver utilizando una variable global es más conveniente resolverlo con una variable local static:

#include<stdio.h>
#include<conio.h>

int x=0;

void imprimir()
{
    x++;
    printf("%i ",x);
}

int main()
{
    imprimir();
    imprimir();
    imprimir();
    getch();
    return 0;
}

Siempre que se pueda hay que evitar la definición de variables globales.

Si una variable local static no se asigna un valor inicial automáticamente se carga el cero, en el problema anterior si no iniciamos x el resultado es el mismo:

void imprimir()
{
    static int x;
    x++;
    printf("%i ",x);
}

Problema 1:

Generar un número aleatorio entre 1 y 100. Pedir que el operador lo adivine mostrando un mensaje si gano o si el número a adivinar es menor o mayor al propuesto.
Permitir solo tres intentos.

Programa: programa213.c

#include<stdio.h>
#include<conio.h>
#include<time.h>

int verificarFin()
{
    static int intentos=3;
    intentos--;
    if (intentos==0)
    {
        printf("Perdio, solo tenia 3 intentos");
        return 1;
    }
    return 0;
}

int jugar()
{
    srand(time(NULL));
    int numero = rand() % 100 + 1;
    int valor;
    do {
        printf("Adivina el numero que pense entre 1 y 100:");
        scanf("%i",&valor);
        if (valor==numero)
        {
            printf("Ganaste");
            break;
        }
        else
            if (valor<numero)
                printf("El numero que pense es mayor\n");
            else
                printf("El nuemro que pense es menor\n");
    } while(verificarFin()==0);
}


int main()
{
    jugar();
    getch();
    return 0;
}

En la función main solo llamamos a la función jugar:

int main()
{
    jugar();
    getch();
    return 0;
}

La función jugar genera un valor aleatorio comprendido entre 1 y 100:

int jugar()
{
    srand(time(NULL));
    int numero = rand() % 100 + 1;

Luego entramos a una estructura repetitiva donde le solicitamos al operador que ingrese un valor comprendido entre 1 y 100 y le mostramos un mensaje si gano o si el valor pensado por la máquina es mayor o menor:

    int valor;
    do {
        printf("Adivina el numero que pense entre 1 y 100:");
        scanf("%i",&valor);
        if (valor==numero)
        {
            printf("Ganaste");
            break;
        }
        else
            if (valor<numero)
                printf("El numero que pense es mayor\n");
            else
                printf("El nuemro que pense es menor\n");

El do/while se repite mientras la función verificarFin retorne un cero:

    } while(verificarFin()==0);

La función verificarFin es donde empleamos una variable local static que representa la cantidad de intentos que puede el operador ingresar, como son tres intentos inicializamos el contador en 3 y cada vuelta le restamos 1:

int verificarFin()
{
    static int intentos=3;
    intentos--;
    if (intentos==0)
    {
        printf("Perdio, solo tenia 3 intentos");
        return 1;
    }
    return 0;
}

Problema propuesto

Solución

programa214.c

#include<stdio.h>
#include<conio.h>

int proximoMultiplo2()
{
    static int mult2;
    mult2+=2;
    return mult2;
}


int main()
{
    int f;
    for(f=1;f<=10;f++)
        printf("%i ",proximoMultiplo2());
    getch();
    return 0;
}

Retornar