Logo Studenta

programacion c ejercicios resueltos-59

¡Estudia con miles de materiales!

Vista previa del material en texto

Programación a muchas escalas
Incluso entre los programadores profesionales hay muchas áreas de programación especializadas. Un 
individuo podría tener una especialidad en el procesamiento de datos de negocios, en escribir compilado-
res o desarrollar procesadores de palabras (una especialidad conocida como "tool making"), en apoyo a la 
investigación y el desarrollo, en desarrollo de presentación gráfi ca, en la escritura de software de entrete-
nimiento o en alguna otra, entre muchas áreas. Sin embargo, una persona puede producir sólo programas 
muy pequeños (unas cuantas decenas de miles de líneas de código en el mejor de los casos). Esta clase de 
trabajo se llama programación en pequeño.
Una aplicación más amplia, como el desarrollo de un nuevo sistema operativo, podría requerir cientos 
de miles o incluso millones de líneas de código. Esta clase de proyectos a gran escala requiere equipos de 
programadores, muchos de ellos especialistas, que deben organizarse de alguna manera o desperdiciarán 
tiempo valioso intentando comunicarse entre sí.
En general, se establece una organización jerárquica a lo largo de las líneas de la gráfi ca de estructura 
de módulo. Una persona, el arquitecto principal o director de proyecto, determina la estructura básica del 
programa y luego delega la responsabilidad de poner en práctica los componentes principales. Dichos 
componentes pueden ser módulos producidos por una descomposición funcional o podrían ser clases 
y objetos que resultan de un diseño orientado a objetos. En proyectos más pequeños, los componentes 
pueden ser delegados directamente a programadores. En cada etapa, la persona a cargo debe tener el 
conocimiento y la experiencia necesarios para defi nir el nivel que sigue en la jerarquía y estimar los recursos 
necesarios para ponerlo en práctica. Este tipo de organización se llama programación en grande.
Los lenguajes de programación y las herramientas de software pueden ayudar mucho para apoyar la 
programación en grande. Por ejemplo, si un lenguaje de programación permite a los programadores de-
sarrollar, compilar y probar partes de un programa de manera independiente antes de juntarlas, entonces 
esto permite que varias personas trabajen en el programa al mismo tiempo. Por supuesto, es difícil apreciar 
la complejidad de la programación en grande cuando se escribe un programa pequeño para una tarea de 
clase. Sin embargo, la experiencia que obtiene en este curso será valiosa cuando comience a desarrollar 
programas más grandes.
Lo siguiente es un ejemplo clásico de lo que sucede cuando se desarrolla un gran programa sin la 
organización cuidadosa y el apoyo de lenguaje apropiado. En la década de 1960, IBM desarrolló un nuevo 
sistema operativo importante denominado OS/360, que fue uno de los primeros ejemplos verdaderos de 
programación en grande. Después de haber escrito el sistema operativo, se encontraron más de 1 000 erro-
res signifi cativos. A pesar de que pasaron años en intentar arreglar estos errores, los programadores nunca 
los redujeron por debajo de 1 000, y en ocasiones las “composturas” producían más errores que los que 
eliminaban.
¿Qué condujo a esta situación? El análisis a posteriori mostró que el código estaba mal organizado y 
que las distintas piezas estaban tan interrelacionadas que nadie pudo arreglarlo. Un cambio aparentemente 
simple en una parte del código ocasionó que fallaran otras partes del sistema. Por último, a un gran costo, 
se creó un sistema completamente nuevo con mejor organización y herramientas.
En los primeros tiempos de la computación, todos esperaban que ocurrieran errores ocasionales, y 
aún fue posible realizar trabajo útil con un sistema operativo defectuoso. Sin embargo, en la actualidad 
las computadoras se emplean cada vez más en aplicaciones críticas —como equipo médico y sistemas de 
control de aviones—, donde los errores pueden ser fatales. Muchas de estas aplicaciones dependen de la 
programación en gran escala. Si en este momento estuviera abordando un moderno avión comercial, bien 
podría hacer una pausa y preguntarse: ¿qué clase de lenguaje y herramientas emplearon cuando escribieron 
los programas para esta cosa? Por fortuna, la mayoría de los grandes esfuerzos en el desarrollo de software 
hoy día usan una combinación de buena metodología, lenguaje apropiado y herramientas organizacionales 
extensas, un método conocido como ingeniería de software.
Caso práctico de resolución de problemas | 147
 www.FreeLibros.me
