Sei sulla pagina 1di 7

Exámen de LP.

Junio 2007 (Teorı́a)

1. Un puntero constante:
A. No se puede modificar, pero los datos a los que apunta sı́ pueden ser modificados.
B. No se puede modificar, y los datos a los que apunta tampoco pueden ser modificados.
C. Se puede modificar para apuntar a una constante diferente.

Solución:
No se puede modificar, pero los datos sı́. La segunda serı́a un puntero constante a datos constantes. La
tercera es un puntero normal.

2. ¿Que significa la siguiente declaración? char *dir [ 4 ] = { "norte", "sur", "este", "oeste" };
A. Se declara un vector de punteros a cadenas de caracteres y se inicializan sus elementos.
B. Es una declaración errónea de una enumeración, pues le sobran las dobles comillas.
C. Se declara un array bidimensional (dir) de caracteres, y al mismo tiempo se inicializan sus elementos.

Solución:
Es un vector de punteros a cadenas de caracteres. Un array bidimensional necesitarı́a dos corchetes más en la
declaración. La diferencia básica es que los punteros pueden apuntar a zonas de memoria de distinto tamaño,
en el array bidimensional se reserva espacio rectangular para filas y columnas. Para todas las columnas se
reserva el mismo espacio. Aún ası́, este array sigue pudiendo direccionarse mediante cuatro corchetes, como
si hubiese sido declarado bidimensional.

3. ¿Cuál de las siguientes declaraciones de funciones es correcta?


A. int func ( int i = 5, int j );
B. int func ( int i = 0, int j = 5, int k);
C. int func ( int i = 2, int j = 5, int k = 10);

Solución:
La última. Si se usan valores por defecto han de usarse a partir de uno en adelante, de lo contrario el
compilador no sabrı́a cuál elegir.

4. Para concatenar dos vectores de caracteres v1, v2, se utiliza la expresión:


A. strcat ( v1, v2 );
B. strcat (v1.length(v1), v2.length(c2));
C. v1 + v2;

Solución:
strcat es la función que se usa para concatenar vectores de caracteres. Ha de disponerse de espacio suficiente
después de v1 para poder escribir v2 a continuación.

5. Cuando se asigna memoria a un array dinámico con el operador new:


A. Es necesario hacerlo en tiempo de compilación.
B. Se debe invocar al operador utilizando un puntero al array.
C. Se puede modificar el tamaño de esta memoria dinámicamente en tiempo de ejecución.

Página 1 de 7
Exámen de LP. Junio 2007 (Teorı́a)

Solución:
La asignación de memoria dinámica se hace en tiempo de ejecución, y el tamaño solicitado puede ser un
valor variable. Se invoca al operador new con el nombre del tipo y un valor integral opcional entre corchetes,
para obtener un puntero al inicio del bloque recien creado, ası́ que no se invoca ”utilizándo” el puntero. El
tamaño de la memoria puede cambiar en tiempo de ejecución, puesto que se puede liberar y solicitar un
bloque mayor. La respuesta correcta es la última.

6. Las clases abstractas:


A. Deben tener al menos una función virtual pura.
B. Permiten instanciar objetos de la propia clase.
C. No permiten utilizar punteros a ellas.

Solución:
Si una clase tiene al menos una función virtual pura entonces es abstracta, con lo que no se pueden instanciar
objetos de la misma.

7. Cuando se trabaja con herencia múltiple y dos o más clases base tienen atributos con el mismo nombre:
A. Esta situación no puede darse porque cuando las clases están relacionadas sus atributos privados tienen
que tener nombres diferentes.
B. El problema de acceso a los miembros de cada clase se resuelve con el operador de resolución de ámbito.
C. Esta situación no puede darse porque está prohibida en herencia múltiple.

Solución:
Se usa el operador de resolución de ámbito :: para referirse a cada uno de los atributos.

8. ¿Qué devuelve la función getNombre(nombre), cuyo prototipo es: char [] getNombre(string nombre);
A. Un vector de caracteres.
B. La dirección de memoria a partir de la cual comienza la variable nombre.
C. La declaración es incorrecta.

Solución:
Si alguna función devolviese un array, tendrı́amos que asignárselo a otro, para poder referirnos a él. Los arrays
se asignan en la declaración y su tamaño ha de ser constante, asi que no puede provenir de la ejecución de
una función. Además, no pueden volver a asignarse después de haberse creado, (recuerda que el nombre
del array es un puntero constante al inicio del propio array) ası́ que serı́a inútil permitir que una función
devolviese un array. La declaración es incorrecta.

