Professional Documents
Culture Documents
Septiembre 2003
1. (2 puntos) Detecta los posibles errores en los siguientes segmentos de programa e intenta corregirlos razonando
su corrección:
(a) i n l i n e main ( )
{ i nt x , y ;
c i n >>x>>y ;
cout<<” El r e s u l t a d o de m u l t i p l i c a r x e y e s : ”<<m u l t i p l i c a r ( x , y ) ;
}
i nt m u l t i p l i c a r ( i nt &a , i nt b )
{ return ( ∗ a ) ∗ b ; }
Solución:
(b) f l o a t v ( 8 ) ;
f l o a t c a l c u l o ( f l o a t x=v , i nt y=1 , f l o a t z = 3 .5 )
{ return x+y+z ; }
bool f u n c i o n 1 ( )
{ i f ( c a l c u l o ( 3 . 2 , 7 ) ! = 1 0 ) return true ;
e l s e return f a l s e ; }
Solución:
a q u i to do c o r r e c t o
(c) i nt f u n c i o n 1 ( r e g i s t e r i nt x , f l o a t y )
{ extern i nt a ;
c i n >>a ;
return ( x−y)+a ; }
Solución:
Solución:
Página 1 de 11
Exámen de LP. Septiembre 2003
2. (3 puntos) Completa los siguientes segmentos de programa para obtener las salidas indicadas:
(a) Con esta sentencia for se pretende calcular la siguiente suma: 1/2 + 1/3 + 1/4 + ... + 1/50
f l o a t suma ( 0 ) , j ;
i nt i =2;
for ( );
co ut <<” R e s u l t a d o : ”<<suma ;
Solución:
for ( j =2; j <=50; suma += ( 1 / j ++));
(b) El vector vector contiene las direcciones donde comienzan 10 cadenas tratadas como cadenas de caracteres:
char *vector[10]; La función ordenar recibe ese vector y ordena sus direcciones de forma que al recorrerlo
(después de ejecutarse la función) se obtiene a partir de él las cadenas ordenadas alfabéticamente. (Se puede
usar las funciones predefinidas para cadenas.)
void o r d e n a r ( )
{ char ∗temp ;
}
Solución:
#include <i o s t r e a m>
using namespace s t d ;
void o r d e n a r ( char ∗ v e c t o r [ ] , i nt s i z e ) {
char ∗ tmp ;
bool cambiado = true ;
i nt d i f f ;
while ( cambiado ) {
cambiado = f a l s e ;
for ( i nt n=0; n < s i z e −1; n++){
i f ( strcmp ( v e c t o r [ n ] , v e c t o r [ n+1] ) > 0 ) {
tmp=v e c t o r [ n ] ;
vector [ n ] = vector [ n+1];
v e c t o r [ n+1] = tmp ;
cambiado=true ;
}
}
}
}
(c) El siguiente programa usa punteros a funciones para obtener el mayor y menor de los elementos introducidos
en un array bidimensional
#include <i o s t r e a m . h>
const i nt f i l =5; const i nt c o l =5;
float buscar ( float matriz [ ] [ col ] , );
f l o a t mayor ( f l o a t x , f l o a t y);
f l o a t menor ( f l o a t x , f l o a t y);
i nt menu ( ) ;
Página 2 de 11
Exámen de LP. Septiembre 2003
void main ( )
{ f l o a t m a t r i z [ f i l ] [ c o l ]={ 0 } , ;
cout<<” I n t r o d u c e l o s e l e m e n t o s de l a m a t r i z \n” ;
for ( i nt i =0; i < f i l ; i ++)
for ( i nt j =0; j <c o l ; j ++) {
cout<<” Ma tr iz [ ”<<i <<” ] [ ”<<j <<” ] ” ; c i n >>m a t r i z [ i ] [ j ] ;
}
switch ( menu ( ) ) {
case 1 : p=mayor ; break ;
case 2 : p=menor ; break ;
}
cout<<” El elemento l o c a l i z a d o e s : ”<<b u s c a r ( ma tr iz , p)<<e n d l ;
}
i nt menu ( ) {
i nt op=0;
do {
cout<<”MENU\n 1 . Mayor\n 2 . Menor” ; c i n >>op ;
} while ( op < 1 ) | | ( op > 2 ) ) ;
return op ;
}
float buscar ( float matriz [ ] [ c o l ] , ) {
f l o a t r e s u l=m a t r i z [ 0 ] [ 0 ] ;
for ( i nt i =0; i < f i l ; i ++)
for ( i nt j =0; j <c o l ; j ++)
return r e s u l ;
}
f l o a t mayor ( f l o a t x , f l o a t y ) {
i f ( x>y )
return x ;
e l s e return y ;
}
f l o a t menor ( f l o a t x , f l o a t y ) {
i f ( x<y )
return x ;
e l s e return y ;
}
Solución:
El puntero p ha de declararse antes de su uso como:
float (∗p ) ( flo a tx , float y ) ;
Ha de agregarse también un segundo parámetro a la función buscar como:
float buscar ( float matriz [ ] [ c o l ] , float (∗p ) ( float x , float y ) ) ;
Dentro del bucle se llama a la función a la que apunte el puntero p
float r e s u l = matriz [ 0 ] [ 0 ] ;
for ( i nt i =0; i < f i l ; i ++){
for ( i nt j =0; j <c o l ; j ++){
r e s u l = p( r esul , matriz [ i ] [ j ] ) ;
}
return r e s u l ;
}
3. (2,5 puntos) Usando aritmética de punteros (no indexando los punteros ni los vectores) y sin emplear las funciones
predefinidas para cadenas (strlen, strcmp, etc), realiza un programa que lea del teclado una cadena de caracteres
cuyo tamaño es conocido en tiempo de ejecución, y que una función de dicho programa devuelva verdadero si
Página 3 de 11
Exámen de LP. Septiembre 2003
el contenido de dicha cadena es un palı́ndromo (palabra o frase que se lee igual de derecha a izquierda que en
sentido inverso) y falso en caso contrario.
Solución:
4. (2,5 puntos) Se dispone de un fichero con acceso directo para almacenar la información correspondiente a las
personas nacidas en una provincia. Para ello se usa la siguiente estructura:
struct t i p o f e c h a
{ unsigned d i a ;
unsigned mes ;
unsigned anno ; } ;
struct ciuda da no
{ char n i f [ 9 ] ; //N. I . F . d e l ciu dadan o
char nombre [ 4 0 ] ; // nombre c o m p l e t o d e l ciu dadan o
tipo fecha fecha nacimiento ; // f e c h a de n a c i m i e n t o d e l ciu dadan o
unsigned v i v o : 1 ; // s i s i g u e v i v o o no d i c h o ciu dadan o
unsigned t i e n e d e s c e n d i e n t e s : 1 ; // s i d i c h o ciu dadan o t i e n e d e s c e n d i e n t e s
};
Escribe un programa que lea de dicho fichero y almacene en otro, también de acceso directo, solo el nif y la fecha
de nacimiento de todas aquellas personas que sigan vivas y que hayan nacido entre 1930 y 1936.
Página 4 de 11
Exámen de LP. Septiembre 2003
Solución:
ciuda da no p ;
while ( ( c i u d a d a n o s . r ea d ( ( char ∗ ) &p , s i z e o f ( ciuda da no ) )
&& ! c i u d a d a n o s . e o f ( ) ) ) {
i f ( ( p . f e c h a n a c i m i e n t o . anno >= 1930
&& p . f e c h a n a c i m i e n t o . anno <= 1 9 3 6 )
&& ( p . v i v o == 1 ) ) {
v i v o s . w r i t e ( ( char ∗ ) &p . n i f , s i z e o f ( char ) ∗TAM NIF ) ;
v i v o s . w r i t e ( ( char ∗ ) &p . f e c h a n a c i m i e n t o , s i z e o f ( t i p o f e c h a ) ) ;
}
}
vivos . close ( ) ;
ciudadanos . c l o s e ( ) ;
}
Página 5 de 11
Exámen de LP. Septiembre 2003
Solución:
private :
i nt ∗∗ d a t o s ;
i nt rows , c o l s ;
void r e s e r v a D a t o s ( ) ;
void l i b e r a D a t o s ( ) ;
void c o p i a D a t o s ( i nt ∗ ∗ ) ;
Ma tr iz : : ˜ Ma tr iz ( ) {
liberaDatos ( ) ;
}
Ma tr iz : : Ma tr iz ( const Ma tr iz &m) {
rows =m. rows ;
c o l s = m. c o l s ;
reservaDatos ( ) ;
c o p i a D a t o s (m. d a t o s ) ;
}
i nt ∗ & Ma tr iz : : operator [ ] ( i nt f i l a ) {
return d a t o s [ f i l a ] ;
}
Ma tr iz : : Ma tr iz ( i nt rows , i nt c o l s ) : rows ( rows ) , c o l s ( c o l s ) {
reservaDatos ( ) ;
}
Ma tr iz & Ma tr iz : : operator=(const Ma tr iz & m) {
i f ( ( rows != m. rows ) | | ( c o l s != m. c o l s ) ) {
liberaDatos ( ) ;
rows = m. rows ;
c o l s = m. c o l s ;
Página 6 de 11
Exámen de LP. Septiembre 2003
reservaDatos ( ) ;
}
c o p i a D a t o s (m. d a t o s ) ;
return ∗ t h i s ;
}
Ma tr iz & Ma tr iz : : operator −(const Ma tr iz & m) {
i f ( ( rows != m. rows ) | | ( c o l s != m. c o l s ) ) {
co ut << ” E r r o r a l r e s t a r m a t r i c e s d i f e r e n t e s ” ;
return ∗ t h i s ;
}
for ( i nt row = 0 ; row < rows ; row++){
for ( i nt c o l = 0 ; c o l < c o l s ; c o l ++){
this −>d a t o s [ row ] [ c o l ] −= m. d a t o s [ row ] [ c o l ] ;
}
}
return ∗ t h i s ;
}
bool operator == ( const Ma tr iz &a , const Ma tr iz &b ) {
i f ( ( a . rows != b . rows ) | | ( a . c o l s != b . c o l s ) ) {
return f a l s e ;
}
for ( i nt row = 0 ; row < a . rows ; row++){
for ( i nt c o l = 0 ; c o l < a . c o l s ; c o l ++){
i f ( a . d a t o s [ row ] [ c o l ] != b . d a t o s [ row ] [ c o l ] ) {
return f a l s e ;
}
}
}
return true ;
}
void Ma tr iz : : l i b e r a D a t o s ( ) {
for ( i nt row = 0 ; row < rows ; row++){
delete [ ] d a t o s [ row ] ;
}
delete [ ] d a t o s ;
}
void Ma tr iz : : c o p i a D a t o s ( i nt ∗∗ d a t o s ) {
for ( i nt row = 0 ; row < rows ; row++){
for ( i nt c o l = 0 ; c o l < c o l s ; c o l ++){
this −>d a t o s [ row ] [ c o l ] = d a t o s [ row ] [ c o l ] ;
}
}
}
void Ma tr iz : : r e s e r v a D a t o s ( ) {
d a t o s = new i nt ∗ [ rows ] ;
for ( i nt n= 0 ; n<rows ; n++){
d a t o s [ n]= new i nt [ c o l s ] ;
for ( i nt c o l= 0 ; c o l <c o l s ; c o l ++){
datos [ n ] [ c o l ] = 0 ;
}
}
}
Ma tr iz sumarAInt ( i nt n , const Ma tr iz & m) {
Ma tr iz r e t (m) ;
for ( i nt row = 0 ; row < m. rows ; row++){
for ( i nt c o l = 0 ; c o l < m. c o l s ; c o l ++){
r e t . d a t o s [ row ] [ c o l ] +=n ;
Página 7 de 11
Exámen de LP. Septiembre 2003
}
}
return r e t ;
}
o str ea m & operator << ( o str ea m & os , Ma tr iz &m) {
for ( i nt row = 0 ; row < m. rows ; row++){
for ( i nt c o l = 0 ; c o l < m. c o l s ; c o l ++){
o s << m[ row ] [ c o l ] << ” , ” ;
}
o s << e n d l ;
}
o s << e n d l ;
return o s ;
}
i nt main ( ) {
Ma tr iz m( 2 , 2 ) ;
m[ 0 ] [ 1 ] = 1 0 ;
m[ 1 ] [ 1 ] = 2 0 ;
co ut << ”M: ”<<e n d l ;
co ut << m;
Ma tr iz z = sumarAInt ( 2 0 0 , m) ;
co ut << ”Z : ”<<e n d l ;
co ut << z<<e n d l ;
Ma tr iz x = m−z ;
co ut << ”X: ”<<e n d l ;
co ut << x<<e n d l ;
i f ( x == z ) co ut << ” e r r o r ”<<e n d l ;
z = x;
i f ( x == z ) co ut << ” son i g u a l e s ”<<e n d l ;
}
6. (3 puntos) Se pretende escribir un programa para calcular las nóminas de una empresa en la que hay dos tipos
de empleados: comerciales y mecánicos. Todos ellos cobran un salario base, que en el caso de un mecánico se
incrementa en 6 euros por hora extra trabajada y en el de un comercial se incrementa con un porcentaje del 5 %
sobre las ventas de cada mes. Si CalcularSueldo( ) calcula el salario mensual de cada empleado, para calcular la
nómina de los empleados de la empresa se puede utilizar una función SumarSueldos( ) que recibe como argumento
un vector de punteros a empleados apuntando a los diferentes comerciales y mecánicos de la empresa y el número
total de empleados, y calcula la suma total de los sueldos de los empleados.
(a) Define la clase empleado cuyo constructor reciba como argumento el sueldo base. Define a partir de ella las
clases comercial y mecánico, que reciban además el porcentaje de ventas y las horas extra respectivamente.
Solución:
#include <i o s t r e a m>
using namespace s t d ;
c l a s s Empleado {
public :
Empleado ( f l o a t s u e l d o B a s e )
: sueldoBase ( sueldoBase ){
}
virtual float c a l c u l a r S u e l d o ()=0;
protected :
float sueldoBase ;
};
c l a s s Co mer cia l : public Empleado {
public :
Página 8 de 11
Exámen de LP. Septiembre 2003
(b) Implementa la función SumarSueldos() de tal manera que utilice ligadura dinámica.
Solución:
f l o a t suma r Sueldo s ( Empleado ∗∗ p l a n t i l l a , i nt numTrabajadores ) {
f l o a t r e t =0;
for ( i nt n = 0 ; n< numTrabajadores ; n++){
r e t += p l a n t i l l a [ n]−> c a l c u l a r S u e l d o ( ) ;
}
return r e t ;
}
Solución:
i nt main ( ) {
Empleado ∗ empresa [ 3 ] ;
empresa [ 0 ] = new Co mer cia l ( 1 0 0 0 , 1 0 0 0 0 ) ;
empresa [ 1 ] = new Mecanico ( 2 0 0 0 , 1 0 ) ;
empresa [ 2 ] = new Co mer cia l ( 8 0 0 , 1 0 0 0 0 0 0 ) ;
f l o a t t o t a l = suma r Sueldo s ( empresa , 3 ) ;
co ut << ” To ta l nomina : ”<< t o t a l <<e n d l ;
}
Página 9 de 11
Exámen de LP. Septiembre 2003
Solución:
#include <i o s t r e a m>
#include < i t e r a t o r >
#include < l i s t >
#include <a l g o r i t h m>
using namespace s t d ;
i nt main ( ) {
l i s t <s t r i n g > l i s t a ;
o s t r e a m i t e r a t o r <s t r i n g > out ( cout , ” , ” ) ;
l i s t a . push ba ck ( ”UNO” ) ;
l i s t a . push ba ck ( ”DOS” ) ;
l i s t a . push ba ck ( ”TRES” ) ;
l i s t a . push ba ck ( ”CUATRO” ) ;
l i s t a . push ba ck ( ”CINCO” ) ;
l i s ta . sort ();
l i s t <s t r i n g > : : i t e r a t o r i = l i s t a . b e g i n ( ) ;
++i ;
l i s t a . erase ( i ) ;
i = l i s t a . end ( ) ;
−−i ;
−−i ;
l i s t a . erase ( i ) ;
co ut << e n d l ;
i = l i s t a . begin ( ) ;
while ( i != l i s t a . end ( ) ) {
co ut << ∗ i << ” , ” ;
i ++;
}
}
(b) Escribe un manipulador propio de entrada para cambiar la base a hexadecimal y otro de salida para cambiar
la precisión a 10 dı́gitos y la longitud de campo a 30 caracteres. Escribir un programa de prueba.
Solución:
#include <i o s t r e a m>
#include <iomanip>
using namespace s t d ;
c l a s s MuyAncho{
};
c l a s s AHex{
};
o str ea m & operator << ( o str ea m & os , MuyAncho &t ) {
o s << s e t p r e c i s i o n ( 1 0 ) ;
o s << setw ( 3 0 ) ;
Página 10 de 11
Exámen de LP. Septiembre 2003
return o s ;
}
i s t r e a m & operator >> ( i s t r e a m & i s , AHex &t ) {
i s >> hex ;
return i s ;
}
i nt main ( ) {
AHex xx ;
MuyAncho mm;
f l o a t n=0;
c i n >> xx >> n ;
co ut << ” [ ” << mm << n << ” ] ” ;
}
Página 11 de 11