Si bien en los capítulos anteriores se han analizado las variables que maneja el lenguaje C y los tipos de datos correspondientes, no se han analizado algunas características relativas a las variables, siendo las más importantes la duración y el ámbito (scope). Combinando estas características se distinguen los diferentes tipos de almacenamiento de C: auto, static, extern y register.
Una variable fija surge al inicio del programa y sobrevive hasta la finalización de la ejecución del mismo, invadiendo constantemente su parte de memo. Por el contrario, una variable automática está asociada a una función o bloque concreto del programa. Por lo tanto, esta función o bloque sólo se creará cuando comience a ejecutarse y desaparecerá al finalizar la ejecución del bloque. En consecuencia, una variable automática puede generarse varias veces y si el bloque o función correspondiente a la variable no se utiliza en una ejecución, la variable no se generará.
Lo anterior tiene una gran influencia en la inicialización, ya que mientras los fijos tengan una única inicialización, los automáticos se inicializarán cada vez que la función o bloque se referencie externamente.
Como veremos más adelante, las variables globales serán fijas y los locales serán automáticos.
El marco o scope es el concepto correspondiente al programa fuente y representa el campo de conocimiento del nombre de una variable. En el lenguaje C se distinguen cuatro tipos de áreas de conocimiento:
El ámbito de la variable depende de donde se encuentre, aunque el static puede cambiar las palabras clave.
Veremos algunos ejemplos para ilustrar lo anterior:
a)
Estas dos variables automáticas (denominadas i) son diferentes ya que tienen el ámbito del bloque.
Todo ello se debe a la localización de las definiciones, al estar dentro de la función la variable, salvo que se diga otra cosa, es automática y su campo es el de bloqueo.
b)
j)
Tenemos dos variables denominadas, una global, otra externa (fija) y otra local, incluida en la función f1.
Los tres primeros resultados se deben a la ejecución de la función f1 (la inicialización es Ø cuando se define exclusivamente) y la última al programa principal.
En algunos lenguajes de alto nivel se distinguen dos tipos de almacenamiento: global y local. En C es posible combinar la duración y el ámbito de las variables, obteniendo diferentes tipos de almacenamiento, teniendo en cuenta la ubicación de la definición de la variable y el uso de las palabras clave extern, static, auto y register.
Veamos el significado de los siguientes indicadores:
extern:
cuando se desea utilizar una variable global fuera del módulo en el que está definida, se realiza una nueva estimación de la variable, pero predefinido el indicador extern, indicando que la definición está en otro lugar.
static:
tiene doble función. Reduce la vista del programa al fichero a las variables definidas externamente (globales). Cambia la duración de los definidos dentro de las funciones a fijos.
auto:
se adapta a variables con marco de bloques pero definidas dentro de las funciones. Dado que estas variables, si no se ajustan a ningún indicador, adoptan las mismas características que el auto indicador, este indicador prácticamente nunca se utiliza.
register:
Este indicador sólo se puede utilizar con variables con vista bloque y su incidencia en el tiempo de ejecución es la ubicación de la variable en un registro general. Esto permite agilizar la ejecución del programa adaptándolo a variables muy utilizadas.
En la figura 1 se recoge un resumen de todas las características.
Una vez analizadas todas las características, vamos a ver el uso que tienen los diferentes tipos de variables expuestas. Podemos distinguir cuatro usos diferentes:
En la figura 2 se puede ver un ejemplo en el que el nuevo tipo de datos de pila que se define en la misma sólo es accesible externamente mediante las funciones push, pop y clear.
En el módulo en el que se utiliza una de estas funciones se hará una mención especificando el indicador extern. Por ejemplo para utilizar push: extern void push ( ).
Las variables vistas hasta el momento son estáticas, es decir, el compilador sabrá la cantidad de memoria que ocupan y por tanto puede predecir su ubicación.
La memoria dinámica es interesante cuando la longitud de los datos que manejamos es variable en función de la ejecución. Los demostradores Pascalez son dinámicos, ya que son solicitados y liberados mediante las funciones new y dispose. En C existe un mecanismo de adquisición y liberación de memoria dinámica mediante las funciones de librería malloc, calloc, realloc y free que se expondrán en el capítulo 11.