Universidad Nacional de Entre Ríos Facultad de Ingeniería Departamento de Informática FUNDAMENTOS DE PROGRAMACIÓN GUÍA PRÁCTICA 6 ARREGLOS ESTÁTICOS Y ESTRUCTURAS Guía práctica 6: Arreglos Estáticos y Estructuras Resumen de Conceptos Arreglos Definición de arreglo. Definimos como arreglo (array) a la estructura de datos formada por una secuencia de elementos homogéneos (de igual tipo). Cada elemento tiene una posición relativa -que puede ser establecida por uno o más índices- dentro de la secuencia. Características de los arreglos estáticos en C++ • • • • • • • • Un arreglo es una colección de datos relacionados de igual tipo e identificados bajo un nombre genérico único. La estructura completa ocupa un segmento de memoria único y sus elementos se almacenan en forma contigua. Para procesar un elemento del arreglo, se debe especificar el nombre de la estructura y uno o más índices que determinan la posición del elemento. Se puede emplear como índice cualquier expresión que arroje un entero dentro del rango establecido (dimensión) para dicho índice. El índice que determina la posición de los elementos de un arreglo comienza siempre con cero. Se debe establecer en la declaración, la cantidad de elementos (dimensión) que puede tener como máximo el arreglo en el programa. C++ admite operar fuera del rango preestablecido por la dimensión, pero con resultados impredecibles. En base al número de índices que determinan la posición de un elemento en el arreglo se habla de arreglos lineales o unidimensionales, bidimensionales y multidimensionales. Declaración e inicialización Los arreglos estáticos en C++ se declaran y definen como cualquier otra variable. Usualmente se establece la dimensión de la estructura, es decir, la cantidad máxima de elementos que puede contener en el programa. Ejemplos: const m = 100; int z[m]; char mensaje[30]; double tabla[4] [12]; static float lista[200]; Para inicializar un arreglo en el programa podemos recorrer cada elemento del arreglo para asignar los valores correspondientes, o bien, pueden inicializarse los elementos en la misma declaración, enumerando la lista de datos a asignar. Ejemplos: int x[100]; for (int i=0; i<99; i++) x[i]= rand( );//recorriendo el arreglo char z[7] = {‘J’, ‘M’, ‘L’, ‘P’, ‘Q’, ‘W’, ‘H’};//enumerando Arreglos como parámetros de funciones Es posible utilizar arreglos como parámetros de funciones. En C++ no es posible pasar por valor un bloque de memoria completo como parámetro a una función, aún si está ordenado como un arreglo, pero está permitido pasar su dirección de memoria, lo cuál es mucho más rápido y eficiente. Al pasar una dirección de memoria estamos efectuando un pasaje por referencia. Para admitir arreglos lineales como parámetros lo único que se debe hacer al declarar la función es especificar en el argumento el tipo de dato que contiene el arreglo, un identificador y un par de corchetes vacíos [ ]. El nombre del arreglo identifica a una variable que contiene la dirección de memoria donde comienza el bloque donde se aloja el arreglo. En otras palabras: el nombre del arreglo tiene la dirección de memoria del elemento 0 del arreglo. Si se trata de pasar como parámetro un arreglo de más de una dimensión, el parámetro formal debe tener los corchetes correspondientes al primer índice vacíos, pero establecer explícitamente las otras dimensiones. Estructuras. El tipo struct. A menudo se requiere organizar los datos de una entidad en una estructura, pero admitiendo información de diferente naturaleza (tipo). C++ dispone para este caso del tipo struct. Un struct en C++ es una colección de componentes, los cuales pueden ser de diferente tipo. Cada componente o miembro debe declararse individualmente. Su sintaxis general es la siguiente: struct compuesta { miembro 1; miembro 2; miembro 3; ..... miembro n; }; En la definición es obligatorio explicitar el tipo struct y a continuación el identificador (compuesta en el ejemplo) de la estructura. Luego, entre llaves deben definirse cada uno de los componentes o miembros). Los miembros individuales de una estructura pueden ser de tipos simples, arrays, punteros (los veremos más adelante) e inclusive struct. En cuanto a los nombres de estos miembros o componentes deben ser diferentes, pero pueden coincidir con el identificador de alguna otra variable definida fuera de dicha estructura. No se puede inicializar un miembro al definir la estructura. Al definir una estructura estamos planteando el esquema de la composición pero sin definir ninguna variable en particular. Para declarar variables de tipo struct se debe indicar lo siguiente: struct ficha x, y; //x e y se declaran de tipo ficha Se puede combinar la definición de la composición de la estructura con la declaración de las variables y con su inicialización: struct ficha{ char *apellido; char *nombres; long dni; int edad; int cant_materias; } x =(“Lopez”, “Gerardo”, 24567890, 21, 11); En este ejemplo, ficha es el nombre de la estructura, x la variable de tipo ficha y los datos especificados entre { } los valores iniciales de los miembros apellido, nombres, dni, edad, cant_materias. Procesamiento de una variable struct Para procesar la información relacionada a una estructura podemos operar con sus miembros individualmente o en ocasiones con la estructura completa. Para acceder a un miembro individual debemos utilizar el identificador de la variable struct, un punto de separación y el nombre del miembro componente. variable.miembro Tipos definidos por el usuario: typedef Es posible en C++ identificar a tipos existentes o estructuras de datos con nombres y tratarlos como si fueran nuevos tipos de datos. Entonces, las variables o funciones podrán declararse en base a estos nuevos nombres que representan tipos de datos de C++. Estos tipos de datos definidos por el usuario no tiene la importancia que revisten en otros lenguajes (Pascal por ejemplo). Para asignar un nombre correspondiente a una definición de tipo en C++ debemos empelar la palabra reservada typedef. Veamos algunos ejemplos: typedef int tabla[50][12]; /*definición del nombre tabla como matriz de 50x12 enteros */ typedef struct { char *apellido; char *nombres; long dni; int edad; int cant_materias; } ficha // definición del tipo ficha como estructura Actividades Ejercicios En los ejercicios que impliquen la codificación de un programa debe observar los pasos siguientes: i) Salvar, compilar, --si es necesario-- depurar, y ejecutar el programa propuesto. ii) Proponer una adecuada interfaz hombre-máquina. Ejercicio 1 Generar aleatoriamente un arreglo lineal a de 120 elementos numéricos, con enteros entre 1000 y 1500 y mostrarlos. Luego ingresar dos valores en las variables m y p. El valor m debe asignar a la posición p del arreglo. Mostrar el vector modificado. Ejercicio 2 Utilice el código del recuadro de la derecha, complételo y diseñe las funciones allí invocadas. ..... int main () const int N=120; gen_array(a,1000,1500,N); cout<<”Valor a insertar:”; cin>>m>>p; insertar(a,N,m,p); .... Ejercicio 3 Leer las calificaciones y dni de un grupo de alumnos que asistieron a una evaluación parcial de Fundamentos de Programación. Generar un vector con los dni de los alumnos aprobados y otro con los dni de los no aprobados (Nota<6). Los datos finalizan con el dni 0. Se desea obtener como información de salida en el orden indicado: a. Un listado de los DNI de los alumnos aprobados. b. Las 2 mayores calificaciones y los DNI de los alumnos que las obtuvieron. c. Un listado con los DNI de los alumnos que no aprobaron la evaluación. Ejercicio 4 Leer N datos numéricos. Obtener la media (M) y la desviación estándar (DS) de la lista. Las expresiones para el cálculo se indican abajo. Utilice 2 funciones llamadas media( ) y desviostd( ) para resolver el caso: x1 + x2 + x3 + ........ + xn N ( x1 − M ) 2 + ( x2 − M ) 2 + ........ + ( xn − M ) 2 DS = N M= Ejercicio 5 Una asociación cooperadora escolar recibe aportes de dinero variable de los estudiantes asociados. Se leen sin orden alguno los montos aportados en el último año y la fecha correspondiente (día, mes). Estos datos terminan con el valor de monto cero. Informe: a) el total recaudado por mes, b) El mes de menor aporte. Para resolver el problema organice un arreglo de 12 elementos con los montos mensuales de los aportes. Ejercicio 6 Genere una matriz de 100x100 elementos. Llenela con valores reales al azar. Muestre la matriz obtenida por pantalla. Realicele las siguientes operaciones y muestre el resultado obtenido. a) Calcule la traza de la matriz. b) Determine el valor máximo y mínimo, y muestre la posición de los mismos. c) Guarde en un vector los promedios de valores de cada fila de la matriz. d) Obtenga la matriz triangular inferior. e) Calcule la desviación estándar de cada una de las columnas y almacene dicho valor en un vector. Ejercicio 7 En una olimpíada estudiantil compiten N alumnos en 3 pruebas (1: matemáticas, 2: física y 3: computación). Se ingresan por cada inscripto el DNI y su número asignado para la competencia (entre 1 y N). Luego, sin orden alguno, se van ingresando ternas con los puntajes de cada prueba: nro de participante, código de actividad (1: matemáticas, 2: física y 3: computación), puntaje en la actividad. Escriba un algoritmo que determine: a) El DNI del ganador de la competencia y el puntaje total obtenido. b) El DNI del estudiante que ocupó el 2do lugar y su puntaje. c) ¿Qué puntaje obtuvo en Computación el ganador de la competencia? Ejercicio 8 Una empresa distribuidora comercializa 25 artículos. Posee 4 sucursales y desea analizar el desempeño de las mismas. Para ello se ingresan los datos correspondientes a las ventas efectuadas en cierto período: código sucursal (1…4), código artículo (1…25), cantidad unidades vendidas. Determine e informe: a. Las cantidades de unidades vendidas por la empresa de cada artículo. b. El total de unidades vendidas por la sucursal 3, sumando todos los artículos. c. La cantidad vendida por la sucursal 1 del artículo 6. d. La sucursal que vendió más unidades del artículo 8. Ejercicio 9 Considere el mismo enunciado del problema anterior. Incorpore –además- los datos de los precios de los 25 artículos que comercializa la empresa. Determine e informe: a) La recaudación de cada sucursal. b) La recaudación de la empresa. c) La sucursal que obtuvo mayor recaudación. Ejercicio 10 Se leen los datos de una matriz o tabla de 5x12 que contiene los valores en mm de lluvias producidas en 5 departamentos de la provincia durante los 12 meses de 2005. Se sabe que en algunos departamentos tienen datos faltantes por lo que aparecen valores negativos (-1) en cada uno de esos casos. Escriba un programa C++ que: a) complete los datos de lluvia faltantes con el promedio anual de precipitación en el departamento correspondiente. Cada promedio debe obtenerse con los datos reales existentes (no contar los -1). b) Amplíe la matriz agregando una nueva columna con los totales de mm caídos en todo el año en cada departamento. Informe: 1) la matriz original de datos, 2) la matriz modificada y 3) los totales anuales de lluvia por departamento. Ejercicio 11 Declare un tipo struct con el nombre ficha_alumno indicando al menos 5 campos de tipo simple correspondientes a los datos de un alumno de la UNER. Luego declare 3 variables de ese tipo. Ejercicio 12 Considere el struct ficha_alumno del ejercicio anterior. Agregue al tipo ficha_alumno un campo llamado materias el cual debe almacenar las calificaciones (de 1 a 10) de las asignaturas aprobadas por cada alumno en su carrera. Considere que la carrera consta de 48 materias. Indique la sintaxis para asignar las calificaciones 8, 7 y 10 a las materias 6, 11 y 12 respectivamente a los miembros correspondientes de una variable de tipo ficha_alumno. Ejercicio 13 Declare una variable x con la cual Ud. pueda representar en un programa C++ a una lista de hasta 200 alumnos, cuyos datos se organizan en la estructura tipo ficha_alumno que creó antes. Ejercicio 14 Un número complejo tiene la forma a+bi donde a y b son números reales. Las operaciones básicas con complejos son: Suma, Resta, Producto y Cociente. Escriba un programa C++ que permita ingresar las componentes de 2 números complejos y a través de un menú el usuario seleccione la operación a realizar. Proponga funciones para cada operación de complejos, que permitan devolver el complejo resultante. Proponga una struct llamado complejo de 2 miembros: parte_real y parte_imag para representar y operar los números complejos. Ejercicio 15 Considere el struct complejo del ejercicio anterior. Escriba una función C++ llamada opera_complex( ) cuyo prototipo se indica abajo: complejo opera_complex(complejo c1, complejo c2, char op) Su objetivo es recibir 2 complejos como parámetros y un carácter que indique la operación: ‘+’,’-‘,’*’. Debe devolver el resultado de la operación. Ejercicio 16 Considere un struct frac que contiene dos miembros enteros a y b que representan el numerador y el denominador de una fracción. Genere una función que reciba dos parámetros de tipo frac y devuelva la sula de los dos valores fraccionarios. Proponga un programa C++ que utilice esta función.