Arrays en C++ – I
Con frecuencia tendremos necesidad de realizar una serie de cálculos u operaciones sobre un conjunto de datos del mismo tipo. La solución más simple es crear tantas variables como sean necesarias, por ejemplo si vamos a registrar 10 temperaturas debemos definir, por ejemplo.
single temp1, temp2,..., temp10;
Esto se vuelve un poco problemático si queremos registrar, digamos 100 temperaturas en lugar de 10.
Para atender este tipo de requerimiento, se creó el concepto de “Array” o Arreglo de datos, o simplemente Arreglo, el cual ofrece una forma más eficiente y elegante de recopilar grandes volúmenes de datos del mismo tipo.
Array, Arreglo
Expresado formalmente, un Array o Arreglo de datos, es una estructura de datos que permite almacenar un conjunto de datos del mismo tipo, definiendo el intervalo con un límite inferior y un límite superior, con un número denominado Índice hacemos referencia a cada elemento individual del arreglo. Se utilizará indistintamente el término Array o Arreglo
Para comprender mejor los arrays, resulta muy útil la siguiente descripción gráfica.
La sintaxis para definir un arreglo en C++ es la siguiente:
TipoDato nombreArray[TamañoArray];
en donde,
TipoDato: Tipo de dato que tendrán los elementos del arreglo.
nombreArray: Nombre que asignamos para referirnos al arreglo.
TamañoArray: Valor entero que delimita el tamaño del arreglo.
Declarando un Arreglo
Si deseamos declarar un arreglo llamado arrTemp con 5 elementos de punto flotante, debemos hacerlo de esta forma:
float arrCalif[5]; //Declara un arreglo de 5 elementos de punto flotante llamado arrCalif
También podemos declarar una arreglo sin límites predeterminados,
float arrCalif[ ]; //Declara un arreglo de elementos de punto flotante llamado arrCalif sin límite.
Accediendo a los elementos del Arreglo
Nota: Los índices de los arreglos se numeran a partir de 0, de modo que si un arreglo tiene por ejemplo 4 elementos, los índices serán 0, 1, 2, 3
Para acceder a un elemento del arreglo debemos usar el nombre del arreglo utilizando el índice del elemento que nos interesa. Por ejemplo, si queremos asignar los valores 2, 5, 8, -9, 100 al arreglo arrTemp lo haremos de la siguiente forma:
arrTemp[0] = 2; arrTemp[1] = 5; arrTemp[2] = 8; arrTemp[3] = -9; arrTemp[4] = 100;
Para que visualices lo que hemos hecho hasta el momento, apóyate en la siguiente imagen.
Podemos recuperar de varias formas un elemento de un arreglo, pero el concepto siempre es el mismo, tomar el índice del elemento que nos interesa y asignarlo a una variable del mismo tipo. Por ejemplo para recuperar la primera y últimas temperaturas del ejemplo lo podemos hacer de la siguiente forma:
float tempInicial, tempFinal; tempInicial = arrTemp[0] tempFinal = arrTemp[4] cout << "Temperatura inicial: " << tempInicial << "Temperatura final: " << tempFinal; Aunque también pudimos hacerlo accediendo directamente a los elementos del arreglo. cout << "Temperatura inicial: " <<arrTemp[0] << "Temperatura final: " <<arrTemp[4];
Modificar los elementos de un Arreglo
También podemos reemplazar los valores de un arreglo, como podrás suponer debemos utilizar el nombre del arreglo y el índice del elemento que queremos modificar, por ejemplo para modificar las temperaturas 2 y 3, lo podemos hacer de la siguiente forma:
arrTemp[2] = 22; arrTemp[3] = arrTemp[4]; //arrTemp[3] recibirá el valor 100
en la segunda asignación puedes observar que asignamos el valor de la temperatura final, ilustrando que también podemos asignar elementos de un arreglo a otro, o a uno mismo.
A continuación te muestro un ejemplo de como hacer una asignación directamente a un arreglo con una entrada del usuario desde el teclado:
Esta forma de asignar ya te debe resultar comprensible:
cin >> arrTemp[4];
Es hora que practiques y modifiques todo lo posible el siguiente programa, verifica el resultado de cada cambio que realices.
// cpp_46_array01.cpp // Este programa forma parte del tutorial de introducción al lenguaje C++ // http://a.ehack.info/leguaje-c-introduccion/ // Se ilustra la declaración de arrays y la asignaciòn y recuperación de // valores en el aareglo. // 2018, Por http://about.me/carlosgbr // Versión 1 // Compilado en https://www.onlinegdb.com/online_c++_compiler #include <iostream> using namespace std; int main() { float arrTemp[5]; //Definimos un Arreglo de 5 elementos reales //Asignamos valores al Arreglo arrTemp[0] = 2; arrTemp[1] = 5; arrTemp[2] = 8; arrTemp[3] = -9; arrTemp[4] = 100; cout << "A continuación se muestran los valores actuales del arreglo" << endl; cout << arrTemp[0] << endl; cout << arrTemp[1] << endl; cout << arrTemp[2] << endl; cout << arrTemp[3] << endl; cout << arrTemp[4] << endl; //Reasignamamos valores en el arreglo de distintas formas. arrTemp[0] = 82; //Asignación directa arrTemp[1] = arrTemp[4]; //Asignación de un elemento del array arrTemp[2] = 8*3; arrTemp[3] = -9 * arrTemp[2]; cout << "¿Cuál es la temperatura final?:" << endl; cin >> arrTemp[4]; cout << "Valores finales del arreglo" << endl; cout << arrTemp[0] << endl; cout << arrTemp[1] << endl; cout << arrTemp[2] << endl; cout << arrTemp[3] << endl; cout << "Temperatura final: " << arrTemp[4] << endl; // Observa la salida de estas sentencias cout << "Salida fuera de índice 1:" << arrTemp[5] << endl; cout << "Salida fuera de índice 2:" << arrTemp[255] << endl; return 0; }
En el programa anterior al final hay 2 sentencias que merecen particular atención:
// Observa la salida de estas sentencias cout << "Salida fuera de índice 1:" << arrTemp[5] << endl; cout << "Salida fuera de índice 2:" << arrTemp[255] << endl;
Recordarás que nuestro arreglo solo está definido para arrTemp[0],…, arrTemp[5], sin embargo el compilador nos permite asignar arrTemp[5] y arrTemp[255], los valores elegidos son al azar, lo importante es ilustrar que estamos utilizando índices que no están definidos en nuestro arreglo.
A los índices que no pertenecen al rango válido de un arreglo se les denomina índices fuera de rango, y su uso, aunque permitido, está desaconsejado. En la segunda parte del curso ahondaremos en este tema.
Como comentario final solo añadiré que los valores que muestra el sistema son valores basura de las localidades de memoria a donde apunta el arreglo y su valor es completamente aleatorio. Y así como podemos leer en índices no definidos, del mismo modo podemos escribir en ellos… con resultados impredecibles.;)
Inicialización de Arreglos
Un arreglo que no se inicializa también contiene basura, por lo que resulta conveniente inicializarlo al momento de declararlo de esta forma:
float arrTemp[5] = {2, 5, 8 ,-9, 100}
Aunque no tiene mucho sentido y de hecho es también desaconsejable, también podemos iniciar parcialmente la lista, por ejemplo:
float arrTemp[5] = {2, 8}
En algunos compiladores esta inicialización asignará en 0 todos los elementos no inicializados de forma explícita, haz la prueba. Lo que si no podemos hacer es inicializar de forma “alternada”
float arrTemp[5] = {2, , 8 , , 100} // Genera un error de compilación
Método alterno para inicializar un Arreglo
Existe una forma alternativa para inicializar un arreglo, tanto en dimensiones como en valores,
float arrTemp[] = {2, 5, 8 ,-9, 100}
De esta forma definimos un arreglo de 5 elementos dinámicamente. La asignación y lectura de valores se realiza como ya se ha revisado en los párrafos anteriores.
Bucles y Arreglos
Considera que tenemos un arreglo llamado ArrPromedio de 100 elementos enteros y queremos asignar a todos los elementos el valor inicial 0. Llenarlo “a mano” a parte de ser lento es susceptible a errores, sin contar la cantidad de código que hay que escribir.
float arrPromedio[100] = {0,0,0,0,0,0,0,0,...,0};
Ya ni se diga si tenemos que imprimir en pantalla todos los elementos, requeriríamos 100 sentencias como esta:
cout << "El elemento 1 tiene el valor de: " << arrPromedio[1] << endl; ... cout << "El elemento 100 tiene el valor de: " << arrPromedio[100] << endl;
Como puedes apreciar trabajar con arreglos de esta forma puede ser muy tedioso y poco práctico.
El bucle for
Anteriormente revisamos el bucle for y su capacidad de hacer recorridos por n cantidad de elementos tomando como pivote un índice. Precisamente esta característica de trabajar con índices hacen al buche for un aliado natural de los arreglos.
Retomando el ejemplo de asignar 100 “0’s” a un arreglo con un bucle for lo podemos hacer de la siguiente forma.
float arrPromedio[100]; for (i = 0; i < 100; i++) { arrPromedio[i] = 0; }
Simple, rápido y elegante.
Y para mostrar el contenido del arreglo es igual de fácil:
for (i = 0; i < 100; i++) { cout << "El valor del elemento : " << i << ", es : " << arrPromedio[i] << endln; }
A continuación se muestra el programa, es simple y conciso, es importante que lo modifiques hasta que quedes completamente satisfecho y tengas muy claro como utilizar bucles for con arreglos. En la siguiente sección se trabaja con bucles for de doble recorrido y es imprescindible que manejes con holgura estos ejemplos.
// cpp_47_array02.cpp // Este programa forma parte del tutorial de introducción al lenguaje C++ // http://a.ehack.info/leguaje-c-introduccion/ // Se ilustra la inicialización y lectura de arreglos utilizando ciclos for // 2018, Por http://about.me/carlosgbr // Versión 1 // Compilado en https://www.onlinegdb.com/online_c++_compiler #include <iostream> using namespace std; int main() { int numeros[5], suma = 0; cout << "Introduce 5 números: "; // Almacenamos los 5 números introducidos en un arreglo // Encontramos la suma de dichos números for (int i = 0; i < 5; ++i) { cin >> numeros[i]; suma += numeros[i]; } cout << "Suma = " << suma << endl; // En esta sección se ilustra el uso de constantes para acceder a los // límites del arreglo. const int ElementosArray = 5; float numprom[ElementosArray], sumap = 0, promedio = 0; cout << "Introduce " << ElementosArray << " números para promediar: "; // Almacenamos los 5 números introducidos en un arreglo // Encontramos la suma de dichos números y realizamos el promedio for (int i = 0; i < ElementosArray; ++i) { cin >> numprom[i]; sumap += numprom[i]; promedio = sumap/ElementosArray; } cout << "Promedio = " << promedio << endl; return 0; }
Terminamos con esta sección con un último ejemplo de uso de arreglos utilizando ciclos for. Nuevamente te invito a que lo modifiques hasta que tengas una comprensión completa de su funcionamiento.
// cpp_48_array03.cpp // Este programa forma parte del tutorial de introducción al lenguaje C++ // http://a.ehack.info/leguaje-c-introduccion/ // Se ilustra el uso de Arreglos Unidimensionales o Vectores // 2018, Por http://about.me/carlosgbr // Versión 1 // Compilado en https://www.onlinegdb.com/online_c++_compiler #include <iostream> using namespace std; int main() { const int TamArray = 100; int valores[TamArray]; float suma = 0, promedio = 0; cout << "A continuación presentamos el cuadrado del 1 al " << TamArray << endl; for (int i = 1; i <= TamArray; ++i) { if (i<=10) { cout << i << " - " << i*i << "\t\t"; } else { cout << i << " - " << i*i << "\t"; } if (i % 5==0) { cout << endl; } } cout << "Ahora mostramos el promedio de los cuadrados del 1 al " << TamArray << endl; for (int i = 1; i <= TamArray; ++i) { suma += i*i; promedio = suma/TamArray; } cout << endl; cout << "El promedio es: " << promedio << "... esto suena a estadística"; return 0; }
Puedes notar que en la primera parte no hay nada nuevo, solo añadimos la suma de los elementos del arreglo, la parte interesante se presenta en la segunda parte. Hasta este momento los límites los habíamos indicado de forma numérica. En la segunda parte se hace declarando una constante.
const int ElementosArray = 5;
A primera vista te podrá parecer extraño, pero si revisas el código completo podrás apreciar una gran ventaja: Si es necesario cambiar el límite (por ejemplo para promediar 10 números) basta con cambiar el valor de la constante
const int ElementosArray = 10;
Y de forma inmediata aplica a todas las secciones donde se utiliza este valor, que podrás ver que son varias. De esta forma minimizamos alguna omisión cuando tenemos que modificar para actualizar el código. El cambio lo hacemos solo en una línea, y aplica para todas las sentencias en donde se utiliza el límite del arreglo.
Referencias
- Arrays, parcialmente se adaptan elementos de Learn C++
- (2) Programas más claros gracias a enum por David Villa
Fuente Imágenes
- “Todas las imágenes de esta sección”: by Nala Systems
Código Fuente
- El código fuente de toda la serie lo puedes descargar en nuestro repositorio en github busca los programas con el nombre del encabezado de cada programa.
- Código de esta sección
Arrays I en C++ by by Roberto C. González is licensed under a Creative Commons Reconocimiento-NoComercial-CompartirIgual 4.0 Internacional License.