Académique Documents
Professionnel Documents
Culture Documents
Curso 2011/2012
Autor: Juan Carlos Cubero Para cualquier sugerencia o comentario sobre este guin de prcticas, por favor, enviad un e-mail a JC.Cubero@decsai.ugr.es
"Lo que tenemos que aprender a hacer, lo aprendemos hacindolo". Aristteles "In theory, there is no difference between theory and practice. But, in practice, there is". Jan L. A. van de Snepscheut "The gap between theory and practice is not as wide in theory as it is in practice". "Theory is when you know something, but it doesnt work. Practice is when something works, but you dont know why. Programmers combine theory and practice: Nothing works and they dont know why".
Acceso identicado
Acceso identicado
Los alumnos deben registrarse electrnicamente en dos sitios distintos: En la Universidad de Granada. Los alumnos deben registrarse electrnicamente en la UGR para poder entrar en las aulas de prcticas de la asignatura. Las instrucciones estn en:
http://www.ugr.es/informatica/alumnos/correo.htm
Se necesita el DNI y el PIN obtenido con la matrcula. El registro electrnico tarda un da (incluso dos) en activarse. Por tanto, realizad el registro al menos tres das antes de la primera sesin de prcticas (que tendr lugar la segunda semana de clases) Una vez que se tenga cuenta de correo en la UGR, el alumno podr iniciar sesin en cualquiera de los ordenadores de la Escuela de Informtica. Para ello, tendr que introducir como usuario y contrasea, los mismos que se han elegido para la UGR. Automticamente, tendr acceso a un sitio de almacenamiento en los servidores de la Escuela. Esto se explica en la primera sesin de prcticas (pgina 22) En la Web del departamento de Ciencias de la Computacin e Inteligencia Articial
https://decsai.ugr.es
La mayor parte de los alumnos ya estn dados de alta en la web con los datos que hemos obtenido de la matrcula. En cualquier caso, el alumno debe comprobarlo durante la primera semana de clases, dando los siguientes pasos: Al entrar en el acceso identicado de la web del departamento, introducir como nombre de usuario y como contrasea el DNI sin la letra del nal (o el nmero de pasaporte). Si puede entrar con xito, acceda a sus datos personales para cambiar el password y subir una foto reciente. Introducid en los datos de contacto una direccin de e-mail que consulte habitualmente, ya que se enviar asiduamente informacin sobre la asignatura. No debe elegirse ninguna direccin de Hotmail ya que la UGR clasica como SPAM muchos correos de dicho servidor.
RegistroWebDECSAI.pdf incluido en http://decsai.ugr.es/jccubero/fp.zip Si no puede entrar, enve un e-mail a JC.Cubero@decsai.ugr.es con su nmero de DNI, Nombre y Apellidos.
Puede
encontrar
instrucciones
ms
detalladas
en
el
chero
Acceso identicado
Una vez tenga acceso a la web del departamento, podr entrar en la asignatura de Fundamentos de Programacin y elegir un grupo de prcticas. Tambin podr acceder al material de la asignatura. El material del primer tema tambin se encuentra en:
http://decsai.ugr.es/jccubero/fp.zip
MUY IMPORTANTE: El alumno nunca deber dar a conocer a un tercero su nombre de usuario y contrasea, ya que es el responsable del mal uso que se pudiese realizar con su cuenta.
Nota: mientras el profesor corrige los ejercicios a un alumno en la primera hora, los alumnos desarrollarn las actividades presenciales de la correspondiente sesin. Cuando las hayan terminado, se pueden poner a trabajar en los problemas de la prxima sesin. 2. Opcionales: Se recomienda que se resuelvan en casa, pero el profesor no los preguntar en las sesiones de prcticas. En la segunda hora, el profesor explicar estos ejercicios a toda la clase. Ampliacin: problemas cuya solucin no se ver, pero que sirven para aanzar conocimientos. El alumno debera intentar resolver por su cuenta un alto porcentaje de stos. No hay que entregar al profesor la solucin de los ejercicios de las distintas sesiones, ya que, durante la segunda hora de prcticas, se proporcionar la solucin a los problemas bsicos y opcionales propuestos. Es muy importante que el alumno revise estas soluciones y las compare con las que l haba diseado. Las actividades marcadas como Seminario han de hacerse obligatoriamente y siempre sern expuestas por algn alumno elegido aleatoriamente. Para la realizacin de estas prcticas, se utilizar el entorno de programacin Microsoft Visual Studio. En la pgina 7 se encuentran las instrucciones para su instalacin en nuestra casa. En cualquier caso, el alumno puede instalar en su casa cualquier otro compilador, como por ejemplo Code::Blocks http://www.codeblocks.org/ Muy importante: La resolucin de los problemas y actividades puede hacerse en grupo, pero la defensa durante las sesiones presenciales es individual. Es muy importante que la asignatura se lleve al da para poder realizar los ejercicios propuestos en estos guiones.
Evaluacin de la asignatura
Evaluacin de la asignatura
La nota nal en la asignatura se computa de la siguiente forma: En Febrero se realizar un examen escrito consistente en la resolucin de varios problemas de programacin relacionados con la materia impartida. La ponderacin de este bloque es del 60 %. La parte prctica se evala de la siguiente forma: Evaluacin continua: Durante las sesiones de prcticas, los alumnos debern defender ante la clase o ante el profesor, los problemas encargados para dicha sesin de prcticas. La ponderacin de esta parte es del 10 %. Exmenes de prcticas: A mediados de Noviembre y a principios de Enero se realizar un examen de prcticas. Cada uno de estos exmenes consistir en la resolucin de un ejercicio de programacin que se extraer de una lista de ejercicios que, previamente, se habr entregado a los estudiantes. Dichas listas de ejercicios se denominarn Listas de Problemas para el Examen Prctico, para diferenciarlas de las Relaciones de Problemas. Cada uno de los dos exmenes durar una hora y se realizar en las aulas de prcticas de la Escuela de Informtica. La ponderacin del primer examen es del 10 % y la del segundo del 20 % La realizacin de las prcticas puede realizarse en grupo, pero la defensa es siempre individual. En Septiembre se guarda la nota de la evaluacin continua y sigue valiendo el 10 % de la nota nal. No hay ningn examen de recuperacin de esta parte. Por otra parte, en Septiembre se realizarn dos exmenes consistentes en la resolucin de varios problemas de programacin relacionados con la materia impartida. Llammosle T y P a dichos exmenes. La ponderacin de ambos exmenes es 60 % para T y 30 % para P. Slo para aquellos alumnos que se presentaron a alguna de las partes (escrita/prcticas) en Febrero: El alumno puede elegir no presentarse a alguna de las parte T o P. En dicho caso, conservara la nota que hubiese obtenido en Febrero. Si no se presenta al examen T, la nota de T sera la que hubiese sacado en el examen escriTo de Febrero y si no se presenta a P, la nota sera la obtenida en las Prcticas de Febrero. Si un alumno se presenta a una de las partes (T o P), la nota obtenida en Febrero en dicha parte NO se conserva (es una nueva calicacin) por lo que la nota de dicha parte podra bajar.
http://www.microsoft.com/spanish/msdn/academico.mspx
La principal restriccin es que no se pueden desarrollar programas comerciales con esta licencia. Para ms informacin sobre las restricciones de la licencia:
http://msdn.microsoft.com/en-us/academic/bb250608.aspx
La versin Ultimate disponible para los alumnos contiene muchas ms herramientas de las que se necesitarn en la asignatura. Si se quiere, puede descargarse directamente desde Internet la versin Express de Visual Studio. Esta versin tambin contiene todas las herramientas y opciones necesarias en esta asignatura, y es la que se usar en las aulas de prcticas:
http://www.microsoft.com/express/Downloads/
Para descargas de versiones anteriores, consultad:
http://msdn.microsoft.com/es-es/express/aa975050.aspx
Los requisitos del sistema, para la instalacin de Visual Studio Express se encuentran en
http://www.microsoft.com/express/Support/
y para Visual Studio 2010 en:
http://www.microsoft.com/spain/visualstudio/products/ 2010-editions/ultimate
Instalar Visual Studio Si se usa el DVD de la fotocopiadora con Visual Studio 2010 Ultimate, se puede instalar la versin completa que incluye todos los lenguajes de Visual Studio como Visual Basic, C#, etc. Al introducir el DVD se lanzar automticamente el programa de instalacin. Selec-
cionamos Instalacin Personalizada. Por ahora, instalamos nicamente la parte correspondiente al lenguaje C++ (posteriormente, podemos instalar el resto de lenguajes) En el caso de que instalemos la versin Visual Studio C++ Express, no se instalarn el resto de lenguajes (que, obviamente, no son necesarios para esta asignatura)
Conguracin
Preparar y acceder a la consola del sistema La consola de Windows (la ventana con fondo negro que aparece al ejecutar el comando cmd.exe, o bien la que sale al ejecutar un proyecto de consola de Visual Studio) no est preparada por defecto para mostrar adecuadamente caracteres latinos como los acentos. Por ejemplo, al ejecutar la sentencia de C++
Atenci5/4n
Para que podamos ver correctamente dichos caracteres, debemos seguir los siguientes pasos: 1. Cambiar la fuente de la consola a una que acepte caracteres Unicode. En la versin de XP de las aulas ya se ha realizado dicho cambio. En nuestra casa, tendremos que hacer lo siguiente:
Inicio->Ejecutar->regedit
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\ \Control\Nls\CodePage y cambiamos el valor que hubiese dentro de OEMCP y ACP por el de 1252. Esta es
la forma recomendada y la que se ha usado en las aulas de prcticas. Requiere reiniciar el ordenador. Muy Importante: Si se usa otra tabla (distinta a 1252), el sistema operativo podra incluso no arrancar. b) Si queremos hacerlo para una nica consola, basta ejecutar el comando
chcp 1252
sobre la consola. El problema es que cada vez que se abre una nueva consola (por ejemplo, como resultado de ejecutar un programa desde Visual C++) hay que realizar este cambio. En nuestro caso, pondramos (por ejemplo, al inicio del programa, justo despus de las declaraciones de las variables) lo siguiente:
system("chcp 1252");
En cualquier caso, remarcamos que esta solucin no es necesaria si se adopta la primera, es decir, el cambio del registro de Windows. Conguracin del entorno Se recomienda que se usen las mismas opciones de conguracin del entorno que las establecidas en las aulas de prcticas. Para ello, deben darse los siguientes pasos. Dentro del chero
Mis Documentos\Visual Studio 2010\Settings Herramientas -> Importar y exportar configuraciones -> Importar la configuracin de entorno seleccionada -> Siguiente
Si se quiere guardar las conguraciones actuales, elegid la primera opcin. Si no se ha trabajado anteriormente con Visual Studio, podemos elegir directamente la segunda opcin:
No, slo importar la nueva configuracin, reemplazando la configuracin actual -> Siguiente -> Examinar
Seleccionamos las opciones guardadas anteriormente en
y hacemos click en Siguiente. Aparecen algunas opciones marcadas con un smbolo de admiracin, indicando que no se van a importar (pues pueden contener informacin privada). Aceptamos y terminamos. Cosas a tener en cuenta: A partir de ahora, si realizamos algn cambio en el entorno o en las opciones de conguracin (Herramientas->Opciones), stas se guardan automticamente en el archivo
Mis Documentos\Visual Studio 2010\ \Settings\CurrentSettings.vssettings Es decir, el archivo SettingsAulasPracticas.vssettings no se modica con
los cambios que efectuemos en las opciones del entorno. Si queremos exportar nuestra conguracin para utilizarla en otro sitio, basta con seleccionar
Herramientas -> Importar y exportar configuraciones -> Exportar la configuracin de entorno seleccionada
y seleccionad el nombre del chero conguracin. La plantilla _fp_2010 En el entorno Visual Studio de las aulas de prcticas, se ha incluido una plantilla con las opciones de conguracin de compilacin ms usuales as como un esqueleto del programa principal que incluye la cabecera que usaremos siempre en nuestros programas. Para instalar esta plantilla en nuestros ordenadores personales, descargad de Internet el chero
http://decsai.ugr.es/jccubero/fp.zip Dentro se encuentra la carpeta Visual Studio\PlantillaFP. Seguid las instrucciones que se encuentran en el chero Instrucciones.txt (simplemente habr que cambiar
una lnea de texto de un chero y copiar unos cheros). Para crear un proyecto nuevo en Visual Studio basado en esta plantilla, basta abrir Visual Studio y seleccionar:
10
_limpiar.bat y _limpiar.exe. El primero es una macro que llama al segundo programa. Ambos cheros deben estar en el directorio del cual cuelgan nuestras carpetas locales de proyectos de Visual Studio. La macro borra todos los cheros auxiliares como los ejecutables, los que contienen informacin de depuracin, etc. En nuestra casa ejecutaremos la macro cuando nos estemos quedando sin espacio en el disco duro y antes de subir a turing los proyectos soluciones de las distintas sesiones prcticas.
11
Ctr-F7 Alt-Ctr-F7 F5 F10 F11 Shift-F11 Shift-F5 Ctr-F5 Ctr-Barra espaciadora F1 F9 Ctr-F10 Ctr-K,Ctr-F Ctr-K,Ctr-D Ctr -
Compilar Generar ejecutable Ejecutar programa (con depuracin) Ejecucin paso a paso (sin entrar en las funciones) Ejecucin paso a paso (entrando en las funciones) Sale de la ejecucin paso a paso de la funcin Detiene ejecucin paso a paso Ejecutar programa (sin depuracin) Autocompleta el cdigo Ayuda Quita o pone un punto de interrupcin Ejecuta instrucciones hasta el cursor y empieza depuracin Aplica formato al texto seleccionado Aplica formato al documento Navega por el texto hacia atrs
12
interes
13
Por qu no funciona? Buscad una solucin. Finalidad: Entender cmo funciona la asignacin entre variables. Dicultad Baja. 4. Cread un programa que nos pida la longitud del radio, calcule el rea del crculo y la longitud de la circunferencia correspondientes, y nos muestre los resultados en pantalla. Recordad que: long. circunf = 2r rea circ = r 2
Usad el literal 3.1416 a lo largo del cdigo, cuando se necesite multiplicar por . Una vez hecho el programa, cambiad las apariciones de 3.1416 por 3.14159, recompilad y ejecutad (La parte de compilacin y ejecucin se realizar cuando se vea en clase de prcticas el entorno de programacin). No hubiese sido mejor declarar un dato constante PI con un valor igual a 3.14159, y usar dicho dato donde fuese necesario? Hacedlo tal y como se explica en las transparencias de los apuntes de clase. Cambiad ahora el valor de la constante PI por el de 3.1415927, recompilad y ejecutad. Finalidad: Entender la importancia de las constantes. Dicultad Baja. 5. Realizar un programa que lea los coecientes reales y de una funcin gaussiana (ver denicin abajo). A continuacin el programa leer un valor de abscisa x y se imprimir el valor que toma la funcin en x
1 e gaussiana(x) = 2
1 2
El parmetro se conoce como esperanza o media y como desviacin tpica (mean y standard deviation en ingls). Para denir la funcin matemtica e usad la funcin exp de la biblioteca cmath. En la misma biblioteca est la funcin sqrt para calcular la raz cuadrada. Para elevar un nmero al cuadrado se puede usar la funcin pow, que se utiliza en la siguiente forma:
pow(base, exponente)
En nuestro caso, el exponente es 2 y la base son correctos, usando el applet disponible en x . Comprobad que los resultados
http://www.danielsoper.com/statcalc/calc54.aspx
o bien algunos de los ejemplos de la gura siguiente (observad que el valor de la desviacin est elevado al cuadrado):
14
Finalidad: Trabajar con expresiones numricas ms complejas. Dicultad Baja. 6. Las ganancias de un determinado producto se reparten entre el diseador y los tres fabricantes del mismo. Disear un programa que pida la ganancia total de la empresa (los ingresos realizados con la venta del producto) y diga cuanto cobran cada uno de ellos, sabiendo que el diseador cobra el doble que cada uno de los fabricantes. El dato de entrada ser la ganancia total a repartir. Utilizad el tipo double para todas las variables. Importante: No repetid clculos ya realizados. Finalidad: Entender la importancia de no repetir cmputos para evitar errores de programacin. Dicultad Baja. 7. Redactar un algoritmo para calcular la media aritmtica muestral y la desviacin estndar (o tpica) muestral de las alturas de tres personas. stos valores sern reales (de tipo double) X= 1 3
3
xi , =
i=1
1 3
(xi X)2
i=1
X representa la media aritmtica y la desviacin estndar. Para resolver este problema es necesario usar la funcin sqrt (raz cuadrada) que se encuentra en la biblioteca cmath. Finalidad: Trabajar con expresiones numricas y con variables para no repetir cmputos. Dicultad Baja. 8. Realizar un programa que declare las variables x, y y z, les asigne los valores 10, 20 y 30 e intercambien entre s sus valores de forma que el valor de x pasa a y, el de y pasa a z y el valor de z pasa a x (se pueden declarar variables auxiliares aunque se pide que se use el menor nmero posible). Finalidad: Mostrar la importancia en el orden de las asignaciones. Dicultad Media. 9. Leed desde teclado tres variables correspondientes a un nmero de horas, minutos y segundos, respectivamente. Disear un algoritmo que calcule las horas, minutos
15
y segundos dentro de su rango correspondiente. Por ejemplo, dadas 10 horas, 119 minutos y 280 segundos, debera dar como resultado 12 horas, 3 minutos y 40 segundos. En el caso de que nos salgan ms de 24 horas, daremos tambin los das correspondientes (pero ya no pasamos a ver los meses, aos, etc) Como consejo, utilizad el operador / que cuando trabaja sobre datos enteros, representa la divisin entera. Para calcular el resto de la divisin entera, usad el operador %. Finalidad: Trabajar con expresiones numricas y con variables para no repetir cmputos. Dicultad Media. 10. Realizad el ejercicio del reparto de la ganancia de un producto, pero cambiando el tipo de dato de la ganancia total a int (el resto de variables siguen siendo double) Finalidad: Trabajar con expresiones numricas que involucren distintos tipos de datos. Dicultad Baja. 11. Realizad el ejercicio del clculo de la desviacin tpica, pero cambiando el tipo de dato de las variables xi a int. Nota: Para no tener problemas en la llamada a la funcin pow (en el caso de que se haya utilizado para implementar el cuadrado de las diferencias de los datos con la media), obligamos a que la base de la potencia sea un real multiplicando por 1.0, por lo que la llamada quedara en la forma pow(base*1.0, exponente) Finalidad: Trabajar con expresiones numricas que involucren distintos tipos de datos. Dicultad Baja. 12. Encontrar el valor de la variable resultado despus de la ejecucin de este cdigo
real1 = 4.0; real2 = 3.0; resultado = real1/real2 - real1*real2; cout << "\nResultado = " << resultado;
Considerad los siguientes casos:
16
RELACIN DE PROBLEMAS I. Introduccin a C++ Nota. Si se desea ver el contenido de una variable real con cout, es necesario que antes de hacerlo, se establezca el nmero de decimales que se quieren mostrar en pantalla. Hacedlo escribiendo la sentencia cout.precision(20);, en cualquier sitio del programa antes de la ejecucin de cout << real1 << "," << real2;. Realizad lo mismo pero asignando los siguientes valores:
double real, otro_real; real = 2e34; otro_real = real + 1; otro_real = otro_real - real; cout << otro_real;
Qu imprime en pantalla? Justicar la respuesta. Finalidad: Entender el problema de la precisin con los reales. Dicultad Media. 14. Disear un programa que lea un carcter (supondremos que el usuario introduce una mayscula), lo pase a minscula y lo imprima en pantalla. Hacedlo sin usar las funciones toupper ni tolower de la biblioteca cctype. Para ello, debe considerarse la equivalencia en C++ entre los tipos enteros y caracteres. Finalidad: Entender la equivalencia de C++ entre tipos enteros y de carcter. Dicultad Baja. 15. Supongamos el siguiente cdigo:
17
RELACIN DE PROBLEMAS I. Introduccin a C++ La variable entero almacenar el valor 55 (el orden en la tabla ASCII del carcter '7'). Queremos construir una expresin que devuelva el entero 7, para asignarlo a la variable entero. Formalmente: Supongamos una variable car de tipo carcter que contiene un valor entre '0' y '9'. Construid un programa que obtenga el correspondiente valor entero, se lo asigne a una variable de tipo int llamada entero y lo imprima en pantalla. Por ejemplo, si la variable car contiene '7' queremos asignarle a entero el valor numrico 7. Nota. La comilla simple para representar un literal de carcter es la que hay en el teclado del ordenador debajo de la interrogacin ?. Finalidad: Entender la equivalencia de C++ entre tipos enteros y de carcter. Dicultad Baja. 16. Razonar sobre la falsedad o no de las siguientes armaciones: a)
cout << a; da como salida la escritura en pantalla de una a. e) Qu realiza cin >> cte, siendo cte una constante entera?
Finalidad: Distinguir entre expresiones de distinto tipo de dato. Dicultad Baja. 17. Escribid una expresin lgica que sea verdadera si una variable de tipo carcter llamada letra es una letra minscula y falso en otro caso. Escribid una expresin lgica que sea verdadera si una variable de tipo entero llamada edad es menor de 18 o mayor de 65. Escribid una expresin lgica que nos informe cuando un ao es bisiesto. Los aos bisiestos son aquellos que o bien son divisibles por 4 pero no por 100, o bien son divisibles por 400. Nota: Cuando se imprime por pantalla (con cout) una expresin lgica que es true, se imprime 1. Si es false, se imprime un 0. En el tema 2 veremos la razn. Finalidad: Empezar a trabajar con expresiones lgicas, muy usadas en el tema 2. Dicultad Baja. 18. Indique qu tipo de dato usara para representar: Edad de una persona Producto interior bruto de un pas. Consultad:
http://es.wikipedia.org/wiki/Anexo:Pa%C3%ADses_por_PIB_ (nominal)
18
RELACIN DE PROBLEMAS I. Introduccin a C++ Estado civil (casado, soltero, separado, viudo) Sexo de una persona (hombre o mujer exclusivamente) Finalidad: Saber elegir adecuadamente un tipo de dato, atendiendo a la informacin que se quiere representar. Dicultad Media.
Problemas de Ampliacin
19. El precio nal de un automvil para un comprador es la suma total del costo del vehculo, del porcentaje de ganancia de dicho vendedor y del I.V.A. Disear un algoritmo para obtener el precio nal de un automvil sabiendo que el porcentaje de ganancia de este vendedor es del 20 % y el I.V.A. aplicable es del 16 %. Dicultad Baja. 20. Declarar las variables necesarias y traducir las siguientes frmulas a expresiones vlidas del lenguaje C++. a) 1+
x2 y
Algunas funciones de
x3 1+y
cmath
1 7
b)
1+
1 3
sin h 2h
cos h
c)
1+
ex x2
Dicultad Baja. 21. Dos locomotoras parten de puntos distintos avanzando en direccin contraria sobre la misma va. Se pide redactar un programa para conocer las distancias que habrn recorrido ambas locomotoras antes de que choquen teniendo en cuenta que la primera locomotora viaja a una velocidad constante V1 , que la segunda viaja a una velocidad constante V2 , la frmula que relaciona velocidad, espacio y tiempo (s = v t) y que el momento en que se producir el choque viene dado por la frmula t= Dicultad Baja. 22. El rea A de un tringulo se puede calcular a partir del valor de dos de sus lados, a y 1 b, y del ngulo que stos forman entre s con la frmula A = ab sin(). Construid 2 D V1 + V2
19
un programa que pida al usuario el valor de los dos lados (en centmetros), el ngulo que stos forman (en grados), y muestre el valor del rea.
Tened en cuenta que el argumento de la funcin sin va en radianes por lo que habr que transformar los grados del ngulo en radianes. Dicultad Baja. 23. Escribir un programa que lea un valor entero. Supondremos que el usuario introduce siempre un entero de tres dgitos, como por ejemplo 351. Escribid en pantalla los dgitos separados por tres espacios en blanco. Con el valor anterior la salida sera:
Dicultad Media. 24. Los compiladores utilizan siempre el mismo nmero de bits para representar un tipo de dato entero (este nmero puede variar de un compilador a otro). Por ejemplo, 32 bits para un int. Pero, realmente, no se necesitan 32 bits para representar el 6, por ejemplo, ya que bastaran 3 bits: 6 = 1 22 + 1 21 + 0 20 110 Se pide crear un programa que lea un entero n, y calcule el mnimo nmero de dgitos que se necesitan para su representacin. Para simplicar los cmputos, suponed que slo queremos representar valores enteros positivos (incluido el cero). Consejo: se necesitar usar el logaritmo en base 2 y obtener la parte entera de un real (se obtiene tras el truncamiento que se produce al asignar un real a un entero) Dicultad Media.
20
Sesin 1
http://www.ugr.es/informatica/alumnos/correo.htm
De esta forma, obtendremos un login y un password que habr que introducir al arrancar los ordenadores en las aulas de prcticas. La cuenta tarda 48 horas an activarse, por lo que el registro debe realizarse al menos dos das antes de la primera sesin de prcticas. Actividad: Instalacin de Visual Studio. Durante la primera semana de clase, el alumno debera instalar en su casa el compilador Visual Studio. Consultad la seccin de Instalacin (pgina 7) de este guin. Actividad: Resolucin de problemas. Realizad una lectura rpida de las actividades a realizar durante la prxima sesin de prcticas en las aulas de ordenadores. Resolved los ejercicios siguientes de la relacin de problemas I, pgina 13 (utilizando nicamente papel y lpiz): Obligatorios: 1, 2, 3, 4, 5, 6 Opcionales: 7, 8 Actividades de Ampliacin Leer el artculo de Norvig: Aprende a programar en diez aos
http://loro.sourceforge.net/notes/21-dias.html
sobre la dicultad del aprendizaje de una disciplina como la Programacin.
21
H:\CCIA\Grado_FP\
Tambin estn accesibles en la web a travs de la pgina web de la asignatura (acceso identicado) Muy Importante. Los cheros que se encuentran en la unidad H: estn protegidos y no pueden modicarse. Por tanto, habr que copiarlos a la unidad local U:, dnde ya s podrn ser modicados. Nota. En el escritorio de XP, se encuentra un acceso directo a la carpeta H:\CCIA\Grado_FP.
https://decsai.ugr.es
El primer programa
Copiando el cdigo fuente En el directorio H:\ccia\Grado_FP\ProblemasI se encuentra el directorio I_Pitagoras. Copiadlo entero a vuestra carpeta local (dentro de U:\FP).
22
Importante: Siempre hay que copiar localmente las carpetas que aparecen en la unidad H: del departamento ya que estn protegidos contra escritura y no se puede trabajar directamente sobre los proyectos incluidos en dichas carpetas. Desde el Explorador de Windows, entrad en la carpeta recin creada en vuestra cuenta:
U:\FP\I_Pitagoras
y observad los cheros que contiene. Cada vez que creemos un programa desde Visual Studio se crear automticamente una carpeta (en este caso I_Pitagoras) con distintos cheros necesarios para el compilador Visual Studio. Por ejemplo, podemos encontrar los cheros
El chero realmente interesante es el que tiene la extensin cpp. En nuestro caso es I_Pitagoras.cpp. Estos sern los cheros sobre los que escribiremos el cdigo de nuestros programas. Este chero se abrir automticamente en el editor de Visual Studio, despus de que hallamos cargado el correspondiente chero I_Pitagoras.sln Haced doble click sobre el chero I_Pitagoras.sln. Debe aparecer una ventana como la de la gura 1 (el sitio exacto en el que se muestran las distintas ventanas del entorno puede cambiar):
23
24
Algunas consideraciones con respecto a la escritura de cdigo en C++ (ver gura 2) Es bueno que, desde el principio se incluyan comentarios indicando el objetivo del programa y resaltando los aspectos ms importantes de la implementacin. Es muy importante una correcta tabulacin de los programas. Por ahora, incluiremos todas las sentencias del programa principal con una tabulacin. Slo es necesario incluir la primera; el resto las pone automticamente el entorno, al pasar a la siguiente lnea. Para facilitar la lectura del cdigo fuente, se deben usar espacios en blanco para separar las variables en la lnea en la que van declaradas, as como antes y despus del smbolo = en una sentencia de asignacin. Dejad tambin un espacio en blanco antes y despus de << y >> en las sentencias que contienen una llamada a cout y cin respectivamente.
No respetar las normas de escritura de cdigo baja puntos en todos los exmenes y prcticas de la asignatura
25
system("pause");
Veamos para qu sirve. Cuando el programa se ejecuta desde el entorno del Visual Studio, automticamente se abre una ventana de consola para ofrecer resultados y leer datos. Cuando el programa termina de funcionar, automticamente se cierra esta ventana, por lo que si haba algn mensaje escrito en ella, no da tiempo a leerlo. Para resolver este problema, ejecutamos el comando pause de la consola del Sistema Operativo. Este comando hace que se muestre el mensaje en pantalla
Compilacin Una vez cargado el programa, pasamos a comprobar si las sentencias escritas son sintcticamente correctas, es decir, pasamos a compilar el programa. Para ello pulsamos Ctr-F7, . o bien sobre el icono Para que el proceso de compilacin se realice de forma correcta y se obtenga el programa ejecutable, es necesario que el cdigo fuente no contenga errores sintcticos. Si aparecen errores, es necesario volver a la fase de edicin, guardar de nuevo el cdigo fuente y repetir la fase de compilacin. Como resultado de la fase de compilacin, en la esquina inferior izquierda del entorno debe aparecer un mensaje del tipo:
Generacin satisfactoria
Una vez compilado el programa, pasamos a generar el ejecutable, I_Pitagoras.exe. Para ello, o bien pulsamos Alt-Ctr-F7 o bien sobre el icono de la barra de herramientas que contiene el texto Volver a generar solucin. Finalmente, para ejecutar el pro-
grama pulsamos pulsamos F5 o sobre el icono . Si se quiere ejecutar directamente, basta pulsar F5, sin dar los dos primeros pasos de compilacin y generacin. Debe aparecer una ventana de comandos del Sistema, en la que se estar ejecutando el programa. La ejecucin del programa se detendr en aquellos puntos del mismo donde
26
se requiera la interaccin del usuario para poder proseguir, es decir, en la operaciones de entrada de datos a travs del dispositivo estndar de entrada. En este ejemplo, sera en las dos operaciones cin. En el resto de los casos, la ejecucin del programa continuar hasta el nal. La introduccin de datos mediante la sentencia cin se hace siempre de la misma manera; primero se introduce el valor que se desee y al terminar se pulsa la tecla RETURN. Introducid ahora los valores pedidos en el ejemplo de Pitgoras y comprobad la respuesta del programa. Como hemos indicado anteriormente, en la fase de generacin del ejecutable se ha creado un chero en el Sistema que se llama igual que nuestro chero pero sustituyendo la extensin cpp por exe, es decir, I_Pitagoras.exe. Este chero se encuentra en el directorio Debug, dentro de la carpeta I_Pitagoras que habamos copiado localmente. Para mostrar que el chero generado es independiente del entorno de programacin, hacemos lo siguiente: 1. Cerramos Visual
Studio
2. Abrid una ventana de Mi PC. 3. Situarse en la carpeta dnde se guard el cdigo fuente. 4. Haced doble click sobre el chero I_Pitagoras.exe. Nota. En la instalacin por defecto de Visual Studio que hagamos en nuestra casa, los cheros de salida e intermedios necesarios por Visual Studio se almacenan en la misma carpeta del proyecto. Prueba del programa Uno poda pensar que una vez que consigo un chero ejecutable a partir de mi cdigo fuente, el problema est terminado. Sin embargo esto no es as. Tras el proceso de compilado se requiere una fase de prueba. Dicha fase intenta probar que el algoritmo planteado resuelve el problema propuesto. Para llevar a cabo esta fase, es necesario ejecutar el programa y vericar que los resultados que obtiene son los esperados. Ahora que podemos ver el resultado obtenido por el programa implementado, veriquemos mediante el siguiente conjunto de pruebas que el programa funciona de forma correcta. lado1 lado2 3 4 1 5 2.7 4.3 1.25 2.75 hip 5 5.099 5.077 3.02
Una vez que el algoritmo supera la fase de prueba, podemos considerar que se ha concluido con la fase inicial del desarrollo del software.
27
28
Para familiarizarnos con los errores ms frecuentes y su correccin vamos a realizar el siguiente proceso: a partir del cdigo fuente del ejemplo I_Pitagoras.cpp, iremos introduciendo deliberadamente errores para conocer los mensajes que nos aparecen. A continuacin se muestran algunos errores posibles. No deben introducirse todos ellos a la vez, sino que han de probarse por separado. 1. Cambiad algn punto y coma por cualquier otro smbolo 2. Cambiad double por dpuble 3. Cambiad la lnea using
4. Poned en lugar de iostream, el nombre iotream. 5. Borrad alguno de los parntesis de la declaracin de la funcin main 6. Introducid algn identicador incorrecto, como por ejemplo cour 7. Usad una variable no declarada. Por ejemplo, en la denicin de variables cambiad el nombre a la variable lado1 por el identicador lado11. 8. Borrad alguna de las dobles comillas en una constante de cadena de caracteres, tanto las comillas iniciales como las nales. 9. Borrad alguna de las llaves que delimitan el inicio y nal del programa. 10. Borrad la lnea using
namespace std; (basta con comentarla con //) //, cambiando las barras anteriores por las si-
11. Cambiad un comentario iniciado con guientes \\ 12. Cambiad la aparicin de lo mismo con cin.
13. Suprimid todo el main. No hace falta borrar el cdigo, basta con comentarlo. 14. Aunque no sea un error, comentad la ltima linea que contiene system("pause"); para comprobar que el programa se ejecuta correctamente, pero no da tiempo a ver los resultados en la consola. Adems de los errores, el compilador puede generar avisos. Estos se muestran en la pestaa Advertencias en la misma ventana de la lista de errores. Estas advertencias indican que algn cdigo puede generar problemas durante la ejecucin. Por ejemplo, al usar una variable que todava no tiene un valor asignado, al intentar asignar un entero grande a un entero chico, etc. Sin embargo, no son errores de compilacin, por lo que es posible generar el programa ejecutable correspondiente.
29
Los errores lgicos y en tiempo de ejecucin Aunque el programa compile, esto no signica que sea correcto. Puede producirse una excepcin durante la ejecucin, de forma que el programa terminar bruscamente (tpico error en Windows de Exception Violation Address) o, lo que es peor, dar una salida que no es correcta (error lgico). Sobre el programa I_Pitagoras.cpp, haced lo siguiente: Cambiad la sentencia
Ejecutad introduciendo los lados 2 y 3. El resultado no es correcto, pero no se produce ningn error de compilacin ni en ejecucin. Es un error lgico. Para mostrar un error de ejecucin, declarad tres variables ENTERAS (tipo int) resultado, numerador y denominador. Asignadle cero a denominador y 7 a numerador. Asignadle a resultado la divisin de numerador entre denominador. Imprimid el resultado. Al ejecutar el programa, se produce una excepcin o error de ejecucin al intentar dividir un entero entre cero.
Archivo->Nuevo Proyecto
30
31
Figura 5: Entorno de Visual Studio Ya estamos en condiciones de resolver el problema pedido. Escribimos el cdigo en la ventana correspondiente a la pestaa I_Voltaje.cpp. Habr que leer desde teclado los valores de intensidad y resistencia y el programa imprimir en pantalla el voltaje correspondiente. Recordad que compilamos con Ctr-F7 y ejecutamos con F5. Nota. Cuando tenemos varias variables en el cdigo, podemos empezar a escribir el nombre de alguna de ellas y antes de terminar, pulsar Ctr-Barra espaciadora. La ayuda nos mostrar los identicadores disponibles que empiecen por las letras tecleadas. A partir de ahora, cada uno de los ejercicios ir en un proyecto nuevo. Implementad los ejercicios que se haban mandado para esta sesin en este orden: 2, 3, 4, 5, 6. Usad en esta sesin el tipo de proyecto "Proyecto Vaco".
32
Sesin 2
33
Actividades de Ampliacin Recordad los conceptos de combinacin y permutacin, que irn apareciendo recurrentemente a lo largo de la carrera. Consultad, por ejemplo
http://www.disfrutalasmatematicas.com/combinatoria/ combinaciones-permutaciones.html
para una introduccin bsica a los conceptos, y
http://club.telepolis.com/ildearanda/index.html
como una referencia a las frmulas que nos proporcionan los cmputos correspondientes. Ejecutad el applet
http://www.disfrutalasmatematicas.com/combinatoria/ combinaciones-permutaciones-calculadora.html
con los valores pertinentes para calcular cuntos nmero distintos se pueden representar utilizando nicamente dos smbolos (0 y 1) en 64 posiciones de memoria. Ejecutad el mismo applet para que muestre en la parte inferior las distintas permutaciones que se pueden conseguir con 2 smbolos (0,1) y 4 posiciones.
34
//
35
Conguracin del proyecto y gestin de errores est usando la variable intensidad sin haberle asignado previamente un valor. An as, podemos generar el chero .exe y ejecutarlo. Hacedlo, para comprobar el error que se obtiene en tiempo de ejecucin. 2. En una segunda fase, cuando ya hemos comprobado que el programa funciona correctamente, se procede a generar el chero ejecutable (.exe) eliminando la informacin de depuracin (entre otras cosas). Esto har que el ejecutable obtenido sea bastante ms pequeo. Para ello, hay que cambiar la conguracin antes de generar el ejecutable. Volvemos a entrar en
Configuracin de soluciones activas y seleccionamos Release. Podemos hacerlo directamente desde el botn disponible
en la esquina superior derecha de la barra de herramientas. Si generamos el programa bajo esta ltima conguracin, veremos que al ejecutarlo no se produce un error durante la ejecucin. Esto es debido, como ya hemos comentado, a que el compilador ya no pierde el tiempo comprobando estos posibles errores de programacin. Por contra, obtendremos un error lgico ya que la variable intensidad contiene basura y al multiplicarla por la variable resistencia el resultado ser basura. A lo largo de la asignatura, usaremos siempre la conguracin Debug, por lo que algunos errores de programacin, como el uso de variables no asignadas previamente, sern detectados por el compilador. Pero debemos tener claro que en en la conguracin Release, o bien en la compilacin realizada con otros compiladores distintos a Visual Studio, no se producir ningn error durante la ejecucin sino un lamentable error lgico. En el entorno Visual Studio de las aulas de prcticas, se ha incluido una plantilla con las opciones de conguracin de compilacin ms usuales (tanto para la conguracin Debug como Release) as como un esqueleto del programa principal que incluye la cabecera que usaremos siempre en nuestros programas. Para crear un programa nuevo basndonos en esta plantilla, basta hacer lo siguiente:
36
Ejercicio. Cread un proyecto nuevo llamado Prueba_Tipos. Declarad variables de tipo int, double, float, double, char y bool. Provocad errores de compilacin y lgicos al mezclar distintos tipos de datos en una misma expresin. Por ejemplo: Asignad a un dato un literal fuera de rango, Forzad un error en ejecucin al dividir un entero por cero, Provocar errores lgicos de desbordamiento con un nico tipo de dato, Provocar errores lgicos de desbordamiento mezclando distintos tipos de dato en una misma expresin, Ejercicio. Copiad a la unidad local la carpeta I_Pitagoras. Cargad el proyecto y cambiad la suma dentro de sqrt por una resta. Ejecutad introduciendo los lados 2 y 3. Como el resultado es la raz cuadrada de un nmero negativo, el ordenador no puede hacer los clculos y muestra -1.#IND. Tal y como se vio en clase de teora, este es el valor de Indeterminacin, representable en los datos de coma otante (double1 es un tipo de dato en coma otante). En este caso se ha producido un error lgico, pero en otro lenguaje de programacin que no utilizase una representacin de reales en coma otante, podra haberse producido un error fatal durante la ejecucin, terminndose de forma brusca el programa. Si sobra tiempo, realizad cualquiera de los ejercicios de ampliacin de la Relacin de Problemas I de la pgina 19
37
38
RELACIN DE PROBLEMAS II. Estructuras de Control Utilizar un variable de tipo string de la forma siguiente:
I)
Nota. Para poder usar el operador de comparacin == entre dos string, hay que incluir la biblioteca string. Si se opta por esta alternativa, el suspenso est garantizado. Por qu? II ) Utilizar dos variables lgicas de la forma siguiente:
string quien_divide; ............. if (a%b==0) quien_divide = "b divide a a" ; ............. if (quien_divide == "b divide a a") cout << b << " divide a " << a;
bool a_divide_b, b_divide_a; ............. if (a%b==0) a_divide_b = true; ............. if (a_divide_b) cout << a << "divide a " << b;
III )
Detectamos si se dividen o no y usamos otras dos variables que me indiquen quien es el dividendo y quien el divisor:
bool se_dividen; int Divdo, Divsor; ............. if (a%b==0){ Divdo = a; ............. if (se_dividen) cout << Dvsor << " divide a " << Dvdo;
Completar la solucin elegida para contemplar tambin el caso en el que alguno de los valores introducidos sea cero, en cuyo caso, ninguno divide al otro. Finalidad: Mostrar cmo se comunican los distintos bloques de un programa a travs de variables que indican lo que ha sucedido en el bloque anterior. Dicultad Media. 5. Se quiere leer un carcter letra_original desde teclado, y comprobar con una estructura condicional si es una letra mayscula. En dicho caso, hay que calcular la minscula correspondiente en una variable llamada letra_convertida. En cualquier otro caso, le asignaremos a letra_convertida el valor que tenga letra_original. Finalmente, imprimiremos en pantalla el valor de letra_convertida. No pueden usarse las funciones tolower ni toupper de la biblioteca cctype.
39
char letra_convertida, letra_original; const int DISTANCIA_MAY_MIN = 'a'-'A'; cout << "\nIntroduzca una letra --> "; cin >> letra_original; if ((letra_original >= 'A') && (letra_original <= 'Z')){ letra_convertida = letra_original + DISTANCIA_MAY_MIN; cout << letra_convertida; } else{ cout << letra_original << " no es una mayscula"; }
El problema es que dentro de la misma sentencia condicional se realizan cmputos (letra_convertida = letra_original + DISTANCIA_MAY_MIN ) y salidas de resultados en pantalla (cout << letra_convertida;). Para evitarlo, se propone el uso de una variable lgica llamada es_mayuscula, de la siguiente forma:
if ((letra_original >= 'A') && (letra_original <= 'Z')) es_mayuscula = true; if (es_mayuscula) letra_convertida = letra_original + DISTANCIA_MAY_MIN; else letra_convertida = letra_original; cout << "\nEl carcter " << letra_original << " una vez convertido es: " << letra_convertida;
Sin embargo, hay un error lgico ya que la variable es_mayuscula se podra quedar sin un valor asignado (en el caso de que la expresin lgica fuese false) El compilador lo detecta y da el aviso al inicio de la sentencia if (es_mayuscula). Comprobadlo para familiarizarnos con este tipo de avisos y proponer una solucin. Moraleja: Hay que garantizar la asignacin de las variables lgicas, en todos los casos posibles Finalidad: Plantear una condicin compuesta y destacar la importancia de incluir un bloque else, para garantizar que siempre se ejecuta el cdigo adecuado, en todas las situaciones posibles. Dicultad Baja. 6. Queremos modicar el ejercicio 5 para leer un carcter letra_original desde teclado y hacer lo siguiente:
40
RELACIN DE PROBLEMAS II. Estructuras de Control Si es una letra mayscula, almacenaremos en la variable la correspondiente letra minscula. Si es una letra minscula, almacenaremos en la variable la correspondiente letra mayscula.
letra_convertida letra_convertida
letra_convertida
Para ello, aadimos una variable nueva es_minuscula para detectar el caso en el que la letra sea una minscula. Si escribimos el siguiente cdigo
if (letra_original >= 'A') && (letra_original <= 'Z') es_mayuscula = true; else es_minuscula = true;
estaremos cometiendo el tipo de error indicado en el ejercicio 5, ya que si le asignamos un valor a una de las variables lgicas, no se lo asignamos a la otra y se queda con basura. Para resolverlo, planteamos la siguiente solucin:
if ((letra_original >= 'A') && (letra_original <= 'Z')){ es_mayuscula = true; es_minuscula = false; } else{ es_mayuscula = false; es_minuscula = true; }
o si se preere, de una forma ms concisa:
es_mayuscula = (letra_original >= 'A') && (letra_original <= 'Z'); es_minuscula = !es_mayuscula;
En este planteamiento hay un error lgico que se comete de forma bastante habitual, cuando se quiere detectar ms de dos situaciones posibles. En la asignacin
es_minuscula = !es_mayuscula;
estamos diciendo que una minscula es todo aquello que no sea una mayscula. Esto no es correcto, ya que un smbolo como # no es ni mayscula ni minscula. Deberamos haber usado lo siguiente:
Completad
ejercicio, asignndole el valor correcto a la variable letra_convertida e imprimid en pantalla el valor de letra_convertida. Finalidad: Plantear una estructura condicional anidada. Dicultad Baja. 7. Para salir de una crisis econmica, el gobierno decide: Bajar un 1 % la retencin scal a los autnomos Para las rentas de trabajo: Se mantiene la misma retencin scal a todos los pensionistas Subir un 6 % la retencin scal a las rentas de trabajo inferiores a 20.000 euros Subir un 8 % la retencin scal a los casados con rentas de trabajo superiores a 20.000 euros Subir un 10 % la retencin scal a los solteros con rentas de trabajo superiores a 20.000 euros Cread un programa que calcule la nueva retencin a aplicar, la aplique a los ingresos e imprima el resultado . En este ejercicio no haremos ninguna lectura con cin, sino que declararemos las variables necesarias (por ejemplo retencion_fiscal, es_autonomo, etc) y les asignaremos los valores que se deseen directamente dentro del cdigo. Nota: Cuando se pide subir un x % la retencin scal, signica que la nueva retencin ser la antigua ms el resultado de realizar el x % sobre la antigua retencin. Finalidad: Plantear una estructura condicional anidada. Dicultad Baja. 8. Una compaa area establece el precio del billete como sigue: en primer lugar se ja una tarifa base de 150 euros, la misma para todos los destinos. Si el destino est a menos de 200 kilmetros, el precio nal es la tarifa inicial. Para destinos a ms de 200 Km, se suman 10 cntimos por cada kilmetro de distancia al destino (a partir del Km 200). En una campaa de promocin, se barajan las siguientes alternativas de polticas de descuento: a) Una rebaja del 3 % en el precio nal, para destinos a ms de 600Km b) Una rebaja del 4 % en el precio nal, para destinos a ms de 1100Km c) Una rebaja del 5 % si el comprador es cliente previo de la empresa. Cread un programa para que lea el nmero de kilmetros al destino y si el billete corresponde a un cliente previo de la empresa. Calcular el precio nal del billete con las siguientes polticas de descuento: Aplicando c) de forma adicional a los descuentos a) y b)
el
42
RELACIN DE PROBLEMAS II. Estructuras de Control Aplicando c) de forma exclusiva con los anteriores, es decir, que si se aplica c), no se aplicara ni a) ni b) Finalidad: Plantear una estructura condicional anidada. Dicultad Media. 9. En el ejercicio 6 se han usado dos variables lgicas (es_mayuscula, es_minuscula), que nos proporciona la distincin entre 4 casos distintos (VV, VF, FV, FF). Sin embargo, slo queremos distinguir tres posibilidades, a saber, es mayscula, es minscula y no es un carcter alfabtico. Para ello, volved a resolver el ejercicio 6 sustituyendo las dos variables lgicas por un tipo enumerado adecuado. Finalidad: Usar el tipo enumerado para detectar cundo se produce una situacin determinada. Dicultad Media. 10. Realizar un programa que lea desde teclado un entero tope e imprima en pantalla todos sus divisores. Para obtener los divisores, basta recorrer todos los enteros menores que el valor introducido y comprobar si lo dividen. A continuacin, mejorar el ejercicio obligando al usuario a introducir un entero positivo, usando un ltro con un bucle post test (do while). Finalidad: Plantear un ejemplo sencillo de bucle y de ltro de entrada de datos. Dicultad Baja. 11. Realizar un programa que lea reales desde teclado y calcule cuntos se han introducido y cual es el mnimo de dichos valores (pueden ser positivos o negativos). Se dejar de leer datos cuando el usuario introduzca el valor 0. Realizad la lectura de los reales dentro de un bucle sobre una nica variable llamada dato. Es importante controlar los casos extremos, como por ejemplo, que el primer valor ledo fuese ya el terminador de entrada (en este caso, el cero). Finalidad: Destacar la importancia de las inicializaciones antes de entrar al bucle. Ejemplo de lectura anticipada. Dicultad Baja. 12. Modiquemos el ejercicio 2 del capital y los intereses de la primera relacin. Supongamos ahora que se quiere reinvertir todo el dinero obtenido (el original C ms los intereses producidos) en otro plazo jo a un ao. Y as, sucesivamente. Construid un programa para que lea el capital, el inters y un nmero de aos N , y calcule e imprima todo el dinero obtenido durante cada uno de los N aos, suponiendo que todo lo ganado (incluido el capital original C) se reinvierte a plazo jo durante el siguiente ao. El programa debe mostrar una salida del tipo:
Total en el ao nmero 1 = 240 Total en el ao nmero 2 = 288 Total en el ao nmero 3 = 345.6 ......................
43
Finalidad: Usar una variable acumuladora dentro del cuerpo de un bucle (aparecer a la izquierda y a la derecha de una asignacin). Dicultad Baja. 13. Sobre el mismo ejercicio del capital y los intereses, construid un programa para calcular cuantos aos han de pasar hasta llegar a doblar, como mnimo, el capital inicial. Los datos que han de leerse desde teclado son el capital inicial y el inters anual. Finalidad: Usar la variable acumuladora en la misma condicin del bucle. Dicultad Baja. 14. Se pide leer un carcter desde teclado, obligando al usuario a que sea una letra mayscula. Para ello, habr que usar una estructura repetitiva do while, de forma que si el usuario introduce un carcter que no sea una letra mayscula, se le volver a pedir otro carcter. Calculad la minscula correspondiente e imprimidla en pantalla. No pueden usarse las funciones tolower ni toupperde la biblioteca cctype. Si se quiere, se puede usar como base el proyecto que resolvi el ejercicio 14 de la relacin de problemas I. Finalidad: Trabajar con bucles con condiciones compuestas. Dicultad Baja. 15. Un nmero entero de n dgitos se dice que es narcisista si se puede obtener como la suma de las potencias n-simas de cada uno de sus dgitos. Por ejemplo 153 y 8208 son nmeros narcisistas porque 153 = 13 + 53 + 33 y 8208 = 84 + 24 + 04 + 84 . Construir un programa que, dado un nmero entero positivo, nos indique si el nmero es o no narcisista. Si se va a usar la funcin pow, no pueden ser ambos argumentos enteros, por lo que forzaremos a que la base (por ejemplo) sea double, multiplicando por 1.0. Finalidad: Ejercitar los bucles. Dicultad Media. 16. Calcular mediante un programa en C++ la funcin potencia xn , y la funcin factorial n! con n un valor entero y x un valor real. No pueden usarse las funciones de la biblioteca cmath. El factorial de un entero n se dene de la forma siguiente: 0! = 1 n! = 1 2 3 n, n 1 Finalidad: Trabajar con bucles controlados por contador. Dicultad Baja. 17. Calcular mediante un programa en C++ el combinatorio n m con n, m valores
enteros. No pueden usarse las funciones de la biblioteca cmath. El combinatorio de n sobre m (con n m) es un nmero entero que se dene como sigue: n! n = m m! (n m)!
44
Finalidad: Trabajar con bucles controlados por contador. Dicultad Media. 18. Todo lo que se puede hacer con un bucle while se puede hacer con un do while. Lo mismo ocurre al revs. Sin embargo, cada bucle se usa de forma natural en ciertas situaciones. El no hacerlo, nos obligar a escribir ms cdigo y ste ser ms difcil de entender. Para comprobarlo, haced lo siguiente: a) Modicad la solucin del ejercicio 10 de forma que el ltro de entrada usado para leer la variable tope, se haga con un bucle pre-test while. b) Modicad la solucin del ejercicio 12 sustituyendo el bucle while por un do while. Observad que debemos considerar el caso en el que el nmero de aos ledo fuese cero. Finalidad: Enfatizar la necesidad de saber elegir entre un bucle pre-test o un bucle post-test. Dicultad Media. 19. Una empresa que tiene tres sucursales decide llevar la contabilidad de las ventas de sus productos a lo largo de una semana. Para ello registra cada venta con tres nmeros, el identicador de la sucursal (1,2 3), el cdigo del producto (1, 2 3) y el nmero de unidades vendidas. Disear un programa que lea desde el teclado una serie de registros compuestos por sucursal, producto, unidades y diga cul es la sucursal que ms productos ha vendido. La serie de datos termina cuando la sucursal introducida vale -1. Por ejemplo, con la serie de datos
1 2 1 2 1 1 1 1 1 3 2 2 2 2 2 1 3 3 -1
10 4 1 1 2 15 6 20 40
Se puede ver que la sucursal que ms productos ha vendido es la nmero 2 con 41 unidades totales. La salida del programa deber seguir exactamente el siguiente formato:
SUCURSAL: 2 VENTAS: 41
Para comprobar que el programa funciona correctamente, cread un chero de texto y re-dirigid la entrada a dicho chero.
45
Finalidad: Ver un bucle en el que se leen varios datos en cada iteracin, pero slo uno de ellos se usa como terminador de la entrada. Dicultad Media. 20. Supongamos una serie numrica cuyo trmino general es: ai = a1 r i1 Cread un programa que lea desde teclado r, el primer elemento a1 y el tope k y calcule la suma de los primeros k valores de la serie, es decir:
i=k
ai
i=1
Realizad la suma de la serie usando la funcin pow para el cmputo de cada trmino ai . Los argumentos de pow no pueden ser ambos enteros, por lo que forzaremos a que la base (por ejemplo) sea double, multiplicando por 1.0. Finalidad: Trabajar con bucles que van acumulando resultados en cada iteracin. Dicultad Baja. 21. La serie del ejercicio 20 es una progresin geomtrica ya que cada trmino de la serie queda denido por la siguiente expresin: ai+1 = ai r Es decir, una progresin geomtrica es una secuencia de elementos en la que cada uno de ellos se obtiene multiplicando el anterior por una constante denominada razn o factor de la progresin. Cread un programa que lea desde teclado la razn r, el primer elemento a1 y el tope k y calcule la suma de los primeros k valores de la progresin geomtrica. En la solucin de este ejercicio NO puede utilizarse la funcin pow. Qu solucin es preferible en trminos de eciencia? sta o la del ejercicio 20? Finalidad: Trabajar con bucles que aprovechan cmputos realizados en la iteracin anterior. Dicultad Baja. 22. Reescribid la solucin a los ejercicios 10, 12 usando un bucle for Finalidad: Familiarizarnos con la sintaxis de los bucles for. Dicultad Baja. 23. Disear un programa para calcular la suma de los 100 primeros trminos de la sucesin siguiente: (1)i (i2 1) ai = 2i No puede usarse la funcin pow. Hacedlo calculando explcitamente, en cada iteracin, el valor (1)i (usad un bucle for). Posteriormente, resolvedlo calculando dicho valor a partir del calculado en la iteracin anterior, es decir, (1)i1 .
46
Finalidad: Enfatizar la conveniencia de aprovechar cmputos realizados en la iteracin anterior. Dicultad Media. 24. El mtodo RLE (Run Length Encoding) codica una secuencia de datos formada por series de valores idnticos consecutivos como una secuencia de parejas de nmeros (valor de la secuencia y nmero de veces que se repite). Esta codicacin es un mecanismo de compresin de datos (zip) sin prdidas. Se aplica, por ejemplo, para comprimir los cheros de imgenes en las que hay zonas con los mismos datos (fondo blanco, por ejemplo). Realizar un programa que lea una secuencia de nmeros naturales terminada con un nmero negativo y la codique mediante el mtodo RLE. Leed los datos desde un chero externo, tal y como se explica en la pgina 60. Entrada: 1 1 1 2 2 2 2 2 3 3 3 3 3 3 5 -1 (tres veces 1, cinco veces 2, seis veces 3, una vez 5) Salida: 31526315 Finalidad: Controlar en una iteracin lo que ha pasado en la anterior. Dicultad Media. 25. Sobre la solucin del ejercicio 12 de esta relacin de problemas, se pide lo siguiente. Supondremos que slo pueden introducirse intereses enteros (1, 2, 3, etc). Se pide calcular el capital obtenido al trmino de cada ao, pero realizando los clculos para todos los tipos de inters enteros menores o iguales que el introducido (en pasos de 1). Por ejemplo, si el usuario introduce un inters de 5, y un nmero de aos igual a 3, hay que mostrar el capital ganado al trmino de cada uno de los tres aos a un inters del 1 %; a continuacin, lo mismo para un inters del 2 %, y as sucesivamente hasta llegar al 5 %. El programa debe mostrar una salida del tipo:
Clculos realizados al 1%: Dinero obtenido en el ao nmero 1 = 2020 Dinero obtenido en el ao nmero 2 = 2040.2 Dinero obtenido en el ao nmero 3 = 2060.6 Clculos realizados al 2%: Dinero obtenido en el ao nmero 1 = 2040 Dinero obtenido en el ao nmero 2 = 2080.8 Dinero obtenido en el ao nmero 3 = 2122.42 .......
Finalidad: Empezar a trabajar con bucles anidados. Dicultad Baja. 26. Cread un programa que ofrezca en pantalla la siguiente salida:
47
1 2 3 4 5 6
2 3 4 5 6
3 4 5 6 4 5 6 5 6 6
Finalidad: Ejercitar los bucles anidados. Dicultad Baja. 27. Cread un programa que ofrezca en pantalla la siguiente salida:
1 2 3 4 5 6
2 3 4 5 6 7
3 4 5 6 7 8
4 5 6 7 8 9
5 6 6 7 7 8 8 9 9 10 10 11
Finalidad: Ejercitar los bucles anidados. Dicultad Media. 28. Modicad los dos ejercicios anteriores para que los valores inicial (1) y nal (6) puedan ser cualesquiera introducidos desde el teclado. Finalidad: Ejercitar los bucles anidados. Dicultad Media. 29. Se dice que un nmero natural es feliz si cumple que si sumamos los cuadrados de sus dgitos y seguimos el proceso con los resultados obtenidos, nalmente obtenemos uno (1) como resultado. Por ejemplo, el nmero 203 es un nmero feliz ya que 22 + 02 + 32 = 13 12 + 32 = 10 12 + 02 = 1. Se dice que un nmero es feliz de grado k si se ha podido demostrar que es feliz en un mximo de k iteraciones. Se entiende que una iteracin se produce cada vez que se elevan al cuadrado los dgitos del valor actual y se suman. En el ejemplo anterior, 203 es un nmero feliz de grado 3 (adems, es feliz de cualquier grado mayor o igual que 3) Escribir un programa que diga si un nmero natural n es feliz para un grado k dado de antemano. Tanto n como k son valores introducidos por el usuario. Finalidad: Ejercitar los bucles anidados. Dicultad Media. 30. Escribir un programa que encuentre dos enteros n y m mayores que 1 que veriquen lo siguiente:
m
i2 = n2
i=1
48
Problemas de Ampliacin
31. Cread un programa que acepte el nmero de un ao e indique si es bisiesto o no. Un ao es bisiesto si es mltiplo de cuatro, pero no de cien. Excepcin a la regla anterior son los mltiplos de cuatrocientos que siempre son bisiestos. Son bisiestos: 1600,1996, 2000, 2004. No son bisiestos: 1700, 1800, 1900, 1998, 2002. Dicultad Baja. 32. Realizar un programa para calcular los valores de la funcin: f (x) = 3x + x2 1 x2
para valores de x enteros en el rango [-3..3]. Dicultad Baja. 33. Realizar un programa para calcular los valores de la funcin: x f (x, y) = 2 y 1 para los valores de (x, y) con x = 50, 48, . . . , 48, 50 y = 40, 39, . . . , 39, 40, es decir queremos mostrar en pantalla los valores de la funcin en los puntos (50, 40), (50, 39), (50, 40), (48, 40), (48, 39), (50, 40) Dicultad Baja. 34. Disear un programa que presente una tabla de grados C a grados Fahrenheit ( F=9/5C+32) desde los 0 grados a los 300, con incremento de 20 en 20 grados. Dicultad Baja. 35. Disear un programa que lea caracteres desde la entrada y los muestre en pantalla, hasta que se pulsa el '.' y diga cuantos separadores se han ledo (espacios en blanco ' ', tabuladores '\t' y caracteres de nueva lnea '\n'). Dicultad Baja. 36. Realizar un programa para calcular la suma de los trminos de la serie 1 1/2 + 1/4 1/6 + 1/8 1/10 + ... 1/(2n 1) + 1/(2n) para un valor n dado. Dicultad Baja.
49
37. Se decide informatizar el acta de un partido de baloncesto para saber qu equipo es el ganador del partido. El acta contiene una serie de anotaciones formadas por una pareja de nmeros cada una, con el dorsal del jugador y el nmero de puntos conseguidos teniendo en cuenta que la ltima anotacin es un valor -1. Por ejemplo 1 2 4 1 4 1 2 3 6 2 3 2 5 2 5 1 1 3 -1 El programa deber indicar si ha ganado el equipo 1 (con los dorsales 1, 2 y 3) o el equipo 2 (dorsales 4, 5 y 6) o han empatado. Por ejemplo, con la entrada anterior, gana el equipo 1. Dicultad Baja. 38. La Unin Europea ha decidido premiar al pas que ms toneladas de hortalizas exporte a lo largo del ao. Se dispone de un registro de transacciones comerciales en el que aparecen tres valores en cada apunte. El primer valor es el indicativo del pas (E: Espaa, F: Francia y A: Alemania), el segundo valor es un indicativo de la hortaliza que se ha vendido en una transaccin (T: Tomate, P: Patata, E: Espinaca) y el tercer valor indica las toneladas que se han vendido en esa transaccin. Disear un programa que lea desde el teclado este registro, el cual termina siempre al leer un pas con indicativo @, y que diga qu pas es el que ms hortalizas exporta y las toneladas que exporta. Por ejemplo, con la entrada E T 10 E T 4 E P 1 E P 1 E E 2 F T 15 F T 6 F P 20 A E 40 @ el pas que ms vende es Francia con un total de 41 toneladas. Dicultad Baja. 39. Disear un programa para jugar a adivinar un nmero. El juego tiene que dar pistas de si el nmero introducido por el jugador est por encima o por debajo del nmero introducido. Como reglas de parada considerad a) que haya acertado o b) se haya hartado y decida terminar (escoged cmo se quiere que se especique esta opcin) Realizar el mismo ejercicio pero permitiendo jugar tantas veces como lo desee el jugador. Dicultad Media. 40. Se dice que un nmero es triangular si se puede poner como la suma de los primeros m valores enteros, para algn valor de m. Por ejemplo, 6 es triangular ya que 6 = 1 + 2 + 3. Una forma de obtener los nmeros triangulares es a travs de la frmula n(n + 1) n N. Se pide construir un programa que obtenga todos los nmeros 2 triangulares que hay menores que un entero k introducido desde teclado, sin aplicar la frmula anterior. Dicultad Baja.
50
41. Escribir un programa que lea una secuencia de nmeros enteros en el rango de 0 a 100 terminada en un nmero mayor que 100 o menor que 0 y encuentre la subsecuencia de nmeros ordenada, de menor a mayor, de mayor longitud. El programa nos debe decir la posicin donde comienza la subsecuencia y su longitud. Por ejemplo, ante la entrada siguiente:
23
25 7
40 45
45 73
73
71 4
9 101
el programa nos debe indicar que la mayor subsecuencia empieza en la posicin 3 (en el 7) y tiene longitud 6 (termina en la segunda aparicin del 73) Dicultad Media. 42. El algoritmo de la multiplicacin rusa es una forma distinta de calcular la multiplicacin de dos nmeros enteros n m. Para ello este algoritmo va multiplicando por 2 el multiplicador m y dividiendo (sin decimales) por dos el multiplicando n hasta que n tome el valor 1 y suma todos aquellos multiplicadores cuyos multiplicandos sean impares. Por ejemplo, para multiplicar 37 y 12 se haran las siguientes iteraciones Iteracin Multiplicando 1 37 2 18 3 9 4 4 5 2 6 1 Multiplicador 12 24 48 96 192 384
Con lo que el resultado de multiplicar 37 y 12 sera la suma de los multiplicadores correspondientes a los multiplicandos impares (en negrita), es decir 37*12=12+48+384=444 Cread un programa para leer dos enteros n y m y calcule su producto utilizando este algoritmo. Dicultad Media. 43. Construid un programa para comprobar si las letras de una palabra se encuentran dentro de otro conjunto de palabras. Los datos se leen desde un chero de la forma siguiente: el chero contiene, en primer lugar un total de 3 letras que forman la palabra a buscar, por ejemplo f e o. Siempre habr, exactamente, tres letras. A continuacin, el chero contiene el conjunto de palabras en el que vamos a buscar. El nal de cada palabra viene determinado por la aparicin del carcter '@', y el nal del chero por el carcter '#'. La bsqueda tendr las siguientes restricciones: Deben encontrarse las tres letras Debe respetarse el orden de aparicin. Es decir, si por ejemplo encontramos la 'f' en la segunda palabra, la siguiente letra a buscar 'e' debe estar en una palabra posterior a la segunda.
51
RELACIN DE PROBLEMAS II. Estructuras de Control Una vez encontremos una letra en una palabra, ya no buscaremos ms letras en dicha palabra. No nos planteamos una bsqueda barajando todas las posibilidades, en el sentido de que una vez encontrada una letra, no volveremos a buscarla de nuevo.
f h m c c Entrada: p c h #
e o o o e e o o
o l f f r r s y
a e i r a a @
@ t a @ a @ o @ @ @
En este caso, s se encuentra. Dicultad Media. 44. Un nmero perfecto es aquel que es igual a la suma de todos sus divisores positivos excepto l mismo. El primer nmero perfecto es el 6 ya que sus divisores son 1, 2 y 3 y 6=1+2+3. Escribir un programa que muestre el mayor nmero perfecto que sea menor a un nmero dado por el usuario. Dicultad Media. 45. El nmero areo se conoce desde la Antigedad griega y aparece en muchos temas de la geometra clsica. La forma ms sencilla de denirlo es como el nico nmero positivo que cumple que 2 = 1 y por consiguiente su valor es 1+ 5 . Se pueden construir aproximaciones al nmero areo mediante la fr= 2 f ib(n + 1) mula an = siendo f ib(n) el trmino n-simo de la sucecin de bonacci f ib(n) que se dene como: f ib(0) = 0, f ib(1) = 1 y f ib(n) = f ib(n 2) + f ib(n 1) para n 2 Escribir un programa que calcule el menor valor de n que hace que la aproximacin dada por an diera en menos de del nmero , sabiendo que n 1. La entrada del programa ser el valor de y la salida el valor de n. Por ejemplo, para un valor de = 0,1 el valor de salida es n = 3 Dicultad Media.
52
Estructura condicional
Sesin 3
Actividades a realizar en casa
Estructura condicional
Actividad: Resolucin de problemas. Resolved los siguientes problemas de la relacin II (pgina 38). Por cada uno de ellos, habr que crear el correspondiente proyecto. Usad el tipo de proyecto _fp_2010 Obligatorios: 2 (Subir ingresos a jubilados) 3 (Ver si dos nmeros se dividen) 4 (Quin divide a quin) 5 (Pasar de mayscula a minscula) 6 (Pasar de mayscula a minscula y viceversa) 7 (Medidas contra la crisis) Opcionales: 8 (Tarifa area)
http://catless.ncl.ac.uk/Risks
que publica peridicamente casos reales en los que un mal desarrollo del software ha tenido implicaciones importantes en la sociedad.
53
Estructura condicional
Herramientas -> Opciones -> Editor de texto -> C/C++ -> Tabulaciones -> Automtico
El chero de conguracin dicha opcin seleccionada.
De forma semi-automtica, podemos seleccionar un bloque de texto con el ratn y pulsar Ctr-K,Ctr-F. De forma manual, podemos seleccionar un bloque de texto con el ratn y pulsar sopara disminuir o aumentar la sangra. Las teclas de bre alguno de los iconos acceso directo para estas operaciones son Shift-Tabulador y Tabulador respectivamente. Visual Studio ofrece tambin un recurso bastante til para la escritura de cdigo. Cuando nuestros programas contienen muchas lneas de cdigo, nos gustara ocultar las partes que se han comprobado que funcionan correctamente. Para ello, basta seleccionar con el ratn un bloque de texto y seleccionar con la derecha
54
Depuracin
Forzad los siguientes errores en tiempo de compilacin, para habituarnos a los mensajes de error ofrecidos por el compilador: Suprimid los parntesis de alguna de las expresiones lgicas de la sentencia if Quitad la llave abierta de la sentencia condicional (como nicamente hay una sentencia dentro del if no es necesario poner las llaves, pero aadimos las llaves a cualquier condicional para comprobar el error que se produce al eliminar una de ellas) Quitad la llave cerrada de la sentencia condicional
Depuracin
" If debugging is the process of removing bugs, then programming must be the process of putting them in. Edsger Dijkstra (1930/2002) ".
Un depurador de programas (debugger en ingls) permite ir ejecutando un programa sentencia a sentencia (ejecucin paso a paso). Adems, nos permite ver en cualquier momento el valor de las variables usadas por el programa. El uso de un depurador facilita la localizacin de errores lgicos en nuestros programas, que de otra forma resultaran bastante difciles de localizar directamente en el cdigo.
"Debuggers dont remove bugs. They only show them in slow motion".
Cargad el proyecto II_Media. Una vez abierto lo compilamos para que se genere la informacin de depuracin. Dicha informacin se puede almacenar en distintos sitios. En la plantilla de _fp_2010 se ha seleccionado que sea sobre un chero con extensin .pdb. Nota. Para ms informacin, id al Explorador de Soluciones, pinchad sobre el proyecto con el click derecho y seleccionad ayuda con F1 sobre:
Proyecto -> Propiedades -> Propiedades de configuracin -> C/C++ -> General -> Formato de la informacin de depuracin
Si en la anterior opcin se eligiese Deshabilitado, no se generara ninguna informacin de depuracin. La idea bsica en la depuracin es ir ejecutando el cdigo lnea a lnea para ver posibles fallos del programa. Para eso, debemos dar los siguientes pasos: 1. Establecer una lnea del programa en la que queremos que se pare la ejecucin. Lo haremos introduciendo un punto de ruptura o (breakpoint) en dicha lnea. Si sospechamos dnde puede estar el error, situaremos el punto de ruptura en dicha lnea. En caso contrario, lo situaremos al principio del programa.
55
Depuracin
Para establecer un punto de ruptura podemos mover el ratn en la parte ms a la izquierda de una lnea de cdigo, y pulsar el botn izquierdo en esa posicin. La instruccin correspondiente queda marcada en rojo. Si en esa lnea ya haba un punto de ruptura, entonces ser eliminado. Tambin podemos colocar el cursor sobre la instruccin y pulsar F9 . Para eliminar un punto de ruptura, se realiza la misma operacin que para incluirlo, sobre la instruccin que actualmente lo tiene. Colocad ahora un punto de ruptura sobre la linea que contiene la primera sentencia condicional if. 2. A continuacin le pediremos al depurador que empiece a ejecutar nuestro programa pulsando como siempre F5 . Esto provocar que se ejecuten todas las sentencias que hay justo antes del punto de ruptura. Llegado a este punto, la ejecucin se pausa y se muestra en amarillo aquella lnea que se va a ejecutar a continuacin (en este caso, la que contiene el punto de interrupcin) 3. Una vez que tenemos la lnea amarilla sobre una instruccin, para proceder a su ejecucin, pulsamos F10 . Slo se ejecuta una sentencia (lnea) y se marca en amarillo la siguiente lnea, en espera a que volvamos a pulsar F10. Desde la barra de herramientas, podemos pinchar sobre el icono Ejecutad varias lneas de programa pulsando F10. Cuando se ejecute una sentencia cin, habr que irse a la ventana de la consola e introducir el valor pedido, y una vez hecho, volver a Visual Studio para proseguir la ejecucin con F10. 4. Para proseguir la ejecucin del programa sin ir paso a paso, basta con pulsar de nuevo F5. Para detener la ejecucin (y por tanto tambin la depuracin), seleccionaramos Shift-F5 , o bien el cuadrado de la barra de herramientas . Importante. No debe abortarse la ejecucin del programa, cerrando la ventana de la consola (a travs de Ctr-C o haciendo click sobre la aspa de la ventana). Esta forma de parar la ejecucin es brusca y el compilador podra no liberar adecuadamente algunos recursos utilizados del sistema operativo. 5. Cuando lleguemos a la ltima lnea del programa, la que contiene la llave cerrada del main, al pulsar F10, se abrir una pestaa nueva sobre un chero denominado crt0.c. Este chero es utilizado internamente por Visual Studio como punto de entrada de la aplicacin. Para evitar que aparezca este chero, cuando lleguemos a la ltima lnea del programa, pulsaremos F5 en vez de F10.
56
Depuracin
Otros recursos: Este comando, accesible tambin con Ctr-F10 , ejecuta todas las instrucciones hasta donde se encuentre actualmente el cursor de la ventana de edicin. Al llegar a l, se marca en amarillo dicha lnea y se queda en espera a que iniciemos una ejecucin paso a paso, o a que prosigamos la ejecucin ininterrumpida con F5. Se utiliza para saltar determinadas sentencias que no queremos revisar. Si pulsamos Ctr-F5 en vez de F5, el programa se ejecutar sin procesar la informacin de depuracin, por lo que, por ejemplo, no se parar en ningn punto de interrupcin. Adems, al ejecutar el programa de este forma, tambin saldr un mensaje al nal con la leyenda Pulse cualquier tecla para continuar. Este mensaje se aadir al que nosotros ya habamos puesto con system("pause"). Podemos iniciar la ejecucin paso a paso desde el principio, sin poner ningn punto de interrupcin, pulsando directamente F10. Esto har que la primera instruccin destacada en amarillo sea la correspondiente a main. Los depuradores de programas permiten consultar los valores que tienen en cada momento algunas de las variables que se utilizan en el programa, para as intentar descubrir dnde puede estar el posible error lgico del programa. EN PRIMER LUGAR, debemos iniciar la depuracin introduciendo un punto de interrupcin y pulsando F5 (o empezando desde el principio con F10). Automticamente aparecen las ventanas siguientes:
Locales: Contiene una lista de las variables denidas en el bloque actual. Por ahora, las que aparecen son las que estn denidas dentro de main. Inspeccin: Contiene variables que explcitamente ha incluido el programador. Ya
veremos en temas posteriores en qu situaciones puede resultar til.
Los valores mostrados para cada variable en las anteriores ventanas, son el valor actual para cada una de ellas. Por valor actual entendemos el valor que tiene dicha variable, antes de que se ejecute la lnea marcada en amarillo. El valor de cada variable se ir actualizando de forma automtica conforme el programa siga su ejecucin. Adems, si durante la ejecucin interrumpida situamos el cursor sobre alguna variable del cdigo escrito .cpp, aparecer automticamente una leyenda informativa con el valor actual de dicha variable. Tambin podemos seleccionar una expresin con el ratn (como cualquier seleccin de texto) y se mostrar la evaluacin de dicha expresin.
57
Depuracin
Observacin nal: El depurador ayuda a encontrar errores al permitir ejecutar las sentencias paso a paso y as comprobar por donde va el ujo de control y ver cmo van cambiando las variables. En cualquier caso, nunca nos cansaremos de repetir que el mejor programador es el que piensa la solucin en papel, antes de escribir una sola lnea de cdigo en el entorno de programacin.
"When your code does not behave as expected, do not use the debugger, think".
58
59
Proyecto -> Propiedades de .... Propiedades de Configuracin -> Depuracin Argumentos del comando -> Editar ->
Tambin pueden leerse datos de un chero desde dentro del propio cdigo fuente del programa, pero esto se ver en el segundo cuatrimestre
2
60
Figura 6: Redireccin de la entrada desde la consola En el cuadro de texto que aparece al seleccionar Editar, introduciremos el smbolo < seguido del nombre del chero de texto que contiene los datos(ver Figura 7). Con el anterior ejemplo sera:
< II_cin_datos_entrada.txt
Por defecto, el entorno busca el chero de entrada de datos en la misma carpeta que el proyecto. Si se quiere, puede indicarse otra carpeta distinta, a travs de la opcin siguiente:
61
62
Ejercicio. Construid un programa para que vaya leyendo nmeros desde la entrada por defecto y los vaya sumando, hasta que se lea el valor -1. Imprimid el resultado. Realizad la entrada desde un chero externo que contendr la serie de valores. Utilizad las herramientas de depuracin vistas en la sesin anterior para inspeccionar el valor de las variables usadas en cada iteracin del bucle.
63
64
while (divisor <= tope){ if (tope % divisor == 0) cout << divisor << " es un divisor de " << tope << endl; divisor++; }
por el siguiente:
while (divisor <= tope){ if (tope % divisor == 0) cout << divisor << " es un divisor de " << tope << endl; else divisor++; }
Qu error se produce? Moraleja: Mucho cuidado con las sentencias condicionales dentro de los bucles: debemos asegurarnos de cambiar apropiadamente las variables involucradas en la condicin del bucle, para que, en algn momento, dicha condicin sea false Como programadores noveles en C++, podemos confundir el operador = con el operador ==. El resultado puede ser un error lgico en nuestro programa, aunque afortunadamente, puede ser detectado en tiempo de compilacin. Vamos a familiarizarnos con el aviso del compilador cuando usamos una sentencia de asignacin en una condicin. Sobre el ejemplo de los divisores, cambiad la lnea en la que aparece la sentencia condicional
65
dnde modulo es una variable entera que habr que declarar previamente. Compilad y observad el aviso que nos da Visual Studio. Qu error lgico se produce y por qu? Para contestar esta pregunta hay que repasar las transparencias de teora en las que se dice que una asignacin es una expresin y se habla sobre la dualidad entre el tipo bool y el tipo
int
66
EsMinuscula comprueba si un carcter pasado como parmetro es una minscula. A dicho parmetro, llamadlo una_letra.
67
b)
Observad que el parmetro una_letra de la funcin EsMinuscula podra llamarse igual que el parmetro caracter de la otra funcin. Esto es porque estn en mbitos distintos y para el compilador son dos variables distintas. Haced el cambio y comprobarlo. Finalidad: Entender el mbito de los parmetros de las funciones, as como las llamadas entre funciones. Dicultad Baja. 5. En el ejercicio 5 de la relacin de problemas I (pgina 14) se vio cmo obtener el valor de ordenada asignado por la funcin gaussiana, sabiendo el valor de abscisa x. Recordemos que esta funcin matemtica dependa de dos parmetros (esperanza) y (desviacin), y vena denida por:
1 e gaussiana(x) = 2
1 2
Cread una funcin para calcular el valor de la funcin gaussiana en un punto arbitrario ledo desde teclado. Cread un programa principal que llame a la funcin. Finalidad: Entender la separacin de E/S con Cmputos en el contexto de las funciones. Dicultad Baja. 6. Vamos a aadir una funcin al ejercicio 4 de esta relacin de problemas. Se pide implementar la funcin Transforma, a la que se le pase como parmetro un char y haga lo siguiente: si el argumento es una letra en mayscula, devuelve su correspondiente letra en minscula, si el argumento es una letra en minscula, devuelve su correspondiente letra en mayscula, si el argumento no es ni una letra mayscula, ni una letra mayscula, devuelve el carcter pasado como argumento. Observad que la constante de amplitud
68
uno,
Conjunto_3_Valores_vs1 Aadid un mtodo pblico Max. Este mtodo tendr la siguiente cabecera: double Max() Observad que el mtodo Max acta sobre los datos de la clase (uno, dos y tres) por lo que no tiene parmetros. Observad la diferencia con la cabecera del ejercicio 1 en el que Max era una funcin que no estaba dentro de ninguna clase.
b) Aadid ahora un mtodo para calcular la media aritmtica de los tres valores. c) Cread un main que llame a los mtodos anteriores. Comprobad que podemos modicar directamente los datos miembro pblicos desde el main, lo cual no es muy recomendable como ya se ha visto en clase de teora. Para resolver este problema, hacemos lo siguiente: d) Copiad el cdigo de la clase anterior y copiadlo dentro de una nueva clase llamada En esta nueva versin, declarad los datos miembro como private, en vez de public. Comprobad que ya no podemos acceder a ellos desde el main, por lo que necesitamos asignarles un valor de otra forma. Para ello, haced lo siguiente: Aadid un constructor a la clase Conjunto_3_Valores_vs2. En dicho constructor, pasaremos los tres valores que habr que asignrselos a los datos miembro (usad la lista de inicializacin, que va precedida de dos puntos). Cread el objeto correspondiente desde el main (el compilador nos obligar a pasar los tres valores en el constructor) II ) Aadid tres mtodos (GetPrimero(), GetSegundo(), GetTercero()) que devuelvan los correspondientes datos miembro, para que as pueda consultarse su valor desde el main.
I)
Conjunto_3_Valores_vs2
e) Supongamos que creamos un objeto con los valores 2, 5, 7. Si ahora quisiramos cambiar de conjunto de datos y trabajar con 3, 9, 1, por ejemplo, tendramos que crear otro objeto distinto. Esto es completamente lcito. En cualquier
69
caso, dependiendo del problema que estemos abordando, podramos estar interesados en permitir cambiar los datos del objeto (su estado) y as no tener que crear otro objeto distinto. Para ello, debemos proporcionar dicha funcionalidad a la clase. Lo hacemos de tres formas alternativas: Creamos la clase
que contendr el mismo cdigo que Conjunto_3_Valores_vs2 y le aadimos un mtodo SetValores que cambie los tres valores a la vez (como ha cambiado el nombre de la clase, habr que cambiar el nombre del constructor). Cread un objeto de esta clase desde el main y llamad a sus mtodos. En esta solucin, asignamos (dentro del constructor) un primer valor a cada uno de los tres datos miembro y posteriormente permitimos su modicacin a travs del mtodo SetValores. Slo permitimos la modicacin conjunta de los tres datos miembro a la misma vez. Alternativamente, Creamos la clase que contendr el mismo cdigo que Conjunto_3_Valores_vs3, salvo que suprimimos el constructor de la clase. Modicad convenientemente el main. En esta solucin, los tres datos miembro slo los podemos asignar con el mtodo nuevo SetValores. Slo permitimos la modicacin conjunta de los tres datos miembro a la misma vez. Alternativamente, creamos la clase que contendr el mismo cdigo que Conjunto_3_Valores_vs4, pero suprimimos el mtodo SetValores, y le aadimos tres mtodos nuevos SetPrimero, SetSegundo, SetTercero, para que cambien cada uno de los valores de forma independiente. Cread un objeto de esta clase desde el main y llamad a sus mtodos. En esta solucin, los tres datos miembro slo los podemos asignar a travs de un mtodo especco para cada uno de ellos. Observad la exibilidad que me ofrece el concepto de clase. El programador decide cmo quiere que se acceda a los datos miembro: prohibiendo cambiar los datos miembro una vez que se ha construido el objeto (versin 2) o permitindolo, bien todos a la vez (versiones 3 y 4) o uno a uno (versin 5). Finalidad: Trabajar con los conceptos bsicos de clases. Dicultad Baja. A partir de ahora, todos los ejercicios deben resolverse utilizando nicamente datos miembro privados.
Conjunto_3_Valores_vs3
Conjunto_3_Valores_vs4
Conjunto_3_Valores_vs5
70
RELACIN DE PROBLEMAS III. Funciones y Clases 8. Cread una clase llamada ParejaEnteros que represente una pareja de enteros cualesquiera. Aadid un constructor y los mtodos que se estimen oportunos para asignarles valores a los enteros y para obtener el valor que stos tengan. Las operaciones que queremos realizar sobre una pareja son calcular el mayor, el menor, comprobar si se dividen, ver quien es el dividendo y quien el divisor, intercambiarlos y calcular el mximo comn divisor. Cread un main que llame a dichos mtodos, para comprobar que estn bien implementados. Le aadira a la clase nmero? Por qu?
Finalidad: Disear la interfaz de una clase. Dicultad Baja. 9. Sobre el ejercicio 8 de esta relacin de problemas se pide crear un programa principal ms completo de la siguiente forma. En el main se leern dos enteros y a continuacin se ofrecer al usuario un men con las opciones para realizar cualquiera de las operaciones denidas en la clase ParejaEnteros. Tambin se ofrecer la posibilidad de imprimir el valor de cada uno de los dos enteros. Una vez ejecutada la operacin, se volver a mostrar el mismo men, hasta que el usuario decida salir (pulsando la tecla 'X', por ejemplo). Finalidad: Organizar un men de opciones que se va repitiendo mientras el usuario no decida salir. Dicultad Media. 10. Denid una clase para representar una progresin geomtrica, tal y como se deni en el ejercicio 21 de la relacin de problemas II. a) Pensad cual debera ser el constructor de la clase y los mtodos bsicos que la clase debera tener. b) Aadid un mtodo llamado SumaHastaInfinito para que calcule la suma dada por: i= a1 ai = 1r i=1 siempre que el valor absoluto de la razn sea menor o igual que 1. c) Aadid un mtodo llamado SumaHasta para que sume los k primeros elementos de la progresin. Para implementar el mtodo SumaHasta, usad el mismo algoritmo (con un bucle for) que se vio como solucin del ejercicio 21 de la relacin de problemas II. Cread un programa principal que construya la progresin con los valores a1 = 3,5 y r = 4,1 y calcule la suma hasta k = 30. d) Cambiemos ahora la implementacin del mtodo SumaHasta. Para ello, en vez de usar un bucle for aplicamos la siguiente frmula que nos da la sumatoria
71
a1 r = a1
i=1
rk 1 r1
Es muy importante remarcar que el programa main no cambia nada. Hemos cambiado la implementacin del mtodo SumaHasta y lo hemos podido hacer sin cambiar el main, ya que ste no tena acceso al cdigo que hay dentro del mtodo. Esto es ocultacin de informacin tal y como se describi en las clases de teora. Nota. La potenciacin (en nuestro ejemplo r k ) es una operacin costosa, por lo que hasta podra ser ms lenta la versin nueva que la antigua usando un bucle for. Probad distintos valores para ver si hay diferencias signicativas. En cualquier caso, lo importante es que mientras no cambiemos la cabecera del mtodo SumaHasta, podemos cambiar su implementacin sin tener que cambiar ni una lnea de cdigo del main. e) Aadid ahora otro mtodo MultiplicaHasta para que multiplique los k primeros elementos de la progresin, aplicando la frmula:
i=k
a1 r i =
i=1
(a1 ak )k
Finalidad: Enfatizar la importancia de la ocultacin de informacin. Dicultad Baja. 11. Se quiere construir una clase DepositoSimulacion para simular prstamos, ofreciendo la funcionalidad descrita en los ejercicios 12 (reinvierte capital e inters un nmero de aos) y 13 (reinvierte capital e inters hasta obtener el doble de la cantidad inicial) de la relacin de problemas II (pgina 44). Por tanto, la clase debe proporcionar, para un capital y unos intereses dados, mtodos para: calcular el capital que se obtendr al cabo de un nmero de aos, calcular el nmero de aos que deben pasar hasta obtener el doble de la cantidad inicial. A la hora de disear la clase, tendremos que analizar cuestiones como: a) Si queremos modicar el capital y el inters una vez creado el objeto, b) Si queremos poder modicarlos de forma independiente, c) Si hay alguna restriccin a la hora de asignar un valor al capital e inters, d) Si es mejor un mtodo para calcular el nmero de aos hasta obtener el doble de la cantidad inicial, o por el contrario es mejor un mtodo para calcular el nmero de aos hasta obtener una cantidad especca.
72
Finalidad: Disear la interfaz de una clase. Dicultad Baja. 12. Se quiere construir una clase para realizar la funcionalidad descrita en el ejercicio 10 de la relacin de problemas I sobre la nmina del fabricante y diseador (pgina 16). La clase debe proporcionar, al menos, los mtodos SalarioNetoDisenador y SalarioNetoFabricante. El criterio del clculo del salario es el mismo (el diseador cobre el doble de cada fabricante) pero adems, ahora se le va a aplicar una retencin scal para el cmputo de los salarios netos. Dicha retencin ser la misma tanto para el fabricante como para el diseador. Analizad las siguientes posibilidades y elegid la que crea ms adecuada, justicndolo: a) Creamos un dato miembro para almacenar el valor de retencin scal y pasamos su valor en el constructor. b) Creamos un dato miembro para almacenar su valor y adems proporcionamos un mtodo para su modicacin. Finalidad: Trabajar con datos miembro constantes. Dicultad Baja. 13. Una empresa quiere gestionar las nminas de sus empleados. El cmputo de la nmina se realiza en base a los siguientes criterios: a) Hay cuatro tipos de categoras laborales: Operario, Base, Administrativo y Directivo. b) Se parte de un salario base que depende de la antigedad del trabajador y de su categora laboral. Para la categora Operario, el salario base es de 900 euros, 1100 el puesto Base, 1200 los Administrativos y 2000 los Directivos. Dicho salario base se incrementa con un tanto por ciento igual al nmero de aos trabajados. c) Los trabajadores tienen complementos en su nmina por el nmero de horas extraordinarias trabajadas. La hora se paga distinta segn la categora: 16 euros por hora para los operarios, 23 para el puesto Base, 25 los Administrativos y 30 los Directivos. Adems, al complemento que sale al computar el nmero de horas extraordinarias, se le aplica una subida con un tanto por ciento igual al nmero de aos trabajados. Se pide disear la interfaz de una clase (tambin hay que incluir los datos miembro privados) para poder trabajar con esta informacin. No se pide implementar la clase, nicamente determinar la interfaz. Finalidad: Disear la interfaz de una clase. Dicultad Media. 14. Transformad la solucin del ejercicio 9 de esta relacin de problemas para que la responsabilidad de la lectura de la opcin introducida por el usuario recaiga en una clase a la que llamaremos Menu. Finalidad: Ver una clase especca que gestione la entrada de datos. Dicultad Media.
73
15. Cread una clase para representar fracciones. El numerador y denominador sern enteros y debe proporcionar un mtodo para normalizar la fraccin, es decir, encontrar la fraccin irreducible que sea equivalente. Para ello, tendr que dividir el numerador y denominador por su mximo comn divisor. Finalidad: Disear la interfaz de una clase. Dicultad Media. 16. En C++, los tipos de datos simples como int, char, double, etc, no son clases. Por tanto, si declaramos una variable real en la forma double real, para calcular el seno de real, llamamos a una funcin en la forma
Valor. Este mtodo debe devolver el valor del real (6.5 en el ejemplo anterior) b) Seno. Para denirlo, llamad a la propia funcin sin de la biblioteca cmath. Debe devolver un double c) ValorAbsoluto. Devolver un tipo double que contendr el valor absoluto del real. No pueden utilizarse las funciones de cmath.
a) Cread un programa principal que llame a dichos mtodos. Observad que sera interesante que nuestro cdigo fuese el siguiente:
74
RELACIN DE PROBLEMAS III. Funciones y Clases realizar la suma de dos variables de tipo MiReal se necesita sobrecargar el operador + (se ver en el segundo cuatrimestre). Nota. Este tipo de clases (MiEntero, MiReal, etc) son proporcionadas por Java de forma standard. En otros lenguajes como SmallTalk o plataformas como .NET (con lenguajes como Visual Basic, C#) no existe la diferencia entre tipos bsicos (como int, double, etc) y todo son clases, siguiendo una losofa orientada a objetos pura. Finalidad: Entender las clases que actan como envolventes (wrappers) de los tipos bsicos. Dicultad Baja.
75
Problemas de Ampliacin
17. Denid funciones aisladas para implementar las soluciones a los siguientes ejercicios de la relacin de problemas II: 16 (factorial y combinatorio), 23 (serie), 15 (narcisista), 29 (feliz). Dicultad Baja. 18. Construid la clase MiEntero que ser utilizada en la forma siguiente:
Valor. Este mtodo debe devolver el valor del entero (un tipo int). b) Factorial. Usad la solucin del ejercicio 16 de la relacin de problemas II
a) (pgina 44). c)
Cread un programa principal que llame a dichos mtodos. 19. Construid la clase MiCaracter que ser utilizada en la forma siguiente:
Valor. Este mtodo debe devolver el valor del carcter. EsMinuscula. Devuelve un bool. EsMayuscula. Devuelve un bool. EsLetra. Devuelve un bool. GetMayuscula. Devuelve un char correspondiente al carcter convertido a mayscula. Si el carcter no es minscula, devuelve el mismo valor del char. GetMinuscula. El recproco del anterior.
76
20. La sonda Mars Climate Orbiter fue lanzada por la NASA en 1998 y lleg a Marte el 23 de septiembre de 1999. Lamentablemente se estrell contra el planeta ya que se acerc demasiado. El error principal fue que los equipos que desarrollaron los distintos mdulos de la sonda usaron sistemas de medida distintos (el anglosajn y el mtrico). Cuando un componente software mandaba unos datos en millas (o libras), otro componente software los interpretaba como si fuesen kilmetros (o Newtons). El problema se habra arreglado si todos hubiesen acordado usar el mismo sistema. En cualquier caso, cada equipo se encuentra ms a gusto trabajando en su propio sistema de medida. Por tanto, la solucin podra haber pasado por que todos utilizasen una misma clase para representar distancias (idem para fuerzas, presin, etc), utilizando los mtodos que les resultasen ms cmodos. Para ello, se pide construir la clase Distancia que contendr mtodos como SetKilometros, SetMillas, etc. Internamente se usar un nico dato miembro privado llamado kilometros al que se le asignar un valor a travs de los mtodos anteriores, realizando la conversin oportuna (una milla es 1,609344 kilmetros). La clase tambin proporcionar mtodos como GetKilometros y GetMillas para lo que tendr que realizar la conversin oportuna (un kilmetro es 0,621371192 millas). Observad que la implementacin de la clase podra haber utilizado como dato miembro privado, una variable millas, en vez de kilmetros. Esto se oculta a los usuarios de la clase, que slo ven los mtodos SetKilometros, SetMillas, GetKilometros y GetMillas. Nota. Otro de los fallos del proyecto fue que no se hicieron sucientes pruebas del software antes de su puesta en marcha, lo que podra haber detectado el error. Esto pone de maniesto la importancia de realizar una batera de pruebas para comprobar el correcto funcionamiento del software en todas las situaciones posibles. Esta parte en el desarrollo de un proyecto se le conoce como pruebas de unidad (unit testing) Finalidad: Trabajar con una clase como una abstraccin de un concepto. Dicultad Baja. 21. Se quiere construir una clase para representar la traccin de una bicicleta, es decir, el conjunto de estrella, cadena y pin. Supondremos que el plato delantero tiene tres estrellas y el trasero tiene 7 piones. La clase debe proporcionar mtodos para cambiar la estrella y el pin, sabiendo que la estrella avanza o retrocede de 1 en 1, y los piones cambian a salto de uno o de dos. Una vez hecha la clase y probada con un programa principal, modicadla para que no permita cambiar la marcha (con la estrella o el pin) cuando haya riesgo de que se rompa la cadena. Este riesgo se produce cuando la marcha a la que queremos cambiar es de la siguiente forma: Primera estrella y pin mayor o igual que 5 Segunda estrella y pin o bien igual a 1 o bien igual a 7 Tercera estrella y pin menor o igual que 4
77
Finalidad: Disear la interfaz de una clase. Trabajar con datos miembro constantes.. Dicultad Media. 22. Construid una clase llamada MedidaAngulo que represente una medida de un ngulo. Al igual que se hizo en el ejercicio 20, la clase aceptar datos que vengan de alguna de las siguientes formas: nmero de grados con decimales (real); nmero de radianes (entero); nmero de segundos (entero); nmero de grados, minutos y segundos (en un struct que represente estos tres valores) Dicultad Baja. 23. Recuperad el ejercicio 5 de esta relacin de problemas sobre la funcin gaussiana. Ahora estamos interesados en obtener el rea que cubre la funcin en el intervalo [, x]. Dicho valor se conoce como la distribucin acumulada (cumulative distribution function) en el punto x, abreviado CDF (x). Matemticamente se calcula
x
realizando la integral
http://dostat.stat.sc.edu/prototype/calculators/index.php3? dist=Normal
Tambin pueden obtenerse un valor aproximado de CDF (x), como por ejemplo, el dado por la siguiente frmula (ver Wikipedia: Normal distribution) CDF (x) = rea hasta (x) 1 gaussiana(x)(b1 t + b2 t2 + b3 t3 + b4 t4 ) dnde: t= 1 1 + b0 x b0 = 0,2316419 b1 = 0,319381530 b2 = 0,356563782
78
RELACIN DE PROBLEMAS III. Funciones y Clases 24. Cread un struct llamado CoordenadasPunto2D para representar un par de valores reales correspondientes a un punto en R2 . Cread ahora una clase llamada Circunferencia. Para establecer el centro, se usar un valor del tipo CoordenadasPunto2D. Aadid mtodos para obtener la longitud de la circunferencia y el rea del crculo interior. Aadid tambin un mtodo para saber si la circunferencia contiene a un punto. Recordemos que un punto (x1 , y1 ) est dentro de una circunferencia con centro (x0 , y0 ) y radio r si se verica que: (x0 x1 )2 + (y0 y1 )2 <= r 2 Observad que el valor de debe ser constante, y el mismo para todos los objetos de la clase Circunferencia. Finalidad: Trabajar con constantes estticas de tipo double. Dicultad Baja. 25. Implementad la clase del ejercicio 13 de esta relacin de problemas. Dicultad Media.
79
Funciones
Sesin 6
Funciones
Actividades a realizar en casa
Actividad: Resolucin de problemas. Resolved los siguientes ejercicios de la relacin de problemas III: Obligatorios: 1 (Mximo de 3 doubles) 2 (Progresin geomtrica) 3 (Tarifa area) 4 (Comprobar si una letra es minscula y pasar a mayscula) 5 (Gaussiana) Opcionales: 6 (Mayscula a minscula y viceversa)
http://www.cplusplus.com/reference/clibrary/ http://www.cppreference.com
Actividades a realizar en las aulas de ordenadores
Durante la primera media hora de clase, seguid las instrucciones indicadas en el apartado siguiente Depuracin de funciones (el otro apartado es para hacerlo en casa), mientras que el profesor corrige individualmente los ejercicios de algunos alumnos. Durante el resto de la sesin, el profesor ir llamando a los alumnos para que expliquen al resto de compaeros los ejercicios de esta sesin.
80
Funciones
Depuracin de funciones
Ejecucin paso a paso dentro de las funciones. Abrid el proyecto III_Max, disponible en el directorio de Material de la Asignatura. Incluid un punto de interrupcin en la primera lnea del main. Ejecutad con F5. Si pulsamos F10 ejecutaremos el programa paso a paso, pero cuando llegue a la sentencia que llama a la funcin Max, el depurador no entrar en el cdigo de dicha funcin. Para poder hacerlo, habr que pulsar F11 justo antes de la llamada a la funcin. Se puede alternar F10 y F11 de forma arbitraria. El icono de acceso directo a esta funcionalidad es . Probadlo. Si pulsamos F11 justo en la llave cerrada del main, el depurador entrar en el cdigo de una funcin especial que se encarga de ejecutar el programa. Para salirnos, o bien pulsamos F5, o bien interrumpimos la ejecucin. Para no entrar en este cdigo, cuando lleguemos a la llave cerrada del main, pulsaremos F10 o F5. Salirse de una funcin. Si durante la depuracin entramos en el cdigo de una funcin, por ejemplo Max, y queremos ejecutar de golpe el resto de la funcin Max y proseguir paso a paso a partir de la lnea desde la que se llam a Max, pulsaremos Shift-F11 . Variables locales. Cuando estemos escribiendo cdigo, la funcin de autocompletar el nombre de las variables con Ctr-Barra espaciadora tambin est disponible dentro de las funciones (para las variables locales). Cuando estamos depurando, en la ventana Variables Locales podemos ver el valor de las variables locales de la funcin activa en ese momento. Obviamente, tambin aparecen los parmetros formales ya que son variables locales a la funcin. Comprobadlo ejecutando paso a paso la funcin Max. Otra forma de ver el valor de una variable local durante la depuracin es dejar el cursor del ratn encima de la variable y aparecer una leyenda en amarillo con el valor que dicha variable tiene en ese momento (al igual que hacamos con las variables del main) Ir a denicin. Otro recurso interesante del entorno de Visual Studio es el siguiente: situad el cursor sobre la llamada a una funcin, por ejemplo, sobre la llamada a Max desde el main. Haced click con el ratn derecha y seleccionad Ir a definicin (o pulsad sobre ). Automticamente, el cursor se situar en la denicin de la funcin. Para el icono volver a la lnea en la que estbamos, pulsaremos Ctr- (navegacin hacia atrs), o bien pincharemos sobre el icono
81
Funciones
En la ventana Vista de Clases, si pinchamos sobre Funciones y variables globales, podremos ver las funciones denidas dentro del chero .cpp. Haciendo doble click sobre cualquier funcin, el cursor se sita en el cdigo de la funcin.
Figura 8: Vista de Clases Una vez hayamos denido una funcin, desde cualquier otra funcin denida con posterioridad, podemos invocarla escribiendo su nombre y la lista de parmetros actuales. Visual Studio permite el uso de Ctr-Barra espaciadora para completar el nombre de la funcin llamada. Adems, saldr automticamente una leyenda informativa con los nombres de los parmetros formales.
82
Funciones
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\ 10.0\NativeDE\StepOver]
y seleccionamos con el click derecho del ratn Nuevo->Valor alfanumrico. Aadimos sendas claves con los nombres NoDepures1 y con los siguientes valores:
std\:\:.*=NoStepInto system=NoStepInto
83
Clases
Sesin 7
Clases
Actividades a realizar en casa
Actividad: Resolucin de problemas. Resolved los siguientes ejercicios de la relacin de problemas III: Obligatorios: 7 (Conjunto de 3 valores) 8 (Pareja de enteros) 10 (Progresin geomtrica) Opcionales: 9 (Pareja de enteros con un men principal)
84
Clases
Sesin 8
Actividades a realizar en casa
Durante la semana del 21 al 25 de Noviembre se realizar el primer examen prctico. Dicho examen se realizar durante las horas de las sesiones prcticas. Para la prxima semana, no hay que resolver ningn problema, pero s hay que hacer lo siguiente: Seguid las instrucciones indicadas en el apartado siguiente Inspeccin de objetos. Esta actividad hay que realizarla en la casa (no ms de 10 minutos). Consultar las soluciones a los siguientes ejercicios (las soluciones estn disponibles en la web de la asignatura y en clase de teora ya se han explicado la mayora) 23 (Gaussiana) 11 (Inters) 12 (Fabricante) 15 (Fraccin) 16 (MiReal) 18 (MiEntero) 13 (Nmina) 14 (Pareja de enteros con el men principal como una clase)
85
Clases
Inspeccin de objetos
Recuperar la solucin del ejercicio 9 disponible en la web de la asignatura (III_ParejaEnteros). Incluid un punto de interrupcin dentro del mtodo MCD tal y como se indica en la gura. Ejecutar el programa introduciendo dos enteros cualesquiera y seleccionar la opcin de calcular el mximo comn divisor. Cuando la ejecucin pare al llegar al punto de interrupcin, abrir la ventana de inspeccin de variables locales:
Finalidad: Trabajar con constructores que determinan la correcta creacin del objeto. Dicultad Media.
86
Problemas Bsicos
1. En clase de teora se ha visto la siguiente clase MiVectorCaracteres.
class MiVectorCaracteres{ private: static const int TAMANIO = 50; char vector_privado[TAMANIO]; int total_utilizados; public: MiVectorCaracteres() :total_utilizados(0) { } int TotalUtilizados(){ return total_utilizados; } void Aniade(char nuevo){ if (total_utilizados < TAMANIO){ vector_privado[total_utilizados] = nuevo; total_utilizados++; } } char Elemento(int indice){ return vector_privado[indice]; } };
Aadir un mtodo que nos diga si el vector es un palndromo, es decir, que se lee igual de izquierda a derecha que de derecha a izquierda. Por ejemplo, {'a','b','b','a'} sera un palndromo. Finalidad: Ejemplo de mtodo que accede a las componentes del vector. Dicultad Baja. 2. Sobre la clase MiVectorCaracteres, aadir un mtodo con la cabecera
87
RELACIN DE PROBLEMAS IV. Vectores para que modique la componente con ndice indice_componente y ponga en su lugar el valor nuevo. Este mtodo est pensado para modicar una componente ya existente, pero no para aadir componentes nuevas. Por tanto, en el caso de que la componente no est dentro del rango correcto, el mtodo no modicar nada. Finalidad: Ejemplo de mtodo que modica el estado del objeto. Gestin de precondiciones. Dicultad Baja. 3. Sobre la clase MiVectorCaracteres, aadir un mtodo IntercambiaComponentes para intercambiar dos componentes del vector. Por ejemplo, si el vector contiene {'h','o','l','a'}, despus de intercambiar las componentes 1 y 3, se quedara con {'h','a','l','o'}. Aadid otro mtodo para invertir el vector, de forma que si el vector contena los caracteres {'a','g','t','b','i','o'}, despus de llamar al mtodo se quedar con {'o','i','b','t','g','a'}. Para implementar este mtodo, llamad el mtodo anterior IntercambiaComponentes. Qu deberan hacer los mtodos si los ndices de componentes no son correctos? Imprimir las componentes del vector desde el main, antes y despus de llamar a dicho mtodo. Observad que se repite el mismo tipo de cdigo cuando se imprimen las componentes del vector. Ya lo arreglaremos en el tema siguiente. Finalidad: Ejemplo de mtodo que modica el estado del objeto. Gestin de precondiciones. Dicultad Baja. 4. Sobre la clase MiVectorCaracteres, aadir un mtodo Elimina para eliminar el carcter que se encuentre en una determinada posicin, de forma que si el vector contena los caracteres {'h','o','l','a'}, despus de eliminar la componente con ndice 2 (la tercera) se quedar con {'h','o','a'}. Qu debera hacer el mtodo si el ndice de componente no es correcto? Finalidad: Ejemplo de mtodo que modica el estado del objeto. Gestin de precondiciones. Dicultad Baja. 5. Sobre
MiVectorCaracteres, se quiere aadir un mtodo EliminaMayusculas para eliminar todas las maysculas. Por ejemplo, despus de aplicar dicho mtodo al vector {'S','o','Y',' ','y','O'}, ste debe quedarse con {'o',' ','y'}. Implementar el siguiente algoritmo:
la clase
Recorrer todas las componentes del vector Si la componente es una mayscula, borrarla
Para borrar la mayscula, se desplazan una posicin a la izquierda todas las componentes que hay a su derecha. Para ello, llamad al mtodo Elimina que se ha denido en el ejercicio 4 de esta relacin de problemas. Finalidad: Recorrido sencillo de un vector con dos bucles anidados. Dicultad Baja.
88
6. El algoritmo del ejercicio 5 es muy ineciente ya que requiere trasladar muchas veces muchas posiciones. Proponer un algoritmo para resolver ecientemente este problema e implementarlo. Consejo: Una forma de hacerlo es utilizar dos variables, posicion_lectura y posicion_escritura que nos vayan indicando, en cada momento, la componente que se est leyendo y el sitio dnde tiene que escribirse. Finalidad: Modicar un vector a travs de dos apuntadores. Dicultad Media.
Problemas de Ampliacin
7. Sobre la clase MiVectorCaracteres, aadir un mtodo para eliminar el exceso de caracteres en blanco, es decir, que suprima todas las secuencias de espacios en blanco mayor de 1. Por ejemplo, si el vector original es (' ','a','h',' ',' ',' ','c'), el vector resultante debe ser (' ','a','h',' ','c'). Debe hacerse lo ms eciente posible. Finalidad: Recorrido de las componentes de un vector, en el que hay que recordar lo que ha pasado en la iteracin anterior. Dicultad Media. 8. Sobre la clase MiVectorCaracteres, aadir un mtodo EliminaRepetidos que quite los elementos repetidos, de forma que cada componente slo aparezca una nica vez. Por ejemplo, si el vector contiene
{'b','a','a','h','a','a','a','a','c','a','a','a','g'}
despus de quitar los repetidos, se quedara como sigue:
{'b','a','h','c','g'}
Se proponen varias alternativas: a) Usando un vector local sin_repetidos en el que almacenamos una nica aparicin de cada componente:
Recorrer todas las componentes del vector original Si la componente NO est en el vector sin_repetidos, aadirla (al vector sin_repetidos) Asignar las componentes de sin_repetidos al vector original
b) El problema del algoritmo anterior es que usa un vector local, lo que podra suponer una carga importante de memoria si trabajsemos con vectores grandes. Por lo tanto, vamos a resolver el problema sin usar vectores locales. Si una componente est repetida, se borrar del vector. Para borrar una componente, podramos desplazar una posicin a la izquierda, todas las componentes que estn a su derecha. El algoritmo quedara:
89
Recorrer todas las componentes del vector original Si la componente se encuentra en alguna posicin anterior, la eliminamos desplazando hacia la izquierda todas las componentes que hay a su derecha
Este algoritmo nos obliga a desplazar muchas componentes cada vez que encontremos una repetida. Proponed una alternativa (sin usar vectores locales) para que el nmero de desplazamientos sea lo menor posible, e implementadla en el mtodo EliminaRepetidos Dicultad Media. 9. Supongamos un chero en el que hay caracteres cualesquiera. Realizar un programa que vaya leyendo dichos caracteres hasta que se encuentre un punto '.'. Queremos contar el nmero de veces que aparece cada una de las letras maysculas ('A', , 'Z'). Una posibilidad sera leer el carcter, y despus de comprobar si es una mayscula, ejecutar un conjunto de sentencias del tipo:
if (letra == 'A') conteo_caracteres[0] = conteo_caracteres[0] + 1; else if (letra == 'B') conteo_caracteres[1] = conteo_caracteres[1] + 1; else if (letra == 'C') conteo_caracteres[2] = conteo_caracteres[2] + 1; else ....
Sin embargo, este cdigo es muy redundante. Proponed una solucin e implementarla. Para resolver este ejercicio puede usarse o bien un vector clsico de enteros, o bien un objeto de una clase que construyamos del tipo MiVectorEnteros (en cuyo caso, sustituiramos los corchetes de acceso a las componentes por el correspondiente mtodo) Finalidad: Disear un vector en el que los ndices de las componentes representan algo. Dicultad Media. 10. Sobre la clase MiVectorCaracteres, aadir un mtodo PosicionCaracteresConsecutivos que calcule la posicin donde se en-
cuentre la primera secuencia de al menos n caracteres consecutivos e iguales a uno que se pase como parmetro al mtodo. Por ejemplo, en el vector de abajo, si n = 3, y el carcter buscado es 'a', entonces dicha posicin es la 4.
{'b','a','a','h','a','a','a','a','c','a','a','a','g'}
Dicultad Media.
11. Escribir un programa que calcule, almacene en un vector y muestre por pantalla los k primeros trminos de la sucesin de Fibonacci de orden n. Tanto n como k sern enteros a leer desde el dispositivo de entrada por defecto.
90
La sucesin de Fibonacci de orden n es una secuencia de nmeros en la que los dos primeros son el 0 y el 1. A partir del tercero, los elementos se calculan como la suma de los n anteriores, si ya hay n elementos disponibles, o la suma de todos los anteriores si hay menos de n elementos disponibles. Por ejemplo, la sucesin de Fibonacci de orden 4 sera la siguiente: 0, 1, 1, 2, 4, 8, 15, 29, . . . El programa debe denir una clase llamada Fibonacci para generar los nmeros de Fibonacci y otra clase del tipo MiVectorEnteros para ir almacenndolos. Dicultad Media.
91
Vectores
Sesin 9
Vectores
Actividades a realizar en casa
Actividad: Resolucin de problemas. Resolved los siguientes ejercicios de la relacin de problemas IV. Entregad un nico chero que contenga la clase MiVectorCaracteres con todos los mtodos pedidos en los siguientes ejercicios. Obligatorios: 1 (Palndromo) 2 (Modica componente) 3 (Invierte) 4 (Elimina componente) 5 (Elimina las maysculas) Opcionales: 6 (Elimina las maysculas ecientemente)
92