Tutorial de programación en C para Linux Parte 10 – Ámbitos de las variables

Si estás siguiendo nuestra serie de tutoriales de programación en C, deberías conocer el concepto de variables. Aunque ya hemos hablado de los fundamentos de las variables, hay otro aspecto importante relacionado con las variables que vamos a tratar aquí: el ámbito de las variables.

Empecemos con el código de intercambio de valores que utilizamos en uno de nuestros tutoriales anteriores:

#include <stdio.h>

void swap (int val1, int val2)
{
int temp = 0;

temp = val1;
val1 = val2;
val2 = temp;

printf("\nSwapped values are: %d and %d", val1,val2);

}

int main()
{
int a=0, b=0;

printf("Enter two integer values\n");

scanf("%d %d",&a,&b);

printf("Entered values are: %d and %d", a,b);

swap(a,b);

return 0;
}

Aquí, en este trozo de código, las variables ‘val1’ y ‘val2’ tienen ámbito local, lo que significa que cobran vida cuando se llama a la función ‘swap’ y mueren en cuanto termina la llamada a ‘swap’. Simplemente no puedes acceder a ‘val1’ y ‘val2’ antes o después de la llamada a la función ‘swap’. Del mismo modo, el ámbito de las variables ‘a’ y ‘b’ también es local – local a la función ‘main’.

Ten en cuenta que estas variables de ámbito local también se conocen como variables automáticas.

Ahora bien, mientras que las variables de ámbito local se limitan al bloque en el que se declaran, hay otro tipo de variables cuyo ámbito es global. Como su nombre indica, las variables de ámbito global pueden utilizarse en todas las funciones. Por ejemplo, la variable «var» es una variable entera global, y puede utilizarse tanto en la función «main» como en la función «swap».

#include <stdio.h>

int var;

void swap (int val1, int val2)
{
int temp = 0;

temp = val1;
val1 = val2;
val2 = temp;

printf("\nSwapped values are: %d and %d", val1,val2);

}

int main()
{
int a=0, b=0;

printf("Enter two integer values\n");

scanf("%d %d",&a,&b);

printf("Entered values are: %d and %d", a,b);

swap(a,b);

return 0;
}

Por defecto, a las variables globales se les asigna el valor «0». Pero no ocurre lo mismo con las variables locales: tienes que asignarles un valor cuando se definen, de lo contrario tienen un valor basura. Por ejemplo, en el siguiente programa:

#include <stdio.h>

int var;

int main()
{
int a;

printf("Local variable 'a' currently holds: %d", a);

printf("\n Global variable var currently holds: %d", var);


return 0;
}

Hay muchas posibilidades de que obtengas un valor distinto de cero para ‘a’. En cambio, ‘var’ siempre será cero al principio.

Siguiendo, ¿puede haber variables globales y locales con el mismo nombre? Pues la respuesta es sí. Bien, entonces qué producirá el siguiente trozo de código en la salida:

#include <stdio.h>

int var = 5;

int main()
{
int var = 10;

printf("Local variable 'a' currently holds: %d", var);

printf("\n Global variable var currently holds: %d", var);


return 0;
}

Bueno, la salida será «10» en ambos casos. La razón es que la variable local ‘var’ anulará a la global ‘var’. Así que la siguiente pregunta lógica es, ¿cómo acceder a la variable global ‘var’ dentro de ‘main’ en este caso? Desgraciadamente, la respuesta es NO. De hecho, debes evitar meterte en situaciones como ésta cuando trabajes con el lenguaje C.

A continuación viene el concepto de variables «externas». En términos sencillos, al utilizar la palabra clave «extern» con cualquier declaración de variable, le estás diciendo al compilador que esta variable ya está declarada/definida en otro lugar y que sólo la estamos utilizando aquí. Por ejemplo, en el siguiente fragmento de código, el compilador no sabe que ‘var’ existe cuando intenta compilar la sentencia printf dentro de la función principal.

#include <stdio.h>

int main()
{

printf("\n Global variable var currently holds: %d", var);


return 0;
}

int var = 5;

Por eso obtiene un error como el siguiente durante la compilación:

main.c: In function ‘main’:
main.c:14:58: error: ‘var’ undeclared (first use in this function)
printf("\n Global variable var currently holds: %d", var);
^
main.c:14:58: note: each undeclared identifier is reported only once for each function it appears in

Pero si declaras ‘var’ como extern aquí, verás que todo funciona bien. Esto se debe a que el compilador llega finalmente a la declaración original de ‘var’.

#include <stdio.h>

int main()
{
extern int var;

printf("\n Global variable var currently holds: %d", var);


return 0;
}

int var = 5;

Y obtiene la salida correcta:

Global variable var currently holds: 5

Así es como funciona extern. Las variables externas se utilizan a menudo cuando tu programa/proyecto está dividido en varios archivos de código fuente y quieres, por ejemplo, utilizar en ‘archivo1’, una variable definida en ‘archivo2’.

Y por último, ya que estamos hablando de ámbitos de variables, sería mejor que habláramos aquí también de las variables «estáticas». Las variables estáticas son especiales en el sentido de que conservan su valor incluso después de salir del ámbito. Esto significa que sólo se inicializan una vez, que es la primera.

static int counter 

A continuación se muestra un fragmento de código que utiliza una variable estática para contar el número de veces que se llama a una función.

#include <stdio.h>

int swap (int val1, int val2)
{
static int counter = 1;
int temp = 0;

temp = val1;
val1 = val2;
val2 = temp;

printf("\n Function called %d times\n", counter);
counter++;
}

int main()
{
int a=9, b=4;

swap(a,b);
swap(a,b);
swap(a,b);

return 0;
}

Este es el resultado:

 Function called 1 times 

Function called 2 times

Function called 3 times

Como puedes ver, la variable «contador» conserva su valor incluso después de salir del ámbito. Al igual que las variables globales, las variables estáticas también tienen un valor por defecto de «0».

Conclusión

En este tutorial hemos tratado varios conceptos importantes, todos ellos relacionados con el ámbito de las variables en el lenguaje de programación C. No olvides crear tus propios programas para comprender mejor la diferencia entre las variables externas, estáticas, globales y locales. Y como siempre, en caso de cualquier duda o consulta, deja un comentario abajo.

También te podría gustar...