Asignatura Taller de Computación I Módulo IV Arreglos unidimensionales y multidimensionales Elaboración Gabriel F. Stancanelli Este material pertenece a la materia Taller de Computación I, de la Carrera de Analista de Sistemas de Computación de Educación a Distancia del INSTITUTO DE TECNOLOGÍA ORT. Todos los derechos reservados. No esta permitida la reproducción total o parcial de este apunte, ni su tratamiento informático, ni la transmisión de ninguna forma o por cualquier medio, ya sea electrónico, mecánico, por fotocopia, por registro u otros métodos, sin el permiso previo de los titulares. 1ra edición Diciembre de 2005. Unidad didáctica IV: Arreglos unidimensionales y multidimensionales Pág. 1 INSTITUTO de TECNOLOGÍA O. R. T. Instituto Incorporado a la Enseñanza Oficial (A-763) Yatay 240 - Buenos Aires - República Argentina Analista de Sistemas de Computación Taller de Computación I UNIDAD DIDÁCTICA IV INDICE UNIDAD DIDÁCTICA IV ............................................................................................................... 2 INDICE ...................................................................................................................................... 2 Introducción y orientaciones para el estudio ................................................................... 3 Objetivos ................................................................................................................................. 3 Aclaraciones previas al estudio ........................................................................................... 3 Arreglos y cadenas de caracteres ............................................................................................. 4 Arreglos unidimensionales y multidimensionales ........................................................ 4 Funciones y arreglos ................................................................................................................. 9 Utilización de la función Random ............................................................................................ 11 Epílogo .................................................................................................................................... 15 Unidad didáctica IV: Arreglos unidimensionales y multidimensionales Pág. 2 INSTITUTO de TECNOLOGÍA O. R. T. Instituto Incorporado a la Enseñanza Oficial (A-763) Yatay 240 - Buenos Aires - República Argentina Analista de Sistemas de Computación Taller de Computación I Introducción y orientaciones para el estudio En el desarrollo de este módulo abordaremos: Arreglos unidimensionales. Arreglos multidimensionales. Manejo de arreglos en rutinas. Cadena de caracteres. Utilización de la función random. Objetivos Pretendemos que al finalizar de estudiar esta Unidad, el alumno logre: Tener un buen manejo de arreglos. Tener un buen manejo de cadena de caracteres. Aclaraciones previas al estudio En este módulo, usted encontrará: Contenidos Conceptualizaciones centrales Bibliografía Referencia de material bibliográfico recomendado Actividades Usted debe tener presente que los contenidos presentados en el módulo no ahondan profundamente en el tema, sino que pretenden ser un recurso motivador, para que a través de la lectura del material, la bibliografía sugerida, y el desarrollo de las actividades propuestas alcance los objetivos planteados en el presente módulo. Cada módulo constituye una guía cuya finalidad es facilitar su aprendizaje. Unidad didáctica IV: Arreglos unidimensionales y multidimensionales Pág. 3 INSTITUTO de TECNOLOGÍA O. R. T. Instituto Incorporado a la Enseñanza Oficial (A-763) Yatay 240 - Buenos Aires - República Argentina Analista de Sistemas de Computación Taller de Computación I Arreglos y cadenas de caracteres En el siguiente capítulo se presentan los arreglos y las cadenas de caracteres. Las cadenas se consideran como un arreglo de tipo char. Arreglos unidimensionales y multidimensionales Los arreglos son una colección de variables del mismo tipo que se referencian utilizando un nombre común. Un arreglo consta de posiciones de memoria contigua. La dirección más baja corresponde al primer elemento y la más alta al último. Un arreglo puede tener una o varias dimensiones. Para acceder a un elemento en particular de un arreglo se usa un índice. Pero ¿qué quiere decir esto y para qué lo usaremos? Pues bien, supongamos que quisiéramos saber el promedio de las calificaciones de un curso luego de una evaluación. Con lo que sabemos hasta ahora sería algo así, suponiendo que son 24 alumnos: #include <stdio.h> #include <iostream.h> int main(){ // Declaramos 24 variables, una para cada alumno Int iAlum1, iAlum2, iAlum3, iAlum4, iAlum5, iAlum6, iAlum7, iAlum8, iAlum9, iAlum10, iAlum11, iAlum12, iAlum13, iAlum14, iAlum15, int iAlum16; iAlum17, iAlum18, iAlum19, iAlum20, iAlum21, iAlum22; int iAlum23, iAlum24; float fProm; // Ahora tenemos que dar el valor de cada una cout << "Alumno 1: "; cin >> iAlum1; cout << " Alumno 2: "; cin >> iAlum2; cout << " Alumno 3: "; cin >> iAlum3; ... cout << " Alumno 24: "; cin >> iAlum24; fProm = ( iAlum1 + iAlum2 + iAlum3 + iAlum4 + ... + iAlum24 ) / 24.0; cout "\n La calificación promedio es: " << fProm; Unidad didáctica IV: Arreglos unidimensionales y multidimensionales Pág. 4 INSTITUTO de TECNOLOGÍA O. R. T. Instituto Incorporado a la Enseñanza Oficial (A-763) Yatay 240 - Buenos Aires - República Argentina Analista de Sistemas de Computación Taller de Computación I } NOTA: Los puntos suspensivos los he puesto para no tener que escribir todo y que no ocupe tanto, no se pueden usar en un programa. Y esto con un ejemplo que tiene tan sólo 24 variables, imagínese si son las calificaciones de todo un colegio. Y precisamente aquí es donde se utilizan los arreglos o arrays. Vamos a hacer el programa con un array. Usaremos nuestros conocimientos de bucles for y de cin. #include <stdio.h> #include <iostream.h> int main(){ int iAlum[24]; // Con esto ya tenemos declaradas las 24 variables float fProm; int IndiceAlumno; //Variable para utilizar en el for // Ahora tenemos que dar el valor de cada una for(IndiceAlumno=0; IndiceAlumno<24; IndiceAlumno++){ cout << "Alumno Nro: ", IndiceAlumno); cin >> iAlum[IndiceAlumno] ); fProm = fProm + iAlum[IndiceAlumno]; } IndiceAlumno = IndiceAlumno / 24; Cout << "\nLa calificación promedio es:" << fProm; } Como se puede observar es un programa más rápido de escribir (y es menos aburrido hacerlo), y más cómodo para el programador que el anterior. Como ya hemos comentado cuando declaramos una variable, lo que estamos haciendo es reservar una zona de la memoria para ella. Cuando declaramos un array, lo que hacemos (en este ejemplo) es reservar espacio en memoria para 24 variables del tipo int. El tamaño del array (24) lo indicamos entre corchetes al definirlo. Esta es la parte de la definición que dice: Un array es un conjunto de variables del mismo tipo que tienen el mismo nombre. Unidad didáctica IV: Arreglos unidimensionales y multidimensionales Pág. 5 INSTITUTO de TECNOLOGÍA O. R. T. Instituto Incorporado a la Enseñanza Oficial (A-763) Yatay 240 - Buenos Aires - República Argentina Analista de Sistemas de Computación Taller de Computación I La parte final de la definición dice: y se diferencian en el índice. En el ejemplo, recorremos el vector mediante un bucle for y vamos dando valores a los distintos elementos del mismo. Para indicar a qué elemento nos referimos, usamos un número entre corchetes (en este caso la variable IndiceAlumno), este número es lo que se llama Indice. El primer elemento del arreglo en C++ tiene el índice 0, El segundo tiene el 1 y así sucesivamente. De modo que si queremos dar un valor al elemento 4 (índice 3) haremos: iAlum[ 3 ] = 8; NOTA: No hay que confundirse. En la declaración del array el número entre corchetes es el número de elementos, en cambio cuando ya usamos el arreglo, el número entre corchetes es el índice. El formato para declarar un arreglo unidimensional es: tipo nombre_arr [ tamaño ] Repasemos viendo otro ejemplo, para declarar un arreglo de enteros llamado listanum con diez elementos se hace de la siguiente forma: int listanum[10]; En C++, todos los arreglos usan cero (0) como índice para el primer elemento. Por tanto, el ejemplo anterior declara un arreglo de enteros con diez elementos desde listanum[0] hasta listanum[9]. La forma como pueden ser accesados los elementos de un arreglo, es de la siguiente manera: listanum[2] = 15; // Asigna 15 al 3er elemento del arreglo listanum num = listanum[5]; // Asigna el contenido del 6to elemento a la variable num Unidad didáctica IV: Arreglos unidimensionales y multidimensionales Pág. 6 INSTITUTO de TECNOLOGÍA O. R. T. Instituto Incorporado a la Enseñanza Oficial (A-763) Yatay 240 - Buenos Aires - República Argentina Analista de Sistemas de Computación Taller de Computación I El lenguaje C++ no realiza comprobación de contornos en los arreglos. En el caso de que sobrepase el final durante una operación de asignación, entonces se asignarán valores a otra variable o a un trozo del código, esto es, si se dimensiona un arreglo de tamaño N, se puede referenciar el arreglo por encima de N sin provocar ningún mensaje de error en tiempo de compilación o ejecución, incluso aunque probablemente se provoque el fallo del programa. Como programador, se es responsable de asegurar que todos los arreglos sean lo suficientemente grandes para guardar lo que pondrá en ellos el programa. C++ permite arreglos con más de una dimensión, el formato general es: tipo nombre_arr [ tam1 ][ tam2 ] ... [ tamN]; Por ejemplo un arreglo de enteros bidimensionales se escribirá como: int tabladenums[50][50]; Observar que para declarar cada dimensión lleva sus propios corchetes. Para acceder a los elementos se procede de forma similar al ejemplo del arreglo unidimensional, esto es, tabladenums[2][3] = 15; // Asigna 15 al 3ª elemento del primer argumento y a la 4ª posición del //segundo argumento num = tabladenums[25][16]; Unidad didáctica IV: Arreglos unidimensionales y multidimensionales Pág. 7 INSTITUTO de TECNOLOGÍA O. R. T. Instituto Incorporado a la Enseñanza Oficial (A-763) Yatay 240 - Buenos Aires - República Argentina Analista de Sistemas de Computación Taller de Computación I A continuación se muestra un ejemplo que asigna al primer elemento de un arreglo bidimensional cero, al siguiente 1, y así sucesivamente. void main(){ int t, //variable para el control de un ciclo for i, //variable para el control del segundo ciclo for num[3][4]; //arreglo de dos dimensiones for(t=0; t<3; t++) for(i=0; i<4; i++) num[t][i]=(t*4)+i*1; for(t=0; t<3; ++t){ for(i=0; i<4; ++i) cout "numero = " << num[t][i] << “\n”; } } En C++ se permite la inicialización de arreglos, debiendo seguir el siguiente formato: tipo nombre_arr[ tam1 ][ tam2 ] ... [ tamN] = {lista-valores}; Por ejemplo: int i[10] = {1,2,3,4,5,6,7,8,9,10}; int num[3][4]={0,1,2,3,4,5,6,7,8,9,10,11}; Actividad 4 - 1: - Declarar un arreglo de 7 elementos, cargarlo con valores constante (inicializándolo), y luego recorrerlo informando el valor mayor. Actividad 4 - 2: - Modificar el ejercicio anterior para que también informe en que posición se encuentra dicho número. Unidad didáctica IV: Arreglos unidimensionales y multidimensionales Pág. 8 INSTITUTO de TECNOLOGÍA O. R. T. Instituto Incorporado a la Enseñanza Oficial (A-763) Yatay 240 - Buenos Aires - República Argentina Analista de Sistemas de Computación Taller de Computación I Funciones y arreglos Cuando se usa un arreglo como un argumento a la función, se pasa sólo la dirección del arreglo y no la copia del arreglo entero. Esto significa que el parámetro (a diferencia de los demás tipos de datos) siempre pasa por dirección o referencia (no hay que poner &) a menos que le antepongamos la palabra const, de esta manera, la variable pasa por valor, es decir pasa constante y no deja que sea modificada. Considerar el siguiente ejemplo en donde se pasa un arreglo a la función imp_rev, observar que no es necesario especificar la dimensión del arreglo cuando es un parámetro de la función. void imp_rev(int n[]); void main(){ int numeros[5]={9,8,7,6,5}; imp_rev(numeros); } void imp_rev(const int n[]){ //en este caso se recibe el parámetro como constante ya que no se modificará int t; for( t=5-1; t>=0; t--) //t comienza en 5-1 ya que son 5 los elementos del //arreglo, y va desde la posición 0 a la 4. Por lo tanto debe comenzar en 4. cout << n[t] << “\n“; } Se muestra otro ejemplo, float enconprom(int tam, const float lista[]){ int i; float suma; suma = 0.0; for ( i=0; i<tam; i++) suma += lista[i]; return(suma/tam); } void main(){ float numeros[]={2.3, 8.0, 15.0, 20.2, 44.01, -3.0, -2.9}; cout << "El promedio de la lista es: ", enconprom(7,numeros) ; } Unidad didáctica IV: Arreglos unidimensionales y multidimensionales Pág. 9 INSTITUTO de TECNOLOGÍA O. R. T. Instituto Incorporado a la Enseñanza Oficial (A-763) Yatay 240 - Buenos Aires - República Argentina Analista de Sistemas de Computación Taller de Computación I Para el caso que se tenga que pasar un arreglo con más de una dimensión, no es necesario indicar la primera dimensión pero, el resto de las dimensiones deben señalarse obligatoriamente, esto es porque como dijimos previamente, pasa la dirección del comienzo del arreglo. Se muestra a continuación un ejemplo: void imprtabla(int tamx,int tamy, const float tabla[][5]){ int x,y; for ( x=0; x<tamx; x++ ){ for ( y=0; y<tamy; y++ ) cout << "t “ << x << y << “= ” << tabla[x][y] << ”\n”; } } En nuestro curso, al momento de utilizar arreglos los declararemos como un tipo de datos definido por nosotros. Por ejemplo si se quiere definir un arreglo de 5 valores enteros lo definiremos como: typedef int ty_vec[5]; luego declararemos la variable vec del tipo ty_vec de la siguiente manera: ty_vec vec; y si al momento de crear la variable, quisiéramos ponerle valor inicial sería de la siguiente forma: ty_vec vec = {56,25,89,48,6}; Al momento de declarar el tipo de datos, es donde se le indica el tamaño total que tendrá el arreglo, se utilizará un valor definido, con lo cual para el ejemplo anterior quedaría de la siguiente forma: #define iMAX 5 typedef int ty_vec[iMAX]; ty_vec vec; ty_vec vec = {56,25,89,48,6}; Actividad 4 - 3: - Modificar el ejercicio anterior para que el ejercicio quede correctamente modularizado y parametrizado. Unidad didáctica IV: Arreglos unidimensionales y multidimensionales Pág. 10 INSTITUTO de TECNOLOGÍA O. R. T. Instituto Incorporado a la Enseñanza Oficial (A-763) Yatay 240 - Buenos Aires - República Argentina Analista de Sistemas de Computación Taller de Computación I Utilización de la función Random Comenzaremos la explicación de este tema con una Actividad: Actividad 4 - 4: - Descargar el programa llamado rnd.cpp de la Unidad IV que se encuentra en la biblioteca de ejercicios, compilarlo, ejecutarlo varias veces y anotar los resultados obtenidos. Anteriormente vimos la manera de cargar valores en un arreglo de manera constante, es decir fijarle valores a las distintas celdas al momento de declarar la variable, esto lo hacíamos de la siguiente forma: #define intMAX 5 typedef int ty_vec[intMAX]; ty_vec vec; ty_vec vec = {56,25,89,48,6}; Veremos a continuación como podemos asignarle números aleatorios a los arreglos. Para ello utilizaremos la función random de la siguiente manera: Crearemos una rutina void CargarRandom La función random (se encuentra en stdlib.h) devuelve un número al azar comprendido entre 0 y el número que le indiquemos a dicha función menos 1. Es decir que el número que le indicamos es la cantidad de números aleatorios que generará. Veamos el ejemplo: void CargarRandom(ty_vec v){ int i; for (i=0; i<intMAX;i++) v[i] = random(50); } Aquí vamos pasando por las distintas celdas del arreglo asignándole un valor aleatorio comprendido entre 0 y 49 (es decir 50 números posibles). Unidad didáctica IV: Arreglos unidimensionales y multidimensionales Pág. 11 INSTITUTO de TECNOLOGÍA O. R. T. Instituto Incorporado a la Enseñanza Oficial (A-763) Yatay 240 - Buenos Aires - República Argentina Analista de Sistemas de Computación Taller de Computación I Acá tenemos todo nuestro código completo #include <iostream.h> #include <conio.h> #include <stdlib.h> #define intMAX 5 typedef int ty_vec[intMAX]; void CargarRandom(ty_vec v); void MostrarArreglo (ty_vec v); void main(){ ty_vec vec; clrscr(); CargarRandom(vec); MostrarArreglo(vec); getch(); } void MostrarArreglo (ty_vec v){ int i; for (i=0; i<intMAX;i++) cout << v[i] << "\n"; } void CargarRandom(ty_vec v){ int i; for (i=0; i<intMAX;i++) v[i] = random(50); } Si ejecutamos varias veces este código, podemos observar que siempre carga las celdas del arreglo con los mismos valores. Para solucionar esto, utilizaremos en conjunto con la función random, otra llamada randomize que se coloca para ejecutarse por única vez antes de invocar a la función random, ésta función no devolverá ningún valor (es una rutina void) y no se le pasa ningún argumento. Randomize inicializa el número generador del valor random con un número random calculado de la hora del sistema. Con lo cual, nuestra rutina CargaRandom quedará de la siguiente manera: void CargarRandom(ty_vec v){ int i; randomize(); for (i=0; i<intMAX;i++) v[i] = random(50); } Unidad didáctica IV: Arreglos unidimensionales y multidimensionales Pág. 12 INSTITUTO de TECNOLOGÍA O. R. T. Instituto Incorporado a la Enseñanza Oficial (A-763) Yatay 240 - Buenos Aires - República Argentina Analista de Sistemas de Computación Taller de Computación I Cabe aclarar que la función random no sólo se utiliza para variables del tipo arreglo. Por último analizaremos varias formas de utilizar la función random. Dijimos anteriormente que random devuelve un número entero comprendido entre 0 y el valor pasado como argumento. Pero supongamos que necesitamos por algún motivo que nos devuelva 30 posibles números pero todos superiores a 100, es decir que de 0 a 99 no nos interesarían. Una posible solución para este problema es: void CargarRandom(ty_vec v){ int i; randomize(); for (i=0; i<intMAX;i++) v[i] = (random(30) + 100); } Veamos la línea en donde utilizamos la función random. Le indicamos que sean 30 valores posibles, de (0 a 29) y al valor devuelto le sumamos 100. Si quisiéramos obtener números negativos, al valor devuelto por la función random se lo multiplicaría por menos 1. v[i] = (random(30) * -1); Hasta acá vimos como obtener números aleatorios. Que pasará si necesitáramos cargar en forma random un arreglo del tipo char con las letras del alfabeto?? Como dijimos anteriormente, random devolverá un número, por tal motivo deberemos convertirlo a letra. Veamos el siguiente código y luego explicaremos en base a él. Por un lado modificaríamos la línea en donde declaramos el arreglo por la siguiente: typedef char ty_vec[intMAX]; Luego, haríamos lo siguiente: v[i] = char(random(26)+65); Esto significa que le solicitamos a la función random un número comprendido entre 0 y 25 (ya que 26 son los caracteres del alfabeto). A este valor devuelto le sumamos 65 ya que es el número correspondiente a la tabla ASCII de la letra A, la 66 es la B, 67 la letra C, y así sucesivamente hasta llegar al número 90 que corresponde a la letra Z. Es decir que si el random nos devuelve el valor 2, le sumamos 65, esto da como resultado 67 es decir que estamos en el valor de la letra C, sólo nos resta convertirla a carácter, esto se hace indicándole que toda esa expresión recién calculada será del tipo char. Unidad didáctica IV: Arreglos unidimensionales y multidimensionales Pág. 13 INSTITUTO de TECNOLOGÍA O. R. T. Instituto Incorporado a la Enseñanza Oficial (A-763) Yatay 240 - Buenos Aires - República Argentina Analista de Sistemas de Computación Taller de Computación I Actividad 4 - 5: - Modificar el ejercicio anterior para que la carga de los valores sea en forma aleatoria. Actividad 4 - 6: - Modificar el ejercicio anterior para que la carga de los valores sea en forma aleatoria controlando que no se repita ningún valor dentro del arreglo. Unidad didáctica IV: Arreglos unidimensionales y multidimensionales Pág. 14 INSTITUTO de TECNOLOGÍA O. R. T. Instituto Incorporado a la Enseñanza Oficial (A-763) Yatay 240 - Buenos Aires - República Argentina Analista de Sistemas de Computación Taller de Computación I Epílogo Este libro trató de proporcionar conocimientos básicos de la programación que permitan sentar una base sólida. Prueba de ello es que se explican las técnicas fundamentales de la programación que se pueden aplicar con independencia del lenguaje de programación. Así, se ha evitado el enfoque basado en explicar las características de un lenguaje de programación concreto y se ha optado por un enfoque basado en conceptos y técnicas. Se ha escogido como lenguaje de programación el C++ debido a que es un lenguaje de programación muy potente, lleno de posibilidades y muy utilizado hoy en día, tanto en el ámbito de la enseñanza como en el de la programación profesional. No necesita tener conocimientos previos para aprender a programar partiendo de cero, avanzando de forma organizada, gradual y sin esfuerzo. Hemos visto cómo es la estructura de un programa. Hemos visto cómo se llevan a cabo en C++. Hemos visto programación estructurada, es decir, sentencias de control: bucles y sentencias condicionales, casting de datos, estructura de datos, arreglos unidimensionales y multidimensionales, funciones, pasajes de parámetros, modularización.... y poco más. Hay otros puntos que no se han tocado, muchas cosas que se verán a lo largo de la carrera. Es decir, que hemos buscado, como dice el refrán, “que aprendan primero a caminar... para luego echar a correr.” Unidad didáctica IV: Arreglos unidimensionales y multidimensionales Pág. 15