3 de agosto de 2016

Ámbitos de variables.

   El Ejemplo 4.4 ilustra el concepto de ámbito de variables, el cual se refiere al nivel de visibilidad o alcance para las variables. Para visualizar mejor el concepto, imagine el ámbito de variables como un conjunto de capas que se sobreponen, todas las capas existen, pero en un momento dado, sólo es accesible una de ellas.

   Las líneas 7-9 declaran los prototipos de tres funciones: función1, función2 y función3, ninguna de las tres regresa ningún valor ni recibe nada como parámetro.

   La línea 11 define una variable global x de tipo entero (int) que es inicializada con el valor de uno; de hecho, observe que todas las variables se llaman igual y que son del mismo tipo.

   Una variable global tiene un alcance de archivo, lo cual quiere decir que dicha variable se reconoce desde el punto de su definición, hasta el final del archivo que la contiene.

   Las variables globales no deberían ser utilizadas debido a que introducen desorden en la estructura de los programas y son susceptibles de ser modificadas de manera accidental o intencional en cualquier parte del archivo, generando con ello resultados o efectos colaterales que invariablemente sumergirán al programador en “entretenidas” sesiones de depuración.

   Además de lo anterior, las variables globales se consideran en general una mala práctica de programación. La intención del Ejemplo 4.4 es ilustrar los ámbitos incluso para las variables globales, pero no pretende de ninguna manera promover su uso.

   Retomando la explicación del ejemplo, la línea 14 declara la variable local a main con valor inicial de diez. El ámbito de ésta variable es el bloque asociado con la función main, por lo que, ¿qué valor imprimirá la función printf de la línea 16?.

   La pregunta es bastante razonable, debido a que hasta la línea 16 se tienen definidas dos variables con el mismo nombre y del mismo tipo; por lo tanto, ¿cual se imprimirá? Si bien es cierto que el alcance de una variable global es de todo el archivo, también lo es que los ámbitos se superponen entre sí, pero no se sobre escriben, es decir, que para la línea 16 el ámbito activo es el de la función main, por lo que el valor que se imprimirá será diez.

   Por otro lado, las líneas 17-20 definen un nuevo ámbito interno delimitado por su propio bloque ( { ... } ) dentro de la función main. Observe que dicho bloque no pertenece a ninguna estructura de control, ya que las llaves no son propias de ninguna estructura de control (de hecho son opcionales), sino que delimitan bloques de código y cada bloque de código tiene su propio ámbito. Éste ámbito interno declara una nueva x con valor de 50, por lo que el valor a imprimir en la línea 19 es 50. Ahora bien, ¿qué valor se imprime en la línea 21?

   La línea 23 hace un sucesivo llamado a las funciones: funcion1, funcion2 y funcion3 respectivamente, mientras que la línea 24 repite dicha sucesión. Para entender la salida del programa, se debe analizar la definición de las funciones.

   Las líneas 31-36 definen a la función funcion1, la cual declara una variable local x en la línea 32 con un valor inicial de 100. Ésta variable, como todas las que se declaran de esta forma, se denominan variables automáticas debido a que se crean y se destruyen cada vez que la secuencia de ejecución entra y sale, respectivamente, de su respectivo ámbito de función. La función imprimirá en las líneas 34 y 35, los valores de 100 y 101 respectivamente, sin importar si la función se llama una vez, tres veces, 456 o 987 veces.

   Por otro lado, las líneas 38-43 definen a la función funcion2, la cual declara una variable local estática (static) en la línea 39 con un valor inicial de 1000. El modificador static instruye al compilador para que no destruya a la variable que es afectada por el modificador cuando la secuencia de ejecución abandone el ámbito en que se definió conservando así su valor. Sin embargo, dicha variable sólo es accesible dentro de su ámbito, esto es, sólo la funcion2 la puede “ver”. Cuando una variable es estática, su valor de inicialización sólo se establece la primera vez que se hace uso de la variable, por lo que sus valores subsecuentes dependerán del último valor asignado o modificado; en éste sentido, los valores que se imprimirán en las líneas 41 y 42 en el primer llamado de la funcion2 serán 1000 y 1001 respectivamente, pero no lo serán en los llamados subsecuentes.

   Finalmente, las líneas 45-48 definen a la función funcion3, la cual no declara ninguna variable pero sí hace uso de una variable en las líneas 46 y 47. Quizá se pregunte ¿cómo es esto posible?, pues es posible debido al uso de la variable global (línea 11), por lo que los valores a imprimir son uno y dos respectivamente.

   Siguiendo la descripción que se acaba de hacer de las funciones, determine los valores que se imprimirán en la salida estándar para las líneas 24 y 26.

   La salida del Ejemplo 4.4 se muestra en la siguiente figura:

Salida del Ejemplo 4.4.