Variables locales y globales.
El concepto de variable local y global es netamente un artificio para ayudar al programador en la construcción de programas complejos, y consiste en hacer que las variables declaradas en un programa estén, por así, decir, "coloreadas". Como ya se ha dicho, un programa en C es una colección de funciones. Supongamos que se asigna un color distinto a las variables locales de cada función del programa. Desde el punto de vista del lenguaje máquina, no hay limitaciones, y cualquier elemento de código puede puede hacer uso de cualquier variable situada dentro del espacio de memoria reservado para el proceso en que nos encontremos. Pero el lenguaje C impone una restricción: las funciones sólo pueden acceder a las variables de su propio "color", esto es, a las variables declaradas dentro de la propia función. Esto haría imposible comunicar entre sí los subprogramas, que no podrían usar información de otros programas, así que se admite que las variables declaradas fuera de toda función no tienen color, y por tanto se puede acceder a ellas desde cualquier función: se denominan variables
globales
.
Puede darse el caso de que exista una variable global con un cierto nombre, y otra de igual nombre en el programa principal o en un subprograma. Entonces se produciría un
conflicto
, y hay que especificar una regla para resolverlo. La regla dice, simplemente, que
la variable local prima sobre la global dentro del subprograma
. Esto es, aun cuando dentro de un subprograma resulten visibles una variable local y otra global de igual nombre, se entiende que toda alusión a ese nombre de variable se refiere a la variable local. Por tanto,
la variable global quedará oculta para el subprograma
. Veamos un ejemplo de todo esto.
Ejemplo
.- Construir un programa que ilustre el uso de variable locales y globales.
#include<stdio.h>
int global_1 = 1, global_2 = 2, global_3 = 3;
void funcion_a(void);
void funcion_b(void);
int main(int argc, char * argv[])
{
int local_main_1 = 11, local_main_2 = 22;
int global_1 = 111;
funcion_a();
funcion_b();
printf("Valores en main():\n\n");
printf("local_main_1 = %d\n", local_main_1);
printf("local_main_2 = %d\n", local_main_2);
printf("global_1 = %d\n", global_1);
printf("global_2 = %d\n", global_2);
printf("global_3 = %d\n", global_3);
}
void funcion_a(void)
{
int local_a_1 = 111, local_a_2 = 222;
int global_2 = 222;
printf("Valores en funcion_a():\n\n");
printf("local_a_1 = %d\n", local_a_1);
printf("local_a_2 = %d\n", local_a_2);
printf("global_1 = %d\n", global_1);
printf("global_2 = %d\n", global_2);
printf("global_3 = %d\n", global_3);
}
void funcion_b(void)
{
int local_b_1 = 1111, local_b_2 = 2222;
int global_3 = 333;
printf("Valores en funcion_b():\n\n");
printf("local_b_1 = %d\n", local_b_1);
printf("local_b_2 = %d\n", local_b_2);
printf("global_1 = %d\n", global_1);
printf("global_2 = %d\n", global_2);
printf("global_3 = %d\n", global_3);
}
/*
Valores en funcion_a():
local_a_1 = 111
local_a_2 = 222
global_1 = 1
global_2 = 222
global_3 = 3
Valores en funcion_b():
local_b_1 = 1111
local_b_2 = 2222
global_1 = 1
global_2 = 2
global_3 = 3333
Valores en main():
local_main_1 = 11
local_main_2 = 22
global_1 = 111
global_2 = 2
global_3 = 3
*/
Este programa se comporta, según puede verse en los resultados que se muestra, como si las variables estuvieran "coloreadas", con excepción de las variables globales. En el gráfico que se muestra a continuación, la columna de la izquierda muestra las variables globales y, para cada función, las variables declaradas localmente. A la derecha se muestra, para cada función, la lista de variables a la que tiene acceso, y el tipo de acceso:
-
La función
funcion_a()
tiene acceso a
local_a_1
,
local_a_2
y
global_2
, que son sus variables locales, y también a
global_1
y
global_3
, que son variables globales. Se ha marcado en
rojo
el acceso a
global_2
, que es local, según las reglas especificadas para el caso de coincidencia (colisión, en la jerga informática) entre el nombre de una variable local y una variable global. La función
funcion_a()
no tiene acceso a la variable global llamada
global_2
.
-
La función
funcion_b()
tiene acceso a
local_b_1
,
local_b_2
y
global_3
, que son sus variables locales, y también a
global_1
y
global_2
, que son variables globales. Se ha marcado en
rojo
el acceso a
global_3
, que es local, según las reglas especificadas para el caso de coincidencia (colisión, en la jerga informática) entre el nombre de una variable local y una variable global. La función
funcion_b()
no tiene acceso a la variable global llamada
global_3
.
-
La función
main()
tiene acceso a
local_main_1
,
local_main_2
y
global_1
, que son sus variables locales, y también a
global_2
y
global_3
, que son variables globales. Se ha marcado en
rojo
el acceso a
global_1
, que es local, según las reglas especificadas para el caso de coincidencia (colisión, en la jerga informática) entre el nombre de una variable local y una variable global. La función
main()
no tiene acceso a la variable global llamada
global_1
.
|
Funciones
|
Variables y tipos de acceso
|
funcion_a()
|
Variable
|
Acceso
|
local_a_1
|
local
|
local_a_2
|
local
|
global_1
|
global
|
global_2
|
local
|
global_3
|
global
|
|
funcion_b()
|
Variable
|
Acceso
|
local_b_1
|
local
|
local_b_2
|
local
|
global_1
|
global
|
global_2
|
global
|
global_3
|
local
|
|
main()
|
Variable
|
Acceso
|
local_main_1
|
local
|
local_main_2
|
local
|
global_1
|
local
|
global_2
|
global
|
global_3
|
global
|
|
|
Problema de las variables globales
.
El paso de información entre funciones puede hacerse mediante dos mecanismos:
-
Variables globales, visibles desde el subprograma
-
Paso de parámetros
El mecanismo consistente en emplear variables globales consiste en hacer que una función (
funcion_a()
, por ejemplo) almacene un valor en una variable global (
global_1
, por ejemplo). Entonces la función
funcion_b()
podrá leer el valor escrito por
funcion_a()
en
global_1
, puesto que tiene acceso global a ella. Este mecanismo, perfectamente viable, tiene un dos problemas potenciales:
-
Al ser visible
global_1
desde (en principio) todas las funciones, podría ocurrir que un paso de información entre una pareja de funciones dada destruyera información utilizada por otra función. En otras palabras, los valores de las variables globales no son "seguros", porque pueden ser modificados sin advertencia previa por cualquier otra función. Por esta razón, se tiende a limitar al máximo la creación de variables globales, o a utilizarlas como constantes, y no como método de comunicación entre programas.
-
Además, un subprograma basado en variables globales queda ligado a ellas: no podrá funcionar si esas variables no se definen globalmente en el programa. Ahora bien, una de las metas de la programación es la reutilización del código, esto es, aprovechar subprogramas ya escritos para construir nuevas aplicaciones con un mínimo de modificaciones y restricciones. Si se puede aprovechar el código del subprograma tal y como se escribiera, sin necesidad de hacer cambios ni de añadir variables globales, se habrá alcanzado el objetivo de la reutilización.
Estas dos razones (la inseguridad de las variables globales y la dificultad añadida para reutilizar código basado en ellas) hacen que resulte preferible una comunicación entre subprogramas basada en el
paso de parámetros
.