9. Dada una clase Clase, la sentencia Clase c();


A. Llama al constructor por defecto y crea un objeto de tipo Clase.
B. Llama al constructor por defecto y crea un objeto de tipo Clase con valores iniciales predefinidos.
C. Declara una función de nombre c que no tiene parámetros, y devuelve resultado de tipo Clase.

Solución:
La última es la respuesta correcta. Para crear un objeto llamando al constructor por defecto han de eliminarse
los paréntesis.Esto es debido, precisamente, a la necesidad de evitar esta duplicidad.

Página 2 de 7
Exámen de LP. Junio 2007 (Teorı́a)

10. ¿Existe algún error en la siguiente declaración de la clase Fruta?


c l a s s Fruta {
s t r i n g nombreFruta ;
float pr ecio ;
public :
Fruta ( ) ;
Fruta ( s t r i n g nombre , f l o a t p = 1 . 1 0 ) ;
const Fruta ( s t r i n g nombre , f l o a t p = 1 . 1 0 ) ;
˜ Fruta ( ) ;
};

A. Cuando hay constructores parametrizados, deben declararse antes que el constructor por defecto.
B. No se pueden declarar los constructores como constantes.
C. El código es correcto.

Solución:
No se puede declarar el constructor como constante.

11. Se desea almacenar el nombre de un alumno, ¿que declaración serı́a la correcta para realizar tal almacenamiento?
Razona tu respuesta brevemente y con claridad.
A. char *nombre;
B. char nombre [40];
C. char nombre [ ];
D. Todas las declaraciones anteriores sirven para almacenar el nombre de un alumno.

Solución:
El primero es un puntero a char. Técnicamente, no almacena realmente el nombre del alumno, sino la dirección
del mismo, aunque eso podrı́a usarse si el nombre estuviese en memoria dinámica o fuese compartido por
más objetos. El segundo es un array que puede almacenar correctamente un nombre de hasta 39 caracteres.
Puesto que reserva esa cantidad de espacio, puede usarse cuando el nombre no se comparte con más objetos.
El tercero solo declara un array, no reserva espacio. Se puede usar para declarar un array parámetro en una
función, pero no para almacenar el nombre del alumno.

12. Indica razonando cuál de las siguientes afirmaciones es la correcta para la sentencia: ”La diferencia entre el
constructor de copia y el operador de asignación es”:
A. Ninguna.
B. El operador de asignación debe copiar la información de un objeto en otro que ya existe, y liberar
previamente la memoria de los atributos dinámicos.
C. El constructor de copia necesita pasar de forma explı́cita dos argumentos: el objeto a copiar y el nuevo
objeto.
D. El operador de asignación necesita pasar de forma explı́cita dos argumentos: el objeto a asignar y el
nuevo objeto.

Solución:
La primera no es correcta. La segunda sı́ lo es. La tercera no, el constructor de copia recibe solamente un
parámetro explı́cito, que es el objeto a copiar. En la cuarta, el único parámetro explı́cito es el objeto a copiar,
el otro (this) es siempre implicito, puesto que ese operador ha de ir siempre dentro de la clase, como un
método miembro.

13. Suponiendo definidas las siguientes funciones, razona si es correcto el código:

Página 3 de 7
Exámen de LP. Junio 2007 (Teorı́a)

i nt p o t e n c i a ( i nt exponente , i nt ba se = 1 ) ;
i nt p o t e n c i a ( i nt exponente , double ba se = 1 . 0 ) ;
void main ( ) {
cout<<” 1 e l e v a d o a 3 : ”<<p o t e n c i a (3)<< e n d l ; }

Solución:
La llamada es ambigua, el compilador no sabe cuál deberı́a ejecutar. Se puede arreglar eliminando los valores
por defecto y obligando a enviarlos explı́citamente

14. ¿Existen errores en el siguiente código? Razónalo e intenta corregirlos:


c l a s s Fecha {
i nt dia , mes , anho ;
public :
Fecha ( i nt d , i nt m, i nt a ) { d i a = d ; mes = m; anho = a ; }
i nt g e t D i a ( ) { return d i a ; } ;
fri end i nt sumaFecha ( i nt num, Fecha f ) { return num + this −>d i a ; }
};

