- Características de los arrays
- Descripción de arrays
- Utilización de arrays
Descripción de arrays
La descripción de arrays hereda algunas características de las descripciones de variables. Para empezar, debemos tener en cuenta que los arrays pueden ser globales y locales, según el lugar de su declaración. De forma similar a las variables, los modificadores const y static también pueden utilizarse para describir un array. Para un array unidimensional de tamaño fijo, la sintaxis de declaración es la siguiente:
type static1D[size]; |
Aquí, type y static1D denotan el nombre de tipo de los elementos y el identificador del array, respectivamente, mientras que size entre corchetes es una constante entera que define el tamaño.
Para los arrays multidimensionales deben especificarse varios tamaños, en función de la cantidad de dimensiones:
type static2D[size1][size2];
|
Los arrays dinámicos se describen de forma similar, salvo que se realiza un salto en los primeros corchetes (antes de utilizar un array de este tipo, debe asignársele el volumen de memoria necesario mediante la función ArrayResize; véase la sección relativa a arrays dinámicos).
type dynamic1D[];
|
Para arrays de tamaño fijo se permite la inicialización: los valores iniciales se especifican para los elementos situados tras el signo igual, como una lista separada por comas, encerrándose toda la lista entre llaves. Por ejemplo:
int array1D[3] = {10, 20, 30}; |
Aquí, un array de enteros de 3 tamaños toma los valores 10, 20 y 30.
Con una lista de inicialización, no es necesario especificar entre corchetes el tamaño del array (para la primera dimensión). El compilador evaluará el tamaño automáticamente por la longitud de la lista. Por ejemplo:
int array1D[] = {10, 20, 30}; |
Los valores iniciales pueden ser tanto constantes como expresiones constantes, es decir, fórmulas que el compilador puede calcular durante la compilación. Por ejemplo, el siguiente array se rellena con el número de segundos de un minuto, una hora, un día y una semana (la representación como fórmulas es más ilustrativa que 86400 o 604800):
int seconds[] = {60, 60 * 60, 60 * 60 * 24, 60 * 60 * 24 * 7}; |
Estos valores suelen diseñarse como una macro del preprocesador al principio del código, y luego el nombre de esta macro se inserta en todos los lugares del texto en que sea necesario. Esta opción se describe en la sección relativa al Preprocesador.
El número de elementos de inicialización no puede exceder el tamaño del array. De lo contrario, el compilador dará el mensaje de error «demasiados inicializadores». Si la cantidad de valores es menor que el tamaño del array, los elementos en reposo se inicializan por cero. Por lo tanto, existe una breve notación para inicializar todo el array con ceros:
int array2D[2][3] = {0}; |
O simplemente llaves vacías:
int array2D[2][3] = {}; |
Ello funciona independientemente del número de dimensiones.
Para inicializar arrays multidimensionales, las listas deben estar anidadas. Por ejemplo:
int array2D[3][2] = {{1, 2}, {3, 4}, {5, 6}}; |
Aquí, el tamaño de la primera dimensión del array es 3; por lo tanto, dos comas enmarcan 3 elementos dentro de las llaves externas. Sin embargo, como el array es bidimensional, cada uno de sus elementos es a su vez un array, siendo 2 el tamaño de cada uno de ellos. Por eso cada elemento representa una lista entre llaves, y cada lista contiene 2 valores.
Supongamos que necesitamos un array transpuesto (el primer tamaño es 2 y el segundo, 3); entonces, su inicialización cambiará:
int array2D[2][3] = {{1, 3, 5}, {2, 4, 6}}; |
Podemos omitir uno o más valores en la lista de inicialización, si es necesario, una vez marcados sus lugares con comas. Todos los elementos omitidos también se inicializarán con cero.
int array1D[3] = {, , 30}; |
Aquí, los primeros elementos serán iguales a 0.
La sintaxis del lenguaje permite colocar una coma después del último elemento:
string messages[] =
|
Esto simplifica la adición de nuevos elementos, especialmente para las entradas de varias cadenas. En concreto, si nos olvidamos de introducir una coma delante del nuevo elemento añadido en un array de cadenas, resultará que las cadenas antigua y nueva se fusionan dentro de un mismo elemento (con el mismo índice), mientras que no aparecerá ningún elemento nuevo. Además, algunos arrays pueden ser generados automáticamente (por otro programa o por macros). Por lo tanto, la apariencia unificada de todos los elementos es natural.
«Montón» y «pila»
Con arrays que pueden ser potencialmente grandes es importante hacer distinguir entre ubicación global y local en la memoria.
La memoria para las variables globales y los arrays está distribuida dentro del «montón», es decir, la memoria libre de que dispone el programa. Esta memoria no está limitada prácticamente por nada, aparte de las características físicas del ordenador y el sistema operativo. El nombre de «montón» se explica por el hecho de que el programa siempre asigna o desasigna áreas de memoria de distinto tamaño, lo que hace que las áreas libres estén dispersas aleatoriamente por todo el volumen.
Las variables locales y los arrays se encuentran en la pila, es decir, una zona de memoria limitada asignada previamente al programa, especialmente para los elementos locales. El nombre de «pila» deriva del hecho de que, durante la ejecución del algoritmo, tienen lugar las llamadas anidadas a funciones,que acumulan sus datos internos según el principio de «apilamiento»: por ejemplo, el terminal llama a OnStart, una función de su código aplicado es invocada desde OnStart, después su otra función es invocada desde la anterior, etc. Al mismo tiempo, al entrar en cada función se crean sus variables locales, que siguen estando ahí cuando se llama a la función anidada. También crea variables locales, que entran en la pila algo por encima de las anteriores. Como resultado, una pila suele contener algunas capas de los datos locales de todas las funciones que se han activado en la ruta a la cadena de código actual. No es hasta que la función que se encuentra en la parte superior de la pila se haya completado que sus datos locales se eliminarán de ahí. En general, la pila es un almacenamiento que funciona según el principio FILO/LIFO (First In Last Out, Last In First Out).
Dado que el tamaño de la pila es limitado, se recomienda crear en ella sólo variables locales. No obstante, los arrays pueden ser lo bastante grandes como para agotar toda la pila muy pronto. Al mismo tiempo, la ejecución del programa finaliza con un error. Por lo tanto, debemos describir los arrays a nivel global como estáticos (static) o asignarles memoria dinámicamente (esto también se hace desde el montón).