













Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Prepara tus exámenes
Prepara tus exámenes y mejora tus resultados gracias a la gran cantidad de recursos disponibles en Docsity
Prepara tus exámenes con los documentos que comparten otros estudiantes como tú en Docsity
Encuentra los documentos específicos para los exámenes de tu universidad
Estudia con lecciones y exámenes resueltos basados en los programas académicos de las mejores universidades
Responde a preguntas de exámenes reales y pon a prueba tu preparación
Consigue puntos base para descargar
Gana puntos ayudando a otros estudiantes o consíguelos activando un Plan Premium
Comunidad
Pide ayuda a la comunidad y resuelve tus dudas de estudio
Ebooks gratuitos
Descarga nuestras guías gratuitas sobre técnicas de estudio, métodos para controlar la ansiedad y consejos para la tesis preparadas por los tutores de Docsity
Asignatura: Metodología de la Programación I, Profesor: Juan Carlos Cubero, Carrera: Ingeniería Informática, Universidad: UGR
Tipo: Ejercicios
1 / 21
Esta página no es visible en la vista previa
¡No te pierdas las partes importantes!














Los vectores almacenan de forma compacta información del mismo tipo sobre una misma entidad.
Los struct (registros) almacenan de forma compacta informa- ción de distinto tipo sobre una misma entidad.
TipoAlumno: NIF Nombre Edad Curso Notas
Diremos que NIF, Nombre, Edad, etc, son los campos de TipoAlumno
TipoHora: horas minutos AM
<nombre_variable>.<nombre_campo>
es una variable del tipo declarado en el struct. Las operaciones serán las mismas que las aplicables al corres- pondiente tipo del campo. Al declarar una variable de tipo struct, los campos estarán a basura.
#include
struct TipoAlumno{ char NIF [9]; char Nombre [200]; bool EsBecario; int Edad; int Curso; };
void Incrementa (int &dato){ dato = dato+1; } int AniosParaTerminar (int curso_actual){ return 5 - curso_actual; } int main(){ TipoAlumno un_alumno;
un_alumno.Edad = 21;
un_alumno.EsBecario = true; cin >> un_alumno.Curso; cin >> un_alumno.Nombre;
// pasamos un int a AniosParaTerminar: cout << AniosParaTerminar (un_alumno.Curso);
// pasamos por referencia un int a Incrementa: Incrementa (un_alumno.Curso);
// pasamos un cstring a strlen: cout << "Núm caract. Nombre = " << strlen(un_alumno.Nombre);
// pasamos un char a toupper: un_alumno.Nombre[0] = toupper (un_alumno.Nombre[0]);
Se pueden construir vectores de structs.
struct TipoAlumno{ char NIF [9]; char Nombre [200]; bool EsBecario; int Edad; int Curso; double notas_practicas[3]; }; int main(){ TipoAlumno clase[100]; int util_clase = 60;
// Primer alumno: clase[0].notas_practicas[0] = 6.7; clase[0].notas_practicas[1] = 5.4; .......
// Segundo alumno: clase[1].notas_practicas[0] = 9.5; clase[0].notas_practicas[1] = 8.4; .......
for (int i=0; i<util_clase; i++){ cout << "\nNombre = " << clase[i].Nombre ...... }
Un campo de un struct puede ser otro struct.
struct TipoNotas{ double Practicas[3]; double Teorico; bool PracticaComplementaria; };
struct TipoAlumno{ char NIF [9]; char Nombre [200]; bool EsBecario; int Edad; int Curso; TipoNotas Notas; };
int main(){ TipoAlumno clase[100];
.......... clase[0].Notas.Practicas[0] = 3.4; clase[0].Notas.Teorico = 5.4; clase[0].Notas.PracticaComplementaria = true; }
Sabemos que un vector no puede asignarse a otro vector.
Un struct sí puede asignarse a otro struct. Se copian automáti- camente los valores de todos los campos.
int main(){ TipoAlumno un_alumno, otro_alumno;
un_alumno.Edad = 21; un_alumno.Curso = 3; strcpy(un_alumno.Nombre, "Juan Carlos"); strcpy(un_alumno.NIF, "22222222E");
otro_alumno = un_alumno;
Curiosamente, si el struct contiene un vector, se asignan to- das las componentes una a una (recordad que los vectores, tal cual, no podían asignarse entre sí)
struct TipoAlumno{ ...... double NotasPracticas[3]; };
int main(){ TipoAlumno un_alumno, otro_alumno; ........ un_alumno.NotasPracticas[0] = 3.4; un_alumno.NotasPracticas[1] = 4.5; un_alumno.NotasPracticas[2] = 5; otro_alumno = un_alumno; // Correcto
struct TipoVector50Doubles{ int utilizadas; double componentes[5]; };
int main(){ TipoVector50Doubles datos, copia;
datos.utilizadas = 3; for (int i=1 ; i<datos.utilizadas; i++) cin >> datos.componentes[i];
copia = datos; ....... }
Como la asignación está permitida entre variables de tipo struct , también es posible pasar un struct completo como parámetro a una función. Puede hacerse por valor o por referencia.
Como siempre, se realiza una copia de todo el struct en la pila.
struct TipoAlumno{ .... } void ImprimeDatosAlumno (TipoAlumno alumno);
int main() TipoAlumno un_alumno;
<asignación a los campos de un_alumno>
ImprimeDatosAlumno (un_alumno); }
void ImprimeDatosAlumno (TipoAlumno alumno){ cout << "\nNombre = " << alumno.Nombre; cout << "\nNIF = " << alumno.NIF; cout << "\nCurso = " << alumno.Curso; ..... }
Como cualquier paso por valor, la modificación del formal no altera el parámetro actual. Lo mismo ocurre con sus campos. Las modificaciones de los campos del formal no modifican los campos del actual.
struct TipoAlumno{ .... } QuitaExcesoEspaciosEnBlanco (char cstring[]); void ImprimeDatosAlumno (TipoAlumno alumno);
int main() TipoAlumno un_alumno;
<asignación a los campos de un_alumno>
ImprimeDatosAlumno (un_alumno); }
void ImprimeDatosAlumno (TipoAlumno alumno){ QuitaExcesoEspaciosEnBlanco (alumno.Nombre); cout << "\nNombre = " << alumno.Nombre; cout << "\nNIF = " << alumno.NIF; cout << "\nCurso = " << alumno.Curso; ...... }
Si pasamos por referencia un struct, las modificaciones de los campos del formal, serán modificaciones de los campos del actual.
void LeeDatosAlumno (TipoAlumno &alumno){ cin >> alumno.NIF; cin >> alumno.Nombre; ..... }
int main(){ TipoAlumno un_alumno, clase[100];
LeeDatosAlumno(un_alumno);
for (int i=0; i<util_clase; i++) LeeDatosAlumno(clase[i]); ......
Una función también puede devolver un struct. Para ello, como siempre, declaramos una variable local de tipo struct y al final ejecutamos un return.
TipoAlumno LeeDatosAlumno (){ TipoAlumno alumno;
cin >> alumno.NIF; cin >> alumno.Nombre; .....
return alumno; }
int main(){ TipoAlumno un_alumno, clase[100];
un_alumno = LeeDatosAlumno();
for (int i=0; i<util_clase; i++) clase[i] = LeeDatosAlumno(); ......
Un paso por valor de un struct duplica memoria en la pila. Si el struct es muy grande, y las restricciones de memoria son importantes, puede usarse un paso por referencia constante :
void ImprimeDatosAlumno (const TipoAlumno &alumno){ cout << "\nNombre = " << alumno.Nombre; cout << "\nNIF = " << alumno.NIF; ...... }
void ImprimeDatosAlumno (const TipoAlumno &alumno){ QuitaExcesoEspaciosEnBlanco(alumno.Nombre); // Error compilac cout << "\nNombre = " << alumno.Nombre; cout << "\nNIF = " << alumno.NIF; ...... }
void ImprimeDatosAlumno (const TipoAlumno &alumno){ char nombre_local[200]; strcpy (nombre_local, alumno.Nombre); QuitaExcesoEspaciosEnBlanco (nombre_local); cout << "\nNombre = " << nombre_local; cout << "\nNIF = " << alumno.NIF; ...... }
Si vamos a crear una función que acceda a las componentes del struct, pasaremos todo el struct y no las componentes in- dividualmente.
struct TipoPunto{ double abscisa; double ordenada; }
// :-(
double DistanciaEuclidea (double abscisa1, double ordenada1, double abscisa2, double ordenada2){ return sqrt( pow(abscisa1-abscisa2 , 2) + pow(ordenada1-ordenada2, 2) ); }
int main(){ TipoPunto punto1, punto2; double distancia;
<Asignación de valores> distancia = DistanciaEuclidea(punto1.abscisa, punto1.ordenada, punto2.abscisa, punto2.ordenada); }