Solución:
En una función global no existe el puntero this, aunque se declare amiga. Puede cambiarse this->dia por
f.getDia() y definir la función fuera de la clase, no necesita ser amiga. Si se define dentro como función
miembro entonces podrı́a prescindirse del parámetro Fecha f

15. ¿Son correctas las siguientes declaraciones y definiciones? Razónalo brevemente y con claridad.
c l a s s Fruta {
float pr ecio ;
public :
Fruta ( i nt p r e c = 0 . 0 ) { p r e c i o = p r e c ; }
};
c l a s s Manzana : public Fruta {
s t r i n g nombre ;
public :
Manzana ( s t r i n g nom = ” r e i n e t a ” ) : Fruta ( i nt p r e c ) { nombre = nom ; }
s t r i n g getNombre ( ) { return nombre ; }
f l o a t g e t P r e c i o ( ) { return p r e c i o ; }
};

Solución:
El constructor de Manzana realiza una llamada al constructor de Fruta en la lista de inicializadores con una
declaración, ha de eliminarse el tipo y dejar solamente el dato. El método getPrecio() intenta acceder a
una variable privada de su clase madre. Para hacerlo posible podrı́a hacerse, al menos, protected la variable
precio en la clase madre.
La conversión entre el parámetro prec y el valor 0.0 se realiza automáticamente eliminando la parte decimal.
Algunos compiladores mostrarán una advertencia.

16. Completar el siguiente trozo de código de forma que se traten correctamente las excepciones:
i nt l e e r E d a d ( ) ;
void main ( ) {
i nt edad ;
edad = l e e r E d a d ( ) ;

Página 4 de 7
Exámen de LP. Junio 2007 (Teorı́a)

i f ( edad < 0 )
throw edad ;
e l s e i f ( ( edad > 90 ) && ( edad < 120 ) )
throw ” A l u c i n a n t e ” ;
e l s e i f ( edad > 120 )
throw s t a t i c c a s t <f l o a t > ( edad ) ;
}
i nt l e e r E d a d ( ) {
i nt e ;
co ut << ” I n t r o d u c e l a edad : ” ;
c i n >> e ;
return e ;
}

