Ámbito de variables en C (scope)

Author
By Darío Rivera
Posted on 2022-08-02 in Lenguaje C

En árticulos anteriores hemos visto declaración de variables y constantes en C. Ya tenemos todo lo necesario para entender qué es el ámbito de las variables lo que significa que ciertas variables estará disponibles únicamente para cierta parte de nuestro código.

Variables privadas (por defecto)

Las variables privadas solamente estarán disponibles en la función o bloque en el cual fueron definidas. Este es el comportamiento por defecto de una variable si no se define como externa o estática.

#include <stdio.h>

int main()
{
    pi();
    printf("PI is %d\n", pi);
}

void pi()
{
    auto int pi = 3.1416;
}

Cuando ejecutamos este programa veremos un valor de PI cada vez diferente. Esto sucede porque la variable pi está definida dentro de la función pi() y no es visible dentro de la función main(). Otro caso ocurre cuando la definimos dentro de un bloque. El siguiente programa siempre va a arrojar error ya que la variable version existe a nivel de bloque.

#include <stdio.h>

int main()
{
    if (1) {
        int version = 1;
    } else {
        int version = 0;
    }

    printf("The version for this file is: %d\n", version);
    return 0;
}

Variables estáticas

Las variables estáticas utilizan el modificador static antes del tipo de variable para indicar que es de tipo estática.

static int version = 1;

A nivel global

A nivel global una variable estática hace que las variables sean visibles solamente dentro de su propio archivo fuente.

main.c

#include <stdio.h>

static int version = 1;

int main()
{
    printf("The version for this file is: %d\n", version);
    return 0;
}

variables.c

int version = 1;

Este programa debe ser compilado de la siguiente manera.

gcc main.c variables.c

La variable version en el archivo main utiliza solamente la referencia local. Si esta variable no fuera definida como static el compilador lanzaría un error porque tenemos dos definiciones de la misma variable a nivel global.

A nivel interno

Este tipo de variables a nivel interno permiten "guardar" la inicialización de un valor en memoria. Veamos el siguiente ejemplo:

#include <stdio.h>

int add(int x)
{
    static int sum = 0;
    sum += 5;
    return sum;
}

int main()
{
    char *name = myname();
    printf("The sum is: %d\n", add(5));
    printf("The sum is: %d\n", add(5));

    return(0);
}

La salida de este programa es:

The sum is: 5
The sum is: 10

Parece extraño, pero todo radica en la ejecución de la línea

static int sum = 0;

La primera vez que se ejecuta se comporta como se espera, define la variable sum con valor cero. La segunda vez que se ejecuta la función asume que la variable ya fue definida en la primera ejecución, por lo cual ya viene con el último valor que tenía que es cinco.

Variables externas

Las variables estáticas utilizan el modificador extern antes del tipo de variable para indicar que es de tipo estática.

extern float pi;

A nivel global

Las variables externas tiene un significado muy profundo en lo relativo a aplicaciones a gran escala. En esencia permite referenciar una variable que ha sido creada en otro archivo. Veamos el siguiente ejemplo.

main.c

#include <stdio.h>

int main()
{
    printf("PI is %.4f\n", pi);
    return 0;
}

mylib.c

float pi = 3.1516;

Nota que ninguno de estos dos archivos referencia al otro con un include. Para compilar este programa debemos indicarle al compilador cada uno de estos archivos de la siguiente manera.

gcc main.c mylib.c

También puedes utilizar archivos de cabecera para abstrar un poco más el código y crear librerías. Esto lo puedes ver un poco más a fondo en nuestro artículo compilación de programas en C.

A nivel interno

A nivel interno el modificador extern hacer visible una variable que no ha sido todavía definida.

#include <stdio.h>

extern int version;

int main()
{
    printf("The version for this file is: %d\n", version);
    return 0;
}

int version = 1;

Funciones externas (por defecto)

En C las funciones por defecto son globales y externas. Esto quiere decir que podemos utilizar funciones de otros archivos impotándolas a nuestro archivo principal. El modificar por defecto es extern.

main.c

#include <stdio.h>

void say_hello();

int main()
{
    say_hello();
    return 0;
}

funciones.c

#include <stdio.h>

extern void say_hello()
{
    printf("Hello!\n");
}

Al compilar este programa no se obtiene warnings ni errores.

gcc main.c funciones.c

Funciones estáticas

Al agregar el modificar static a una función esta será visible solamente en su propio archivo fuente. Si tomas el ejemplo anterior y cambias extern por static verás un error del compilador.

Por otro lado puedes sobreescribir una función externa en un archivo agregando el modificador static.

main.c

#include <stdio.h>

static void say_hello()
{
    printf("Hello local!\n");
}

int main()
{
    say_hello();
    return 0;
}

funciones.c

#include <stdio.h>

extern void say_hello()
{
    printf("Hello!\n");
}

Acerca de Darío Rivera

Author

Ingeniero de desarrollo en PlacetoPay , Medellín. Darío ha trabajado por más de 6 años en lenguajes de programación web especialmente en PHP. Creador del microframework DronePHP basado en Zend y Laravel.

Sólo aquellos que han alcanzado el éxito saben que siempre estuvo a un paso del momento en que pensaron renunciar.