148 | Capítulo 4: Entrada de datos al programa y el proceso de diseño de software
Prueba y depuración
Una parte importante de la implementación de un programa es probarlo (corroborar los resultados). 
Por ahora debe comprender que no hay nada mágico respecto a la computadora. Es infalible sólo si 
la persona que escribe las instrucciones e introduce los datos es infalible. No confíe en que ha obte-
nido respuestas correctas hasta que haya comprobado sufi cientes a la mano para convencerse de que 
el programa está funcionando.
De aquí en adelante, estas secciones de Prueba y depuración ofrecen consejos prácticos acerca de 
cómo probar sus programas y qué hacer si un programa no funciona como se tenía previsto. Pero no 
espere hasta que haya encontrado un error para leer las secciones de Prueba y depuración. Es mucho 
más fácil evitar errores que arreglarlos.
Al probar programas que introducen valores de datos desde un archivo, es posible que fallen las 
operaciones de ingreso. Y cuando falla el ingreso en C++, la computadora no emite un mensaje de 
advertencia ni termina el programa. El programa simplemente continúa su ejecución e ignora las 
operaciones de entrada adicionales en ese archivo. Las dos causas más comunes para que falle el 
ingreso son datos no válidos y el error de fi n de archivo (end-of-fi le error).
Un error de fi n de archivo ocurre cuando el programa ha leído todos los datos de entrada dispo-
nibles en el archivo y necesita más datos para llenar las variables en sus sentencias de entrada. Es 
posible que el archivo de datos simplemente no haya sido preparado de manera adecuada. Quizá 
contiene menos datos que los requeridos por el programa. O tal vez el formato de los datos de entra-
da sea erróneo. Dejar espacios en blanco entre valores numéricos es asegurarse de que habrá proble-
mas. Por ejemplo, es posible que se desee que un archivo de datos contenga tres valores enteros: 25, 
16 y 42. Observe lo que sucede con estos datos:
2516 42
y este código:
inFile >> i >> j >> k;
Las dos primeras operaciones de entrada consumen los datos del archivo, dejando a la tercera sin 
datos para leer. El fl ujo inFile entra en estado de falla, así que a k no se le asigna un nuevo valor 
y la computadora continúa con la ejecución de la siguiente sentencia del programa.
Si el archivo de datos se prepara de manera correcta y aún hay un error de fi n de archivo, el 
problema está en la lógica del programa. Por alguna razón el programa intenta muchas operaciones 
de entrada. Podría ser un simple descuido como especifi car demasiadas variables en una sentencia de 
entrada particular. Podría ser un mal uso de la función ignore, que ocasiona que los valores sean 
omitidos de manera inadvertida; o podría ser un defecto grave en el algoritmo. Se deben verifi car 
todas estas posibilidades.
La otra fuente principal de falla de entrada, datos no válidos, tiene varias causas posibles. La más 
común es un error en la preparación o introducción de los datos. Los datos numéricos y de caracteres 
combinados de modo inapropiado en la entrada pueden ocasionar que falle el fl ujo de entrada si se 
supone que lea un valor numérico, pero el marcador de lectura se coloca en el carácter que no está 
permitido en el número. Otra causa es usar el nombre de variable equivocado (que puede ser del tipo 
de datos erróneo) en una sentencia de entrada. Declarar una variable del tipo de datos erróneo es una 
variación del problema. Por último, dejar una variable (o incluir una extra)en una sentencia de en-
trada puede causar que el marcador de lectura termine posicionado en el tipo de datos equivocado.
Otro descuido, uno que no causa falla de entrada pero ocasiona frustración del programador, es 
usar cin o cout en una sentencia I/O cuando su intención es especifi car un fl ujo de archivo. Si usa 
erróneamente cin en lugar de un fl ujo de archivo de entrada, el programa se detiene y espera la 
entrada desde el teclado. Si por error emplea cout en lugar de un fl ujo de archivo de salida, se ob-
tiene un resultado inesperado en la pantalla.
Al darle un marco de trabajo que lo ayude a organizar y seguir la pista de los detalles relaciona-
dos con el diseño e implementación de un programa, la descomposición funcional (y, después, el 
diseño orientado a objetos), debe, sobre todo, ayudar a evitar muchos de estos errores.
 www.FreeLibros.me
