Problemas de Programación 1 12-11-2015 Registros 1. Representación parcial de permisos de conducción Los problemas planteados en esta clase van a utilizar registros de un tipo denominado Permiso, que representan información relativa a permisos de conducir. En este conjunto de problemas planteados, vamos a considerar únicamente dos datos asociados a los permisos de conducir: el número de puntos y el hecho de que el titular del permiso sea un conductor novel. Definición del tipo Sin mirar la solución que aparece más abajo, define el tipo denominado Permiso para que las variables de dicho tipo puedan reflejar la información previamente comentada. Implementación de un módulo denominado permiso A continuación se muestra el fichero de cabecera (permiso.h) de un módulo denominado permiso, que incluye la definición del tipo Permiso y de unas cuantas funciones para trabajar con registros de tipo Permiso. Se pide el código del fichero de implementación (permiso.cc) del módulo permiso. /* * Los registros de tipo Permiso representan (de forma muy parcial) permisos de conducir por * puntos. Únicamente tenemos en cuenta el número de puntos y el hecho de si el titular es un * conductor novel o no. */ struct Permiso { int puntos; bool novel; /* Aquí irían las definiciones de campos para otra información como nombre, apellidos, DNI, * fecha de expedición, tipo de carnet, ... */ }; /* * Pre: --* Post: Ha devuelto un permiso que representa el permiso de conducir de una persona que acaba de * obtenerlo. */ Permiso obtener(); /* * Pre: --* Post: Ha devuelto «true» si y solo si el titular del permiso «p» es un conductor novel. */ bool esNovel(Permiso p); /* * Pre: --* Post: Ha devuelto la cantidad de puntos asociados al permiso de conducir «p». */ int puntos(Permiso p); /* * Pre: --* Post: Ha modificado el permiso «p» para indicar que el titular de este permiso ya no es un * conductor novel. */ void yaEsExperimentado(Permiso& p); Problemas de Programación 1 12-11-2015 /* * Pre: puntosExtra > 0 * Post: Ha incrementado la cantidad de puntos asociados al permiso de conducir «p» según el * valor del parámetro «puntosExtra», sin sobrepasar la cantidad legal máxima de 15 puntos. */ void sumarPuntos(Permiso& p, int puntosExtra); /* * Pre: sancion > 0 * Post: Ha disminuido la cantidad de puntos asociados al permiso de conducir «p» según del valor * del parámetro «sancion». */ void sancionar(Permiso& p, int sancion); 2. Representación canónica de números racionales Un número racional se representa como un cociente de dos enteros, denominados numerador y denominador. El denominador no puede ser igual a 0. Ejemplos de números racionales: 1 3 -2 4 -2 , 75 , 17 , -9 , -3 Dado un número racional, hay un número infinito de números racionales equivalentes a él: −1 3 = 1 −3 = −2 6 = 2 −6 = −3 9 = 3 −9 = −4 12 = 4 −12 = Se denomina representante canónico de un conjunto de números racionales equivalentes a aquel cuyo denominador es positivo y su numerador y denominador son primos entre sí. En el ejemplo anterior, el representante canónico del conjunto es el racional −31 . Dado un número racional, interesará sustituirlo por un racional equivalente que sea el representante canónico del conjunto de racionales equivalentes al primero. Esta operación la denominaremos reducción del racional, obteniendo como resultado su representante canónico. Dado el siguiente fichero de interfaz (racional.h) de un módulo denominado racional, se debe: • Definir un tipo denominado Racional, que permita representar números racionales canónicos. • Completar el código de las funciones del módulo racional, en su correspondiente fichero de implementación racional.cc. • Añadir un módulo principal con una función main que, para comprobar el funcionamiento del módulo, escriba en la pantalla el racional 98 resultante de realizar la siguiente operación: 24 + 16 − 83 × 68 ÷ −43 . [( ) ] ( /* * Representación de números racionales canónicos. */ struct Racional { ... }; /* * Pre: * Post: * */ Racional denominador != 0 Ha devuelto un registro de tipo Racional cuyo valor es el representante canónico de numerador/denominador. definirRacional(int numerador, int denominador); /* * Pre: «a» y «b» son racionales representantes canónicos. * Post: Ha devuelto a + b. */ Racional sumar(Racional a, Racional b); ) Problemas de Programación 1 12-11-2015 /* * Pre: «a» y «b» son racionales representantes canónicos. * Post: Ha devuelto a - b. */ Racional restar(Racional a, Racional b); /* * Pre: --* Post: Ha devuelto -a. */ Racional opuesto(Racional a); /* * Pre: «a» y «b» son racionales representantes canónicos. * Post: Ha devuelto a × b. */ Racional multiplicar(Racional a, Racional b); /* * Pre: «a» y «b» son racionales representantes canónicos y b != 0. * Post: Ha devuelto a/b. */ Racional dividir(Racional a, Racional b); /* * Pre: a != 0 * Post: Ha devuelto 1/a */ Racional inverso(Racional a); /* * Pre: --* Post: Ha devuelto el valor del numerador del número racional «a». */ int numerador(Racional a); /* * Pre: --* Post: Ha devuelto el valor del denominador del número racional «a». */ int denominador(Racional a); /* * Pre: --* Post: Ha devuelto el valor real de «a» */ double valorReal(Racional a); /* * Pre: --* Post: Ha escrito el racional «a» en la pantalla. */ void escribir(Racional a); /* * Pre: --* Post: Ha devuelto true si y solo si los racionales «a» y «b» son iguales. */ bool sonIguales(Racional a, Racional b);