Solución:
La función main debe devolver un entero.
try {
i f ( edad < 0 )
throw edad ;
e l s e i f ( ( edad > 90 ) && ( edad < 120 ) )
throw ” A l u c i n a n t e ” ;
e l s e i f ( edad > 120 )
throw s t a t i c c a s t <f l o a t > ( edad ) ;
} catch ( i nt e ) {

} catch ( char ∗ e ) {

} catch ( f l o a t e ) {

17. Indicar cuál será la salida del siguiente programa, explicando brevemente cómo se llega a esa conclusión.
#include <i o s t r e a m>
using namespace s t d ;
#include <v e c t o r >
double suma ( v e c t o r < f l o a t > v ) ;
void main ( ) {
vector < float > vect ;
for ( unsigned i nt i = 0 ; i != 1 0 ; i++ )
v e c t . push ba ck ( i ) ;
co ut << ”La suma e s : ” << suma ( v e c t ) << e n d l ;
}
double suma ( v e c t o r < f l o a t > v ) {
double r e s u l t a d o ( 0 ) ;
for ( v e c t o r < f l o a t > :: i t e r a t o r i t e = v . b e g i n ( ) ; i t e != v . end ( ) ; i t e ++ )
r e s u l t a d o += ∗ i t e ;
return r e s u l t a d o ;
}

Solución:
Aparecerá la frase ”La suma es: 45”. Realiza la suma de los 10 primeros números float que guarda en un
vector. Para recorrer el vector se usa un iterador que empieza apuntando al primer elemento y que termina
cuando apunta al que deberı́a estar después del último.

Página 5 de 7
Exámen de LP. Junio 2007 (Teorı́a)

18. Dada la definición de la clase Habitacion, completar la función actualizar, de forma que todas las habitaciones
almacenadas en el fichero binario ”clinica” cuyo número esté comprendido entre 100 y 120 (ambos incluidos),
queden vacı́as (el NIF del paciente será la cadena vacı́a).
const unsigned i nt TAMNIF ( 1 0 ) ;
class Habitacion {
unsigned i nt numero ;
char n i f [ TAMNIF ] ;
public :
H a b i t a c i o n ( unsigned i nt num = 0 , char n i f E n t r a d a [ ] = ” \0 ” ) {
numero = num ;
strcpy ( nif , nifEntrada ) ; }
void p u t N i f ( char nuevo Nif [ ] ) { s t r c p y ( n i f , nuevo Nif ) ; }
unsigned i nt getNumero ( ) { return numero ; }
char ∗ g e t N i f ( ) { return n i f ; }
}
void a c t u a l i z a r ( ) {
Habitacion h ;
fstream f l u j o ( ” c l i n i c a ” , ) ;
while ( ! f l u j o . e o f ( ) ) {
i f ( ( h . getNumero ( ) >= 100 ) && ( h . getNumero ( ) <= 120 ) ) {
h . putNIf ( ” \0 ” ) ;
}
}
flujo . close ( );
}

Solución:
No debe usarse la forma "\0" para indicar cadena vacı́a, el compilador agrega un final de cadena a ""
automáticamente. Tampoco debe iniciarse un array de char con la cadena vacı́a, pues el compilador la crea
con caracteres constantes. Se debe agregar const para evitar la conversión.
#include <i o s t r e a m>
#include <f s t r e a m>
using namespace s t d ;
const unsigned i nt TAMNIF ( 1 0 ) ;
class Habitacion {
unsigned i nt numero ;
char n i f [ TAMNIF ] ;
public :
H a b i t a c i o n ( unsigned i nt num = 0 , const char n i f E n t r a d a [ ] = ” ” ) {
numero = num ;
strcpy ( nif , nifEntrada ) ; }
void putNIF ( const char nuevo Nif [ ] ) { s t r c p y ( n i f , nuevo Nif ) ; }
unsigned i nt getNumero ( ) { return numero ; }
char ∗ g e t N i f ( ) { return n i f ; }
};
void a c t u a l i z a r ( ) {
Habitacion h ;
f s t r e a m f l u j o ( ” c l i n i c a ” , i o s : : i n | i o s : : out | i o s : : b i n a r y ) ;
while ( ( f l u j o . r ea d ( ( char∗)&h , s i z e o f ( H a b i t a c i o n ) ) ) && ( ! f l u j o . e o f ( ) ) ) {
i f ( ( h . getNumero ( ) >= 100 ) && ( h . getNumero ( ) <= 120 ) ) {
h . putNIF ( ” ” ) ;
}
f l u j o . s e e k p ( s i z e o f ( H a b i t a c i o n ) ∗ −1, i o s : : cur ) ;
f l u j o . w r i t e ( ( char∗)&h , s i z e o f ( H a b i t a c i o n ) ) ;
}
flujo . close ( );

Página 6 de 7
Exámen de LP. Junio 2007 (Teorı́a)

19. En el siguiente programa, indicar cómo se resuelven todos los mensajes (mediante ligadura dinámica o estática)
y qué función se ejecuta (clase base o clase derivada).
c l a s s ba se {
protected :
i nt b ;
public :
v i r t u a l void mo str a r ( ) { co ut << ” b= ” << b << e n d l ; }
void a lma cena r ( ) { c i n >> b ; }
};
c l a s s d e r i v a d a : public ba se {
protected :
i nt d ;
public :
void mo str a r ( ) { co ut << ” b= ” << b << ” , d= ” << d << e n d l ; }
void a lma cena r ( ) { c i n >> b >> d ; }
};
void main ( ) {
ba se obj1 , ∗p ;
d e r i v a d a obj2 , ∗q ;
p = &o b j 1 ;
p −> a lma cena r ( ) ;
p −> mo str a r ( ) ;
q = &o b j 2 ;
q −> a lma cena r ( ) ;
q −> mo str a r ( ) ;
p = &o b j 2 ;
p −> a lma cena r ( ) ;
p −> mo str a r ( ) ;
}

Solución:

p->almacenar: estatica base


p->mostrar: dinámica base
q->almacenar: estatica derivada
q->mostrar: estática derivada
p->almacenar: estatica base
p->mostrar: dinámica derivada

Resumen:
Puntero a... Apuntando a... Tipo de método Ligadura Se ejecuta la versión de...
------------- --------------- --------------- -------- ----------------------------
base base normal Estática base
base base virtual Dinámica base
base derivada normal Estática base
base derivada virtual Dinámica derivada !!
derivada derivada normal Estática derivada
derivada derivada virtual Estática derivada

Página 7 de 7

Potrebbero piacerti anche