En capítulos posteriores verá que puede probar módulos por separado. Si se asegura de que cada 
módulo funciona por sí mismo, su programa debe funcionar cuando reúne todos los módulos. Probar 
módulos por separado es menos trabajo que intentar probar un programa completo. En una sección 
más pequeña de código es menos probable que se combinen errores múltiples que produzcan un 
comportamiento difícil de analizar.
Sugerencias de prueba y depuración
 1. Las sentencias de entrada y salida comienzan siempre con el nombre de un objeto de fl ujo, y los 
operadores >> y << apuntan en la dirección en que van los datos. La sentencia
cout << n;
envía datos al fl ujo de salida cout, y la sentencia
cin >> n;
envía datos a la variable n.
 2. Cuando un programa introduce desde un archivo o produce hacia él, asegúrese de que cada sen-
tencia I/O desde o hacia el archivo emplee el nombre del fl ujo de archivo, no cin o cout.
 3. La función open relacionada con un objeto ifstream u ofstream requiere una cadena C como 
argumento. El argumento no puede ser un objeto string. En este punto del libro, el argumen-
to sólo puede ser a) una cadena literal o b) la cadena C devuelta por la llamada de función 
myString.c_str(), donde myString es de tipo string.
 4. Cuando abra un archivo de datos para ingreso, asegúrese de que el argumento para la función 
open proporcione el nombre correcto del archivo como existe en el disco.
 5. Al leer una cadena de caracteres en un objeto string, el operador >> se detiene en, pero no 
consume, el primer carácter de espacio en blanco posterior.
 6. Asegúrese de que cada sentencia de entrada especifi que el número correcto de variables, y que 
cada una de dichas variables sea del tipo de datos correcto.
 7. Si sus datos de entrada se combinan (caracteres y valores numéricos), asegúrese de ocuparse de 
los espacios en blanco intermedios.
 8. Imprima por eco los datos de entrada para comprobar que cada valor está donde pertenece y en 
el formato apropiado. (Esto es muy importante, porque una falla de entrada en C++ no produce 
un mensaje de error ni termina el programa.)
Resumen
Los programas operan en datos. Si los datos y programas se mantienen separados, los datos están 
disponibles para uso con otros programas, y el mismo programa se puede ejecutar con diferentes 
conjuntos de datos de entrada.
El operador de extracción (>>) introduce datos desde el teclado o un archivo, y los almacena en 
la variable especifi cada como su operando derecho. El operador de extracción omite cualquier carác-
ter de espacio en blanco para hallar el siguiente valor de datos en el fl ujo de entrada. La función get 
no omite caracteres de espacio en blanco; introduce el siguiente carácter y lo almacena en la variable 
char especifi cada en su lista de argumentos. Tanto el operador >> como la función get dejan el 
marcador de lectura posicionado en el siguiente carácter por leer. La siguiente operación de entrada 
comienza a leer en el punto indicado por el marcador.
El carácter de nueva línea (denotado por \n en un programa de C++) marca el fi n de una línea 
de datos. Cada vez que usted oprime la tecla Return o Enter crea un carácter de nueva línea. Su pro-
grama genera una nueva línea cada vez que emplea el manipulador endl o produce de modo explí-
cito el carácter \n. La línea nueva es un carácter de control; no se imprime. Dicho carácter controla 
el movimiento del cursor en la pantalla o la posición de una línea en una impresora.
Los programas interactivos alertan al usuario en cada ingreso de datos y le informan de resulta-
dos y errores. Diseñar diálogo interactivo es un ejercicio en el arte de la comunicación.
 Resumen | 149
 www.FreeLibros.me

Continuar navegando