Herramientas de usuario

Herramientas del sitio


variables

¡Esta es una revisión vieja del documento!


Variables

Supongamos que se declara la variable x como se muestra en la figura de abajo a la izquierda. El diagrama de la derecha nos permite definir los siguientes conceptos: variable, valor, identificador y tipo.

El identificador de una variable x es el nombre que se le da a esa variable, en este caso x. El valor es lo que almacena la variable en un instante dado, en este momento 5. Tipo es el conjunto al cual se restrigen los valores que puede almacenar la variable, en este caso int. Más específicamente un int está restringido en C a enteros comprendidos en el intervalo [-231, 231[.

Por último la variable es el área de memoria destinada a almacenar el valor y por lo tanto cuando hablemos de la variable x, no nos referimos a su identificador, si no que al espacio de memoria que ocupa. El identificador x es sólo un rótulo que permite distinguirla de otras variables.

Ejercicio

Haga un diagrama equivalente al anterior pero para la declaración:

double pi= 3.14159;

Tiempo de vida y alcance de una variable

Una variable tiene un tiempo de vida. La variable nace, es decir se crea cuando se le asigna un espacio en memoria. La variable muere, es decir se destruye cuando ese espacio es liberado para ser ocupado por otras variables.

El alcance de una variable es el o los trozos de código en donde su identificador es conocido. Típicamente un identificador es conocido solo a partir de la línea en donde se declara la variable. Pero hasta donde es válido usar el identificador varía según la clase de la variable. En C se distinguen 3 clases de variables según su tiempo de vida: globales, automáticas y dinámicas.

Variables globales

Son todas las variables que se declaran fuera de una función. Por ejemplo:

int v;
double w= 12;

int main() {
...
}

Una variable global se crea al momento de lanzar el programa (es decir cuando se crea el proceso) y solo se destruye cuando el programa termina (el proceso termina). Una variable global puede no tener un valor inicial, como la variable v más arriba. O se puede especificar una constante como valor inicial para que se asigne en el momento de lanzar el programa. El alcance de una variable global comprende desde el punto del código en donde se declara hasta el final del archivo. Pero una variable global puede quedar oculta si se declara una variable automática con el mismo nombre.

variables automáticas

La variables automáticas son las variables que se declaran dentro de una función. También se llaman variables locales. Por ejemplo en el siguiente código:

double fact(int n) {
  int p= 1.0;
  while (n>1)  {
    p*= n;
    n--;
  }
  return p;
}

El parámetro n de la función fact y la variable local p son variables automáticas. El parámetro n se crea en el momento de invocar la función y se destruye al retornar la función (tiempo de vida). La variable p se crea cuando se ejecuta la instrucción que la declara y en este caso se destruye al retornar la función.

Existen casos más sutiles como por ejemplo:

double sum_difs(double x[], double y[], int n) {
  double sum= 0.0;
  int i;
  for (i= 0; i<n; i++) {
    double max= x[i], min= y[i];
    if (max<min) {
      double t= min;
      min= max;
      max= t;
      /* Aquí se destruye t y termina su alcance */
    } 
    sum += max - min;
    /* Aquí se destruyen max y min, y termina su alcance */
  }
}

Al comienzo de una secuencia de instrucciones delimitadas por { }, se pueden declarar nuevas variables automáticas, como se observa con las variables max y t en el código de más arriba. El alcance de estas variables termina con la llave '}' que cierra la secuencia en donde se declararon. Son destruidas cuando la ejecución sale fuera del bloque en que se declaran.

Observe que variables declaradas al inicio de la función como x y sum tienen una sola reencarnación por cada invocación de sum_difs. En cambio max tendrá n reencarnaciones en total porque se crea y destruye una variable max por cada iteración del ciclo for. Por otra parte el número de reencarnaciones de t es variable. Si en una iteraciones no se cumple la condición del if interno, la variable t simplemente no se creará.

Un caso más complicado se produce al considerar la versión recursiva de fact:

double fact(int n) {
  int res= 1;
  if (fact>1) {
    res= n*fact(n-1);
  return res;
}

Si se invoca fact(6) se invocará recursivamente fact(5), fact(4), fact(3), fact(2) y fact(1). Al comienzo de fact(6) se crea la primera reencarnación de res y vive hasta el retorno final de fact(6) a pesar de que su alcance queda oculto mientras se ejecuta fact(5). Esta última crea por su parte la segunda reencarnación de res y que vive hasta el retorno de fact(5). Y así se crean nuevas reencarnaciones de res en cada llamada recursiva de fact hasta que fact(1) crea la última reencarnación.

Variables dinámicas

La última categoría de variables corresponde a las variables dinámicas. Estas son variables anónimas, es decir no poseen un identificador. Se caracterizan porque se crean explícitamente invocando la función malloc y se destruyen también explicitamente con la función free. Para entenderlas es necesario estudiar los punteros.

variables.1343566919.txt.gz · Última modificación: 2012/07/29 13:01 por lmateu