Declaración de variables
Una característica de C++, es la necesidad de declarar las variables que se usarán en un programa. Esto resulta chocante para los que se aproximan al C++ desde otros lenguajes de programación en los que las variables se crean automáticamente la primera vez que se usan. Se trata, es cierto, de una característica de bajo nivel, más cercana al ensamblador que a lenguajes de alto nivel, pero en realidad una característica muy importante y útil de C++, ya que ayuda a conseguir códigos más compactos y eficaces, y contribuye a facilitar la depuración y la detección y corrección de errores y a mantener un estilo de programación elegante.
Uno de los errores más comunes en lenguajes en los que las variables se crean de forma automática se produce al cometer errores ortográficos. Por ejemplo, en un programa usamos una variable llamada prueba, y en un punto determinado le asignamos un nuevo valor, pero nos equivocamos y escribimos prubea. El compilador o interprete no detecta el error, simplemente crea una nueva variable, y continúa como si todo estuviese bien.
En C++ esto no puede pasar, ya que antes de usar cualquier variable es necesario declararla, y si por error usamos una variable que no ha sido declarada, se producirá un error de compilación.
Cómo se declaran las variables
Ya hemos visto la mecánica de la declaración de variables, al mostrar la sintaxis de cada tipo en el capítulo 2.
El sistema es siempre el mismo, primero se especifica el tipo y a continuación una lista de variables y finalmente un punto y coma.
La declaración de variables es uno de los tipos de sentencia de C++. La prueba más clara de esto es que la declaración terminará con un ";". Sintaxis:
<tipo> <lista de variables>; |
También es posible inicializar las variables dentro de la misma declaración. Por ejemplo:
int a = 1234;
bool seguir = true, encontrado; |
Declararía las variables a, seguir y encontrado; y además iniciaría los valores de a y seguir con los valores 1234 y true, respectivamente.
En C++, contrariamente a lo que sucede con otros lenguajes de programación, las variables no inicializadas tienen un valor indeterminado (con algunas excepciones que veremos más tarde), y contienen lo que normalmente se denomina "basura". Cuando se declara una variable se reserva un espacio de memoria para almacenarla, pero no se hace nada con el contenido de esa memoria, se deja el valor que tuviera previamente, y ese valor puede interpretarse de distinto modo, dependiendo del tipo.
Ámbitos
Llamamos ámbito a la zona desde que cierto objeto es accesible.
En C++ solemos referirnos a dos tipos de ámbitos: temporal y de . Así, el ámbito temporal indica el intervalo de tiempo en el que un objeto existe o es accesible. El ámbito de nos dice desde donde es accesible.
En este capítulo hablaremos un poco sobre el ámbito de las variables, pero no entraremos en muchos detalles todavía, ya que es un tema largo.
Por otra parte, las funciones (y otros objetos de los que aún no hemos hablado nada), también tienen distintos ámbitos.
Ámbito de las variables
Dependiendo de dónde se declaren las variables, podrán o no ser accesibles desde distintas partes del programa. Es decir, su ámbito de y temporal dependerá del lugar en que se declaren.
Las variables declaradas dentro de un bucle, serán accesibles sólo desde el propio bucle, esto es, tendrán un ámbito local para el bucle. Esto es porque las variables se crean al inciar el bucle y se destruyen cuando termina. Evidentemente, una variable que ha sido destruida no puede ser accedida, por lo tanto, el ámbito de está limitado por el ámbito temporal.
Nota: En compiladores de C++ antiguos, (y en algunos modernos y mal implementados), no existe este ámbito, que sin embargo está descrito en la norma ANSI.
En estos compiladores, las variables declaradas dentro de un bucle tienen el mismo ámbito temporal y de que las variables locales. Es decir, existen y son accesibles desde el punto en que se declaren hasta el final de la función.
Si usamos uno de esos compiladores no será posible, por ejemplo, usar varios bucles con declaraciones de variables locales de bucle con el mismo nombre.
for(int i=0; i < 100; i++) HacerAlgo(i);
for(int i=0; i > -100; i--) DeshacerAlgo(i);
|
Las variables declaradas dentro de una función, y recuerda que main también es una función, sólo serán accesibles para esa función, desde el punto en que se declaran hasta el final. Esas variables son variables locales o de ámbito local de esa función.
Al igual que ocurre con las variables locales de bucle, en las de función, las variables se crean al inciar la función y se destruyen al terminar.
Las variables declaradas fuera de las funciones, serán accesibles desde todas las funciones definidas después de la declaración. Diremos que esas variables son globales o de ámbito global.
El ámbito temporal de estas variables es también global: se crean junto con el programa, y se destruyen cuando el programa concluye.
Las variables globales son las únicas que son inicializadas automáticamente con valor cero cuando se declaran. Esto no sucede con ninguna variable local.
En todos los casos descritos, el ámbito temporal coincide con el de : las variables que no pueden ser accedidas es porque no existen todavía o porque han sido destruídas. Más adelante veremos casos en que estos ámbitos no coinciden.
Una variable global declarada después de la definición de una función no será accesible desde esa función, por eso, normalmente se declaran las variables globales antes de definir las funciones.
Pero esto es hablando de forma general, en realidad, en C++ está mal visto usar variables globales, ya que se consideran poco seguras.
Ejemplo:
int EnteroGlobal; // Declaración de una variable global
int Funcion1(int a); // Declaración de un prototipo
int main() {
// Declaración de una variable local de main:
int EnteroLocal;
// a una variable local:
EnteroLocal = Funcion1(10);
// a una valiable global:
EnteroGlobal = Funcion1(EnteroLocal);
return 0;
}
int Funcion1(int a)
{
char CaracterLocal; // Variable local de funcion1
// Desde aquí podemos acceder a EnteroGlobal,
// y también a CaracterLocal
// pero no a EnteroLocal
if(EnteroGlobal != 0)
return a/EnteroGlobal;
return 0;
} |
De modo que en cuanto a los ámbitos locales tenemos varios niveles:
<tipo> funcion(parámetros) // (1)
{
<tipo> var1; // (2)
for(<tipo> var2;...) // (3)
...
<tipo> var3; // (4)
...
return var;
} |
(1) Los parámetros se comportan del mismo modo que variables locales, tienen ámbito local a la función.
(2) Las variables declaradas aquí, también.
(3) Las declaradas en bucles, son de ámbito local en el bucle.
(4) Las variables locales sólo son accesibles a partir del lugar en que se declaren. Esta variable: var3, es de ámbito local para la función, pero no es accesible en el código previo a su declaración.
Es una buena costumbre inicializar las variables locales.
Los ámbitos pueden ser alterados mediante ciertos modificadores que veremos en otros capítulos.
Enmascaramiento de variables
Generalmente no es posible, y no suele ser necesario, declarar dos variables con el mismo nombre, pero hay condiciones bajo las cuales es posible hacerlo.
Por ejemplo, podemos declarar una variable global con un nombre determinado, y declarar otra variable (del mismo tipo o de otro diferente) de forma local en una función, usando el mismo nombre.
En ese caso decimos que la segunda declaración (la local), enmascara a la primera (la global). Con eso queremos decir que el a la variable global está bloqueado o enmascarado por la local, que es a la única que podemos acceder directamente.
Por ejemplo:
int x;
int main() {
int x;
x = 10;
return 0;
} |
En este programa, cuando asignamos 10 a x estamos accediendo a la versión local de la variable x. En la función main, la variable global x está enmascarada, y no puede accederse a ella directamente.
Del mismo modo, una variable de ámbito de bucle o de ámbito de bloque puede enmascarar a una variable global o local, o a una de un bloque o bucle más externo:
int x = 10;
{
int x = 0;
for(int x = 0; x < 10; x++) HacerAlgoCon(x);
} |
En este caso la declaración de x dentro del bloque enmascara la declaración anterior, y a su vez, la declaración dentro del bucle for enmascara a la declaración del bloque.
Otra cuestión sería qué utilidad pueda tener esto.
Operador de ámbito
Existe un método para acceder a una variable global enmascarada por una variable local. Se trata del operador de ámbito, que consiste en dos caracteres de dos puntos seguidos (::).
Veremos este operador con más detalle en el capítulo dedicado a los espacios con nombre, pero veamos ahora cómo lo podemos usar para acceder a una variable global enmascarada:
int x; // Variable global
int main()
{
int x; // Variable local que enmascara a la global
x = 10; // Accedemos a la variable local
::x = 100; // Mediante el operador de ámbito accedemos a la global
return 0;
} |
El operador de ámbito, usado de este modo, permite acceder al espacio de variables global. Pero este no es más que un uso restringido del operador, que tiene muchas más aplicaciones.
Ir al Principio
Comentarios