Herramientas de usuario

Herramientas del sitio


variables

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
variables [2012/08/04 00:45] – [Variables globales] lmateuvariables [2014/08/06 16:20] (actual) lmateu
Línea 1: Línea 1:
-===== Variables =====+====== 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. 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.
Línea 9: Línea 9:
 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. 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 ====+=== Ejercicio ===
  
 Haga un diagrama equivalente al anterior pero para la declaración: Haga un diagrama equivalente al anterior pero para la declaración:
Línea 17: Línea 17:
 </code> </code>
  
-==== Tiempo de vida y alcance de una variable ====+===== 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.+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.+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 ====+===== Variables globales =====
  
 Son todas las variables que se declaran fuera de una función.  Por ejemplo: Son todas las variables que se declaran fuera de una función.  Por ejemplo:
Línea 40: Línea 40:
 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. 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 ====+===== 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: 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:
Línea 46: Línea 46:
 <code> <code>
 double fact(int n) { double fact(int n) {
-  int p= 1.0;+  double p= 1.0;
   while (n>1)  {   while (n>1)  {
     p*= n;     p*= n;
Línea 57: Línea 57:
 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. 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:+Existen casos más sutiles para el tiempo de vida de una variable automática como por ejemplo:
  
 <code> <code>
Línea 80: Línea 80:
              
 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á. 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á.
 +
 +==== Inicialización ====
 +
 +Es importante destacar que si la declaración de una variable automática no incluye un valor inicial, éste queda indeterminado y //¡rara vez resulta ser 0!//  Acceder al valor de una variable automática no inicializada es un error de programación en el 99.9% de los casos.  Esto contrasta con la variables globales que al no ser inicializadas toman el valor 0 por omisión.
  
 === Ejercicio: uso incorrecto de variables === === Ejercicio: uso incorrecto de variables ===
Línea 101: Línea 105:
 El problema con este programa es que se usa la variable v sin haberle dado un valor inicial.  El supuesto del programador es que v conserva su valor de una iteración a la otra.  Pero esto constituye un error conceptual, aun cuando muchos compiladores no diagnostican el problema.  De hecho, los compiladores no están obligados a entregar un error.  Peor aún: ¡esto podría funcionar!  Acá la creación y destrucción de la variable v es solo conceptual.  Un compilador generaría un código muy ineficiente si efectivamente creara y destruyese la variable v en cada iteración del for.  Cuando el compilador genera el código para una función, calcula cuál es espacio máximo que necesita para almacenar todas sus variables y asigna su memoria en la pila al inicio de la función.  El costo de esta asignación de memoria es marginal: sumar una constante al puntero a la pila.  Por lo tanto la declaración de variables dentro del cuerpo de un ciclo tiene costo 0. El problema con este programa es que se usa la variable v sin haberle dado un valor inicial.  El supuesto del programador es que v conserva su valor de una iteración a la otra.  Pero esto constituye un error conceptual, aun cuando muchos compiladores no diagnostican el problema.  De hecho, los compiladores no están obligados a entregar un error.  Peor aún: ¡esto podría funcionar!  Acá la creación y destrucción de la variable v es solo conceptual.  Un compilador generaría un código muy ineficiente si efectivamente creara y destruyese la variable v en cada iteración del for.  Cuando el compilador genera el código para una función, calcula cuál es espacio máximo que necesita para almacenar todas sus variables y asigna su memoria en la pila al inicio de la función.  El costo de esta asignación de memoria es marginal: sumar una constante al puntero a la pila.  Por lo tanto la declaración de variables dentro del cuerpo de un ciclo tiene costo 0.
  
-=== Variables y funciones recursivas ===+===== Variables y funciones recursivas =====
  
 Un caso más complicado se produce al considerar la versión recursiva de fact: Un caso más complicado se produce al considerar la versión recursiva de fact:
Línea 107: Línea 111:
 <code> <code>
 double fact(int n) { double fact(int n) {
-  int res= 1; +  double res= 1; 
-  if (fact>1) {+  if (n>1) {
     res= n*fact(n-1);     res= n*fact(n-1);
 +  }
   return res;   return res;
 } }
Línea 116: Línea 121:
 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. 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 ====+===== 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 explícitamente con la función free.  Para entenderlas es necesario estudiar los [[punteros|punteros]]. 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 explícitamente con la función free.  Para entenderlas es necesario estudiar los [[punteros|punteros]].
  
  
variables.1344041114.txt.gz · Última modificación: 2012/08/04 00:45 por lmateu