ÍNDICE Capítulo #1 Introducción 1.1. PRÓLOGO -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 1.2. DEFINICIÓN DE PROGRAMACIÓN ----------------------------------------------------------------------------------------------------------------------- 2 1.3. HISTORIA DEL LENGUAJE “C” --------------------------------------------------------------------------------------------------------------------------------- 2 1.4. MÉTODO A SEGUIR PARA LA SOLUCIÓN DE PROBLEMAS -------------------------------------------------------- 2 1.5. MÉTODOS PARA LA ELABORACIÓN DE ALGORITMOS ------------------------------------------------------------------ 3 1.6. EDITOR DE TEXTOS DE TURBO C -------------------------------------------------------------------------------------------------------------------------- 3
Capítulo #2 Variables, Constantes, Operadores y Expresiones 2.1. LAS VARIABLES --------------------------------------------------------------------------------------------------------------------------------------------------------------------- 5 2.1.1. Tipos T ipos de Datos -------------------------------------------------------------------------------------------------------------------------------------------------------- 5 2.1.2. Modificadores del Tipo de Datos -------------------------------------------------------------------------------------------------------------- 6 2.1.3. Turbo C es Sensible al Tamaño de las Letras--------------------Letras----------------------------------------------------------------- 7 2.2. LAS CONSTANTES 2.2.1. Constantes Hexadecimales Hexadecimales y Octales ---------------------------------------------------------------------------------------------------- 7 2.2.2. Constantes de Cadena --------------------------------------------------------------------------------------------------------------------------------------- 7 2.2.3. Constantes de Caracteres Caracteres de Diagonal Invertida --------------------------------------------------------------------------- 7 2.3. OPERADORES 2.3.1. Operadores Aritméticos ----------------------------------------------------------------------------------------------------------------------------------- 8 2.3.2. Operadores Relacionales y Lógicos -------------------------------------------------------------------------------------------------------- 9 2.3.3. Operador de Asignación ---------------------------------------------------------------------------------------------------------------------------------- 10 2.4. EXPRESIONES --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 10 2.5. ESCRIBIENDO FÓR MULAS MULAS MATEMÁTICAS EN “C” --------------------------------------- 11
Capítulo #3 Operaciones de Entrada-Salida de Datos 3.1. ESTRUCTURA GENERAL DE UN PROGRAMA EN LENGUAJE “C” --------------------- 12 3.2. ESPEFICADORES DE FORMATO ----------------------------------------------------------------------------------------------------------------------------- 13 3.3. ENTRADA Y SALIDA S ALIDA DE DATOS ----------------------------------------------------------------------------------------------------------------------------- 13 3.4. ENTRADA Y SALIDA DE CARACTERES Y CADENAS DE CARACTERES ----------------------- 18
Capítulo #4 Estructuras Selectivas 4.1 SENTENCIA if() ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 21 4.2 if()’s ANIDADOS ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- 28 4.3 SENTENCIA switch() ------------------------------------------------------------------------------------------------------------------------------------------------------------- 32
Capítulo #5 Estructuras Repetitivas 5.1 SENTENCIA for() for() --------------------------------------------------------------------------------------------------------------------------------------------------------------------5.1.1 Programas Programas con for() for() y, sentencias sentencias de entrada entrada y salida salida de datos: printf() y scanf()5.1.2 Programas Programas con for() for() e if() if() ----------------------------------------------------------------------------------------------------------------------------5.1.3 Programas con for() e if()’s anidados --------------------------------------------------5.2 CICLO do{…PROCESO…}while(condici do{…PROCESO…}while(condición); ón); ---------------------------------------------------5.3 CICLO while(condición){…PROCESO…} while(condición){…PROCESO…} -------------------------------------------------------5.4 SENTENCIA break; break; ----------------------------------------------------------------------------------------------------------------------------------------------------------------5.5 SENTENCIA continue; --------------------------------------------------------------------------------------------------------------------------------------------------------5.6 PROBLEMAS PROPUESTOS ----------------------------------------------------------------------------------------------------------------------------------------
34 35 37 39 41 43 43 43 44
Capítulo #6 Funciones Definidas por el Usuario sin Parámetros -------------------------------------------------------------------- 46 Capítulo #7 Arreglos de Memoria 7.1 ARREGLOS DE MEMORIA UNIDIMENSIONALES ------------------------------------------------------------------------------------- 52 7.2 PROBLEMAS PROPUESTOS ------------------------------------------------------------------------------------------------------------------------------------------ 56 7.3 ARREGLOS DE MEMORIA BIDIMENSIONALES ----------------------------------------------------------------------------------------- 61 7.4 PROBLEMAS PROPUESTOS ------------------------------------------------------------------------------------------------------------------------------------------- 63
Capítulo #8 ----------------------------------------- 64 Funciones Definidos por el Usuario con Parámetros ---------------------------RECURSIVIDAD --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 68
Capítulo #9 Apuntadores, Tipos de Datos Definidos por el Usuario y Archivos de Datos 9.1 APUNTADORES ------------------------------------------------------------------------------------------------------------------------------------------------------------------------9.1 Conceptos Básicos -------------------------------------------------------------------------------------------------------------------------------------------------9.1.2 Declaración Declaración de Apuntadores Apuntadores ----------------------------------------------------------------------------------------------------------------------9.2 TIPOS DE DATOS DEFINIDOS POR EL USUARIO ---------------------------------------------------------------------------------9.3 ARCHIVOS DE DATOS -----------------------------------------------------------------------------------------------------------------------------------------------------9.3.1 Apertura y Cierre de un Archivo Archivo -------------------------------------------------------------------------------------------------------------9.3.2 Creación de un Archivo -----------------------------------------------------------------------------------------------------------------------------------
69 69 70 71 74 74 75
Capitulo #10 Aplicación de los Archivos de Datos 10.1 PROGRAMAS QUE INVOLUCRAN ARCHIVOS DE DATOS ---------------------------------------------------------10.2 PROGRAMAS DE CORTE DE CONTROL CONTROL -------------------------------------------------------------------------------------------------------10.3 PROGRAMAS DE ALTAS, BAJAS Y CAMBIOS ----------------------------------------------------------------------------------------10.3.1 Procesamiento Procesamiento de un Archivo ------------------------------------------------------------------------------------------------------------------
78 85 90 91
Capítulo #1 Introducción 1.1. PRESENTACIÓN Saber programar es una herramienta imprescindible para cualquier profesionista, más en el área de la ingeniería, pues le permite solucionar problemas complejos mediante la realización de cálculos matemáticos que procesan grandes cantidades de datos. En los últimos años ha habido una mayor tendencia al uso de C entre programadores profesionales. Entre Entre las muchas razones de la popularidad popularidad de C están las siguientes:
C es un lenguaje de programación estructurado, de alto nivel, flexible y orientado a funciones. C tiene ciertas características de bajo nivel de las que sólo se dispone normalmente en ensamblador o en lenguaje máquina. Los programas escritos en C son transformados por los compiladores en pequeños programas objeto que se ejecutan eficientemen e ficientemente. te. Existen compiladores de C comerciales para la mayoría de las computadoras personales, minicomputadoras minicomputadoras y grandes computadoras. C no depende en gran manera de la máquina. Los programas escritos en C se pueden llevar fácilmente de una computadora a otra.
Durante mi estancia como estudiante en la F.I.M.E.-U.A.N.L. aprendí a programar en FORTRAN, BASIC y COBOL, todos estos lenguajes eran no estructurados. Una vez que terminé la carrera y comencé a impartir cátedra, me correspondió enseñar PASCAL, QUICKBASIC y COBOL. Tanto PASCAL como QUICKBASIC ya incluían características de la programación estructurada; la diferencia radica en que en la programación programación estructurada las instrucciones se ejecutan de manera secuencial y esta secuencialidad no se ve interrumpida en ningún momento. Un lenguaje estructurado tiene además instrucciones repetitivas y selectivas ; todas ellas con un principio y un fin bien claro y definido. La principal instrucción que rompe con la secuencialidad de un programa es la sentencia goto, por eso su uso ya ha sido descontinuado. Ahora, en la F.I.M.E. ya impartimos Lenguaje C, Visual Fox Pro y Progress, todos ellos soportan la programación estructurada, aunque aunque en el caso caso de Visual Fox Pro y Progress también soportan soportan la Programación Programación Orientada a Objetos. La realización de este libro, es el resultado del esfuerzo coordinado de cada uno de los autores; esperamos sea un apoyo que le permita, al estudiante, visualizar en forma práctica práctica las instrucciones más importantes y utilizadas para comprender y aprender la filosofía de la Programación Estructurada.
Atentamente I.A.S. Edgar Danilo Domínguez Vera, M.C.
Maestro en Ciencias de Administración Administración con especialidad en Sistemas
1.2. DEFINICIÓN DE PROGRAMACIÓN DE COMPUTADORAS. Es muy difícil dar una definición de lo que es la programación por lo que comenzaré por decir que la programación no es una ciencia exacta, aquí no hay soluciones únicas, un problema puede ser resuelto por programación, sin embargo, puede puede haber programas programas diferentes que solucionan el mismo mismo problema. problema.
En la programación no hay reglas estrictas porque no se trata de aplicar una fórmula. Es inútil tratar de aprender a programar por memorización. En la programación hay herramientas y el objetivo es usar esas herramientas con un orden lógico que nos ayuden a resolver un problema. Mucho se ha discutido acerca de que la programación es un arte. Hay algo de verdad en lo anterior pero también es ciencia porque trata de entender la realidad y procura desarrollar una solución mediante técnicas y métodos ya existentes. Por lo tanto, podemos decir que la programación de computadoras es la habilidad de interpretar un problema; llevar ese problema a un nivel de abstracción tal que permita desarrollar un algoritmo de solución que posteriormente pueda convertirse en un código que sea interpretable por una computadora . 1.3. HISTORIA DEL LENGUAJE “C” El lenguaje C es un lenguaje de alto nivel que combina el poder de un lenguaje ensamblador con la facilidad de uso y portabilidad de un lenguaje de alto nivel. Fue desarrollado en 1972 en los laboratorios de Bell de AT & T. Fue diseñado por Dennis Ritchie como un lenguaje en el cual se escribió el sistema operativo UNIX. Originalmente fue usado para programar sistemas operativos. Sin embargo, con el transcurso de los años debido a su flexibilidad y su poder, junto con la disponibilidad de compiladores C de alta calidad, para todo tipo de computadoras de todos tamaños, se ha hecho popular en la industria, para una gran cantidad de aplicaciones. Un lenguaje estándar es el que describe todas las construcciones y especificaciones de su sintaxis para que puedan ser ejecutadas en cualquier computadora. El lenguaje C estándar usualmente llamado ANSI fue adoptado por el Instituto de Estándares Nacionales Americanos (ANSI) en 1989.
1.4. MÉTODO A SEGUIR PARA LA SOLUCIÓN DE PROBLEMAS Ya que una computadora no piensa, para que realice un trabajo útil debemos proporcionar una serie de instrucciones, las cuales forman un programa. Pero programar implica más que una lista de instrucciones. La solución de problemas es un componente crucial de la programación. Antes de escribir un programa para la solución de un problema en particular, debemos considerar cuidadosamente todos los aspectos del problema y luego, desarrollar y organizar una solución. Antes de hacer tus propios problemas debes aplicar el siguiente método para la solución del problema propuesto. 1. Especificar los requerimientos. Esto consiste en establecer el problema y entenderlo claramente, así como determinar con precisión lo que se requiere para su solución. Se debe descartar todo lo que no es importante y llegar a la raíz del mismo, y si después de esto, el problema no queda totalmente definido debemos pedir más información a la persona que quiere resolverlo. 2. Análisis. El análisis consiste en identificar las entradas del problema (datos conocidos), las salidas deseadas (datos que se desean conocer) y cualquier requisito o restricción adicional para lograr la solución. Identificar qué información es proporcionada por los datos del problema y qué resultados se deben computarizar y desplegar. 3. Diseño . Lo siguiente es desarrollar una lista de pasos a seguir para la solución del problema llamada ALGORITMO y verificar que el algoritmo resuelva el problema como se intenta. Escribir el algoritmo es la parte más difícil del proceso de solución de problemas. 4. Una vez que se tenga el algoritmo hay que verificar que sea correcto antes de seguir adelante. 5. Implementación. Implementar el algoritmo como programa. Se requiere conocer un lenguaje de programación ya que cada paso del algoritmo se convierte a una o varias líneas de código en el lenguaje seleccionado. 6. Verificación y Prueba. Probar el trabajo completo y verificar que trabaja como se esperaba usando diferentes conjuntos de datos.
1.5. MÉTODOS PARA LA ELABORACIÓN DE ALGORITMOS.
Hay dos métodos para la elaboración de algoritmos: Diagramas de flujo y pseudo código .
Para la elaboración de diagramas de flujo se utilizan una serie de símbolos que representan una acción computacional, tales como entrada de datos, impresión de datos, operaciones matemáticas, selección de alternativas, repetición de pasos, etc. Es conveniente tomar en cuenta las siguientes reglas generales para la elaboración de diagramas de flujo: 1. Utilice símbolos estandarizados 2. Desarrolle el diagrama de flujo de tal forma que se lea de arriba hacia abajo y de izquierda a derecha siempre que sea posible. No cruce líneas de flujo. Use puntas de flechas para indicar dirección. 3. Mantenga el diagrama de flujo claro, legible, simple. Deje suficiente espacio entre los distintos símbolos. Si la solución a un problema es larga y compleja, divídala en varios diagramas de flujo. 4. Escriba mensajes sencillos para describir los distintos pasos a lo largo del diagrama de flujo. 5. Escriba en forma clara y legible los símbolos. El pseudo código es una especie de lenguaje de programación que permite escribir: entrada de datos, impresión de datos, operaciones matemáticas, selección de alternativas, repetición de pasos etc. Recuerde que todas las computadoras digitales, independientemente de su tamaño, son básicamente dispositivos electrónicos que pueden transmitir, almacenar y manipular información (datos).
1.6. EJECUCIÓN DE UN PROGRAMA. La ejecución de un programa supone lo siguiente: 1. Un conjunto de información conocida, los datos de entrada, se introducen en la computadora (desde un teclado, un disquete, un disco duro, etc.) y se almacenan en una porción de la memoria de ésta, tradicionalmente en la memoria RAM. Para entender lo que es la memoria RAM observe la figura donde se representa a una computadora que está pensando, de aquí se deduce que la memoria RAM es un medio de almacenamiento de datos volátil ya que cuando se apaga la computadora, toda información que había en la memoria RAM se pierde, a menos de que la hayamos almacenado en otro dispositivo como un disco. 2. Los datos de entrada se procesarán para producir ciertos resultados deseados que se les llama los datos de salida. 3. Los datos de salida, y probablemente algunos de los datos de entrada, se imprimirán en papel o se presentarán en un monitor.
RAM
Por otro lado, el procesamiento de datos mediante un programa puede representarse con la siguiente figura.
Entrada de Datos
Salida de datos (resultados)
Se introducen datos a la memoria RAM (desde el teclado), ahí mismo de procesan y posteriormente se genera un resultado (se presentan en el monitor o en papel).
1.7 Instalación del Dev-C++.
Ya hemos comentado que el propio Dev-C++ no es un compilador en sí, sino un entorno de programación que utiliza un compilador. Podríamos bajarnos el IDE por un lado, y el compilador por el otro, instalarlo y utilizarlo. Sin embargo teniendo en cuenta que en la página tenemos un paquete que lo reúne todo, será cuestión de aprovechar la circunstancia y no complicarnos la vida. Vamos a la página oficial del Dev-C++: http://www.bloodshed.net/dev/devcpp.html En la sección Downloads tenemos la siguiente versión: Dev-C++ 5.0 beta 8 (4.9.8.0) (12 MB) with Mingw/GCC 3.2 y varios lugares para descargarlo. Pinchamos en cualquiera de ellos y a esperar; son unos 13 megas aproximadamente. Una vez descargado tendremos un ejecutable auto-instalable. Doble clic en él y se podrá a punto. Lo único que tenemos que seleccionar es el directorio de destino así como si queremos iconos en el escritorio, menú inicio o quick-launch. Es recomendable dejar el directorio por defecto (c:\devcpp) o al menos usar una ruta de directorios que no tenga espacios en los nombres de directorios.
Conociendo el entorno.
Antes que nada me gustaría comenzar con la definición de algo con lo que vamos a tratar mucho a lo largo del documento: el concepto de proyecto. Un proyecto no es más que una agrupación de todos los ficheros que requiere una aplicación, así como de su configuración específica. Cuando en el Dev-C++ creamos un proyecto se crea un fichero .dev. Es un fichero de texto que contiene referencias a los ficheros necesarios para compilar nuestra aplicación (ficheros de código, ficheros de encabezado…) así como las opciones necesarias específicas de esa aplicación (como pueden ser referencias a bibliotecas no estándar que se necesitan para compilar).
Una vez ejecutado el programa tendremos algo así:
1. Menú y barras de herramientas Aquí tenemos los menús con los típicos comandos de Windows (abrir, guardar, copiar y pegar…) También tenemos una serie de iconos en las barras de herramientas que no son más que una parte de las opciones que tenemos en los menús, así que por tanto, no creo que haga falta explicarlos uno por uno. Si aún así no te aclaras, puedes dejar el ratón encima de un icono durante unos segundos y aparecerá una ayuda emergente. En ella se incluye una descripción básica y el atajo de teclado asociado a la función del icono, si este existe. (Como veremos, los atajos de teclado también se pueden configurar) 2. Explorador de proyectos y clases e información de depuración. Dependiendo de la pestaña que seleccionemos en esta área tendremos acceso a: a) Explorador de proyectos, que muestra los archivos por los que está formado nuestro proyecto -y por tanto nuestra aplicación- bien sean de código, de encabezados, o de recursos. b) Explorador de clases, una de las funciones más útiles y que ya conoceréis si habéis visto el Visual Studio. En este caso veremos cada una de las estructuras/clases definidas en los ficheros de nuestro proyecto, así como los métodos y datos que forman parte de la estructura/clase, incluyendo sus argumentos y su tipo. También veremos una lista de las funciones globales que tenemos en el proyecto, también con sus argumentos. Pulsando doble clic en un método, función o clase, iremos directamente al archivo y línea donde se ha definido. c) Información de depuración, aquí podremos definir las variables que queramos cuando estemos depurando un programa. 3. Área de edición. Aquí aparecerán los ficheros de código que abras. Puedes tener abierto más de un fichero a la vez, y seleccionarlo por medio de las pestañas que aparecerán en la parte superior de este área. 4. Resultados de la compilación y controles de depuración.
En ésta serie de pestañas encontraremos información acerca del proceso de compilación y depuración. Cuando seleccionemos una pestaña se expandirá para mostrarnos los resultados, al tiempo que aparecerá una nueva pestaña que se sumará a las cinco anteriores: la pestaña Cerrar. Pulsándola volveremos a tener el mismo espacio que teníamos antes. En la pestaña compilador veremos los errores y advertencias que ha generado la compilación de nuestro código (si los hubiera). Pulsando doble clic en uno de ellos nos remitirá directamente a la línea que provocó dicho error o advertencia. En la pestaña resultados del compilador, tendremos toda la salida que genera el compilador gcc (que recordemos se maneja por línea de comandos) Esto también incluye errores y avisos, al igual que en la pestaña anterior. Sin embargo no tenemos la opción del doble clic para ir directamente a la línea que provocó el error.
Menú archivo: - Nuevo: Aquí podemos crear un nuevo fichero de código fuente en blanco (que no es otra cosa que un fichero de texto); un nuevo proyecto seleccionado entre varios tipos un fichero de definición de recursos (los recursos se utilizan en la programación con la API win32); o crear una plantilla a partir del código que tenemos que se convertirá en otro tipo de proyecto. Una plantilla en este caso, es un nuevo tipo de proyecto, que nos sirve de base para empezar a programar. Por ejemplo puedes definir una plantilla “hola mundo” que ya contenga los ficheros y el código necesario para imprimir en pantalla el famoso mensaje. De la misma manera los p rogramas en win32 tienen unas estructuras básicas (función WinMai n, definición e inclusión de encabezados…) que poseen todos los programas. Puedes generar una plantilla, y así no tienes que teclear lo básico cada vez. - Propiedades: Muestra las características de los ficheros del proyecto (o del fichero actual si no hay proyecto) como líneas totales, líneas de código, líneas comentadas, tamaño… - Importar: Solo tenemos la opción de importar un proyecto de Visual C++. Lo que hace esta opción es transformar el proyecto de visual C++ en un proyecto de Dev-C++, con sus dependencias de bibliotecas y ficheros de código, pero no trasforma el código para que sea posible su compilación directamente con DevC++. Sólo lo he probado con proyectos simples y funciona bastante bien. Cabe decir que es inútil trasformar un proyecto de Visual C++ que utilice MFC, ya que Dev-C++ no tiene soporte para ellas. Su mayor utilidad reside en trasformar un proyecto que utilice las API Win32, que sí soporta el compilador. - Exportar: Podemos exportar el fichero de código actual a un fichero HTML o RTF, o exportar el proyecto a HTML. Puede ser útil para la distribución o para colgar el código en una página web de forma ordenada. Menú Edición: - Insertar: Tenemos las opciones de insertar la fecha y hora actual o una plantilla de una cabecera básica para la descripción del fichero fuente. Sin embargo podemos agregar nuestros propios elementos a este menú. Más adelante veremos cómo hacerlo. El icono insertar que aparece en una de las barras de herramientas cumple la misma función que éste menú. - Intercambiar header/source : Conmuta entre los archivos de código fuente y su archivo de encabezado asociado. Para que esto funcione, ambos archivos deben tener el mismo nombre, y cambiar solamente en su extensión (Por ejemplo: main.cpp y main.h) Esta opción también está disponible haciendo clic derecho en el área de edición y seleccionando la misma opción (siempre que tengamos un fichero abierto, claro) - Añadir o quitar marcador / ir a marcador. Sirve para crear una marca en una línea concreta de un fichero de código (no tienen porqué estar todas en el mismo fichero) para luego desplazarnos a ella de una forma más rápida. También tenemos un icono en la barra de herramientas con esta función. - Agregar comentario: Agrega un comentario de C++ ( // ) si hacemos una selección y elegimos esta opción, comentará todas las líneas de la selección. - Quitar comentario : Realiza la función contraria a la anterior. - Poner/quitar margen: Hace una sangría a la línea/selección.
Menú Búsqueda: Tiene las opciones típicas de búsqueda y reemplazo. Cabe destacar una función de búsqueda en varios ficheros, así como los comandos Ir a línea y el siempre útil comando Ir a función, que busca entre las funciones del fichero actual.
Menú Ver:
Nada del otro mundo. mundo. Podemos seleccionar seleccionar qué barras de herramientas herramientas queremos queremos que muestre el Dev-C++, así como si queremos que muestre el explorador de proyectos/clases. También podemos elegir si queremos que el explorador de proyectos y clases, así como los resultados del compilador; se muestren anclados al programa principal (por defecto) defecto) o como como una ventana aparte. Por último podemos podemos cambiar las opciones de los resultados resultados del compilador para que esté siempre visible, o sólo cuando sea necesario (es decir, cuando compilemos nuestro programa y surjan surjan errores o advertencias) advertencias) Yo os recomiendo la segunda opción.
Menú Proyecto: - Nuevo código fuente: crea un nuevo fichero de código que se añada automáticamente al proyecto. Cuando lo salves por primera vez te pedirá el nombre del fichero. - Añadir al proyecto: permite añadir ficheros al proyecto. - Quitar del proyecto : muestra un cuadro de diálogo con los ficheros pertenecientes a nuestro proyecto para poder eliminar eliminar los que queramos queramos (se eliminan eliminan del proyecto, proyecto, no se borran de su ubicación) ubicación) - Propiedades del proyecto: para cada proyecto podemos definir unas opciones diferentes de las comunes a las definidas en el compilador. co mpilador. Por ejemplo podemos vincular con más bibliotecas, añadir ‘flags’ de compilación o activar la depuración, de forma que todas estas configuraciones sólo se aplicarán a nuestro proyecto.
Menú Ejecutar: ejecutable/librería. Como ya dije los - Compilar: compila y vincula el fichero o el proyecto entero para crear el ejecutable/librería. archivos que no fueron modificados no son recompilados. - Compilar el archivo actual : compila el fichero que estás editando actualmente. No se vincula. - Ejecutar: Ejecuta el programa (si existe ejecutable) ¡Ojo! Este comando no compila, por lo que si has modificado tu programa, pero no lo recompilas, y le das a este botón (suponiendo que ya tuvieras un ejecutable en el directorio de trabajo) ejecutará la versión anterior. Puede parecer una tontería, pero considerando que me ha pasado unas cuantas veces (la mayoría de las cuales han acabado en intentos de suicidio) creo que es mejor recalcarlo. - Parámetros: Si queremos que nuestro ejecutable reciba algún tipo de parámetro se pone aquí. Sólo los parámetros, no no hace falta repetir repetir de nuevo nuevo el nombre del ejecutable. ejecutable. - Compilar y ejecutar : Compila, vincula y automáticamente ejecuta el programa (si no hubo ningún error, claro) - Reconstruir todo : Borra todos los archivos de código objeto, para recompilar todos los ficheros de código fuente. También vincula todos. En definitiva, reconstruye el proyecto de cero. Se consigue el mismo efecto que pulsando “Limpiar “Limpiar resultados” y luego “Compilar” “Compilar” en este mismo mismo menú. - Revisar sintaxis : Comprueba si la sintaxis del código es correcta. No genera código objeto alguno. Es lo mismo que invocar al compilador con la opción -fsyntax-only - Limpiar resultados : Borra todos los archivos de código objeto y el ejecutable, si existen. - Análisis de perfil . Muestra la información del profiler, que consiste en datos estadísticos acerca de las funciones del programa, como el número de veces que son llamadas, el tiempo que tardan en ejecutarse, el porcentaje de tiempo tiempo total del programa programa que que se ejecutan… etc. Sirve Sirve para encontrar las funciones funciones más más utilizadas utilizadas o más lentas, con el fin de optimizar éstas. Aunque el IDE contempla estas opciones, no funcionan correctamente en esta versión, aunque cuando actualicemos el programa a la versión 4.9.8.5 funcionarán correctamente. - Reiniciar ejecución del programa : Esta opción sólo está disponible si estás ejecutando tu programa. Selecciónalo para reiniciar el programa.
Menú depurar: Ya que veremos este asunto más delante de forma detallada, no me voy a extender mucho. Espero que las explicaciones que no se entiendan ahora sean respondidas entonces. - Depurar: Creo que está claro, ¿no? Inicia la depuración del proyecto. ☺ - Parar ejecución. Finaliza la ejecución del programa, así como el modo depuración. - Parámetros. Igual que la opción del menú compilar, pero sólo se aplica cuando estemos depurando el proyecto.
- Añadir quitar punto de ruptura: Añade un breakpoint, es decir, un punto en el cual la ejecución del programa se detendrá. - Siguiente paso: Siguiente instrucción del programa - Avanzar paso a paso: Igual que el anterior, pero ejecuta los pasos dentro de un procedimiento. - Saltar paso: Esta opción debería ser traducida como continuar. Continúa la ejecución del programa hasta que se encuentre otro breakpoint o finalice. - Ir a cursor: Se ejecuta el programa hasta que llegue al punto donde está el cursor (si no hay un breakpoint antes) - Añadir watch : Abre un cuadro de diálogo para introducir la variable que queremos observar en tiempo de ejecución. La variable y su contenido aparecerá en el área 2 (siempre que tengamos seleccionada esa pestaña. - Observar variables: Selecciona la l a pestaña ‘Depurar’ del área 2. - Ver ventana del CPU: Debug avanzado ☺ Podemos observar los registros de la máquina en un momento de la ejecución.
Menú Herramientas Aquí tenemos las opciones de configuración del IDE y del compilador. También tenemos algunas herramientas ya incluidas con el programa, aunque también podemos agregar objetos a este menú para definir nuestras propias herramientas, herramientas, y tenerlas tenerlas a mano.
1.8. PASOS PARA EJECUTAR (CORRER) UN PROGRAMA. 1. Escribir el código en la pantalla de edición. 2. grabar el programa en un disco y asignar un nombre, el cual debe ser de máximo ocho caracteres, sin espacios, acepta letras, números y guiones medios, tal y como se muestra en la siguiente figura.
3. Compilar hasta quitar todos los errores de sintaxis, para esto tendrá que corregir, grabar el programa y volver a compilar hasta que ya no halla errores. Para compilar el programa deberá activar la primera opción que está en el menú Compile . Cuando ya no hay errores de sintaxis aparecerá una caja de diálogo como en la siguiente figura
4. Correr el programa y verificar los resultados en la pantalla de ejecución. Para ejecutar el programa deberá activar la primera opción que está en el menú Run. Los resultados del programa aparecerán en la ventana de ejecución como en la siguiente figura.
Capítulo #2 Variables, Constantes, Operadores y Expresiones Las variables se utilizan para expresar una solución generalizada a un problema, por el contrario las constantes dan una solución particularizada. Esto es, la siguiente operación:
507 + 8 9 = 596 está compuesta por dos constantes los números 507 y 89, y que por estar en una ecuación matemática se les llama operandos, mismos que al sumarse generan una tercer constante que es 596. Además, la operación está compuesta por dos operadores, el signo de más y el igual. La anterior expresión, es una solución particular que involucra a dos números. Sin embargo, para representar una solución generalizada tendríamos que utilizar variables, entonces tendríamos lo siguiente:
C=A+B De esta forma, la expresión anterior involucra a tres variables (operandos), estas son A, B y C, de esta manera, se representa una solución generalizada ya que se puede dar diversos valores para A y B, generando un valor diferente para C. En un programa computacional, se hace uso de variables, constantes y operadores. De esta forma, se genera un programa que puede solucionar muchos problemas de un mismo tipo, esto se debe gracias a las variables.
2.1. LAS VARIABLES Ahora bien, las variables deben recibir un nombre para poder identificarlas, obviamente, a estos nombres se les llama identificadores. En Lenguaje C un identificador puede tener de uno a varios caracteres (letras, números o subrayados). El primer caracter debe ser una letra o un subrayado. Aquí hay ejemplos de identificadores correctos e incorrectos. No se recomienda que los nombres de identificadores tengan más de 32 caracteres porque lenguaje C ya no reconoce los caracteres posteriores.
Correcto Contador
Incorrecto 8contador
Prueba23 Alto_balance
Hola!tu Alto..balance
2.1.1. Tipos de Datos
Las variables se deben declarar antes de ser utilizadas en un programa, generalmente al principio del mismo ó de una función y antes de cualquier proposición ejecutable. Una declaración de variable notifica sus propiedades . Consta de un nombre de tipo y uno o varios nombres de identificadores. Los tipos de datos en C son: Tipo char int float double void
Descripción Carácter Entero Real simple precisión Real doble precisión Nulo o Vacío
Ancho en bits 8 16 32 64 0
Bytes 1 2 4 8
Rango -128 a 127 -32,768 a 32,767 3.4 E-38 a 3.4E+38 1.7E-308 a 1.7E+308 Sin valores
a) Se usan variables tipo caracter ( char) para guardar caracteres ASCII, éstos pueden ser letras, números o caracteres especiales, sin embargo, una variable char que contiene números no se puede utilizar en operaciones matemáticas algebraicas. b) Las variables tipo enteras ( int) se usan para cantidades numéricas enteras, es decir, que no necesitan decimales, con este tipo de variables se controlan los ciclos repetitivos como for() y do{..}while(). c) Se usan variables reales (también llamadas de punto flotante) de simple y de doble precisión ( float y double) para valores numéricos que requieran fracción decimal o cuando la aplicación requiera de valores grandes. La diferencia entre float y double es la magnitud del número más grande (o más pequeña) que pueden almacenar, esto es, una variable double puede almacenar un número aproximadamente diez veces más grande que un float. d) Se usan variables tipo void para ayudar a mejorar la comprobación de tipos, se discutirá más adelante.
2.1.2. Modificadores del Tipo de Datos
Excepto para void, los tipos básicos tienen varios modificadores que los preceden. Se usa un modificador para alterar el significado de un tipo base y que pueda encajar con las necesidades de diversas situaciones. Los modificadores son: signed unsigned long short Se pueden aplicar los modificadores signed, unsigned, long y short para los tipos base char (caracter) e int (entero). Sin embargo, se puede aplicar también long a double. Enseguida, se muestra una lista de ejemplo de la forma en cómo se declaran variables.
long int matricula; char nombre[30], hora[3]; float calficacion1, calificacion2, promedio; int grupo, salon, frecuencia_semana; En el ejemplo anterior tenemos la variable matricula como larga entera ( long int), es decir, esta variable no acepta decimales porque su tipo base es entera ( int), pero además se le agregó el modificador del tipo de datos de largo ( long). Con esto es posible dar valores con 6 o 7 dígitos. Si la variable matricula fuera solamente entera ( int), no podríamos dar valores grandes porque estaríamos fuera de rango (-32,768 a 32,767). Tenemos la variable nombre de tipo caracter ( char) con una longitud de 30, esto implica que podemos manejar nombres con máximo 30 posiciones, contando letras y espacios en blanco, aunque es conveniente utilizar sólo 29 de ellos para dejar un caracter de control propia de lenguaje C. Posteriormente se explicará su uso. Dado que la variable hora aceptará valores como M1, M2,M3…V1,V2..N1,N6, entonces es de tipo caracter con tres posiciones, dejando la última posición para el caracter de control. La variables calificacion1, calificacion2 y promedio pueden presentarse con decimales, por eso se declararon como reales ( float). La variable grupo aceptará valores como 01,02,03…15 o más pero en ningún momento aceptará valores mayores a 32,767 por lo tanto es de tipo entero ( int). La variable salon recibirá valores como 1101, 1102, 2101, 2202, 3101…etc. y por el mismo motivo que la anterior variable, es de tipo entero ( int). Finalmente, la variable frecuencia_semana también es entera e indica cuantas horas de clase de esa materia se imparten por semana, por ejemplo, Programación Básica y Programación Avanzada I y II tienen una frecuencia de 3 horas-clase por semana, hay otras materias que serán de 2 ó 5 horas-clase, pero ninguna se imparte 2.5 o 3.40 horas-clase por semana, es decir, no hay fracciones de hora.
2.1.3 Turbo C es sensible al Tamaño de las Letras Turbo C es sensible al tamaño de las letras, es decir, en el ejemplo anterior tenemos a la variable matricula , escrita con letras minúsculas, sin embargo, turbo C no es capaz de reconocer a Matricula o MATRICULA como la misma variable, de este modo, se debe tener cuidado que durante toda la codificación de un programa, la variable se utilice de la misma forma de cómo fue declarada.
2.2. LAS CONSTANTES
En Turbo C las constantes se refieren a los valores fijos que el programa no puede cambiar; ejemplos de constantes en la solución de un problema hay muchos, tal como: la gravedad (9.8 m/s2 ó 32 ft/s2), el valor de PI (3.1416), etc. De esta forma, las constantes pueden ser de cualquier tipo básico. Las constantes caracter están encerradas entre comillas simples. Por ejemplo, ‘a’, ‘%’. Las constantes enteras son números sin componente decimal y las constantes reales requieren el uso del punto y la fracción decimal. Tipo de dato char int long int short int unsigned int float double
Constante de Ejemplo ‘a’, ‘\n’, ‘9’ 1, 123, 2100,-234 37950, -51452 10, -12, 90 10000, 987, 17953 123.23, 4.3e-3 123.23, 12312333, -0.9876324, 1.0E100
Las constantes dentro de un programa en Lenguaje C se declaran con la instrucción #define seguido del nombre de la constante en mayúscula y el valor que tomará dicha constante. Sintaxis #define nombre valor Ejemplos: #define MILLAS 0.62137 #define PI 3.1416 #define MAX_LONGITUD 100
2.2.1. Constantes Hexadecimales y Octales Lenguaje C permite especificar constantes enteras en hexadecimal u octal en vez de decimal. Una constante en hexadecimal debe comenzar por 0x (un cero seguido por una equis). Una constante octal empieza con cero. Estos son algunos ejemplos: int hex=0xFF int oct=011 La primer constante hexadecimal es equivalente a 255 en decimal y la segunda constante en octal equivale a 9 decimal.
2.2.2. Constantes de Cadena
Turbo C soporta otro tipo de constante además de las de tipos de datos predefinidos: la cadena de caracteres. Una cadena es un conjunto de caracteres que se encierran entre comillas dobles. Por ejemplo, “esto es una prueba”. No se debe confundir las cadenas con los caracter, esto es, una constante caracter se encierra en comillas simples: ‘a’, sin embargo, “a” es un a cadena que contiene una sola letra.
2.2.3. Constantes de Caracteres de Diagonal Invertida El uso de comillas simples para encerrar todas las constantes de caracteres funciona para la mayoría de los caracteres imprimibles, pero algunos, como retorno de carro es imposible introducir por teclado. Por esta razón , Lenguaje C proporciona las constantes especiales de caracter de diagonal invertida
Código \b
Significado Retroceso
\f \n \r \t \” \’ \0 \\ \v \a \N \x
Alimentación de hoja Nueva línea Retorno de carro Tabulador horizontal Doble comilla Simple comilla Nulo Diagonal invertida Tabulador vertical Alerta Constante octal (N es constante octal) Constante hexadecimal
Nota: La constante \n significa avance de línea y retorno de carro, en pocas palabras, es la tecla .
2.3. OPERADORES Un operador es un símbolo que le dice a la computadora que realice manipulaciones matemáticas o lógicas específicas. Lenguaje C tiene tres clases generales de operadores: aritméticos, relacionales y lógicos, y sobre bits. Además tiene algunos operadores especiales para tareas particulares
2.3.1. Operadores Aritméticos Los operadores aritméticos son:
Operador + * / % -++
Acción Resta Suma Multiplicación División Módulo división (residuo) Decremento. Menos unario Incremento. Más unario.
Estos operadores se pueden subdividir en unarios (++, - - ) y binarios (+,-,*,/, %) Hay dos operadores binarios que se refieren a una división: / y %, sin embargo, cuando se aplica la división (/) a enteros o caracter el resultado se trunca, por ejemplo, 10/3 será igual a 3 en la división entera. El operador módulo de la división (%) recoge el resto (residuo) de una división entera y tiene como restricción que no se puede usar sobre tipos float o double. El operador + + añade un uno a su operando y, - - le resta uno, por lo tanto las siguientes operaciones son equivalentes. X + + es equivalente a X = X + 1 X - - es equivalente a X = X – 1 Ahora bien, estos operadores pueden preceder o seguir al operando, es decir X=X+1 se puede dar como X++ o ++X En el primer caso se denomina posincremento y en el segundo caso se denomina preincremento, de esta manera si tenemos: X = 10 Y = ++X
El valor de Y sería 11, porque C incrementa primero X y después lo asigna a Y, pero si tuviéramos X = 10 Y=X++ El valor de Y sería 10 y después se incrementaría X. En ambos casos, X estaría a 11, la di ferencia está en el momento en que se hace, sí antes o después de la asignación.
2.3.1.1 Reglas para la Evaluación de Expresiones Aritméticas 1. Todas las subexpresiones deben ser evaluadas por separado. Las subexpresiones dentro de paréntesis tienen prioridad por encima de todas las demás. 2. La regla de prioridad de los operadores dice que los operadores en la misma subexpresión son evaluados en el siguiente orden unario ++, - - primero binario *, /, % enseguida binario +, al último 3. La regla de la asociatividad dice que los operadores unarios en la misma subexpresión y en el mismo nivel de prioridad, tales como ++ y - -, son evaluados de derecha a izquierda (asociatividad a la derecha). Por otro lado, los mismos operadores binarios en la misma subexpresión y en el mismo nivel de prioridad, tales como + y -, son evaluados de izquierda a derecha (asociatividad a la izquierda). 4. Para alterar los niveles de prioridad se pueden usar paréntesis. De esta forma, las subexpresiones dentro de paréntesis anidados se evalúan de las más interna a la más externa
2.3.2. Operadores Relacionales y Lógicos
Los operadores relacionales se refieren a las relaciones que los valores pueden tener unos con otros, y los lógicos se refieren a la manera en que tienen lugar estas relaciones. La clave de los conceptos relacionales y lógicos es la idea de falso y verdadero. En Lenguaje C, verdad es cualquier valor distinto de cero, mientras que cero es falso . De esta forma, las expresiones que usan operadores relacionales y lógicos devolverán 0 para falso y 1 para verdadero. Se usan los operadores relacionales para determinar las relaciones de una cantidad con otra. Siempre devuelven 1 ó 0, dependiendo del resultado de la prueba. A Continuación tenemos los operadores a los que nos hemos referido Operadores Relacionales Operador Acción > Mayor que >= Mayor o igual que < Menor que <= Menor o igual que == Igual != No igual Operadores Lógicos Operador Acción && AND || OR ! NOT Los operadores lógicos se usan para soportar las operaciones básicas de AND, OR, NOT de acuerdo con la siguiente tabla de verdad que usa 1 para verdad y 0 para falso. p 0 0 1
Q 0 1 1
p AND q 0 0 1
p OR q 0 1 1
NOT p 1 1 0
1
0
0
1
0
Los operadores relacionales y lógicos tienen menor prioridad que los aritméticos. Esto significa que C evalúa una expresión como 10 > 1 + 12 como si se escribiera 10 > (1+12) , el resultado de esta expresión es cero, es decir, falso. Así, 5==1 generará un cero que es falso, y 5>1 generará un uno, que es verdadero. Lenguaje C permite combinar varias operaciones en una expresión como se muestra aquí: 10 > 5 && ! ( 10 < 9 ) || 3<= 4, esta expresión será verdad. solución: 10>5 =1; 10<9=0 pero cambia a 1 por ! y finalmente 3<=4 = 1, entonces tenemos que: 1 && 1 || 1 que equivale a verdad
La prioridad relativa de los operadores relacionales y lógicos es la siguiente: Más alto Más bajo
! >, >=, <, <= = =, != ||, &&
2.3.3. Operador de Asignación
El operador de asignación es el signo igual (=), este operador es el que se utiliza para referirse a fórmulas matemáticas, no debe confundirse con el doble igual ( = = ) el cual es un operador relacional. Es conveniente recordar la diferencia entre una fórmula y una ecuación matemática. Una fórmula es aquella en cual una variable está completamente despejada, por el contrario, una ecuación puede tener operadores y operandos en ambos lados de la igualdad. Ejemplo de fórmulas matemáticas Fuerza = masa * aceleracion Area = base * altura / 2 Volumen = alto *largo * ancho Ejemplo de ecuaciones matemáticas 3 x 2 + 3 y = 2 k + 5 C 2 = A 2 + B 2
En Lenguaje C cuando se trata de fórmulas matemáticas, antes de un operador de asignación debe haber una variable completamente despejada y no puede haber operadores de ningún tipo, porque entonces ya no sería una fórmula sino una ecuación matemática.
2.4. EXPRESIONES ARITMÉTICAS
Los operadores, constantes y variables constituyen las expresiones aritméticas ó fórmulas. Una expresión en lenguaje C es cualquier combinación válida de estas piezas. Cuando se mezclan constantes y variables de diferentes tipos en una expresión, lenguaje C las convierte al mismo tipo. El compilador convertirá todos los operandos al tipo de operando más grande según la base de esta operación, tal como se describe en estas reglas de conversión de tipos. a) Todos los char y short int se convierten a int. Todos los float a double. b) Para todo par de operandos, lo siguiente ocurre en secuencia. Si uno de los operandos es un long double, el otro se convierte a long double. Si uno de los operandos es double, el otro se convierte a double. Si uno de los operandos es long, el otro se convierte a long. Si uno de los operandos es unsigned, el otro se convierte en unsigned.
Se puede forzar a una expresión a ser de un tipo específico usando la construcción llamada cast . El formato general de un cast es: (tipo de dato) expresión donde tipo es uno de los estándar de datos de lenguaje C. Por ejemplo si X es un entero y se quiere uno asegurar que la computadora evaluaría las expresión X/2 como de tipo float para garantizar un componente fraccional, se escribiría (float) X / 2 Aquí el cast (float) se asocia con X, que provoca que la computadora convierta al 2 a float también y el resultado será float. Sin embargo, se debe ser cuidadoso si se trata de escribir el cast de esta forma (float) (X/2) En este caso, la computadora trae una división entera y convierte el resultado de esa a float. Los cast son útiles cuando la variable que controla un ciclo, como for() la cual debe ser forzosamente entera, se requiere para realizar una operación de tipo float, por ejemplo:
int I; float K; for(I=1; I<=100; I++) { K = (float) I/3; }
2.5. ESCRIBIENDO FÓRMULAS MATEMÁTICAS EN C Fórmula
En C se escribe
A=BC
A=B*C
m=
y b x c
m=(y-b)/(x-c)
d = b2 – 4ac
d =b*b-4*a*c
D=A+B+C
D=A+B+C
1
K= 1
K=1/(1+sqrt(X))
X
Fórmula
En C se escribe
A=BC
A=B*C
o
d=pow(b,2)-4*a*c
Fórmula
En C se escribe
m=
y b xc
m=(y-b)/(x-c)
Fórmula d = b2 – 4ac
En C se escribe d =b*b-4*a*c o d=pow(b,2)-4*a*c
Fórmula D=A+B+C
En C se escribe D=A+B+C
Fórmula
En C se escribe
1
K= 1
X
K=1/(1+sqrt(X))
Capítulo #3 Operaciones de Entrada-Salida de Datos 3.1. ESTRUCTURA GENERAL DE UN PROGRAMA EN LENGUAJE ‘C’ Antes de seguir adelante, daremos un panorama general de la estructura de un programa en lenguaje C. La primera parte de un programa en C son las directivas del preprocesador que empiezan con el símbolo “ #” y que son utilizadas por el preprocesador para que el compilador sepa que son instrucciones que debe obtener de las bibliotecas o archivos que tiene lenguaje C, listos para usarlos, tales como que proporciona a C las bibliotecas estándar de entrada y salida. La directiva de preprocesador va a ser una de las directivas que va a estar presente en la mayoría de nuestros programas, generalmente al principio de estos, su significado es standard input-output, y es necesaria para poder introducir datos al programa y para que éste mande información al usuario, que puede ser en el monitor de la computadora o una impresora. La siguiente parte del programa es la declaración de variables y constantes. En esta sección se establecen los nombres de los identificadores así como su tipo de datos y en algunos casos su longitud . En la última sección del programa se escriben las instrucciones, indicando paso a paso el algoritmo definido para dar solución a un problema. Cabe mencionar que lenguaje C es un lenguaje orientado a funciones, donde la función principal es llamada main() (principal), esta función estará presente en todos los programas que se realicen. Enseguida, se dará un pequeño programa de ejemplo y se le pide al alumno que “corra ó ejecute” el programa.
Diagrama 3-1.
/* prog3-1.c */ #include main() { int edad; edad=37; printf("Mi edad es de %d a¤os \n",edad); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
El anterior programa se desglosa de la siguiente manera
a) la primer línea /* prog1.c */ es un comentario. Los comentarios sirven en un programa para ayudar, a una persona que vea el código, a entenderlo. Antes del comentario se coloca “ /* ”, enseguida se escribe el comentario, y al final del mismo se coloca “*/”. Los comentarios pued en ir en cualquier parte de un programa y no tienen ejecución alguna dentro de un programa. En este caso particular, el comentario de este programa nos ayuda a saber que el nombre del programa es prog3-1.c. b) La segunda línea #include , es la directiva del prepocesador que ya explicamos en párrafos anteriores. c) La tercer y cuarta línea, main() y { , indican el inicio del programa.. d) La quinta línea int edad; , indica que se declara una variable que se utilizará en el programa, esta variable se llama edad y es de tipo entero, es decir, no aceptará números decimales. e) La sexta línea edad=37; , indica que a la variable edad se le asigna el valor de 37, es decir, se le da el valor de 37. f) La séptima línea printf("Mi edad es de %d años \n",edad);. printf() es una función que envía datos a la pantalla de la computadora. El mensaje, que está encerrado entre comillas, aparecerá en el monitor de la computadora, el %d es un especificador de formato que permite imprimir valores enteros. El \n es una constante de caracter de diagonal invertida que indica nueva línea g) La octava línea getche(), es una función que en este caso se utiliza para detener la ejecución del programa hasta que reciba un valor y poder ver los resultados del programa. h) La última línea “ } /* fin de la función main() */ “ , la llave “}“ indica el final de la función main(), en este caso particular indica también, el fin de la codificación del programa, y el comentario es para recordar que es el fin de la función main(). i) Todas las líneas que terminan con punto y coma son instrucciones y/o funciones de lenguaje C, sin embargo, se debe tener cuidado porque no todas las líneas de código llevan punto y coma.
3.2. ESPECIFICADORES DE FORMATO Para poder visualizar los valores de las variables se deben utilizar funciones de salida de datos como el printf(), éste debe ir acompañado de especificadores de formato los cuales varían según el tipo de datos que se desee visualizar.
Código
Tipo de dato que visualiza
%d %i %f %c %s %e %g %ld %u %o %p %% %n
Decimal (entero). Decimal. Real o punto flotante de simple precisión. Un solo caracter. Cadena de Caracteres. Notación científica. Usa %e o %f, la que sea más corta. Long o largas enteras. Decimal sin signo. Octal. Puntero. Imprime un signo %. El argumento asociado será un puntero entero en el que pondrá el número de caracteres escritos. Hexadecimal.
%x
3.3. ENTRADA Y SALIDA DE DATOS. Los datos pueden almacenarse en variables de dos formas diferentes, por operaciones de asignación o por el uso de alguna instrucción de entrada de datos como scanf().
El bloque o símbolo utilizado en diagramas de flujo para representar una acción de entrada de datos, es decir, la introducción de un valor desde el teclado a la memoria RAM de la computadora, es el siguiente:
Cuando se usa la función scanf(), ésta lee el valor de un dispositivo de entrada, casi siempre del teclado, y lo almacena en la celda asignada para recibir dicho valor. La sintaxis de esta función es:
SINTAXIS:
scanf (“cadena de control”, lista de arg umentos);
A continuación, tenemos el bloque o símbolo que se utiliza para representar una operación matemática y es el siguiente:
La operación matemática se ejecuta en la memoria RAM, para que esto sea posible, las variables de una fórmula aritmética deben tener un valor.
Por otro lado, para poder visualizar valores de variables en el monitor de la computadora (salida de datos), se debe utilizar la función printf(), la cual se representa en diagrama de flujo de la siguiente manera:
Aunque esta visualización se muestra, generalmente, en el monitor de la co mputadora también puede ser en una impresora. La sintaxis de esta función es:
SINTAXIS:
printf (“cadena de control”, lista de argumentos);
3.4. EJEMPLOS DE PROGRAMAS CON ENTRADA-SALIDA DE DATOS Y EXPRESIONES ARITMETICAS. A continuación se presentan algunos ejemplos de programas donde se pondrá en práctica toda la teoría explicada hasta estos momentos. Se recomienda al maestro hacer primeramente, en el pizarrón, el diagrama de flujo correspondiente y simultáneamente explicar el código a sus alumnos. Finalmente, los alumnos deben practicar en las computadoras con el software apropiado.
Diagrama 3-2.
/* prog3-2.c */ #include #include /* convierte de pies a metros */ main() { int PIES; float METROS; system("cls"); printf("introduzca en numero de pies a convertir \n"); scanf("%d", &PIES); METROS = PIES * 0.3084; /* formula de conversion */ printf("%d pies son %f metros \n", PIES, METROS); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
El programa prog3-2.c tiene dos variables: PIES y METROS, la primera es de tipo entero ( int), la segunda es real de simple precisión ( float). La función system(“cls”) se utiliza para limpiar la pantalla donde se visualizan los resultados del programa. Como se podrá observar, en el scanf() se escribe el amperson “&” , este carácter es necesario para que funcione adecuadamente, por el momento comentaremos que indica la dirección de memoria donde se almacenó el valor de la variable, sin embargo, por la complejidad de su conceptaulización se dejará para posteriores explicaciones. En lenguaje C es posible tener en las expresiones a variables de diferente tipo como está en la fórmula de este programa. La limitante de prog3-2.c es que no se puede hacer conversiones de pies con número reales, solamente enteros. Además, cuando se ejecute el programa se verá un resultado con 6 o 7 decimales. Para quitar la limitante y permitir sólo 2 decimales en el resultado, se tiene el siguiente programa prog3-3.c.
/* prog3-3.c */ #include #include /* convierte de pies a metros */ main() { float PIES, METROS; system("cls"); printf("introduzca en numero de pies a convertir \n"); scanf("%f", &PIES); METROS = PIES * 0.3084; /* formula de conversion */ printf("%8.2f pies son %8.2f metros \n", PIES, METROS); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
Las diferencias entre prog3-2.c y prog3-3.c se reflejan en la declaración de variables, ahora ambas son de tipo real de simple precisión ( float). En el segundo printf() podemos observar, en el especificador de formato, 8.2 entre % y f, esto indica que los valores que se verán en los resultados serán de máximo 8 caracteres, los cuales serán de máximo cinco números en la parte entera y dos en la parte decimal, el punto decimal también se contabiliza entre los 8 caracteres. Con esto aparecerán sólo dos decimales en el resultado. A continuación, tenemos el programa prog3-4.c que calcula el área de un cuadrado.
Diagrama 3-4.
/* prog3-4.c */ #include #include /* calcula el area de un cuadrado */ main() { float AREA,LADO; system("cls"); printf("Introduzca la longitud del lado \n"); scanf("%f",&LADO); AREA = LADO * LADO; printf("El area de un cuadrado con lado = %8.2f es %8.2f \n",LADO,AREA); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
En seguida, con el programa prog3-5.c calcularemos el área de un triángulo. El cálculo del área está limitada por la longitud de los lados, esto es, si LADO1=31, LADO2=45 y LADO3=22 centímetros, entonces estos lados si pueden formar un triángulo, pero si LADO1= 98, LADO2=45 y LADO3=12 centímetros, entonces estos lados no pueden formar un triángulo. En Conclusión, si la sumatoria de los lados más pequeños es mayor al lado más grande, se puede formar un triángulo. Para el primer caso 31+22=53, dado que 53 es mayor a 45 se forma el triángulo, pero en el segundo caso donde 45+12=57 y dado que 57 es menor que 98, no se puede formar el triángulo. La fórmula para determinar el área es:
Área = LADOS(LADOS LADO1)(LADOS LADO2)(LADOS LADO3) donde, LADOS =(LADO1+LADO2+LADO3)/2 Por lo tanto al ejecutar el programa prog3-5.c, si se dan tres lados que no forman un triángulo se generará un error. La función sqrt() se utiliza para calcular la raíz cuadrada, misma que necesita de la directiva del preprocesador llamada que se escribió al principio del programa indicando el uso de una función matemática. Diagrama 3-5.
/* prog3-5.c */ #include #include #include /* calcula el area de triangulo en base a sus lados */ main() { float LADO1,LADO2,LADO3,AREA,OPERACION,LADOS; system("cls"); printf("Dame la longitud del lado # 1 \n"); scanf("%f",&LADO1); printf("Dame la longitud del lado # 2 \n"); scanf("%f",&LADO2); printf("Dame la longitud del lado # 3 \n"); scanf("%f",&LADO3); LADOS=(LADO1+LADO2+LADO3)/2; OPERACION=LADOS*(LADOS-LADO1)*(LADOS-LADO2)*(LADOS-LADO3); AREA=sqrt(OPERACION); printf("El area del triangulo es %8.2f \n",AREA); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
En otro ejemplo tenemos el programa prog3-6.c en el cual encontrará la definición de la constante PI con valor de 3.1416, así mismo, encontrará la función pow() que permite elevar cualquier número a cualquier potencia.
Diagrama 3-6.
/* prog3-6.c */ #include #include #include #define PI 3.1416 /* calcula el area de un circulo */ main() { float RADIO,AREA; system("cls"); printf("Dame el radio del circulo \n"); scanf("%f",&RADIO); AREA=PI*pow(RADIO,2); printf("El area de un circulo con radio %8.2f es %8.2f \n",RADIO,AREA); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
Por otro lado, en el programa prog3-7.c se plantea un problema de caída libre, en el cual una niña deja caer su cartera desde el último piso de la torre de Sears en Chicago cuya altura es de 1,454 pies. Calcule la velocidad de impacto al llegar al suelo. V=
2gh
Donde V es la velocidad final, g es la gravedad equivalente a 32 pies/seg2 y h es la altura de la torre igual a 1,454 pies
En este programa encontramos la definición de una constante llamada GRAVEDAD con un valor de 32, también se realiza una raíz cuadrada con sqrt() y se incluye la directiva del preprocesador
Diagrama 3-7.
/* prog3-7.c */ #include #include #include #define GRAVEDAD 32 /* resuelve un problema de caida libre */ main() { float ALTURA, VALOR,VEL_FINAL; system("cls"); printf("Dame la altura de la torre \n"); scanf("%f",&ALTURA); VALOR= 2*GRAVEDAD*ALTURA; VEL_FINAL=sqrt(VALOR); printf("La Velocidad Final es %8.2f pies/seg \n",VEL_FINAL); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
Otro problema será resuelto con el programa prog3-8.c el cual hace la conversión grados Fahrenheit a centígrados. La fórmula de conversión es C= (5/9) (F-32).
Diagrama 3-8.
/* prog3-8 */ #include #include /* convierte de grados fahrenheit a grados centigrados */ main() { float CENT,FAHR; system("cls"); printf("Dame los grados fahrenheit a convertir \n"); scanf("%f",&FAHR); CENT=(5.0/9.0)*(FAHR-32); printf("%8.2f grados fahrenheit equivale %8.2f grados centigrados \n",FAHR,CENT); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
Finalmente, en el programa prog3-9.c se resuelve el siguiente problema. Un avión que se encuentra volando a una altura de 10,000 pies y a 150 millas por hora, desarrolla velocidades relativas con respecto al viento de 300 millas por hora en la parte superior del ala y 80 millas por hora debajo del ala. Si el área del ala es de 160 pies 2 , ¿Cuál será la fuerza perpendicular a ella? Suponiendo que la densidad a 10,000 pies de altura es p=0.001756 slugs/pies 3 . La fórmula es
Fuerza = A *
1 2
p (V12 – V22 )
Donde A es el área de la ala del avión: 160 pies 2 ; p es la densidad a 10,000 pies de altura: 0.00175; V1 es la velocidad relativa del viento en la parte superior del ala: 300 millas por hora, V2 es la velocidad relativa del viento en la parte inferior del ala: 80 millas por hora. El factor que debe usarse para convertir las millas por hora a pies por segundo es 44/30.
Diagrama 3-9.
/* prog3-9.c */ #include #include #include /* resuelve un problema de aviacion */ #define DENSIDAD 0.001756 main() { float AREA,V1,V2,FUERZA; system("cls"); printf("Dame el area del ala \n"); scanf("%f",&AREA); printf("Dame la velocidad relativa del viento en la parte superior del ala \n"); scanf("%f",&V1); printf("Dame la velocidad relativa del viento en la parte inferior del ala \n"); scanf("%f",&V2); /* convertir las millas por hora a pies por segundo */ V1=(44.0/30.0)*V1; V2=(44.0/30.0)*V2; FUERZA= AREA * (1.0/2.0) * DENSIDAD * (pow(V1,2)-pow(V2,2)); printf("la fuerza del viento perpendicular al ala es de %8.2f slugs-ft/seg2 \n",FUERZA); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
3.5. ENTRADA Y SALIDA DE CARACTERES Y CADENAS DE CARACTERES.
Existen otras funciones semejantes a printf() y scanf(), que permiten la introducción de datos a la computadora desde el teclado. Estas funciones son:
Función getchar() getche() getch() putchar() gets() puts()
Operación Lee un caracter desde el teclado, espera retorno de carro. Lee un caracter con eco, no espera retorno de carro. Lee un caracter sin eco, no espera retorno de carro. Escribe un caracter en la pantalla Lee una cadena de caracteres desde el teclado Escribe una cadena de caracteres en la pantalla
La principal característica de las funciones anteriores es que los valores insertados son caracteres y/o cadenas de caracteres, mismas que pueden almacenar cualquier caracter incluyendo números. Aun cuando en la variables caracter se pueden almacenar números, su utilización, generalmente, es para almacenar letras, espacios en blancos y cualquier otro carácter. Otra consideración que se debe tener presente es que cuando se almacenan números en variables de tipo caracter no se pueden realizar operaciones algebraicas.
Ejemplo #1: Sean operador1, operador2, variables de tipo enteras. int operador1, operador2; Se les asigna el valor de 40 y 20 respectivamente operador1=40 operador2=20 Se realiza una operación resultado = operador1+operador2 La solución a la anterior operación es resultado = 60 Ejemplo #2: Por otro lado, sean operador1 y operador2 variables de tipo caracter
char operador1, operador2; Se les asigna el valor de 40 y 20 respectivamente operador1=”40” operador2=”20” Se realiza la operación resultado = operador1+operador2 La solución a la anterior operación es resultado = ”4020” En el ejemplo #1 se realizó una operación algebraica, en el ejemplo #2 se realizó una concatenación. De hecho podemos ver que en la asignación del ejemplo #2, los valores se escribieron entre comillas en un intento por denotar que no es una asignación algebraica. En el programa prog3-10.c encontrará un ejemplo del uso de gets() y puts(), donde gets() se utiliza para insertar el nombre de una persona
Diagrama 3-10.
/* prog3-10.c */ #include #include /* envia un saludo al usuario */ main() { char NOMBRE[30]; system("cls"); printf("Dame tu nombre \n"); gets(NOMBRE); printf("¡Hola!, %s, ¿Como Estas? \n",NOMBRE); puts("¡Soy yo!, tu computadora..."); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
1. La línea correspondiente a char NOMBRE[30] significa que se declara una variable llamada NOMBRE, de tipo carácter, que permite insertar hasta 30 caracteres, por este motivo podemos decir que la variable NOMBRE es una cadena de caracteres, también conocida como string. Ahora bien, aunque esta variable permite insertar hasta 30 caracteres, se debe tomar en cuenta que lenguaje C coloca al final de una cadena de caracteres un terminador nulo, esto significa que si usted corre el programa e inserta 30 o más caracteres el programa producirá un error, por lo que recomendamos insertar máximo 29 caracteres. 2. La línea que se refiere a gets(NOMBRE);, es la instrucción que permite insertar, desde el teclado, el nombre de alguna persona. 3. La línea correspondiente a printf("¡Hola!, %s, ¨Como Estas? \n",NOMBRE) , es la instrucción que permite ver el nombre y un mensaje en la pantalla de su computadora. %s es un especificador de formato que permite visualizar una cadena de caracteres. 4. La línea que se refiere a puts("!Soy yo!, tu computadora..."); es una instrucción que se permite enviar una cadena de caracteres al monitor de la computadora. Ahora bien, aunque en este programa utilizamos gets() para introducir el nombre, desde el teclado, a la computadora, esto no impide que utilicemos scanf(). Esto lo puede verificar en el siguiente programa llamado prog3-11. C, donde se ha sustituido gets() por scanf(), y sustituimos puts() por printf(). /* prog3-11.c */ #include #include /* envia un saludo al usuario */ main() { char NOMBRE[30]; system("cls"); printf("Dame tu nombre \n"); scanf(" %[^\n]",NOMBRE); printf("¡Hola!, %s, ¿Como Estas? \n",NOMBRE); printf("¡Soy yo!, tu computadora..."); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
En la línea scanf(“ %[^\n]”, NOMBRE);, bien podría usarse el especificador de formato %s en lugar de %[^\n]. La diferencia va estar en que con %s, al correr el programa, no se podrá dar en espacios en blanco entre el nombre y los apellidos, y con %[^\n] si podrá hacerse. Para ver esta situación se le pide que ejecute el programa haciendo los cambios correspondientes. La diferencia entre puts() y printf(), está en que puts() sólo puede imprimir una cadena de caracteres, no puede imprimir variables, printf() si puede hacerlo. Por lo tanto, SERÍA INCORRECTO ESCRIBIR: puts(“¡Hola!, %s, ¿Cómo Estas? \n”, NOMBRE), ya que esta línea implica imprimir el valor de la variable NOMBRE. En el último programa de este capítulo se verá el uso de getchar() y getche(), el especificador de formato %c y como convertir de letras mayúsculas a minúsculas y viceversa. Observe el programa prog3-12.c. En el caso de la función toupper() que convierte de minúscula a mayúscula, si se le pulsa una letra que ya es mayúscula no produce ningún cambio, lo mismo sucede con tolower() que convierte de mayúscula a minúscula, si se le inserta una letra que ya es minúscula no produce ningún c ambio. En ambas funciones, si se inserta un caracter que no es una letra, tampoco se hará ningún cambio. Al ejecutar el programa observará la diferencia entre getchar() y getche().
Diagrama 3-12.
/* prog3-12.c */ #include #include #include /* imprime una letra minuscula y mayuscula */ main() { char MIN,MAY,CMIN,CMAY; system("cls"); puts("\n Dame un letra Minuscula \n"); MIN=getche(); puts("\n Dame un letra Mayuscula \n"); MAY=getchar(); CMIN=toupper(MIN); /* devuelve el equivalente en mayuscula */ CMAY=tolower(MAY); /* devuelve el equivalente en minuscula */ printf("\n La mayuscula de %c es %c \n", MIN, CMIN); printf("\n La minuscula de %c es %c \n", MAY, CMAY); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
3.6 DEFICIENCIAS EN LOS PROGRAMAS La mayor parte de los programas realizados en este capítulo presentan algunas deficiencias, las cuales en la medida que avance el curso deberán ser corregidas. La mayor parte de éstas se debe n a la posible inserción de datos que arrojarán resultados incongruentes o que no tienen significados en la realidad, por ejemplo: a) En los programas prog3-2.c y prog3-3.c que hacen la conversión pies a metros, si se insertan números negativos el resultado que se arrojaría el programa no tiene ningún sentido en la realidad. b) Lo mismo sucede en programa prog3-4.c, que calcula el área de un cuadrado, pues al insertar un número negativo, el resultado no tiene sentido alguno. c) En el caso del programa prog3-5.c, que calcula el área de un triángulo; si se insertan datos que no forman un triángulo, el programa generará un error, pues la función que calcula la raíz cuadrada: sqrt(), no puede generar un resultado si el radical es negativo. d) En el programa prog3-6.c, que calcula el área de un círculo; si se inserta un radio negativo, el programa arrojará un resultado sin sentido. e) Lo mismo sucede en programa prog3-7.c que calcula la velocidad final de un objeto en caída libre cuando éste llega al suelo; si se inserta una altura negativa, el resultado no tiene sentido. f) En el caso del programa prog3-8.c, que realiza la conversión de la temperatura de grados farenheit centígrados, no se presenta problema alguno, porque la conversión de valores negativos si tienen sentido en la realidad. g) Finalmente, en el programa prog3-9.c que calcula la fuerza perpendicular en la ala de un avión, se presenta problemas similares, pues si se inserta una área negativa del ala del avión, los resultados no tienen sentido alguno en la realidad. En algunos de estos programas, el programador deberá decidir qué hacer cuando se inserten valores de cero, pues por ejemplo, no se puede calcular el área de un cuadro con lado=0, porque no existe un cuadrado con esas dimensiones. Por otro lado, es necesario que el alumno sepa diferenciar entre lo que significa que un programa arroje resultados sin sentido ó que genere un error, ya que son situaciones completamente diferentes. Se dejará que el maestro aborde el tema y explique esto, así como que el mismo alumno experimente con los programas.
3.7 PROBLEMAS PROPUESTOS. a) Realice un programa que eleve al cuadrado y al cubo cualquier número, y que imprima el número junto a su cuadrado y su cubo. b) Antes de despegar un avión, el piloto anuncia el tiempo estimado de vuelo en minutos, realice un programa que le ayude a determinar el porcentaje de avance del vuelo, teniendo como dato conocido al tiempo transcurrido del vuelo en minutos. c) Un maestro desea determinar el porcentaje de aprobados y reprobados en un grupo; sólo sabe cuántos alumnos han aprobado y cuántos han reprobado. Realice un programa que le ayude a calcular estos porcentajes. d) Una maestra midió la altura de Juanito al principio y al final de año escolar. Realice un programa que le ayude a determinar el porcentaje de crecimiento de Juanito.
Capítulo #4 Estructuras Selectivas if() y switch() La programación estructurada maneja instrucciones selectivas, repetitivas y secuenciales. A estas instrucciones se les llama estructuras porque tienen un principio y un fin bien definido. La finalidad de la programación estructurada es que las instrucciones se ejecuten secuencialmente. Existe una instrucción llamada goto. El uso que se le da a esta instrucción es para alterar la secuencia de ejecución normal de un programa. Anteriormente, cuando no existían los lenguajes estructurados, la sentencia goto era muy utilizada. Sin embargo, desde que este tipo de lenguajes aparecieron, la instrucción goto quedó relegada y su uso descontinuado. La razón de esto es porque rompe la estructuración de un programa, haciéndolo más difícil de entender y de modificar. De hecho, utilizar goto, en un programa, es sinónimo de un programa obsoleto y de mala calidad. Por lo tanto, no se recomienda su uso. Aquí surge la polémica, ¿cuándo un programa es de buena calidad?. Para empezar, este tema está más ampliamente explicado en la rama de la ingeniería que se denomina Ingeniería de Software. Solamente diremos que el buen programa es aquél que es fácil de entender, fácil de modificar y que arroja los resultados correctos. Por lo tanto, cuando hagamos un programa debemos hacernos la siguiente consideración: Si este programa que estoy haciendo, lo ve una persona que tiene conocimientos medios-avanzados acerca del lenguaje, ¿será capaz de entenderlo?.
4.1 SENTENCIA if()
Volviendo al tema de las estructuras selectivas. Estas son utilizadas en un programa cuando tenemos que decidir entre dos caminos (alternativas) ó más. En el caso de if() se utiliza cuando tenemos que elegir entre dos caminos: Falso y Verdadero. Muchas son las situaciones, dentro de la programación, que enfrentan esta situación, por ejemplo, un alumno sólo puede estar aprobado o reprobado, una persona sólo puede ser del sexo masculino o femenino, una mercancía puede estar entregada o no, una mujer puede estar embarazada o no, etc. en fin, hay muchas situaciones que son binarias, es decir, sólo tienen dos alternativas. Dentro de la instrucción if() haremos uso de los operadores relacionales y los lógicos . Durante este punto abordaremos programas que se enfrentan a situaciones binarias. La sentencia if() escoge entre dos caminos según sea la condición: Falso o Verdadero. Ahora bien, es necesario recalcar que el if() puede tener solamente parte verdadera, mientras que la parte falsa se puede omitir. La parte falsa del if() comienza con la cláusula else, de este modo tanto la parte falsa como la parte verdadera están delimitados por llaves { }.
La figura para representar la sentencia if(), en diagramas de flujo, es la siguiente:
PROCESO 1
CONDICION
F
V PROCESO 2
PROCESO 3
PROCESO 4 Lo que se debe destacar de la anterior figura es que las líneas de falso y verdadero se unen para continuar un mismo camino.
Prog.4-1
Prog.4-2
Prog.4-3
Prog.4-4
Prog.4-5
Prog.4-6
Prog.4-7
Prog.4-8
Prog.4-9
Prog.4-10
Prog.4-11
Prog.4-12
Prog.4-13
Prog.4-14
Prog.4-15
Prog.4-16
Prog.4-17
En el primer programa de este capítulo prog4-18.c se trata de conocer la situación académica de un alumno en una materia según las calificaciones en dos exámenes parciales, de este modo, encontrará que si el PROMEDIO es mayor o igual que 70, la variable SITUACION tendrá el valor de APROBADO , pero si el PROMEDIO es menor a 70, la variable SITUACION tendrá el valor de REPROBADO. En este caso en particular, el if() tiene parte falsa y parte verdadera. Observe que la variable SITUACION es del tipo carácter con máximo 30 caracteres, así mismo, observe que para asignar valor a la variable SITUACION se utilizó la función strcpy(), que significa copiar una cadena de caracteres: STRING COPY. Para que esta función funcione adecuadamente se debe agregar, al principio del programa, la directiva del preprocesador .
/* prog4-18.c */ #include #include #include #include /* programa determina, en base a las calificaciones de los parciales, el promedio del alumno y si esta aprobado o reprobado */ main() { long int MATRICULA; char NOMBRE[30], SITUACION[30]; float PARCIAL1, PARCIAL2, PROMEDIO; system("cls"); printf("Dame la matricula \n"); scanf("%ld",&MATRICULA); printf("Dame el nombre \n"); scanf(" %[^\n]",NOMBRE); printf("Dame la calificacion del primer parcial \n"); scanf("%f",&PARCIAL1); printf("Dame la calificacion del segundo parcial \n"); scanf("%f",&PARCIAL2); PROMEDIO=(PARCIAL1+PARCIAL2)/2; if(PROMEDIO>=70) { strcpy(SITUACION,"APROBADO"); } else { strcpy(SITUACION,"REPROBADO"); } /* fin del if */ printf("El alumno con matricula %ld Se llama %s \n",MATRICULA,NOMBRE); printf("tiene promedio de :%8.2f y esta %s\n", PROMEDIO,SITUACION); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
En el siguiente programa prog4-19.c encontrará un if() que compara si dos valores son iguales. Observe que la comparación se realiza con doble igual (= =).
/* prog4-19.c */ #include #include #include main() { int VALOR1,VALOR2; system("cls"); printf("Dame el primer numero \n"); scanf("%d",&VALOR1); printf("Dame el segundo numero \n"); scanf("%d",&VALOR2); if(VALOR1==VALOR2) { printf("Los numeros son iguales\n"); } else { printf("Los numeros son diferentes\n"); } /* fin del if */ printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
En seguida tenemos el programa prog4-20.c en él encontrará un if() que compara si dos cadenas de caracteres son iguales. Este programa es muy delicado, por lo que le recomendamos ser muy cuidadoso, por ejemplo, si la primer cadena es FIME y la segunda fime, el resultado será que las cadenas son diferentes porque una tiene letras mayúsculas y la otra minúsculas, esto es, la computadora no reconoce que es lo mismo. Por otro lado, si la primer cadena es FIME y la segunda FIME, pero por error, al teclear la segunda cadena, dimos un espacio en blanco después de la E, el resultado será que las cadenas son diferentes. Por eso, al correr el programa, asegúrese de teclear exactamente iguales las dos cadenas. También observe que la comparación se realizó con la función strcmp(), que significa comparación de cadenas: STRING COMPARE. El signo de admiración significa una negación. Observe que no se utilizan los signos de igual como en el anterior programa.
/* prog4-20.c * /#include #include #include /* */ main() { char CADENA1[30],CADENA2[30]; system("cls"); printf("Dame la primer cadena \n"); scanf(" %[^\n]",CADENA1); printf("Dame la segunda cadena \n"); scanf(" %[^\n]",CADENA2); if(!strcmp(CADENA1,CADENA2)) { printf("Las cadenas son iguales\n"); } else { printf("Las cadenas son diferentes\n"); } /* fin del if */ printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
A continuación tenemos el programa pro4-21.c el cual hace una comparación para determinar, a partir de dos números, cuál es mayor. Si se introducen dos números iguales el programa arrojará un resultado incongruente. Como ejercicio, se dejará al alumno que modifique el programa, de forma que no se presente esta incongruencia.
/* prog4-21.c */ #include #include #include main() { int VALOR1,VALOR2; system("cls"); printf("Dame el primer numero \n"); scanf("%d",&VALOR1); printf("Dame el segundo numero \n"); scanf("%d",&VALOR2); if(VALOR1>VALOR2) { printf("El valor1: %d es mayor que el valor2: %d\n",VALOR1,VALOR2); } else { printf("El valor2: %d es mayor que el valor1: %d\n",VALOR2,VALOR1); } /* fin del if */ printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
Ahora tenemos el programa prog4-22.c el cual hace una comparación entre dos cadenas para determinar cuál es mayor. Si se teclean dos cadenas exactamente iguales, el programa arrojará un resultado incongruente. Al igual que el programa anterior, se dejará al alumno la modificación del programa para que no se presente esta incongruencia.
/* prog4-22.c */ #include #include #include /* determina, a partir de dos cadenas de caracteres, cual es mayor */ main() { char CADENA1[30],CADENA2[30]; int RESULTADO; system("cls"); printf("Dame la primer cadena \n"); scanf(" %[^\n]",CADENA1); printf("Dame la segunda cadena \n"); scanf(" %[^\n]",CADENA2); RESULTADO=strcmp(CADENA1,CADENA2); if(RESULTADO>0) { printf("La cadena1: %s es mayor a la cadena2: %s \n",CADENA1,CADENA2); } else { printf("La cadena2: %s es mayor a la cadena1:%s \n",CADENA2,CADENA1); } /* fin del if */ printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
Auxiliados con los programas prog4-22.c y prog4-23.c analizaremos como funciona internamente el if() . De esta manera, cuando se ejecuta un if(), se realiza una operación que puede devolver un valor de cero o diferente de cero. Observe que El programa prog4-6.c es el mismo que el prog4-2.c pero está modificado. Aquí se agregó la variable RESULTADO, y la operación RESULTADO=VALOR1==VALOR2. De tal forma que si VALOR1 es igual a VALOR2, RESULTADO tendrá valor de uno, si no es así, RESULTADO tendrá valor igual a cero. De este modo, para el if(), si la operación da resultado de uno es verdadero, si da resultado diferente a uno es falso .
/* prog4-23.c */ #include #include /* */ /* este programa es el mismo que prog4-2.c pero modificado */ main() { int VALOR1,VALOR2, RESULTADO; printf("Dame el primer numero \n"); scanf("%d",&VALOR1); printf("Dame el segundo numero \n"); scanf("%d",&VALOR2); RESULTADO=VALOR1==VALOR2; if(RESULTADO) { printf("Los numeros son iguales\n"); } else { printf("Los numeros son diferentes\n"); } /* fin del if */ printf("Resultado %d \n", RESULTADO); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
Si en el anterior programa cambiáramos la fórmula y tuviéramos RESULTADO=VALOR1>VALOR2, donde VALOR1=53 y VALOR2=21, el RESULTADO sería igual uno, pero si VALOR1=23 y VALOR2=59, el RESULTADO sería igual a cero. Todo esto es válido cuando se trata de variables numéricas .
Sin embargo, cuando se trata de una comparación de cadenas de caracteres resulta lo siguiente: RESULTADO=strcmp(CADENA1, CADENA2) En estas condiciones tenemos tres posibles resultados Primero, la variable RESULTADO es igual cero cuando las cadenas son iguales. Segundo, la variable RESULTADO es mayor a cero cuando la CADENA1 es mayor a la CADENA2. Y finalmente, la variable RESULTADO es menor a cero cuando la CADENA1 es menor a la CADENA2. Por otro lado, si CADENA1=”A” y CADENA2=”a” y RESULTADO=str(CADENA1,CADENA2), la variable resultado sería menor que cero porque le código ASCII de A=65 y el código ASCII de a=97. Por lo tanto “a es mayor que A”.
4.1.1 . Funciones de Cadena de Caracteres.
Con el siguiente programa prog4-24.c se verá el uso de funciones de cadena, en este caso la función isdigit() que determina si una cadena es un dígito (número) o no. /* prog4-24.c */ #include #include #include /* determina si un caracter es un digito (numero) */ main() { char CARACTER; printf("Dame un caracter \n"); CARACTER=getchar(); if(isdigit(CARACTER)) { printf("Si es digito: %c \n",CARACTER); } else { printf("No es digito: %c \n",CARACTER); } /* fin del if */ printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
Como ejercicio se dejará que el alumno investigue y utilice las siguientes funciones de cadena: isalnum() isalpha() iscntrl() isgraph() islower() isprint() ispunct() isspace() isupper() isxdigit() strcat()
strchr() En el siguiente programa prog4-25.c, se verá el uso del % como operador matemático binario. En necesario recalcar, que no se debe confundir el signo del porciento ( %) cuando se usa dentro de la función scanf() o printf() y cuando se usa en una operación matemática. Esto es, cuando se usa dentro de la función scanf() o printf() este signo es parte del especificador de formato, pero cuando se usa dentro de una operación matemática este signo es una operación de módulo (residuo) de una división entre números enteros. De este modo, si tuviéramos lo siguiente: Resultado=25/5 entonces Resultado=5 Resultado=25%5 entonces Resultado=0 Resultado=25/4 entonces Resultado=6.25 Resultado=25%4 entonces Resultado=1 Para resolver el siguiente problema del programa prog4-25.c, el cual determina si un número es par ó impar, se utilizó, en la fórmula matemática, el módulo (%) del número dado dividiéndolo entre dos. Posteriormente, dentro del if() se invirtió la salida con el signo de exclamación ( !). Un inconveniente de este programa es que cuando el número analizado sea cero se imprimirá un resultado incongruente.
/* prog4-25.c */ #include #include #include /* */ main() { int NUMERO,RESULTADO; printf("Dame un numero \n"); scanf("%d",&NUMERO); RESULTADO=NUMERO%2; if(!RESULTADO) { printf("El numero %d es par \n",NUMERO); } else { printf("El numero %d es impar \n", NUMERO); } /* fin del if */ printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
Hasta el momento hemos utilizado el if() con parte falsa y verdadera. Como dijimos anteriormente, hay ocasiones que el if() puede tener solamente parte verdadera. Para ver este ejemplo desarrollaremos el programa prog4-26.c, el cual tiene la siguiente redacción. Se desea calcular el pago del recibo de luz de una persona. Los datos de entrada son: Número de Medidor, Cantidad de Kilowatts con consumidos, costo del kilowatt y saldo anterior. Si no se pago el recibo anterior habrá un recargo de quince pesos. La manera de saber si el recibo anterior se pagó o no, es preguntar
si el saldo anterior es mayor a cero. Por lo tanto, el pago se calcula multiplicando la cantidad de kilowatts consumidos por el costo del kilowatt, y si el recibo anterior no fue pagado se agrega el recargo y el saldo anterior.
/* prog4-26.c */ #include #include /* */ main() { long int MEDIDOR; float KILOWATT,COSTO_KWT,SALDO_ANTERIOR, PAGO; printf("Dame el numero de medidor \n"); scanf("%ld",&MEDIDOR); printf("Dame la cantidad de kilowatts consumidos \n"); scanf("%f",&KILOWATT); printf("Dame el costo por kilowatt \n"); scanf("%f",&COSTO_KWT); printf("Dame el saldo anterior\n"); scanf("%f",&SALDO_ANTERIOR); PAGO=KILOWATT*COSTO_KWT; if(SALDO_ANTERIOR>0) { PAGO=PAGO+15+SALDO_ANTERIOR; } /* fin del if */ printf("El Pago a realizar por el medidor # %ld es $ %8.2f \n",MEDIDOR,PAGO); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
4.2 if() ‘s ANIDADOS Los if()’s anidados se refiere al hecho de que hay una instrucción if() dentro de otra instrucción if(). Para entender este concepto analizaremos el programa prog4-27.c en el que podemos ver que por la parte falsa del primer if() hay otro if(). Otro detalle que se debe observar es que los dos if() tienen parte falsa y verdadera, esto no siempre sucede así. Este programa es el mismo que el prog4-21.c pero está modificado.
/* prog4-27.c */ #include #include /* determina, a partir de dos valores, cual es mayor */ main() { int VALOR1,VALOR2; printf("Dame el primer numero \n"); scanf("%d",&VALOR1); printf("Dame el segundo numero \n"); scanf("%d",&VALOR2); if(VALOR1==VALOR2) { printf("No se puede determinar cual numero es mayor porque son iguales \n"); } else { if(VALOR1>VALOR2) { printf("El valor1: %d esmayor que el valor2: %d\n",VALOR1,VALOR2); } else { printf("El valor2: %d es mayor que el valor1: %d\n",VALOR2,VALOR1); } /* fin del if(VALOR1>VALOR2) */ } /* fin del if(VALOR1==VALOR2) */ printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
A continuación tenemos el programa prog4-28.c es el mismo que prog4-22.c pero modificado para mostrar el uso de los if() anidados.
/* prog4-28.c */ #include /* */ #include #include #include main() { char CADENA1[30],CADENA2[30]; int RESULTADO; system("cls"); printf("Dame la primer cadena \n"); scanf(" %[^\n]",CADENA1); printf("Dame la segunda cadena \n"); scanf(" %[^\n]",CADENA2); RESULTADO=strcmp(CADENA1,CADENA2); if(!RESULTADO) { printf("No se puede determinar cual cadena es mayor porque son iguales \n"); } else { if(RESULTADO>0) { printf("La cadena1: %s es mayor a la cadena2: %s \n",CADENA1,CADENA2); } else { printf("La cadena2: %s es mayor a la cadena1:%s \n",CADENA2,CADENA1); } /* fin del if(RESULTADO>0) */ } /* fin del if(!RESULTADO) */ printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
Continuando con los ejemplos de if() anidados tenemos el programa prog4-29.c, que es el mismo programa prog4-26.c pero modificado.
/* prog4-29.c */ #include /* determina si un numero es par o impar */ #include #include main() { int NUMERO,RESULTADO; system("cls"); printf("Dame un numero \n"); scanf("%d",&NUMERO); if(NUMERO==0) { printf("No se puede determinar si el numero es par o impar porque es CERO \n"); }else { RESULTADO=NUMERO%2; if(!RESULTADO) { printf("El numero %d es par \n",NUMERO); } else { printf("El numero %d es impar \n", NUMERO); } /* fin del if(!RESULTADO) */ } /* fin del if(NUMERO) */ printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
Por otro lado, tenemos el programa prog4-30.c que determina el grado del acero cuando se conocen los valores para T1 Y T2. De esta manera, el acero se considera de grado 1 si T1 excede a 0.95 y T2 excede a 0.75; de grado 2 si T1 excede a 0.95 pero T2 no excede a 0.75; y de grado 3 si T1 no es mayor que 0.95.
/* prog4-30.c */ #include /* determina el grado del acero */ #include main() { float T1,T2; printf("Dame el valor de T1 \n"); scanf("%f",&T1); printf("Dame el valor de T2 \n"); scanf("%f",&T2); if(T1>0.95 && T2>0.75) { printf("El grado del acero es #1 \n"); } else { if(T1>0.95 && T2<0.76) { printf("El grado del acero es #2 \n"); } /* fin del if(T1>0.95 && T2<0.76) */ else { if(T1<0.96) { printf("El grado del acero es #3 \n"); } /* fin del if(T1<.096) */ } /* fin del if(T1>0.95 && T2>0.75) */ } /* fin del if(T1>0.95 && T2>0.75) */ printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche();
} /* fin de la funcion main() */
En el anterior programa prog4-30.c se utilizó, dentro de algunos if() , el operador lógico AND (doble amperson) &&, el cual se utiliza para comprobar una doble condición. No se debe confundir el amperson que se utiliza dentro del scanf() porque tienen diferente función. En seguida tenemos el programa prog4-31.c que calcula los pagos de los recibos de luz en base a las siguientes tarifas: 14 KWH o menos $30 pesos Los siguientes 51 KWH $0.50 por KWH Exceso sobre 65 KWH $0.25 por KWH
/* prog4-31.c */ #include /* calcula los pagos de los recibos de luz */ #include main() { float KWH,PAGO,EXCESO; printf("Dame los Kilowatts-hora consumidos\n"); scanf("%f",&KWH); if(KWH<=14) { PAGO=30; } else {
if(KWH>65) { EXCESO=KWH-65; PAGO=30+51*0.50+EXCESO*0.25;
} else { EXCESO=KWH-14; PAGO=30+EXCESO*.50; } /* fin del if(KWH>65) */ } /* fin del if(KWH<=14) */ printf("El pago debe ser de $%8.2f pesos\n",PAGO); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
Para poner fin a este punto de los if() anidados, en el programa prog4-32.c se resuelve un problema para determinar si tres longitudes pueden formar un triángulo.
/* prog4-32.c */ #include #include /* */ main() { float LADO1,LADO2,LADO3,LADOS,LARGO; printf("Dame lalongitud del lado 1\n"); scanf("%f",&LADO1); printf("Dame lalongitud del lado 2\n"); scanf("%f",&LADO2); printf("Dame lalongitud del lado 3\n"); scanf("%f",&LADO3); if(LADO1!=0 && LADO2!=0 && LADO3!=0) { if(LADO1==LADO2) { if(LADO1>LADO3) { LADOS=LADO2+LADO3; LARGO=LADO1; } else { LADOS=LADO1+LADO2; LARGO=LADO3; } /* fin del if(LADO1>LADO3) */ } /* fin del if(LADO1==LADO2) */ if(LADO1==LADO3) { if(LADO1>LADO2) { LADOS=LADO2+LADO3; LARGO=LADO1; } else { LADOS=LADO1+LADO3; LARGO=LADO2; } /* fin del if(LADO1>LADO2) */ } /* fin del if(LADO1==LADO3) */ if(LADO2==LADO3) { if(LADO2>LADO1) { LADOS=LADO1+LADO3; LARGO=LADO2; } else { LADOS=LADO2+LADO3; LARGO=LADO1; } /* fin del if(LADO2>LADO1) */ } /* fin del if(LADO2==LADO3) */ if(LADO1!=LADO2 && LADO1!=LADO3 && LADO2!=LADO3) { if(LADO1>LADO2 && LADO1>LADO3) { LADOS=LADO2+LADO3; LARGO=LADO1; } else { if(LADO2>LADO1 && LADO2>LADO3)
{ LADOS=LADO1+LADO3; LARGO=LADO2; } else { if(LADO3>LADO1 && LADO3>LADO2) { LADOS=LADO2+LADO1; LARGO=LADO3; } /* fin del if(LADO3>LADO1 && LADO3>LADO2) */ } /* fin del if(LADO2>LADO1 && LADO2>LADO3) */ } /* fin del if(LADO1>LADO2 && LADO1>LADO3) */ }/* fin del if(LADO1!=LADO2 && LADO1!=LADO3 && LADO2!=LADO3)*/ if(LADOS>LARGO) { printf("Si pueden formar un triangulo \n"); } else { printf("No pueden formar un triangulo \n"); } /* if(LADOS>LARGO) */ } else { printf("\n\nUno o mas de los numeros insertados son CERO\n"); printf("por lo tanto no es triangulo\n"); } printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
4.3 SENTENCIA switch()
La sentencia switch() se utiliza cuando tenemos dos opciones ó más a elegir, así como dos ó más posibilidades a escoger según un determinado problema.
La figura para representar la sentencia switch(), en diagramas de flujo, es la siguiente:
PROCESO 1
SALIDA 3
VARIABL E
SALIDA 1
SALIDA 2
PROCESO 4
PROCESO 3
PROCESO 2
PROCESO 5
Nota: Todas las salidas se unen para seguir un mismo camino.
En el siguiente programa prog4-33.c podemos elegir entre varias opciones para calcular el área de diversas figuras geométricas.
/* prog4-33.c */ #include #include #include #include #define PI 3.1416 /* programa menu para obtener el area de diversas figuras */ void gotoxy(int x,int y); /*Declaración de función gotoxy(x,y)*/ main() { int OPCION; float RADIO,AREA,LADO,BASE,ALTURA; system("cls"); gotoxy(20,5); printf("Menu para obtener el Area de diversas figuras\n"); gotoxy(10,8); printf("1.-Circulo"); gotoxy(10,10); printf("2.-Esfera"); gotoxy(10,12); printf("3.-Cuadrado"); gotoxy(10,14); printf("4.-Triangulo"); gotoxy(15,20); printf("Elija una opcion: "); scanf("%d",&OPCION); switch(OPCION) { case 1: { system("cls"); printf("Dame el radio \n"); scanf("%f",&RADIO); AREA=PI*pow(RADIO,2); printf("El area del circulo con radio=%8.2f es %8.2f\n",RADIO,AREA); break; } /* fin del case 1 */ case 2: { system("cls"); printf("Dame el radio \n"); scanf("%f",&RADIO); AREA=4*PI*pow(RADIO,2); printf("El area de la esfera con radio=%8.2f es %8.2f\n",RADIO,AREA); break; } /* fin del case 2 */ case 3: { system("cls"); printf("Dame la longitud del lado \n"); scanf("%f",&LADO); AREA=LADO*LADO; printf("El area del cuadrado con lado=%8.2f es %8.2f\n",LADO,AREA); break;
} /* fin del case 3 */ case 4: { system("cls"); printf("Dame la longitud de la Base\n"); scanf("%f",&BASE); printf("Dame la Altura\n"); scanf("%f",&ALTURA); AREA=BASE*ALTURA/2.00; printf("El area del triangulo con base=%8.2f, altura=%8.2f es %8.2f\n",BASE,ALTURA,AREA); break; } /* fin del case 4 */ default: { printf("La opcion elegida no esta disponible\n"); } /* fin del default */ } /* fin del switch */ printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */ /*funcion gotoxy(x,y)*/ void gotoxy(int x, int y) { COORD coord; coord.X = x; coord.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } /*fin de la funcion gotoxy(x,y)*/
4.4 PROBLEMAS PROPUESTOS. Al realizar los siguientes programas establezca mecanismos para impedir el cálculo de operaciones matemáticas que arrojen resultados irreales o erróneos. a) Auxiliado de las estructuras selectivas, modifique los programas del capítulo #3. Elimine algunas deficiencias señaladas en el apartado correspondiente . Tome como ejemplo, el código siguiente que se refiere prog3-2.c. Observe las modificaciones que se incluyeron, en el caso del if(), no permite calcular la conversión con valores negativos. /* prog3-2.c */ /* Programa modificado para eliminar deficiencias utilizando if() */ #include /* convierte de pies a metros */ main() { int PIES; float METROS; clrscr(); printf("introduzca en numero de pies a convertir \n"); scanf("%d", &PIES); if(PIES<=0) { printf("el numero insertado es cero o menor a cero \n"); printf("no tiene sentido hacer conversiones con este numero\n"); printf("si desea intentar de nuevo debera de ejecutar otra vez el programa\n"); } else { METROS = PIES * 0.3084; /* formula de conversion */ printf("%d pies son %f metros \n", PIES, METROS); } /* fin del if */ printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
b) Usted conoce el espacio total en un disco duro y también conoce el espacio ocupado. Realice un programa que calcule el espacio disponible. c) Usted está leyendo un libro. Realice un programa que le ayude a calcular el avance de lectura en cualquier momento. d) Se ha dejado caer, desde el reposo, una billetera de una torre. Realice un programa que le ayude a calcular el porcentaje de distancia recorrido a los 2.3 segundos. Los siguiente problemas propuestos son los mismos del capítulo 3, ahora deberá eliminar las deficiencias correspondientes, utilizando las estructuras selectivas. e) Realice un programa que eleve al cuadrado y al cubo cualquier número, y que imprima el número junto a su cuadrado y su cubo. f) Antes de despegar un avión, el piloto anuncia el tiempo estimado de vuelo en minutos, realice un programa que le ayude a determinar el porcentaje de avance del vuelo, teniendo como dato conocido al tiempo transcurrido del vuelo en minutos. g) Un maestro desea determinar el porcentaje de aprobados y reprobados en un grupo; sólo sabe cuántos alumnos han aprobado y cuántos han reprobado. Realice un programa que le ayude a calcular estos porcentajes. h) Una maestra midió la altura de Juanito al principio y al final de año escolar. Realice un programa que le ayude a determinar el porcentaje de crecimiento de Juanito.
Capítulo #5 Estructuras Repetitivas for(), do{…}while() y while(){…} Las estructuras repetitivas permiten que una serie de pasos, instrucciones o funciones se repitan con una secuencia predeterminada.
Existen dos clases de estructuras repetitivas, las que se controlan por centinela y las que lo hacen por contador. La diferencia es que en las estructuras controladas por centinela no se conoce de antemano las veces en que se repetirá un proceso y en las controladas por contador, esto sí se conoce. Lenguaje C tiene dos funciones repetitivas que se controlan por centinela y son: do{…}while() y en las cuales el proceso se repite mientras la condición es verdadera , sin embargo, entre estas dos, la diferencia es que en el caso del do{…}while(), la condición para repetir el proceso está al final del mismo, y en el caso del while() {…}, la condición está el principio. Aquí surge la pregunta obvia, ¿Cuándo y en qué caso utilizar una ó la otra?. La respuesta es que se debe ver la situación particular de cada programa ya que en algunos casos es indiferente cuál se utilice, pero en otros, es más útil una que otra. Esto se puede determinar con la experiencia que cada programador tenga. while(){…},
Por otro lado, lenguaje C tiene una función que se controla por contador en este caso es el for(). Es necesario comentar que en una buena parte de los problemas a que se enfrenta un programador, se pueden utilizar ambas estructuras, es decir, las controladas por centinela o por contador, sin embargo, no son pocas las ocasiones en que sólo se puede utilizar una de las dos. Por ejemplo, analizaremos el problema a que se refiere el programa prog5-1.c. Finalmente, antes de pasar a ejemplos de programas en este capítulo, haremos una importante aclaración. Esta es que, así como existen if() ’s anidados, es decir un if() dentro de otro if() , también existen for() anidados, do{…}while() y while(){…} anidados etc. Es necesario tener esto en mente porque aunque en este folleto no halla programas que exhiban estos ejemplos, dichas estructuras anidadas existen y son de uso común. 5.1 CICLO do{…}while(condición); Esta sentencia es un ciclo repetitivo controlado por centinela donde la condición para que se repita el proceso se encuentra al final del mismo. Esta estructura se utiliza cuando no se conoce de antemano cuántas veces se repetirá un proceso que está inmerso en este ciclo. Es conveniente recordar que el proceso se repetirá mientras la condición sea verdadera . Por ejemplo:
do{ Instrucción 1; Instrucción 2; Instrucción 3; Instrucción 4; Instrucción 5; }while(centinela!=0) El anterior ciclo puede entenderse así: Repita las instrucciones 1,2,3,4 y 5 mientras centinela sea diferente a cero.
La secuencia para representar la sentencia do{…}while(condición);, en diagramas de flujo, es la siguiente:
RAPTOR
PROCESO
CONDICION
La manera en que se trabaja con do/while en raptor es la misma primero el proceso después la condición. De la anterior figura cabe mencionar que el falso y el verdadero NO se unen para continuar un solo camino. Esta es la principal diferencia con el if(), que utiliza el mismo símbolo (un triángulo) pero en el if(), el falso y el verdadero sí se unen.
Es importante señalar que algunos autores prefieren utilizar un triángulo para señalar una estructura selectiva como lo es el if() y un rombo para referirse a una estructura repetitiva como lo son do{…}while(condición) y while(condición){…}, sin embargo, esa distinción es innecesaria pues con la experiencia en la programación, se puede determinar de antemano, con relativa facilidad, cómo habrá de codificarse. Se recomienda analizar, dentro de este capítulo, cómo las estructuras selectivas y repetitivas se complementan para la validación de campos o variables.
Entonces comenzaremos con una serie de programas que utilicen el do{…}while(condición); En el programa prog5-1.c se tiene la siguiente situación: Se deja caer una pelota desde una altura de determinada (en metros), rebota y cada vez su altura es de dos tercios de su altura en el rebote anterior. Elabore un programa que determine el número del rebote en el que la altura de la pelota es igual o inferior cincuenta centímetros. Además, deberá imprimir el número de cada rebote y su correspondiente altura. Para resolver este problema, necesariamente utilizaremos una estructura de repetitiva controlada por centinela ya que no se puede utilizar la controlada por contador; de las dos disponibles utilizaremos do{…}while() por ser la que tiene la condición al final del proceso repetitivo y se ajusta más a nuestro problema. Se utiliza una estructura controlada por centinela porque no sabemos cuántas veces se tendrá que calcular la nueva altura de la pelota después de cada rebote ya que esto depende de la altura de la que se deja caer la pelota. Por lo tanto, no sabemos cuántas veces se repetirá el proceso, entonces, para este caso en particular, utilizar una estructura controlada por centinela es la única opción para resolver el problema. Observe la siguiente codificación.
/* prog5-1.c*/ #include #include /* Pelota que rebota 2/3 partes de su altura anterior */ main() { int REBOTE; float ALTURA; REBOTE=0; printf("Dame la altura inicial de donde se deja caer la pelota, en metros\n"); scanf("%f",&ALTURA); if(ALTURA>0) { printf("Rebote Altura\n"); do{ REBOTE=REBOTE+1; ALTURA=ALTURA*2/3; /* imprimir todos los rebotes con sus alturas */ printf("%d %8.2f\n",REBOTE,ALTURA); }while(ALTURA>0.50); printf("Despues del rebote # %d, la altura es %8.2f\n",REBOTE,ALTURA); } else { printf("La altura insertada es cero o menor a cero \n"); printf("no tiene sentido hacer calculos con este numero \n"); printf("si dese intentar de nuevo debera de ejecutar, otra vez, el programa\n"); } /* fin del if */
printf("\n\n pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main */
Otro ejemplo lo tenemos en el programa prog5-2.c el cual es una adaptación del programa prog35.c., es este caso, al final del programa se pregunta si se desea continuar; si la respuesta es afirmativa deberá insertarse el número 1.
/* prog5-2.c */ #include #include #include #include /* calcula el area de triangulo en base a sus lados */ main() { float LADO1,LADO2,LADO3,AREA,OPERACION,LADOS; int OPCION; do{
A continuación tenemos el programa prog5-3.c, que es una adaptación del programa prog3-8.c. En esta ocasión, también se pregunta al final del programa si se desea continuar y si la respuesta fuere afirmativa deberá
insertarse una “S”, ya sea mayúscula o minúscula. Por lo tanto, observe como en la condición del while() se colocó una doble condición de “S” mayúscula ó “s” minúscula con el objetivo de no generar errores cuando se pulse una u otra. Además, se debe negar la condición con ( !) para que funcione adecuadamente.
/* prog5-3.c */ #include #include #include /* convierte de grados fahrenheit a grados centigrados */ main(){ float CENT,FAHR; char OPCION[2]; do{ system(“cls”);
printf("Dame los grados fahrenheit a convertir \n"); scanf("%f",&FAHR); CENT=(5.0/9.0)*(FAHR-32); printf("%8.2f grados fahrenheit equivale %8.2f grados centigrados \n",FAHR,CENT); printf("¨Deseas continuar haciendo conversiones? \n"); printf("\n\n Pulsa la letra 'S' para continuar o cualquier otra letra para terminar\n"); scanf(" %[^\n]",OPCION); }while( !strcmp(OPCION,"S") || !strcmp(OPCION,"s")); } /* fin de la funcion main() */
5.2 CICLO while(condición){ …} El modo de operación de este ciclo es semejante al do{…}while(condicion); . La diferencia está en el lugar que ocupa la condición. En el do{…}while(condicion); el proceso siempre se ejecutará por lo menos una vez porque la condición se encuentra al final del proceso. Por el contrario, con el ciclo while(condición){…} puede suceder que el proceso no se ejecute ni siquiera una vez porque la condición se encuentra al principio del proceso.
La secuencia para representar la sentencia while(condición){...}, en diagramas de flujo, es la siguiente:
RAPTOR
Al trabajar con raptor es posible el uso de un while, de forma parecida a la de un do/while excepto que primero hay que declarar una variable ya sea por el creador del programa o por el usuario para que la condición se cumpla o no y al final del proceso volver a preguntar por la condición para saber si se seguirá ejecutando o se terminara el programa. Veamos el siguiente programa prog5-4.c. Observe como antes de while(OPCION==1) tuvimos que incluir la operación de asignación OPCION=1 , esto con la finalidad de que el proceso se ejecute por lo menos
una vez. Si no se hubiera incluido esta operación el proceso nunca se ejecutaría. Compare cuidadosamente con el Programa prog5-2.c.
/* prog5-4.c */ #include #include #include /* calcula el area de triangulo en base a sus lados */ main(){ float LADO1,LADO2,LADO3,AREA,OPERACION,LADOS; int OPCION; OPCION=1; while(OPCION==1) { system(“cls”);
printf("Dame la longitud del lado # 1 \n"); scanf("%f",&LADO1); printf("Dame la longitud del lado # 2 \n"); scanf("%f",&LADO2); printf("Dame la longitud del lado # 3 \n"); scanf("%f",&LADO3); LADOS=(LADO1+LADO2+LADO3)/2; OPERACION=LADOS*(LADOS-LADO1)*(LADOS-LADO2)*(LADOS-LADO3); AREA=sqrt(OPERACION); printf("El area del triangulo es %8.2f \n",AREA); printf("\n \n ¨Deseas analizar otro triangulo? \n"); printf("Pulsa el numero 1 para continuar o cualquier otro numero para terminar\n"); scanf("%d",&OPCION); } /* fin del while */ } /* fin de la funcion main() */
5.3 VALIDACIÓN DE CAMPOS O VARIABLES. La validación de campo o variables es asegurarse que el ingreso de datos tiene un rango o forma que no puede violentarse porque entonces se cae en un error o inconsistencia. Por ejemplo, si estamos capturando calificaciones, éstas sólo deben de estar entre cero y cien, de otra forma se vuelve un dato incongruente para el contexto en el que se está utilizando. Por otro lado, se mencionó que algunos autores prefieren utilizar un triángulo para señalar una estructura selectiva como lo es el if() y un rombo para referirse a una estructura repetitiva como lo son do{…}while(condición); y while(condición){…}.
Sin embargo, el autor de este folleto considera que esa distinción es innecesaria, pues con la experiencia en la programación, se puede determinar de antemano, con relativa facilidad, cómo habrá de codificarse dicho triángulo. Por ejemplo, cuando en un triángulo de diagrama de flujo, el falso y el verdadero se unen, invariablemente la codificación será una estructura selectiva, es decir, es un if() , pero, cuando no se unen, la codificación corresponderá a una estructura repetitiva, en este caso, do{…}while(condición); ó while(condición){…}. Sin embargo, se debe ser muy cuidadoso, porque hay ocasiones en que un triángulo de condición deberá codificarse en ambas formas, esto es, como estructura selectiva y repetitiva. Para sostener esta afirmación, se analizará el siguiente programa prog5-5.c que es el mismo que el prog4-1.c, sin embargo se han quitado algunas deficiencias. En este caso se desea calcular el promedio de la calificación a partir de dos calificaciones parciales; el programa está mejorado pues no permitirá que se inserten, a la memoria RAM de la computadora, calificaciones menores a cero ó mayores a cien. Si se inserta una calificación inválida, el programa imprimirá en el monitor un mensaje de error y pedirá que se inserte otra calificación, de esta manera, el programa no avanzará hasta que se tecleé una calificación válida. Observe la codificación y verá que se utilizó un if() para imprimir el mensaje de error y un do{…}while(condición); para que se pueda pedir nuevamente otra calificación.
/* prog5-5.c */ #include #include #include #include /* programa determina, en base a las calificaciones de los parciales, el promedio del alumno y si esta aprobado o reprobado */ /* En este programa se observa como se complementan las estructuras selectivas y repetitivas */ main(){ long int MATRICULA; char NOMBRE[30], SITUACION[30]; float PARCIAL1, PARCIAL2, PROMEDIO; system(“cls”); printf("Dame la matricula \n"); scanf("%ld",&MATRICULA); printf("Dame el nombre \n"); scanf(" %[^\n]",NOMBRE); do{ printf("Dame la calificacion del primer parcial \n"); scanf("%f",&PARCIAL1); if(PARCIAL1<0 ||PARCIAL1>100) { printf("Calificacion del Primer parcial Invalida,"); printf("favor de insertar otro numero\n\n"); } /* fin del if del PARCIAL1 */ }while(PARCIAL1<0 ||PARCIAL1>100); do{ printf("Dame la calificacion del segundo parcial \n"); scanf("%f",&PARCIAL2); if(PARCIAL2<0 ||PARCIAL2>100) { printf("Calificacion del Segundo parcial Invalida,"); printf("favor de insertar otro numero\n\n"); } /* fin de if del PARICIAL2 */ }while(PARCIAL2<0 ||PARCIAL2>100); PROMEDIO=(PARCIAL1+PARCIAL2)/2; if(PROMEDIO>=70) { strcpy(SITUACION,"APROBADO"); } else { strcpy(SITUACION,"REPROBADO"); } /* fin del if */ system(“cls”);
printf("El alumno con matricula %ld Se llama %s \n",MATRICULA,NOMBRE); printf("tiene promedio de :%8.2f y esta %s\n", PROMEDIO,SITUACION); printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main() */
Este mecanismo de validación se utiliza para impedir que se inserte a la computadora, información que no tiene sentido para una organización, por ejemplo, los meses del año sólo pueden ser del 1 al 12; el año de nacimiento de una persona no puede ser mayor al año que transcurre; la edad de una persona no puede ser negativa ni más grande de lo lógicamente aceptable, etc.
5.4 SENTENCIA for() La función for() es una estructura repetitiva que se controla por contador y la figura que se utiliza para representarla en diagramas de flujo es:
PROCESO 2
INCREMENTO O DECREMENTO
PROCESO 1
FOR también puede ser interpretado en raptor usando un do/while pero de distinta forma. Lo que se hace en este caso es declarar el valor de I después poner un do/while donde la condición será con respecto a I, después el proceso y al terminarlo poner el aumento de I.
RAPTOR
Es conveniente recordar que en las estructuras controladas por contador, si se conoce de antemano las veces en que un proceso se repetirá, y sólo se repetirá mientras la condición es verdadera. La codificación de la anterior figura es: for(INICIAR; CONDICION; INCREMENTO o DECREMENTO) { PORCESO1; } /* fin del for */
Observe que INICIAR está separada de CONDICION con un punto y coma, lo mismo sucede con CONDICION e, INCREMENTO o DECREMENTO Así mismo, se puede apreciar un apartado de iniciar que es la parte donde se coloca el valor inicial del contador. En el apartado de condición se coloca el número de veces en que se repetirá el proceso1. El apartado de incremento o decremento indica el número en que el contador, se incrementará o decrementará, con cada repetición de Proceso1. Por último, el Proceso2 se realizará después de que se haya cumplido la condición. Por ejemplo: La siguiente instrucción:
for(Contador=1; Contador<25 ; Contador++) { instrucción 1 instrucción 2 instrucción 3 instrucción 4 instrucción 5
} /* fin del for */
El anterior ciclo puede leerse de la siguiente forma: Realiza las instrucciones 1,2,3,4,y 5 desde que el contador vale uno mientras que sea menor a veinticinco, con incrementos de uno. Con el programa prog5-6.c resolverá la siguiente ecuación cuadrática para cuando “X” toma diez valores diferentes a partir que X=15 con incrementos de 3. La ecuación es la siguientes: Y=6X 2 +4X-3, en este programa se utiliza la función for(), que es una estructura repetitiva controlada por contador.
/* prog5-6.c */ #include #include #include #include /* imprime la tabulacion de la ecuacion cuadratica */ /* y=6x2+4x-3 */ main(){ float x,y; int I; system(“cls”); /* limpiar la pantalla de ejecucion */
printf("Tabular la ecuacion cuadratica y=6x2+4x-3 \n"); printf("introduzca el valor de X \n"); scanf("%f",&x); for(I=1;I<=10;I++){ y=6*pow(x,2)+4*x-3; /* ecuacion cuadratica tabular */
Con el programa prog5-7.c se resolverá el programa anterior pero ahora se utilizará una estructura repetitiva controlada por centinela.
/* prog5-7.c */ #include #include #include #include /* imprime la tabulacion de la ecuacion cuadratica */ /* y=6x2+4x-3 */ main(){ float x,y; int I; system(“cls”); /* limpiar la pantalla de ejecucion */
printf("Tabular la ecuacion cuadratica y=6x2+4x-3 \n"); printf("introduzca el valor de X \n"); scanf("%f",&x); I=1; do{ y=6*pow(x,2)+4*x-3; /* ecuacion cuadratica a tabular */ printf("Cuando X=%8.2f, Y= %8.2f \n",x,y); x=x+3; I=I+1; }while(I<=10); printf("\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main */
Con los programas prog5-8.c y prog5-9.c vamos a determinar la sumatoria de los primeros cien números enteros, es decir, del uno al cien. En el prog5-8.c se utiliza una estructura repetitiva controlada por contador y en el prog5-9.c se utiliza una controlada por centinela.
/* prog5-8.c */ #include #include #include /* suma los primeros cien numeros enteros */ main(){ int SUMA,I; system(“cls”); /* limpiar la pantalla de ejecucion */
printf("Calcular la sumatoria del 1 al 100 \n"); SUMA=0;
/* prog5-9.c */ #include #include #include /* suma los primeros cien numeros enteros */ main(){ int SUMA,I; system(“cls”); /* limpiar la pantalla de ejecucion */
printf("Calcular la sumatoria del 1 al 100 \n"); SUMA=0; I=1; do{ SUMA=SUMA+I; I=I+1; }while(I<=100); printf("La sumatoria es %d\n",SUMA); printf("\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main */
Como se verá, estos últimos programas pueden resolverse con estructuras repetitivas controladas por contador y por centinela, esto no siempre es así, por lo que el alumno deberá aprender a utilizar ambas estructuras.
Los programas del prog5-10.c al prog5-15.c, resolverán algunos problemas con la estructura repetitiva controlada por contador, es decir, el for(), se dejará que el alumno practique haciéndolos de nuevo con la estructura controlada por centinela, si es que esto fuera posible. El programa prog5-10.c permite leer un valor para “A”, luego calcula e imprime la suma de los ocho números: 1, 1+A, 1+2A, 1+3A…, 1+7A .
/* prog5-10.c */ #include #include #include /* suma 1,1+A, 1+2A, 1+3A+...+1+7A */ main(){ int SUMA,I,A; system(“cls”); /* limpiar la pantalla de ejecucion */
printf("Calcular la sumatoria 1,1+A, 1+2A, 1+3A+...+1+7A \n"); printf("Dame el Valor de A\n"); scanf("%d",&A);
El programa prog5-11.c calcula el promedio de “N” números.
/* prog5-11.c */ #include #include #include /* obtiene el promedio de N numeros */ main() { int I,N; float SUMA,NUMERO,PROMEDIO; system(“cls”); /* limpiar la pantalla de ejecucion */
printf("Obtener el promedio de N numeros \n"); printf("¨Cuantos numeros son?\n"); scanf("%d",&N); SUMA=0; for(I=1;I<=N;I++) { printf("Dame el numero %d: \n",I); scanf("%f",&NUMERO); SUMA=SUMA+NUMERO; } /* fin del for */ PROMEDIO=SUMA/N; printf("Sumatoria=%8.2f y el promedio= %8.2f\n",SUMA,PROMEDIO); printf("\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main */
El programa prog5-12.c determina si un número es primo o no.
/* prog5-12.c */ #include #include #include /* Determinar si un numero es primo */ main() { int I,N,NUMERO,PRIMO,RESIDUO; system(“cls”); /* limpiar la pantalla de ejecucion */
printf("Determinar si un numero es primo \n"); printf("Dame el numero a analizar \n"); scanf("%d",&NUMERO); RESIDUO=0; N=NUMERO/2; for(I=2;I<=N;I++) { RESIDUO=NUMERO%I; printf("Cuando I=%d, Residuo=%d \n",I,RESIDUO); if(RESIDUO==0) { I=N; PRIMO=0; } /* fin del if RESIDUO==0 */ } /* fin del for */ if(PRIMO==0) { printf("\n El Numero=%d No es primo \n",NUMERO); } else { printf("\n El Numero=%d Si es primo \n",NUMERO); } /* fin del if PRIMO==0 */ printf("\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main */
El programa prog5-13.c calcula el factorial de un número.
/* prog5-13.c */ #include #include #include /* Calcular el factorial de un numero */ main(){ int I,NUMERO; long int FACT; system(“cls”); /* limpiar la pantalla de ejecucion */
printf("Calcular el factorial de un numero \n"); printf("Dame el numero \n"); scanf("%d",&NUMERO); FACT=1; for(I=2;I<=NUMERO;I++){ FACT=FACT*I; } /* fin del for */ printf("\n El Factorial de %d es: %ld \n",NUMERO,FACT); printf("\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main */
El programa prog5-14.c permite imprimir la tabla de multiplicar de cualquier número.
/* prog5-14.c */ #include #include #include /* Imprime la tabla de multiplicar de un numero */ main(){ int I,TABLA,RES; system(“cls”); /* limpiar la pantalla de ejecucion */
printf("Imprimir la tabla de multiplicar de un numero \n"); printf("Dame el numero \n"); scanf("%d", &TABLA); for(I=1;I<=10;I++){ RES=TABLA*I; printf("\n %d * %d = %d \n",TABLA,I,RES); } /* fin del for */ printf("\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche();
El programa prog5-15.c permite determinar el elemento mayor de una lista de “N” números.
/* prog5-15.c */ #include #include #include /* Determinar el elemento mayor de una lista de N numeros */ main(){ int I,N; float NUMERO,MAY; system(“cls”); /* limpiar la pantalla de ejecucion */
printf("Determinar el elemento mayor de una lista de N numeros \n"); printf("¨¿Cuantos numeros son?\n"); scanf("%d",&N); printf("Dame el elemento # 1: \n"); scanf("%f",&NUMERO); MAY=NUMERO; for(I=2;I<=N;I++){ printf("Dame el elemento # %d: \n",I); scanf("%f",&NUMERO); if(NUMERO>MAY) { MAY=NUMERO; } /* fin del if */ } /* fin del for */ printf("\n El elemento mayor es: %8.2f \n",MAY); printf("\n Pulse cualquier tecla para regresar a la pantalla de edicion"); getche(); } /* fin de la funcion main */
A continuación tenemos el programa prog5-16.c que es el mismo de prog5-5.c, pero ahora se puede calcular el promedio de varios alumnos en una misma corrida del programa.
/* prog5-16.c */ #include #include #include #include /* programa que determina, en base a las calificaciones de los parciales, el promedio de varios alumnos y si estan aprobados o reprobados */ main() { long int MATRICULA; char NOMBRE[30], SITUACION[30]; float PARCIAL1, PARCIAL2, PROMEDIO; int I,N; system(“cls”);
printf("¨Cuantos alumnos son?\n"); scanf("%d",&N); for(I=1;I<=N;I++) { system(“cls”);
printf("Introduzca los datos del alumno # %d \n",I); printf("Dame la matricula \n"); scanf("%ld",&MATRICULA); printf("Dame el nombre \n"); scanf(" %[^\n]",NOMBRE); do{ printf("Dame la calificacion del primer parcial \n"); scanf("%f",&PARCIAL1); if(PARCIAL1<0 || PARCIAL1>100) { printf("Calificacion del Primer parcial Invalida,"); printf("favor de insertar otro numero\n\n"); } /* fin del if del PARCIAL1 */ }while(PARCIAL1<0 || PARCIAL1>100); do{ printf("Dame la calificacion del segundo parcial \n"); scanf("%f",&PARCIAL2); if(PARCIAL2<0 || PARCIAL2>100) { printf("Calificacion del Segundo parcial Invalida,"); printf("favor de insertar otro numero\n\n"); } /* fin del if del PARCIAL2 */ }while(PARCIAL2<0 || PARCIAL2>100); PROMEDIO=(PARCIAL1+PARCIAL2)/2; if(PROMEDIO>=70) { strcpy(SITUACION,"APROBADO"); } else { strcpy(SITUACION,"REPROBADO"); } /* fin del if */ printf("El alumno %s tiene promedio:%8.2f esta %s\n", NOMBRE,PROMEDIO,SITUACION); printf("\n \n Pulse cualquier tecla para continuar\n"); getche(); } /* fin del for */ printf("\n \n Pulse cualquier tecla para regresar a la pantalla de edicion\n"); getche(); } /* fin de la funcion main() */
El siguiente programa es el prog5-17.c que es una adaptación del prog4-14.c, pero ahora se puede calcular el pago de varios recibos en una misma corrida del programa.
/* prog5-17.c */ #include #include #include /* calcula los pagos de los recibos de luz */ main() { float KWH,PAGO,EXCESO; int I,N; system(“cls”);
printf("¨Cuantos recibos de luz son? \n"); scanf("%d",&N); for(I=1;I<=N;I++) { system(“cls”);
printf("Dame los Kilowatts-hora consumidos por el recibo #%d\n",I); scanf("%f",&KWH); if(KWH<=14) { PAGO=30; } else { if(KWH>65) { EXCESO=KWH-65; PAGO=30+51*0.50+EXCESO*0.25; } else { EXCESO=KWH-14; PAGO=30+EXCESO*.50; } /* fin del if(KWH>65) */ } /* fin del if(KWH<=14) */ printf("El pago debe ser de $%8.2f pesos\n",PAGO); printf("\n \n Pulse cualquier tecla para continuar \n"); getche(); } /* fin del for */ } /* fin de la funcion main() */
5.5 LA SENTENCIA break;
La sentencia break ; se utiliza para terminar la ejecución de ciclos o salir de una sentencia switch(). Se puede utilizar dentro de las sentencias do{…}while(),while(), for() o switch() .
5.6 LA SENTENCIA continue;
La sentencia continue; se utiliza para saltarse el resto de la pasada actual a través de un ciclo. El ciclo no termina cuando se encuentra una sentencia continue, sencillamente no se ejecutan las sentencias que se encuentran a continuación en él y se salta directamente a la siguiente pasada a través del ciclo. Se puede utilizar dentro de una sentencia do{…}while(),while(), for() o switch()..
5.7 PROBLEMAS PROPUESTOS. a) Loenardo Fibonacci, un rico comerciante italiano del siglo XIII, introdujo una serie de números conocidos hoy en día como números de Fibonacci. Los primeros 16 de ellos son: 1,1,2,3,5,8,13,21,34,55,89,144,233,377,610. Cada número de una secuencia de números de fibonacci es la suma de los dos números que preceden inmediatamente al número considerado. Esto es: 1+1=2 1+2=3 2+3=5 3+5=8 5+8=13 8+13=21 …etc. Esta secuencia tiene aplicaciones prácticas en botánica, teoría de redes eléctricas y otros campos. Realice el programa que determine los primeros 50 números de la serie de Fibonacci. b) Realice un programa que calcule la sumatoria de la siguiente serie: C= ai bi= a1b1+a2b2+a3b3+a4b4, desde que i=1 hasta que i=4. c) Una dama de edad avanzada desea pintar el piso del kiosco sin desperdiciar nada de pintura. Ella sabe por experiencia que se necesita un cuarto de pintura para cubrir 37 pies cuadrados de área. Si el piso del kiosco tiene diez pies de diámetro ¿qué cantidad de pintura debería comprar?. Realice un programa que resuelva el anterior problema. d) Realice un programa que calcule los valores desde que N=1 hasta N=20 en incrementos de uno e imprima encabezados de lo siguiente: 3 N 10 N N N N2 N3 e) Realice un programa que calcule la depreciación de un automóvil Valor del Auto=$ 1,800,000 Vida=6 Rescate=$ 120,000 Imprima los siguientes encabezados “Año Depreciación Depreciación Acumulada Valor Anual” La fórmula de la depreciación anual constate para cada año de vida útil Depreciación = f)
Costo Valorde Re scate VidaUtil
En la fábrica de sillas Bibliomodel, el pago a sus empleados está basado en una tarifa diaria más un incentivo, el cual depende del número de sillas producidas durante el día. Calcule el salario de cada empleado. Por ejemplo, a un salario básico de $3.50 dólares por hora y con 60 centavos de incentivo por cada silla producida por encima de 50 unidades, un empleado que ensamble 76 sillas r ecibirá:
(3.50)(8)+(76-50)(0.60)=28.00+15.60=$43.60 g) Dado un conjunto de números (mínimo 20, máximo 50), realice un programa que: 1. Sume los números dados. 2. Muestre cuál es el número menor. 3. Muestre cuál es el número mayor. 4. Muestre el cantidad de valores iguales a 25. 5. Muestre la cantidad de valores mayores a 20 y menores a 70. h) Utilizando el teorema de Pitágoras, realice un programa que determine las tercia de números menores a cien y que formen un triángulo rectángulo, por ejemplo, 05-12-13, 40-50-30 y 26-24-10, son tercias de números que cumplen dicha condición. i) Asuma que ha invertido $1,000 pesos en una caja popular. La junta directiva le ha asegurado que usted duplicará su inversión en cada dos años. Elabore un programa que calcule su inversión cada año. El procedimiento deberá imprimir una lista semejante a la siguiente:
2 años 4 años 6 años 8 años 10 años 12 años 14 años
$ 200 $ 400 $ 800 $ 1,600 $ 3,200 $ 6,400 $12,800
j)
Realice un programa dirigido a los niños de educación primaria. El programa deberá hacer diez preguntas sencillas de historia, biología o matemáticas. Así mismo, en cada pregunta se deberán establecer por lo menos 4 opciones de respuesta, si se inserta una opción invalida, el programa deberá advertir al niño para que escoja sólo entre las opciones ofrecidas. Después de cada respuesta, el programa deberá mostrar un registro de la cantidad de preguntas contestadas correctamente, de las incorrectas y de las que faltan por contestar. Al terminar deberá imprimir una calificación. k) El número de sonido emitidos por un grillo en un minuto es una función de la temperatura. Como resultado de esto, ¡es posible determinar el nivel de temperatura utilizando al grillo como termómetro!. La fórmula de la función es: t =
l)
N 4
+40, donde t representa la temperatura en grados Fahrenheit y n representa el
número de sonidos emitidos en un minuto. Elabore un programa que determine e imprima los valores para t cuando n toma los valores de 40,50,60,70,…,140,150. El tiempo que requiere un satélite para dar una revolución completa alrededor de la tierra y a una determinada altura es una función de su velocidad. La fórmula para una altitud de 100 millas es t =
1.540 s
donde t es el tiempo y s es la velocidad del satélite en miles de millas por hora. Elabore un programa que calcule e imprima t para los valores de s 18,19,20,…24.
,
Capítulo #6 Funciones Definidas por el Usuario sin Parámetros Lenguaje C es un lenguaje orientado a funciones, de tal forma que printf(), scanf(), for(), if(), switch(), do{…}while (), while(), getche(), main(), pow(), sqrt(), etc. son funciones. A estas funciones se les llama predeterminadas porque ya existen en lenguaje C. De esta manera, lenguaje C permite que el programador haga sus propias funciones, a éstas les llama funciones definidas por el usuario. Así mismo, dentro de estas funciones hay de dos tipos, las que tienen y las que no tienen parámetros. En este capítulo utilizaremos las funciones definidas por el usuario sin parámetros por ser las más sencillas y fáciles, es recomendable que los alumnos interesados, estudien por cuenta propia las funciones definidas por el usuario con parámetros. En el siguiente programa prog6-1.c que es el mismo que el prog4-16.c pero ahora está hecho con funciones. Aquí podemos encontrar las siguientes cosas: En los programas anteriores las variables han sido declaradas dentro de la función main() , en este programa están declaradas afuera y para ser precisos antes de la función main() , cuando esto sucede a estas variables se les llama variables globales. Por lo tanto cuando, hay variables declaradas dentro de una función se les llama variables locales a la función. En resumen, en un programa puede haber variables locales y globales. Su función, su uso y manejo tienen una diferencia notable por lo que es conveniente que los alumnos interesados en este tema lo estudien por cuenta propia. Por otro lado, cuando se manejan funciones se deben considerar tres cosas: La declaración (prototipo) de la función, la llamada a la función y la definición de la función . Así mismo, se utilizaron líneas de comentario para identificar cada una de estas tres partes. Observe que tanto en la declaración como en la definición de la función se anota void, lo cual indica que las funciones no contienen parámetros, también se dice que estas funciones no retornan ningún valor. En la definición de la función se escriben las instrucciones que están dentro de la función, a esto también se le llama cuerpo de la función , estas instrucciones se ejecutarán cuando se llame a la función. Al final del cuerpo de función se escribe la sentencia return; que indica el regreso a la posición de donde fue llamada la función. Compare el programa prog6-1.c con el programa prog4-16.c para que observe las diferencias entre un programa con y sin funciones. DIAGRAMAS DE FLUJO
FUNCION MAIN
MENU
CIRCULO
CUADRADO
ESFERA
TRIANGULO
/* prog6-1.c */ #include #include #include #define PI 3.1416 /* programa menu para obtener el area de diversas figuras utilizando funciones*/ /* declaracion de las funciones */ void menu(); void circulo(); void esfera(); void cuadrado(); void triangulo(); /* declaracion de variables globales */ int OPCION; float RADIO,AREA,LADO,BASE,ALTURA; main() { menu(); /* llamada a la funcion menu() */ system("pause"); } /* fin de la funcion main() */ /* definicion de funciones */ void menu() { system("cls"); printf("\tMenu para obtener el Area de diversas figuras\n\n"); printf("\t\t\t1.-Circulo\n"); printf("\t\t\t2.-Esfera\n"); printf("\t\t\t3.-Cuadrado\n"); printf("\t\t\t4.-Triangulo\n\n"); printf("\t\tElija una opcion: "); scanf("%d",&OPCION); switch(OPCION) { case 1: { circulo(); /* llamada a la funcion circulo() */ break; } /* fin del case 1 */ case 2: { esfera(); /* llamada a la funcion esfera() */ break; } /* fin del case 2 */ case 3: { cuadrado(); /* llamada a la funcion cuadrado() */ break; } /* fin del case 3 */ case 4: { triangulo(); /* llamada a la funcion triangulo() */ break; } /* fin del case 4 */ default: { printf("La opcion elegida no esta disponible\n"); } /* fin del default */ } /* fin del switch */ } /* fin de la funcion menu() */ void circulo() { system("cls"); printf("Dame el radio \n"); scanf("%f",&RADIO); AREA=PI*pow(RADIO,2);
printf("El area del circulo con radio=%8.2f es %8.2f\n",RADIO,AREA); return; } /* fin de la funcion circulo() */ void esfera() { system("cls"); printf("Dame el radio \n"); scanf("%f",&RADIO); AREA=4*PI*pow(RADIO,2); printf("El area de la esfera con radio=%8.2f es %8.2f\n",RADIO,AREA); return; } /* fin de la funcion esfera */ void cuadrado() { system("cls"); printf("Dame la longitud del lado \n"); scanf("%f",&LADO); AREA=LADO*LADO; printf("El area del cuadrado con lado=%8.2f es %8.2f\n",LADO,AREA); return; } /* fin de la funcion cuadrado */ void triangulo() { system("cls"); printf("Dame la longitud de la Base\n"); scanf("%f",&BASE); printf("Dame la Altura\n"); scanf("%f",&ALTURA); AREA=BASE*ALTURA/2.00; printf("El area del triangulo con base=%8.2f, altura=%8.2f es %8.2f\n",BASE,ALTURA,AREA); return; } /* fin de la funcion triangulo */
Las funciones pueden ser concebidas como programas pequeños dentro de un programa o mejor dicho subprogramas. El símbolo que se utiliza para representar a una función es el siguiente:
Programa 6.2 El Señor López ha recibido una oferta de empl eo de la Compañía de juguetes “Ensueño” con la oportunidad elegir entre dos sistemas de pago. Puede recibir un salario mensual de $5,000 y $50 de aumento cada mes, o puede recibir un salario mensual de $5,000 con un aumento anual de $800. Realice un programa que determine el salario mensual para los siguientes tres años. El programa debe determinar los salarios acumulados después de cada mes y a partir de esta información determinar el mejor método de pago.
DIAGRAMA DE FLUJO
FUNCION MAIN
DATOS
CISION
/* prog6-2.c */ #include /* Determinar cual opcion de salario es mejor */ /* declaracion de las funciones */ void datos(); void opcion_1(); void opcion_2(); void decision(); /* declaracion de variables globales */ float SALARIO_MENSUAL, SALARIO_MENSUAL2, AUMENTO_MENSUAL, AUMENTO_ANUAL; float TOTAL_1, TOTAL_2,MESES; int MES,CAMBIO_ANUAL, PERIODO; main() { TOTAL_1=0; TOTAL_2=0; datos(); /* llamada a la funcion datos() */ opcion_1(); /* llamada a la funcion opcion_1() */ opcion_2(); /* llamada a la funcion opcion_2() */ decision(); /* llamada a la funcion decision() */ printf("\n\n Pulse cualquier tecla para regresar a la pantalla de edicion\n"); getche(); } /* fin de la funcion main() */ /* definicion de funciones */ void datos() {
do{ clrscr(); printf("Dame el salario mensual\n"); scanf("%f",&SALARIO_MENSUAL); SALARIO_MENSUAL2=SALARIO_MENSUAL; printf("Dame el aumento mensual\n"); scanf("%f",&AUMENTO_MENSUAL); printf("Dame el aumento anual\n"); scanf("%f",&AUMENTO_ANUAL); printf("¨A cuantos a¤os desea hacer el calculo?\n"); scanf("%d",&PERIODO); MESES=PERIODO*12; if(SALARIO_MENSUAL<=0 || AUMENTO_MENSUAL<=0 || AUMENTO_ANUAL<=0 || PERIODO<=0) { printf("\n\n Uno o mas datos insertados NO son validos,"); printf("\n favor de revisarlos e intentar de nuevo\n"); printf(" Pulse cualquier tecla para continuar\n"); getche(); } /* fin del if */ }while(SALARIO_MENSUAL<=0 || AUMENTO_MENSUAL<=0 || AUMENTO_ANUAL<=0 || PERIODO<=0); } /* fin de la funcion datos */ void opcion_1() { clrscr(); printf("Calculo de la Primera Opcion\n"); printf("Mes Salario Mensual Acumulado\n"); for(MES=1;MES<=MESES;MES++) { TOTAL_1=TOTAL_1+SALARIO_MENSUAL; SALARIO_MENSUAL=SALARIO_MENSUAL+AUMENTO_MENSUAL; printf("%d %8.2f %8.2f\n",MES,SALARIO_MENSUAL,TOTAL_1); } /* fin del for */ printf("OPCION 1: TOTAL DE SUELDO FINAL DEL AÑO %d :$%12.2f \n",PERIODO,TOTAL_1); printf("Pulse cualquier tecla para continuar\n"); getche(); return; } /* fin de la funcion opcion_1 */ void opcion_2() { clrscr(); printf("Calculo de la Segunda Opcion\n"); printf("Mes Salario Mensual Acumulado\n"); for(MES=1;MES<=MESES;MES++) { TOTAL_2=TOTAL_2+SALARIO_MENSUAL2; CAMBIO_ANUAL=CAMBIO_ANUAL+1; if(CAMBIO_ANUAL==13) { SALARIO_MENSUAL2=SALARIO_MENSUAL2+AUMENTO_ANUAL; CAMBIO_ANUAL=1; } /* fin del if */ printf("%d %8.2f %8.2f\n",MES,SALARIO_MENSUAL2, TOTAL_2); } /* fin del for */ printf("OPCION 2: TOTAL DE SUELDO FINAL DEL AÑO %d :$%12.2f \n",PERIODO,TOTAL_2); printf("Pulse cualquier tecla para continuar\n"); getche(); return; } /* fin de la funcion opcion_2 */ void decision() { clrscr(); printf("OPCION 1: TOTAL DE SUELDO FINAL DEL AÑO %d :$%12.2f \n",PERIODO,TOTAL_1); printf("OPCION 2: TOTAL DE SUELDO FINAL DEL AÑO %d :$%12.2f \n",PERIODO,TOTAL_2); if(TOTAL_1==TOTAL_2) { printf("\n\n Ninguna opcion es mejor que la otra\n"); }
else { if(TOTAL_1>TOTAL_2) { printf("\n\n La mejor opcion es la numero 1\n"); } else { printf("\n\n La mejor opcion es la numero 2\n"); } /* fin del if TOTAL_1>TOTAL_2 */ } /* fin del if TOTAL_1==TOTAL_2 */ return; } /* fin de la funcion decision */
Capítulo #7 Arreglos de Memoria Un arreglo es una colección de variables del mismo tipo que se referencian utilizando un nombre común. Un arreglo de memoria le permite a la computadora recordar valores pasados.
7.1 ARREGLOS DE MEMORIA UNIDIMENSIONALES El formato general para la declaración de un arreglo unidimensional es tipo nombre_variable [tamaño]
Aquí tipo declara el tipo de variable del arreglo. El nombre_variable es el nombre de la variable que es arreglo de memoria. El tamaño es la cantidad de elementos que guardará el arreglo. Por ejemplo, el siguiente arreglo llamado lista podrá almacenar 15 elementos enteros. int Li sta[15];
No debe confundirse con la forma de declarar un variable de cadena de caracteres. Por ejemplo: char nombre[30]; char nombre[15][30];
En el primer caso se declaró una variable que es una cadena de caracteres y que puede almacenar hasta 30 caracteres. En el segundo caso se declaró un arreglo de cadena de caracteres; este arreglo de memoria podrá almacenar hasta quince cadenas con 30 caracteres cada cadena.
Problema 7.1: Realice un programa que lea e imprima los elementos de una lista de “N” números. Prog7-1.c.
Función “main”
Función “leer_elementos”
Función “imprimir_elementos” /* prog7-1.c */ #include /* declaracion de funciones */ void Leer_Elementos(); void Imprimir_Elementos(); /* declaracion de variables globales */ int I,N,Lista[100]; main() { /* llamar a la funciones */ Leer_Elementos(); Imprimir_Elementos(); } /* fin de la funcion main() */ /* -------------------------------------- */ /* definicion de las funciones */ void Leer_Elementos() { system("cls"); printf("¿Cuantos elementos tiene la lista de numeros? \n"); scanf("%d",&N); for(I=1;I<=N;I++) { clrscr(); printf("Dame el Elemento[%d] \n",I); scanf("%d",&Lista[I]); } /* fin del for */ return; } /* fin de la funcion Leer_Elementos() */ /* -------------------------------------- */ void Imprimir_Elementos() { system("cls"); for(I=1;I<=N;I++) { printf("Elemento[%d]=%d \n",I,Lista[I]); } /* fin del for */ printf("\n \n Pulse cualquier tecla para continuar \n"); getche(); return; } /* fin de la funcion Imprimir_Elementos() */
Problema7.2: Realice un programa que sume los elementos de una lista de “N” números. Prog7-2.c.
Función “main”
Función “leer_elementos”
Función “imprimir_elementos”
Función “sumar_elementos”
/* prog7-2.c */ #include /* declaracion de funciones */ void Leer_Elementos(); void Sumar_Elementos(); void Imprimir_Elementos(); /* declaracion de variables globales */ int I,N,Lista[100],Sumatoria; main() { /* llamar a las funciones */ Leer_Elementos(); Sumar_Elementos(); Imprimir_Elementos(); } /* fin de la funcion main() */ /* -------------------------------------- */ /* defincion de las funciones */ void Leer_Elementos() { system("cls"); printf("¨Cuantos elementos tiene la lista de numeros? \n"); scanf("%d",&N); for(I=1;I<=N;I++) { system("cls"); printf("Dame el Elemento[%d] \n",I); scanf("%d",&Lista[I]); } /* fin del for */ return; } /* fin de la funcion Leer_Elementos() */ /* -------------------------------------- */ void Sumar_Elementos() { Sumatoria=0; for(I=1;I<=N;I++) { Sumatoria=Sumatoria+Lista[I]; } /* fin del for */ return; } /* fin de la funcion Sumar_Elementos() */ /* -------------------------------------- */ void Imprimir_Elementos() { system("cls"); for(I=1;I<=N;I++) { printf("Elemento[%d]=%d \n",I,Lista[I]); } /* fin del for */ printf("La sumatoria de los elementos es %d \n",Sumatoria); printf("\n \n Pulse cualquier tecla para continuar \n"); getche(); return; } /* fin de la funcion Imprimir_Elementos() */
Problema 7.3: Realice un programa que determine el elemento mayor de una li sta de “N” números. 3.c.
Prog7-
Función “main”
Función “Leer_Elementos”
Función “Imprimir_Elementos”
Función “Elemento_mayor”
/* prog7-3.c */ #include /* declaracion de funciones */ void Leer_Elementos(); void Elemento_Mayor(); void Imprimir_Elementos(); /* declaracion de variables globales */ int I,N,Mayor,Lista[100]; main() { /* llamar a la funciones */ Leer_Elementos(); Elemento_Mayor(); Imprimir_Elementos(); } /* fin de la funcion main() */ /* -------------------------------------- */ /* definicion de funciones */ void Leer_Elementos() { system("cls"); printf("¿Cuantos elementos tiene la lista de numeros? \n"); scanf("%d",&N); for(I=1;I<=N;I++) { system("cls"); printf("Dame el Elemento[%d] \n",I); scanf("%d",&Lista[I]); } /* fin del for */ return; } /* fin de la funcion Leer_Elementos() */ /* -------------------------------------- */ void Elemento_Mayor() { Mayor=Lista[1]; for(I=2;I<=N;I++) { if(Lista[I]>Mayor) { Mayor=Lista[I]; } /* fin if(Lista[I]>Mayor) */ } /* fin del for */ return; } /* fin de la funcion Elemento_Mayor() */ /* -------------------------------------- */ void Imprimir_Elementos() { system("cls"); for(I=1;I<=N;I++) { printf("Elemento[%d]=%d \n",I,Lista[I]); } /* fin del for */ printf("El elemento mayor de esta lista es; %d \n",Mayor); printf("\n \n Pulse cualquier tecla para continuar \n"); getche(); return; } /* fin del funcion Imprimir_Elementos() */
Problema 7.4: Realice un programa que haga la búsqueda secuencial de un número en una lista de “N” números e imprima si fue encontrado o no. Suponga que ningún elemento se repite en la lista. Prog7-4.c. En este programa se puede observar que la variable Encontrado se utiliza como una variable de control que implica que si Encontrado=0 no se encontró el número buscado en la lista, pero si Encontrado=1 implica que el número buscado si está en la lista. Por otro lado, en la función Busqueda() se utilizó la sentencia continue que implica que termine el sin for() terminar su ejecución.
Función “main”
Función “Leer_Elementos”
Función “imprimir_elementos”
Función “busqueda”
/* prog7-4.c */ /*#include prog7-4.c */ #include /* declaracion de funciones */ /*void declaracion de funciones */ Leer_Elementos(); void voidLeer_Elementos(); Busqueda(); void voidBusqueda(); Imprimir_Elementos(); void Imprimir_Elementos(); /* declaracion de variables globales */ /*int declaracion de variables globales */ I,N,Buscado,Encontrado,Lista[100]; int I,N,Buscado,Encontrado,Lista[100]; char OPCION[2]; char OPCION[2]; main() main() { { /* llamar a las funciones */ /*Leer_Elementos(); llamar a las funciones */ Leer_Elementos(); do{ do{ system("cls"); system("cls"); Busqueda(); Busqueda(); printf("\n \n ¨Deseas hacer otra busqueda en la misma lista de numeros? \n"); printf("\n \n ¨Deseas hacer en olacualquier misma lista numeros? printf("Pulse la letra 'S' otra para busqueda continuar, otradeletra para \n"); printf("Pulse la letra 'S' para continuar, o cualquier otra letra para terminar\n terminar\n"); scanf(" scanf("%[^\n]",OPCION); %[^\n]",OPCION); }while(!strcmp(OPCION,"S") }while(!strcmp(OPCION,"S")||||!strcmp(OPCION,"s")); !strcmp(OPCION,"s")); } }/*/*fin findedelalafuncion funcionmain() main()*/*/ /*/*---------------------------------------------------------------------------*/*/ /*/*definicion definiciondedelas lasfunciones funciones*/*/ void voidLeer_Elementos() Leer_Elementos() {{ system("cls"); system("cls"); printf("¨Cuantos printf("¨Cuantoselementos elementostiene tienelalalista listadedenumeros? numeros?\n"); \n"); scanf("%d",&N); scanf("%d",&N); for(I=1;I<=N;I++) for(I=1;I<=N;I++) {{ system("cls"); system("cls"); printf("Dame printf("DameelelElemento[%d] Elemento[%d]\n",I); \n",I); scanf("%d",&Lista[I]); scanf("%d",&Lista[I]); } }/*/*fin findel delfor for*/*/ return; return; } }/*/*fin findedelalafuncion funcionLeer_Elementos() Leer_Elementos()*/*/
/*/*---------------------------------------------------------------------------*/*/ void voidBusqueda() Busqueda() {{ Encontrado=0; Encontrado=0; printf("Dame printf("Dameelelnumero numerobuscado: buscado:\n"); \n"); scanf("%d",&Buscado); scanf("%d",&Buscado); for(I=1;I<=N;I++) for(I=1;I<=N;I++) {{ if(Buscado==Lista[I]) if(Buscado==Lista[I]) {{ Encontrado=1; Encontrado=1; continue; continue; } }/*/*fin findel delif(Buscado==Lista[I]) if(Buscado==Lista[I])*/*/ } }/*/*fin findel delfor for*/*/ if(Encontrado==1) if(Encontrado==1) {{ printf("\n printf("\n\n\nElElnumero numeroSISIfue fueencontrado encontrado\n"); \n"); }} else else {{ printf("\n printf("\n\n\nElElnumero numeroNONOfue fueencontrado encontrado\n"); \n"); } }/*/*fin finif(Encontrado) if(Encontrado)*/*/ Imprimir_Elementos(); Imprimir_Elementos();/*/*llamada llamadaa alalafuncion funcionImprimir_Elementos() Imprimir_Elementos()*/*/ printf("\n printf("\n\n\nPulse Pulsecualquier cualquiertecla teclapara paracontinuar continuar\n"); \n"); getche(); getche(); return; return; } }/*/*fin findedelalafuncion funcionBusqueda Busqueda*/*/ /*/*---------------------------------------------------------------------------*/*/ void voidImprimir_Elementos() Imprimir_Elementos()
{{ for(I=1;I<=N;I++) for(I=1;I<=N;I++) {{ printf("Elemento[%d]=%d\n",I,Lista[I]); \n",I,Lista[I]); printf("Elemento[%d]=%d findel delfor for*/*/ } }/*/*fin return; return; findedelalafuncion funcionImprimir_Elementos() Imprimir_Elementos()* * } }/*/*fin
Problema 7.5. Utilice Funciones Definidas por el Usuario sin Parámetros y arreglos de memoria unidimensionales. Se deja caer una pelota desde una altura de 50 metros, rebota y cada vez su altura es de dos tercios de su altura en el rebote anterior. a) Elabore un programa que determine e imprima la altura de la pelota desde el primer rebote hasta que la altura de la pelota sea igual ó menor a un centimetro. b) Determine e imprima en cuál número del rebote en la altura de la pelota ya es igual o inferior a cincuenta centímetros. c) Calcule e imprima la altura promedio de la pelota en todos los rebotes. d) Calcule e imprima cuantos rebotes le proporcionan a la pelota una altura superior al promedio.
Función “main”
Función “inciso_a”
Función “inciso_b”
Función “inciso_c”
Función “inciso_d” prog7-5.c*/*/ /*/*prog7-5.c /* Pelotaque querebota rebota2/3 2/3partes partesdedesusualtura alturaanterior anterior*/*/ /* Pelota #include #include declaraciondedefunciones funciones*/*/ /*/*declaracion voidinciso_a(); inciso_a(); void voidinciso_b(); inciso_b(); void void inciso_c(); void inciso_c(); voidinciso_d(); inciso_d(); void declaraciondedevariables variablesglobales globales*/*/ /*/*declaracion float ALTURA[1000],ALTO,ALT_PROM; float ALTURA[1000],ALTO,ALT_PROM; intI,REBOTE,POSICION,ARRIBA; I,REBOTE,POSICION,ARRIBA; int main() main() {{ system("cls"); system("cls"); llamara alas lasfunciones funciones*/*/ /*/*llamar inciso_a(); inciso_a(); while(ALTO>0) while(ALTO>0) {{ inciso_b(); inciso_b(); inciso_c(); inciso_c(); inciso_d(); inciso_d(); break; romperelelciclo ciclowhile while*/*/ break; /*/*romper
}}/* /*fin findel delwhile while*/ */ }} /* /* fin finde de la lafuncion funcion main() main()*/ */ /* /* --------------------------------------------------------------------------- */ */ /* /*definicion definicionde delas lasfunciones funciones*/ */ void void inciso_a() inciso_a() {{ system("cls"); system("cls"); REBOTE=0; REBOTE=0; ALTO=1; ALTO=1; printf("Dame printf("Damela laaltura alturainicial inicialde dedonde dondese sedeja dejacaer caerla lapelota, pelota,en enmetros\n"); metros\n"); scanf("%f",&ALTO); scanf("%f",&ALTO); if(ALTO>0) if(ALTO>0) {{ do{ do{ REBOTE=REBOTE+1; REBOTE=REBOTE+1; ALTO=ALTO*2.0/3.0; ALTO=ALTO*2.0/3.0; ALTURA[REBOTE]=ALTO; ALTURA[REBOTE]=ALTO; }while(ALTO>0.01); }while(ALTO>0.01); /* /*imprimir imprimirtodos todoslos losrebotes rebotescon consus susalturas alturas*/ */ printf("\n\nImprimir printf("\n\nImprimirlos losRebotes Rebotesyysus susAlturas\n"); Alturas\n"); printf("Rebote printf("Rebote Altura\n"); Altura\n"); for(I=1;I<=REBOTE;I++) for(I=1;I<=REBOTE;I++) {{ printf("%d %8.4f\n",I,ALTURA[I]); printf("%d %8.4f\n",I,ALTURA[I]); }}/* /*fin findel delfor for*/ */ printf("Respuesta printf("Respuestaaala laPregunta Preguntadel delinciso incisoA\n"); A\n"); printf("\nTotal printf("\nTotalde deRebotes Rebotes%d%dhasta hastaalcanzar alcanzaraltura=1 altura=1cm. cm.o omenor\n",REBOTE); menor\n",REBOTE);
}} else else {{ printf("La printf("Laaltura alturainsertada insertadaes escero cerooomenor menoraacero cero\n"); \n"); printf("no printf("notiene tienesentido sentidohacer hacercalculos calculoscon coneste estenumero numero\n"); \n"); printf("si printf("sidese deseintentar intentarde denuevo nuevodebera deberade deejecutar, ejecutar,otra otravez, vez,el elprograma\n"); programa\n"); }}/* fin del if */ /* fin del if */ printf("\n\n printf("\n\npulse pulsecualquier cualquiertecla teclapara paracontinuar"); continuar"); getche(); getche(); return; return; }}/* /*fin finde dela lafuncion funcioninciso_a inciso_a*/ */ /* /* --------------------------------------------------------------------------- */ */ void void inciso_b() inciso_b() {{ system("cls"); system("cls"); for(I=1;I<=REBOTE;I++) for(I=1;I<=REBOTE;I++) {{ if(ALTURA[I]<=0.50) if(ALTURA[I]<=0.50) {{ POSICION=I; POSICION=I; I=REBOTE; I=REBOTE; }}/* /*fin findel delif if*/ */ }}/* /*fin findel delfor for*/ */ printf("Respuesta printf("Respuestaa ala laPregunta Preguntadel delinciso incisoB\n"); B\n"); printf("\nEl cms oo menor menor es es %d,con %d,con altura altura printf("\nEl rebote rebote en en que que la la altura es 50 cms %8.4f\n",POSICION,ALTURA[POSICION]); %8.4f\n",POSICION,ALTURA[POSICION]); printf("\n\n printf("\n\npulse pulsecualquier cualquiertecla teclapara paracontinuar"); continuar"); getche(); getche(); return; return; }}/* /*fin finde dela lafuncion funcioninciso_b inciso_b*/ */ /* /* --------------------------------------------------------------------------- */ */ void void inciso_c() inciso_c() {{
system("cls"); system("cls"); ALT_PROM=0; ALT_PROM=0; for(I=1;I<=REBOTE;I++) for(I=1;I<=REBOTE;I++) {{ ALT_PROM=ALT_PROM+ALTURA[I]; ALT_PROM=ALT_PROM+ALTURA[I]; } findel delfor for*/*/ } /*/*fin ALT_PROM=ALT_PROM/REBOTE; ALT_PROM=ALT_PROM/REBOTE; printf("Respuestaa alalaPregunta Preguntadel delinciso incisoC\n"); C\n"); printf("Respuesta printf("Laaltura alturaPromedio Promedioeses%8.4f\n",ALT_PROM); %8.4f\n",ALT_PROM); printf("La printf("\n\npulse pulsecualquier cualquiertecla teclapara paracontinuar"); continuar"); printf("\n\n getche(); getche(); return; return; findedelalafuncion funcioninciso_c inciso_c*/*/ } }/*/*fin
--------------------------------------*/*/ /*/*-------------------------------------voidinciso_d() inciso_d() void { { system("cls"); system("cls"); ARRIBA=0; ARRIBA=0; for(I=1;I<=REBOTE;I++) for(I=1;I<=REBOTE;I++) {{ if(ALTURA[I]>ALT_PROM) if(ALTURA[I]>ALT_PROM) {{ ARRIBA=ARRIBA+1; ARRIBA=ARRIBA+1; findel delifif*/*/ } }/*/*fin } /* fin del for*/*/ } /* fin del for printf("Respuestaa alalaPregunta Preguntadel delinciso incisoD\n"); D\n"); printf("Respuesta printf("Laaltura alturaPromedio Promedioeses%8.4f\n",ALT_PROM); %8.4f\n",ALT_PROM); printf("La printf("TotaldedeRebotes Rebotes%d\n",REBOTE); %d\n",REBOTE); printf("Total printf("Numerodederebotes rebotessuperior superioralalpromedio: promedio:%d\n",ARRIBA); %d\n",ARRIBA); printf("Numero printf("\n\n pulse cualquier tecla para regresar pantalladedeedicion"); edicion"); printf("\n\n pulse cualquier tecla para regresar a alalapantalla getche(); getche(); return; return; findedelalafuncion funcioninciso_d inciso_d*/*/ } }/*/*fin
7.2 PROBLEMAS PROPUESTOS: Arreglos de Memoria Unidimensionales
Problema 7.6. Realice un programa que imprima la tabla de multiplicar de cualquier número. Problema 7.7. Realice un programa que haga la búsqueda secuencial de un número en una lista de “N” números e imprima si fue encontrado o no. Suponga que los elementos de la lista se pueden repetir, si se repite imprima el número de veces que está repetido. Problema7.8. Realice un programa que sume los elementos de dos listas de números y guarde los valores en una tercera lista. Problema 7.9. Utilice Funciones Definidas por el Usuario sin Parámetros. En dos arreglos unidimensionales se tiene la siguiente información de “N” personas. En el primero, se tiene la altura en metros. En el segundo, se tiene el peso en kilogramos. En un tercer arreglo unidimensional deberá calcular el Índice de Masa Corporal (IMC) según la siguiente fórmula. IMC=Peso/ Altura 2 En un cuarto arreglo unidimensional deberá almacenar el resultado de acuerdo al IMC según la siguiente tabla: IMC Resultado Menos de 19 Bajo en Peso 19 a 25 Peso Normal 25 a 30 Sobre Peso Mayor de 30 Obesidad a) Elabore un programa que determine e imprima el Índice de Masa Corporal (IMC) promedio. b) Determine e imprima cuántas y cuáles personas están por encima o igual al promedio, y cuántas y cuáles por debajo del mismo.
c) Determine e imprima en cuántas personas pertenecen a cada categoría y el porcentaje que representan del total.
7.3 ARREGLOS DE MEMORIA BIDIMENSIONALES. Los arreglos bidimensionales permiten contemplar filas y columnas tal como sucede una matriz matemática como en el siguiente ejemplo: -25 12 -70 63
30 90 -36 42
89 -25 79 78
-45 50 -81 -27
La matriz de posiciones sería la siguiente, considere (Filas, Columnas) 1,1 2,1 3,1 4,1
1,2 2,2 3,2 4,2
1,3 2,3 3,3 4,3
1,4 2,4 3,4 4,4
En el ejemplo anterior tenemos una matriz con dimensión de 4 por 4, pero como ya sabemos pueden ser de N por N.
Problema 7.10: Para ver un ejemplo de la forma como se manejan los arreglos bidimensionales haremos un programa que sume los elementos de la diagonal principal de la matriz ( prog7-11.c). Para el caso de la matriz presentada como ejemplo, los elementos que forman parte de la diagonal principal son: -25 + 90 + 79 - 27 = 117, las posiciones que ocupan dichos elementos son (1,1) (2,2) (3,3) y (4,4). Es importante notar que en este programa estamos usando for() anidados.
Función “main”
Función “carga_matriz”
Función “suma_diagonal”
Función “imprimir_resultado”
/* prog7-10.c prog7-10.c */ */ /* #include /* suma suma la la diagonal diagonal principal principal de de una una matriz matriz */ */ #include /* /* declaracion de funciones */ /* declaracion de funciones */ void carga_matriz(); carga_matriz(); void void suma_diagonal(); void suma_diagonal(); void imprime_resultado(); void imprime_resultado(); /* declaracion declaracion de de variables variables globales globales */ */ /* int Matriz[10][10], I, J, N, SUMA, fila, columna; int Matriz[10][10], I, J, N, SUMA, fila, columna; main() main() {{ clrscr(); clrscr(); /* llamada llamada aa las las funciones funciones /* carga_matriz(); carga_matriz(); suma_diagonal(); suma_diagonal(); imprime_resultado(); imprime_resultado(); } /* fin de la funcion main() } /* fin de la funcion main() /* /* /* /*
*/ */
*/ */
------------------------------------------- */ */ ------------------------------------------definicion de funciones */ definicion de funciones */
void carga_matriz() carga_matriz() void { { clrscr(); clrscr(); printf("Dame printf("D ame la dimension dimension dimension de la la matriz matriz matriz \n"); \n"); printf("Dame printf("Da me la dim ension de scanf("%d",&N); scanf("%d",&N); for(I=1;I<=N;I++) for(I=1;I<=N;I++) {{ for(J=1;J<=N;J++) for(J=1;J<=N;J++) {{ printf("Dame printf("Dame el elemento[%d, elemento[%d,%d] %d] \n",I,J); \n",I,J); printf("Dame printf("Dame el elemento[%d,% elemento[%d,%d] d] \n",I,J); \n",I,J); scanf("%d",&Matriz[I][J]); scanf("%d",&Matriz[I][J]); /* fin fin del del for(J=1;J<=N;J++) for(J=1;J<=N;J++) */ */ }} /* } /* fin del for(I=1;I<=N;I++) */ } /* fin del for(I=1;I<=N;I++) */ return; return; } /* fin de la funcion carga_matriz */ } /* fin de la funcion carga_matriz */ /* ------------------------------------------------------------------------------------- */ */ /* void suma_diagonal() void suma_diagonal() {{ SUMA=0; SUMA=0; for(I=1;I<=N;I++) for(I=1;I<=N;I++) {{ for(J=1;J<=N;J++) for(J=1;J<=N;J++) {{ if(I==J) if(I==J) {{ SUMA=SUMA+Matriz[I][J]; SUMA=SUMA+Matriz[I][J]; } /* fin del if(I==J) */ } /* fin del if(I==J) */ /* fin fin del del for(J=1;J<=N;J++) for(J=1;J<=N;J++) */ */ }} /* } /* fin del for(I=1;I<=N;I++) */ } /* fin del for(I=1;I<=N;I++) */ return; return; } /* fin de la funcion suma_matriz */ } /* fin de la funcion suma_matriz */ /* ------------------------------------------- */ /* ------------------------------------------- */ void imprime_resultado() void imprime_resultado() { { system("cls"); system("cls"); fila=5; fila=5; for(I=1;I<=N;I++) for(I=1;I<=N;I++) {{ columna=5; columna=5; for(J=1;J<=N;J++) for(J=1;J<=N;J++) {{ //gotoxy(columna,fila); //gotoxy(columna,fila); printf("%d",Matriz[I printf("%d ",Matriz[I][J]); ][J]); printf("%d",Matriz[ printf("%d",Matriz[I][J]); I][J]); columna=columna+10; columna=columna+10; } /* fin del for(J=1;J<=N;J++) */ } /* fin del for(J=1;J<=N;J++) */ printf("\n"); printf("\n");
printf("\n"); fila=fila+1; fila=fila+1; }} /* /* fin fin del del for(I=1;I<=N;I++) for(I=1;I<=N;I++) */ */ printf("\n dia gonal pri ncipal %d\n",SUMA );; printf("\n \n \n La La suma suma de de la la diagonal diagonal diag onal principal principal prin cipal es es %d\n",SUMA); %d\n",SUMA) %d\n",SUMA); printf("Pulse printf("Pu cualq cont inuar \n") ; printf("Pulse printf("Pulse lse cualquier cualquier cualquier uier tecla tecla para para continuar continuar conti nuar \n"); \n"); getche(); getche(); return; return; }} /* /* fin fin de de imprime_resultado imprime_resultado */ */
Problema 7.11. Realizar el siguiente programa con funciones sin parámetros. En un arreglo bidimensional de 30x6 se tiene almacenadas las calificaciones de treinta alumnos en seis exámenes diferentes. Realice un programa que que obtenga lo siguiente. siguiente. a) El promedio de calificaciones de los treinta alumnos en los seis exámenes. b) El alumno o alumnos que obtuvieron la mayor calificación en el tercer examen, en cualquier caso deberá imprimir cuantos alumnos fueron. c) El examen en el que el promedio del grupo fue el más alto. d) Cuántos alumnos están aprobados y cuántos reprobados así como el porcentaje que representa. /* /* prog7-11.c prog7-11.c */ */ #include #include /* /* declaracion declaracion de de funciones funciones */ */ void void leer_datos(); leer_datos(); void void inciso_a(); inciso_a(); void void inciso_b(); inciso_b(); void void inciso_c(); inciso_c(); void void inciso_d(); inciso_d(); /* /* declaracion declaracion de de variables variables globales globales */ */ int int I, I, J, J, FILA, FILA, COLUMNA, COLUMNA, EXAMENES, EXAMENES, ALUMNOS,MAYORES[10]; ALUMNOS,MAYORES[10]; int int CONTAR,POSICION; CONTAR,POSICION; float float CAL[10][10], CAL[10][10], PROMEDIO[10],MAYOR,PROM_EX[10],SUMA; PROMEDIO[10],MAYOR,PROM_EX[10],SUMA; float float APROBADOS,REPROBADOS,PORC_APROBADOS, APROBADOS,REPROBADOS,PORC_APROBADOS, PORC_REPROBADOS; PORC_REPROBADOS; main() main() {{ system("cls"); system("cls"); /* /* llamada llamada aa las las funciones funciones */ */ leer_datos(); leer_datos(); inciso_a(); inciso_a(); inciso_b(); inciso_b(); inciso_c(); inciso_c(); inciso_d(); inciso_d(); }} /* /* fin fin de de la la funcion funcion main() main() */ */ /* /* ------------------------------------------------------------------------------------- */ */ /* /* definicion definicion de de funciones funciones */ */ void void leer_datos() leer_datos() {{ system("cls"); system("cls"); printf("¨Cuantos printf("¨C Al printf("¨Cuantos printf("¨Cuantos uantos Alumnos Alumnos Alumnos umnos son? son? \n"); \n"); scanf("%d",&ALUMNOS); scanf("%d",&ALUMNOS); printf("¨Cuantos printf("¨C Ex son printf("¨Cuantos printf("¨Cuantos uantos Examenes Examenes Examenes amenes son? son? son?? \n"); \n"); scanf("%d",&EXAMENES); scanf("%d",&EXAMENES); for(I=1;I<=ALUMNOS;I++) for(I=1;I<=ALUMNOS;I++) {{ system("cls"); system("cls"); printf("Dame printf("Da Cal ificaciones es Alu mno ## %d\n",I); %d\n printf("Dame printf("Dame me las las Calificacion Calificacion Calificaciones es del del Alumno Alumno Alumno %d\n",I); %d\n",I); ",I); for(J=1;J<=EXAMENES;J++) for(J=1;J<=EXAMENES;J++) {{ do{ do{ printf("Dame printf("D ame ca lififacion printf("Dame printf("Da me la la calififacion calififacion cal ififacion del del Examen Examen %d\n",J); %d\n",J); scanf("%f",&CAL[I][J]); scanf("%f",&CAL[I][J]); if(CAL[I][J]<0 || CAL[I][J]>100)
if(CAL[I][J]<0 || CAL[I][J]>100) {if(CAL[I][J]<0 || CAL[I][J]>100) printf("Calificacion on Invalida,"); Invalida,"); { printf("Calificaci printf("favor printf("f avor de insertar i nsertar otro otro,"); numero\n"); numero\n"); printf("Calificacio printf("Calificacion n Invalida,"); Invalida } /* fin del if */ printf("favor printf("favor de insertar insertar otro otro numero\n"); numero\n"); }while(CAL[I][J]<0 || CAL[I][J]>100); } /* fin del if */ } /* }while(CAL[I][J]<0 fin del for(J=1;J<=EXAMENES;J++) */ || CAL[I][J]>100); } /*} fin del for(I=1;I<=ALUMNOS;I++) */ /* fin del for(J=1;J<=EXAMENES;J++) */ printf("\n\nPulse printf("\n cualquier cualquier tecla tecla para*/ continuar\n"); continuar\n"); } /* fin \nPulse del for(I=1;I<=ALUMNOS;I++) getche(); printf("\n\nPulse printf("\n\nPulse cualquier cualquier tecla para continuar\n"); continuar\n"); return; getche(); } /* fin de la funcion leer_datos */ return; } /* fin de la funcion leer_datos */ /* ------------------------------------------- */ void inciso_a() /* ------------------------------------------*/ {void inciso_a() { system("cls"); SUMA=0; system("cls"); for(I=1;I<=ALUMNOS;I++) SUMA=0; {for(I=1;I<=ALUMNOS;I++) {for(J=1;J<=EXAMENES;J++) {for(J=1;J<=EXAMENES;J++) { SUMA=SUMA+CAL[I][J]; } /* SUMA=SUMA+CAL[I][J]; fin del for(J=1;J<=EXAMENES;J++) */ PROMEDIO[I]=SUMA/EXAMENES; } /* fin del for(J=1;J<=EXAMENES;J++) */ SUMA=0; PROMEDIO[I]=SUMA/EXAMENES; } /* fin del for(I=1;I<=ALUMNOS;I++) */ SUMA=0; } /* fin del for(I=1;I<=ALUMNOS;I++) */ printf("Promedios printf("Promedios por Alumno\n"); Alumno\n"); for(J=1;J<=EXAMENES;J++) printf("Promedios printf("Promedios por por Alumno\n"); Alumno\n"); {for(J=1;J<=EXAMENES;J++) EX%d\t",J); EX%d\t",J); { printf(" } /* fin del for(J=1;J<=EXAMENES;J++)*/ printf(" EX%d\t",J); EX%d\t",J); printf("\tPromedio printf("\ \n"); } /* fintPromedio\n"); del for(J=1;J<=EXAMENES;J++)*/ printf("\tPromedio\n printf("\tPromedio\n"); "); for(I=1;I<=ALUMNOS;I++) {for(I=1;I<=ALUMNOS;I++) {for(J=1;J<=EXAMENES;J++) {for(J=1;J<=EXAMENES;J++) printf("%8.2f",CAL[ printf("% 8.2f",CAL[I][J]); I][J]); { } /* fin del for(J=1;J<=EXAMENES;J++) */ printf("%8.2f",CAL printf("%8.2f",CAL[I][J]); [I][J]); printf("\tAlumno printf("\t Alumno #%d=%8.2f\n", #%d =%8.2f\n",I,PROMEDI I,PROMEDIO[I]); O[I]); } /* fin del for(J=1;J<=EXAMENES;J++) */ } /* fin del for(I=1;I<=ALUMNOS;I++) */ printf("\tAlumno printf("\tAlumno #%d=%8.2f\n" #%d=%8.2f\n",I,PROMED ,I,PROMEDIO[I]); IO[I]); printf("\n\nPulse printf("\n cualquier cualquier tecla tecla para*/ continuar\n"); continuar\n"); } /* fin \nPulse del for(I=1;I<=ALUMNOS;I++) getche(); n\nPulse cualquier printf("\n\nPulse printf("\ cualquier tecla para continuar\n"); continuar\n"); return; getche(); } /* fin de la funcion inciso_a */ return; } /* fin de la funcion inciso_a */ /* ------------------------------------------- */ void inciso_b() /* ------------------------------------------*/ {void inciso_b() { /* tercer examen */ J=3; /* tercer examen */ MAYOR=CAL[1][J]; MAYOR=CAL [1][J]; J=3; for(I=2;I<=ALUMNOS;I++) MAYOR=CAL[1][J]; MAYOR=CAL[1][J]; {for(I=2;I<=ALUMNOS;I++) { if(CAL[I][J]>MAYOR) {if(CAL[I][J]>MAYOR) MAYOR=CAL[I][J]; { MAYOR=CAL[I][J]; } /* fin del [I][J]; if() */ MAYOR=CAL[I][J]; MAYOR=CAL } /* } fin del for(I=1;I<=ALUMNOS;I++) */ /* fin del if() */ } /* fin del for(I=1;I<=ALUMNOS;I++) */ for(I=1;I<=ALUMNOS;I++) {for(I=1;I<=ALUMNOS;I++) { if(CAL[I][J]==MAYOR) {if(CAL[I][J]==MAYOR) MAYOR=CAL[I][J]; { MAYOR=CAL[I][J]; CONTAR=CONTAR+1; MAYOR=CAL[I][J]; MAYOR=CAL[ I][J]; MAYORES[CONTAR]=I; MAYORES[C ONTAR]=I; CONTAR=CONTAR+1; } /* MAYORES[CONTAR]=I; fin del if() */ MAYORES[CO NTAR]=I; } /* } fin del for(I=1;I<=ALUMNOS;I++) */ /* fin del if() */ } /* fin del for(I=1;I<=ALUMNOS;I++) */
printf("Alumnos printf("Alumnoscon conlalacalificacion calificacionmas masAlta AltaenenelelTercer TercerExamen\n"); Examen\n"); for(I=1;I<=CONTAR;I++) for(I=1;I<=CONTAR;I++) {{ printf("AlumnoNumero Numero%d\n",MAYORES[I]); %d\n",MAYORES[I]); printf("Alumno } /* fin del for(I=1;I<=CONTAR;I++) } /* fin del for(I=1;I<=CONTAR;I++) */*/ printf("\n\nPulsecualquier cualquiertecla teclapara paracontinuar\n"); continuar\n"); printf("\n\nPulse getche(); getche(); return; return; } /* findedelalafuncion funcioninciso_b inciso_b*/*/ } /* fin -------------------------------------------*/*/ /*/*------------------------------------------voidinciso_c() inciso_c() void { { SUMA=0; SUMA=0; for(I=1;I<=ALUMNOS;I++) for(I=1;I<=ALUMNOS;I++) {{ for(J=1;J<=EXAMENES;J++) for(J=1;J<=EXAMENES;J++) {{ PROM_EX[J]=PROM_EX[J]+CAL[I][J]; PROM_EX[J]=PROM_EX[J]+CAL[I][J]; findel delfor(J=1;J<=EXAMENES;J++) for(J=1;J<=EXAMENES;J++)*/*/ } }/*/*fin findel delfor(I=1;I<=ALUMNOS;I++) for(I=1;I<=ALUMNOS;I++)*/*/ } }/*/*fin for(J=1;J<=EXAMENES;J++) for(J=1;J<=EXAMENES;J++) {{ PROM_EX[J]=PROM_EX[J]/EXAMENES; PROM_EX[J]=PROM_EX[J]/EXAMENES; printf("Promedio examen#%d #%d= =%8.2f\n",J,PROM_EX[J]); %8.2f\n",J,PROM_EX[J]); printf("Promedio enenelelexamen } /* fin del for for(J=1;J<=EXAMENES;J++) } /* fin del for for(J=1;J<=EXAMENES;J++) */*/ MAYOR=PROM_EX[1]; MAYOR=PROM_EX[1]; for(I=0;I<=ALUMNOS;I++) for(I=0;I<=ALUMNOS;I++) {{ if(PROM_EX[I]>MAYOR) if(PROM_EX[I]>MAYOR) {{ MAYOR=PROM_EX[I]; MAYOR=PROM_EX[I]; POSICION=I; POSICION=I; } /* findel delif() if()*/*/ } /* fin findel delfor(I=2;I<=ALUMNOS;I++) for(I=2;I<=ALUMNOS;I++)*/*/ } }/*/*fin printf("ElExamen Examendel delpromedio promediomas masalto altoeses%d%dcon con%8.2f\n",POSICION+1,MAYOR); %8.2f\n",POSICION+1,MAYOR); printf("El printf("\n\nPulsecualquier cualquiertecla teclapara paracontinuar\n"); continuar\n"); printf("\n\nPulse getche(); getche(); return; return; findedelalafuncion funcioninciso_c inciso_c*/*/ } }/*/*fin -------------------------------------------*/*/ /*/*------------------------------------------voidinciso_d() inciso_d() void {{ system("cls"); system("cls"); for(I=1;I<=ALUMNOS;I++) for(I=1;I<=ALUMNOS;I++) {{ if(PROMEDIO[I]>=70) if(PROMEDIO[I]>=70) {{ APROBADOS=APROBADOS+1; APROBADOS=APROBADOS+1; } } else else REPROBADOS=REPROBADOS+1; { { REPROBADOS=REPROBADOS+1; findel delif() if()*/*/ } }/*/*fin } /* fin del for(I=1;I<=ALUMNOS;I++) } /* fin del for(I=1;I<=ALUMNOS;I++) */*/ PORC_APROBADOS=APROBADOS/ALUMNOS*100; PORC_APROBADOS=APROBADOS/ALUMNOS*100; PORC_REPROBADOS=REPROBADOS/ALUMNOS*100; PORC_REPROBADOS=REPROBADOS/ALUMNOS*100; printf("Aprobados %8.2f Porcentaje PorcentajeAprobados=%8.2f\n",APROBADOS,PORC_APROBADOS); Aprobados=%8.2f\n",APROBADOS,PORC_APROBADOS); printf("Aprobados = =%8.2f printf("Reprobados= =%8.2f %8.2f Porcentaje PorcentajeReprobados=%8.2f\n",REPROBADOS,PORC_REPROBADOS); printf("Reprobados Reprobados=%8.2f\n",REPROBADOS,PORC_REPROBADOS); printf("\n\nPulse cualquier tecla para volver a la pantalla de edicion \n"); printf("\n\nPulse cualquier tecla para volver a la pantalla de edicion \n"); getche(); getche(); return; } /* return; fin de la funcion inciso_d */ } /* fin de la funcion inciso_d */
7.4 PROBLEMAS PROPUESTOS: Arreglos de Memoria Bidimensionales
Problema 7.12: Realice un programa que sume los elementos de la diagonal secundaria de una matriz. Problema 7.13: Realice un programa que sume los elementos centrales de una matriz. Problema 7.14: Realice un programa que sume los elementos periféricos de una matriz. Problema 7.15: Realice un programa que sume los elementos de la matriz triangular superior. Problema 7.16: Realice un programa que sume los elementos de la matriz triangular triangular inferior. Problema 7.17: Realice un programa que sume dos matrices y guarde el resultado en una tercera matriz. Problema 7.18: Realice un programa que determine cuántos elementos pares y cuántos impares hay en una matriz y cuántos de ellos son Cero. Problema 7.19: Realice un programa que suma las filas y las columnas de una matriz. Se deberá imprimir la sumatoria por fila y por columnas. Problema 7.20: Realice un programa que determine el elemento mayor de una matriz así como su posición Problema 7.21: Realice un programa que multiplique multiplique matrices. Problema 7.22: Realice un programa que resuelva un problema de ecuaciones simultaneas a través del método: Gauss-Jordan y Montante. Problema 7.23. En este programa utilice variables enumeradas. En un arreglo bidimensional de 12x3 se tiene los costos de producción de tres departamentos: dulces, bebidas y conservas. Los costos de producción corresponden a cada mes de año anterior. Escriba un programa que pueda proporcionar la siguiente información. información. e) ¿En qué mes se registro el mayor costo de producción de dulces?. f) ¿Promedio anual de los costos de producción de bebidas. g) ¿En qué mes se registró el mayor costo de producción en bebidas y en que mes el de menor costo. h) ¿Cuál fue el rubro que tuvo el menor menor costo de producción en diciembre?
Capítulo #8 Funciones definidas por el usuario con Parámetros Hasta el momento, al nombre de todas las funciones que han sido definidas por el usuario se les antepone la palabra void, esto en la declaración y la definición de la función; en la llamada de la función esta palabra se omite. Cuando Cuando se escribe void, se está diciendo que la función no regresa valores, por eso al final de la función se escribe return. La función main () también puede llevar void y funciona igual. La palabra void puede ser sustituida por cualquier tipo de datos: int, char, float, etc. Esto indica el tipo de datos que la función puede regresar., y cuando la función devuelve valores se escribe return y entre paréntesis la la variable que está está regresando. Durante el presente capitulo se presentarán una serie de programas que intentarán que se vea de forma práctica el paso paso de parámetros parámetros entre funciones. funciones. En el programa prog8-1.c con la declaración de la función: char minusc_a_mayusc (char minusc); se puede deducir que esta función regresa regresa una variable de tipo carácter y lleva como como parámetro la variable minusc que también es de tipo carácter. En la definición de la función se puede observar que hay una variable local llamada c1 misma que va a tomar el valor que tenga la variable minusc. También, dentro de esta función aparece un if() simplificado: simplificado: c2=(c1>='a' && c1<='z') ?('A'+c1-'a'):c1;. Si este if() simplificado no se logra entender no se preocupe, más adelante podrá hacerlo. Por último, observe que al final de la definición de la función aparece la instrucción return(c2) donde se indica que c2 contiene el equivalente en mayúscula de la letra que se pulsó y este valor de regresa para ser depositado su valor en la variable mayusc. /* prog8-1.c */ #include #include /* convertir un caracter en minuscula a mayúscula utilizando utilizando una funcion definida por el usuario */ main() { char minusc,mayusc; minusc,mayusc; /* declaracion de la funcion */ char minusc_a_mayusc(char minusc); printf("Por favor, favor, introduce una letra minuscula minuscula : "); scanf("%c",&minusc); /* llamada a la funcion */ mayusc=minusc_a_mayusc(minusc); printf("\nLa mayuscula mayuscula equivalente equivalente es %c\n\n",mayusc); %c\n\n",mayusc); getche(); } /* termina la funcion main() */ /* ---------------------------------------------------------------------------------------------------- */ /*definicion de la funcion */ char minusc_a_mayusc(char c1) { char c2; c2=(c1>='a' && c1<='z') ?('A'+c1-'a'):c1; return(c2); } /* termina funcion minusc_a_mayusc */
En el Programa prog8-2.c, con la declaración de la función int máximo (int a, int b); se puede observar que esta función regresa una variable de tipo entero y lleva como co mo parámetros a las variables “a” y “b” int máximo (int x, int y), están las variables que también son de tipo entero. Ya en la definición de la función: “x” y “y”, donde “x” tomará el valor de “a” y “y” tomará el valor de “b”. Dentro de esta función hay un if() simplificado que en esta ocasión es más fácil de entender que en el ejemplo anterior. La variable “z” es una variable local a la función maximo() , misma que tomará el valor del número mayor de los dos valores que hayan sido introducidos. Observe que la función puede pero no regresa ningún valor, esto es fácilmente deducible porque el final de la función maximo() sólo esta: return 0;. /* prog8-2.c */ #include #include /* determina el valor maximo de dos valores */ main() { int a,b; /* declaracion de la funcion */ int maximo(int a,int b); printf("dame printf("dame el valor valor de a : \n"); scanf("%d",&a); printf("dame printf("dame el valor valor de b : \n"); scanf("%d",&b); /* llamada a la funcion maximo */ maximo(a,b); maximo(a,b); getche(); } /* termina la funcion main() */ /* ---------------------------------------------- */ /* definicion de la funcion */ int maximo(int x,int y) { /* variable local a la funcion maximo */ int z; z=(x>=y) ? x:y; printf("\n\nValor printf("\n\nValor maximo = %d\n",z); %d\n",z); return 0; } /* termina funcion maximo */
Diagrama.
En el programa prog8-3.c tenemos que con la declaración de la función: long int factorial(int n); se puede deducir que esta función regresa un valor largo entero y lleva como parámetro a la variable “n” que es de tipo entero. Con la definición de la función: long int factorial(int m ) podemos ver que la variable “m” tomará el valor de variable “n”. La función calculará el factorial del número mismo que se almacenará en la variable prod, y con la instrucción return(prod) el valor de prod se regresará y se almacenará en la variable res. /* prog8-3.c */ #include main() { int n; long int res; /* declaracion de la funcion */ long int factorial(int n); printf("Dame n para factorial : "); scanf("%d",&n); /* llamada a la funcion factorial */ res=factorial(n); printf("\nel factorial de %d = %ld\n\n",n,res); getche(); } /* termina funcion main() */ /* ----------------------------------- */ /*definicion de la funcion */ long int factorial(int m) { int i; long int prod=1; if(m > 1) for(i=2 ; i<=m ; ++i) prod *=i; return(prod); } /* termina funcion factorial */
Diagrama.
Observe en el programa pro8-4.c como la función maximo() se llama la primera vez y se lleva como parámetros a las variables “a” y “b”, y el número mayor de estos dos se guarda en “d”, después se llama la segunda ocasión y se lleva como parámetros a “c” y “d”, y se imprime el valor mas grande de los tres valores que inicialmente se habían tecleado. Observe que a diferencia a lo que pasó en programa prog8-2.c, ahora la función maximo() si regresa un valor, lo podemos deducir porque ahora, al final de la función aparece: return(z);. /* prog8-4,c */ #include /* determinar la mayor de tres cantidades enteras */ main() { int a,b,c,d; /* leer las tres cantidades enteras */ printf("dame el valor de a : \n"); scanf("%d",&a); printf("dame el valor de b : \n"); scanf("%d",&b); printf("dame el valor de c : \n"); scanf("%d",&c); /* calcular y visualisar el valor maximo */ /* llamada a la funcion maximo */ d=maximo(a,b); /* llamada a la funcion maximo */ printf("\n\nmaximo = %d\n",maximo(c,d)); getche(); } /* termina funcion main() */ /* ------------------------------------------------ */ /* definicion de la funcion */ maximo (x,y) /* determinar el mayor de dos cantidades enteras */ int x,y; { int z; z=(x>=y) ? x:y; return(z); } /* termina funcion maximo */
Diagrama.
En el programa prog8-5.c observe como la variable “a” es un variable local a la función main() pero también es una variable local a la función modificar(). Corra este programa y vea el comportamiento de esta variable dentro y fuera de la función main() . /* prog8-5.c */ #include /* ver comportamiento de una variable global y una local */ main() { int a=2; printf("\n a = %d (desde main, antes de llamar a la funcion)",a); /* llamada a la funcion modificar*/ modificar(a); printf("\n a = %d (desde main, despues de llamar a la funcion)",a); getche(); }/* fin de la funcion main() */ /* ------------------------------------------------- */ /* definicion de la funcion */ modificar(a) int a; { a*=3; printf("\n a = %d (desde la funcion, despues de modificar el valor)",a); return; } /* termina funcion modificar */
Diagrama.
RECURSIVIDAD Se llama recursividad a un proceso mediante el que una función se llama así misma de forma repetida, hasta que se satisface alguna determinada condición. El proceso se utiliza para computaciones recursivas en las que cada acción se determina en función de un resultado anterior. Se pueden escribir en esta forma muchos problemas iterativos. La recursividad es una técnica de programación importante. Se utiliza para realizar una llamada a una función desde la misma función. Como ejemplo útil se puede presentar el cálculo de números factoriales. La recursividad y la iteración están muy relacionadas, cualquier acción que pueda realizarse con la recursividad puede realizarse con iteración y viceversa. Normalmente, un cálculo determinado se prestará a una técnica u otra, sólo necesita elegir el enfoque más natural o con el que se sienta más cómodo. Podemos distinguir dos tipos de recursividad: Directa: Cuando un subprograma se llama a sí mismo una o más veces directamente. Indirecta: Cuando se definen una serie de subprogramas usándose unos a otros. Un algoritmo recursivo consta de una parte recursiva, otra iterativa o no recursiva y una condición de terminación. La parte recursiva y la condición de terminación siempre existen. En cambio la parte no recursiva puede coincidir con la condición de terminación. Se deben satisfacer dos condiciones para que se pueda resolver un problema recursivamente. Primero, el problema se debe escribir en forma recursiva, y segundo, la sentencia del problema debe incluir una condición de fin.
En el programa prog8-6.c se puede ver un programa que utiliza recursividad, es decir una función que se llama así misma. Observe como en la declaración de la función void inverso(void); la función no regresa valores y además se lleva una argumento vacío ( void). /* prog8-6.c */ #include #define EOLN '\n' /* leer una linea de texto y escrbirla en orden inverso utilizando recursividad */ main() { /* declaracion de la funcion */ void inverso(void); printf("introduce una linea de texto\n"); /* llamada a la funcion inverso */ inverso(); getche(); }/* fin de la funcion main() */ /* ------------------------------------ */ /* definicion de la funcion */ void inverso(void) /* leer una linea de caracteres y escribirla en orden inverso */ { char c; if((c=getchar())!=EOLN) { inverso(); /* la funcion se llama asi misma */ putchar(c); } /* fin del if((c=getchar())!=EOLN) */ return; } /* termina funcion inverso */
Problema 8.1: Realice el programa que calcule el factorial de un número utilizando recursividad. Problema 8.2: Realice el programa que calcule la serie de Fibonacci utilizando recursividad.
Capítulo #9 Apuntadores, Tipos de Datos definidos por el usuario y Archivos Archivos de Datos. 9.1 APUNTADORES El entendimiento y correcto uso de los apuntadores es crítico para la creación correcta de la mayoría de los programas de C. Hay tres razones para ello: Primera, los apuntadores proporcionan los medios mediante los que las funciones modifican sus argumentos de la llamada. Segunda, se pueden utilizar para soportar las rutinas de asignación dinámica de C. Tercera, se pueden sustituir por arreglos de memoria en muchas situaciones para incrementar la eficiencia. Además de ser una de las características más poderosas de C, los apuntadores son también una de las más peligrosas. Por ejemplo, usando apuntadores sin inicializar o fuera de control se puede provocar la caída del sistema. Quizá peor, es más común el usar incorrectamente los apuntadores, que provocar errores que son difíciles de encontrar.
9.1.1 Conceptos Básicos Dentro de la memoria de la computadora cada dato almacenado ocupa una o más celdas contiguas de memoria, por ejemplo palabras o bytes adyacentes. El número de celdas de memoria requeridas para almacenar un dato depende de su tipo. Así, un carácter ( char) será normalmente almacenado en un byte (8 bits) de memoria; un entero ( int) usualmente necesita necesita dos bytes contiguos; contiguos; un número real real de simple presición ( float) cuatro bytes contuiguos, y una cantidad en doble precisión ( double) puede requerir 8 bytes contiguos. Antes de seguir adelante es necesario recalcar que la memoria de una computadora está organizada por celdas adyacentes numeradas consecutivamente, desde el principio hasta el fin del área de memoria. La mayoría de la compuadtoras usan el sistema de numeración hexadecimal para asignar las direcciones de celdas de memoria consecutivas, aunque algunas computadoras computadoras usan el sistema octal de numeración. De esta forma, supongamos que v es una variable que representa que representa un determinado dato. El compilador automáticamente asignará celdas de memoria para este dato. El dato puede ser accedido si conocemos su localización ( la dirección) de la primera celda de memoria. La dirección de memoria de v puede ser determinada mediante la expresión &v, donde & es un operador unario, llamado operador de dirección, que proporciona la dirección del operando. En la siguiente expresión vamos a asignar a la variable pv la dirección de v.
pv = & v Esta nueva variable pv es un apuntador a v, desde su “posición” hasta el lugar donde v está almacenada en memoria. Se debe recordar que pv representa la dirección de v y no su valor. La relación de pv y v está ilustrada en la siguiente figura. Dirección de v
Valor de v
pv v El dato representado por v (el dato almacenado en las celdas de memoria de v) puede ser accedido mediante la expresión *pv, donde * es un operador unario, llamado operador de indirección, que opera sólo sobre una variable variable apuntador. Por tanto * pv y v representan el mismo dato (el contenido de las mismas celdas de memoria). Además, si escribimos pv=&v y u=pv , entonces u y v representan el mismo valor, por ejemplo, el valor de v puede ser indirectamente indirectamente asignado a u (se asume que u y v están declaradas del mismo tipo). En resumen, un apuntador es una variable que contiene una d irección de memoria. Normalmente Normalmente esta dirección es una posición de otra variable en la memoria. Aunque podría ser la dirección de un puerto o de la RAM de propósito general, tal como la memoria intermedia de vídeo (buffer). Si una variable contiene la dirección de otra variable se dice que la primera variable apunta a la segunda.
9.1.2 Declaración de Apuntadores Los apuntadores como cualquier otra variable, deben ser declarados antes de ser usados d entro de un programa en C. Sin embargo, la interpretación de una declaración de apuntador es un poco diferente de la declaración de otras variables. Cuando una variable apuntador es definida, el nombre de la variable debe ir precedido por un asterisco asterisco (*). Este Este identifica identifica que la variable variable es un apuntador. El tipo de dato dato que aparece en la declaración se refiere al tipo de objeto del apuntador, esto es, el tipo de dato que se almacena en la dirección representada por el apuntador, en vez del apuntador mismo. Observe el programa prog9-1.c. /* prog9-1.c */ #include #include main() { /* declaracion de variables */ int u; int v; int *pu; /* apuntador a un entero */ int *pv; /* apuntador a un entero */ u=3; /* asigna a u el valor de 3 */ pu=&u; /* asigna direccion direccion de u a pu */ v=*pu; /* asina valor de u a v */ pv=&v; /* asigna direccion direccion de v a pv */ printf("\n \n u=%d &u=%d pu=%d printf("\n \n v=%d &v=%d pv=%d getche(); } /* fin de la funcion main() */
*pu=%d \n",u,&u,pu,* \n",u,&u,pu,*pu); pu); *pv=%d \n",v,&v,pv,* \n",v,&v,pv,*pv); pv);
Con el programa prog9-2.c observe como se realiza una operación matemática común y corriente, y después una operación matemática usando un apuntador. /* prog9-2.c */ #include #include main() { int u1, u2; int v; int *pv; /* variable apuntador */ v=3; u1=2*(v+5); /* expresion matematica comun */ pv=&v; /* pv apunta apunta u2=2*(*pv+5); /* expresion printf(" u1=%d u2=%d getche(); } /* fin de la funcion main()
a v */ */ matematica equivalente usado el apuntador*/ \n",u1,u2); \n",u1,u2); */
En el programa prog9-3.c, observe como la variable v cambia de valor por medio de una reasignación indirecta, es decir, utilizando el apuntador.
/* prog9-3.c */ #include #include main() { int v; int *pv;
/*
v=3; pv=&v; /* printf(" *pv=%d
variable apuntador */ pv apunta a v */ v=%d \n",*pv,v); \n",*pv,v);
*pv=7; /* reasignacion indirecta */ printf(" *pv=%d v=%d \n",*pv,v); \n",*pv,v); getche(); } /* fin de la funcion main() */
9.2 TIPOS DE DATOS DEFINIDOS POR EL USUARIO Lenguaje C permite crear cinco clases diferentes de tipos de datos personalizados: Estructurado. Es un grupo de variables bajo un 1. Tipo de Datos Estructurado un mismo nombre. nombre. 2. Tipo de Datos de Campo Bit. Es una variación del estructurado y permite un acceso fácil a los bits de una palabra. palabra. 3. Tipo de Datos Unión. Habilita para definir el mismo trozo de memoria como dos o más tipos diferentes de variables. 4. Tipo de Datos de Enumeración. Es una lista de símbolos 5. El último tipo de datos se crea usando: typedef .,., y simplemente crea un nuevo nombre para un tipo existente. Como preámbulo al manejo de archivos de datos nos enfocaremos es este último, utilizando typedef . Como dijimos anteriormente. Lenguaje C permite definir nuevos nombres de datos explícitamente usando la palabra clave clave typedef . Realmente no está creando una nueva clase datos, sino definiendo un nuevo nombre para un tipo existente. Los siguientes son ejemplos de cómo se puede declarar este tipo de datos.
typedef struct{ long int matricula; char nombre[15]; char ap_paterno[15]; char ap_materno[15]; } alumno; alumno universidad;
Con el anterior ejemplo podemos decir que la estructura se llama alumno (también se dice que el nombre del registro es alumno ) y tiene las siguientes variables: matricula, nombre, ap _ paterno paterno y ap _ materno materno. Enseguida se declaró a la variable universidad como del tipo alumno. En este caso se dice que la variable universidad es una variable de tipo registro. Otro ejemplo sería:
typedef struct{ long int No_cuenta; char nombre_cliente[15]; char calle[30]; int numero; char colonia[30]; char ciudad[30]; char estado[30]; } direccion; direccion cliente;
La estructura se llama direccion con las siguientes variables: No _ cuenta, nombre_cliente, calle, numero , colonia, ciudad y estado. Enseguida, se declaró la variable cliente del tipo de direccion. Como anteriormente se hizo la aclaración la variable cliente es una variable tipo registro. En el programa pro9-4.c, la estructura se llama jornada con las siguientes variables: Num _ Empleado, Nombre , Horas _ Trab y Num _ Depto. Así mismo, la variable tipo registro se llama empleado. En este programa se puede ver como se utilizó la variable tipo registro. Dentro de los scanf() se escribió la variable tipo registro, después un punto y por último un nombre de variable de la estructura, por ejemplo: empleado.Num_Empleado. Nota el programa prog9-4.c es el mismo que prog6-2.c en el que se muestra el uso de typedef /* prog9-4.c */ #include #include #include /* declaracion de funciones */ void inicializar(); void proceso(); void sueldos(); void departamentos(); /* declaraci•n de variables globales */
typedef struct{ long int Num_Empleado; char Nombre[30]; float Horas_Trab; int Num_Depto; } jornada; jornada empleado; char Descripcion[30]; int Empleados, Contador; int Cantidad1, Cantidad2, Cantidad3; float Horas_Norm, Horas_Ext, Sueldo; float Acum1, Acum2,Acum3; main() { /* llamadas a la funcion */ inicializar(); proceso(); departamentos(); } /* fin de la funcion main() */ /* ----------------------------------------- */ /* definicion de funciones */ void inicializar()
{ Cantidad1=0; Cantidad2=0; Cantidad3=0; Acum1=0; Acum2=0; Acum3=0; return; }/* fin de la funcion inicializar() */ /* ----------------------------------------- */ void proceso() { printf("¨Cuantos empleados son? \n"); scanf("%d",&Empleados); for(Contador=1;Contador<=Empleados;Contador++) { printf("Introduzca los datos del empleado: %d \n",Contador); printf("Dame el numero de Empleado \n"); scanf("%ld",&empleado.Num_Empleado); printf("Dame el nombre del Empleado \n"); scanf(" %[^\n]",empleado.Nombre); printf("Dame las horas trabajadas \n"); scanf("%f",&empleado.Horas_Trab); do{ printf("Dame el numero de Departamento <1 al 3> \n"); scanf("%d",&empleado.Num_Depto); if(empleado.Num_Depto<1 || empleado.Num_Depto>3) { printf("\n \n ERROR! Departamento NO Existe! \n"); printf("Pulse un numero de departemento existente <1 al 3>\n"); } else { sueldos(); /* llamada a la funcion sueldo */ } }while(empleado.Num_Depto<1 || empleado.Num_Depto>3); } /* fin del for */ return; } /* fin de la funcion proceso() */ /* ----------------------------------------- */ void sueldos() { if(empleado.Horas_Trab>48) { Horas_Norm=48; Horas_Ext=empleado.Horas_Trab - 48; } else { Horas_Norm=empleado.Horas_Trab; Horas_Ext=0; } /* fin if(Hrs_Trab>48) */ switch(empleado.Num_Depto) { case 1: { Sueldo=Horas_Norm*10+Horas_Ext*18; strcpy(Descripcion,"Ventas"); Cantidad1=Cantidad1+1; Acum1=Acum1+Sueldo; break; } /* fin del case 1 */ case 2: { Sueldo=Horas_Norm*13+Horas_Ext*20; strcpy(Descripcion,"Produccion");
Cantidad2=Cantidad2+1; Acum2=Acum2+Sueldo; break; } /* fin del case 2 */ case 3: { Sueldo=Horas_Norm*15+Horas_Ext*25; strcpy(Descripcion,"Sistemas"); Cantidad3=Cantidad3+1; Acum3=Acum3+Sueldo; break; } /* fin del case 3 */ } /* fin del switch */
printf("Numero de Empleado: %ld \n",empleado.Num_Empleado); printf("Nombre del Empleado: %s \n",empleado.Nombre); printf("Del Departamento : %s \n",Descripcion); printf("Tiene un sueldo de $%8.2f \n",Sueldo); printf("\n \n Pulse cualquier tecla para continuar \n"); getche(); return; } /* fin de la funcion sueldos */ /* ----------------------------------------- */ void departamentos() { printf("\n \n El departamento de Ventas tiene %d empleados \n",Cantidad1); printf("Los cuales ganan en conjunto $%10.2f pesos\n",Acum1); printf("\n \n El departamento de Produccion tiene %d empleados \n",Cantidad2); printf("Los cuales ganan en conjunto $%10.2f pesos\n",Acum2); printf("\n \n El departamento de Sistemas tiene %d empleados \n",Cantidad3); printf("Los cuales ganan en conjunto $%10.2f pesos\n",Acum3); printf("\n \n Pulse cualquier tecla para continuar \n"); getche(); return; } /* fin de la funcion departamentos */
9.3 ARCHIVOS DE DATOS. Muchas aplicaciones requieren leer información de un periférico auxiliar de almacenamiento. Tal información se almacena en el periférico en la forma de un archivo de datos. Por tanto, los archivos de datos permiten almacenar información de modo permanente, para ser accedida o alterada cuando sea necesario. En C existen dos tipos de archivos de datos: Archivos secuenciales de datos (o estándar) y archivos orientados a sistema (o de bajo nivel). Generalmente es más fácil trabajar con archivos de datos secuenciales que con los orientados a sistema, y por tanto son los más usados. Los archivos de datos secuenciales se pueden dividir en dos categorías: Los archivos que contienen caracteres consecutivos y los archivos sin formato . En este apartado nos enfocaremos a los archivos secuenciales de datos que contienen caracteres consecutivos.
9.3.1 Apertura y Cierre de un Archivo
Cuando se trabaja con archivos secuenciales de datos, el primer paso es establecer un área de buffer, donde la información se almacena temporalmente mientras se está transfiriendo entre la memoria de la computadora y el archivo de datos. Esta área de buffer permite leer y escribir información del archivo más rápidamente de lo que sería posible de otra manera. El área de buffer se establece escribiendo
FILE *ptvar; donde FILE (escribe con mayúsculas) es un tipo especial de estructuras que establece el área de buffer y ptvar es la variable apuntador que indica el principio de esta área.
Un archivo de datos debe ser abierto antes de ser creado o procesado. Esto asocia el nombre del archivo con el área de buffer (con el archivo secuencial). También se especifica cómo se va a usar el archivo: sólo para lectura, sólo para escritura, para lectura/escritura, en el que se permite las dos operaciones. Para abrir un archivo se usa la función de biblioteca fopen(). Esta función se escribe típicamente como:
ptvar = fopen(nombre-archivo,tipo-archivo); donde nombre-archivo y tipo-archivo son cadenas que representan, respectivamente, el nombre del archivo y la manera en la que el archivo será utilizado. Tipo-archivo “r” “w” “a” “r+” “w+” “a+”
Significado Abrir un archivo existente sólo para lectura Abrir un nuevo archivo sólo para escritura. Si existe el archivo será destruido y creado uno nuevo en su lugar. Abrir un archivo existente para añadir información. Se creará uno nuevo sino existe. Abrir un archivo existente para lectura y escritura. Abrir un archivo nuevo para escritura y lectura. Si existe el archivo será destruido y creado uno nuevo en su lugar. Abrir un archivo existente para leer y añadir información. Se creará un archivo nuevo sino existe.
Cuando ya no se va trabajar con los archivos, estos deben cerrase con:
fclose(puntero del archivo) Las funciones más comunes para manipular un archivo son:
fopen() : fclose() : fwrite() : fread() : feof(): sizeof() : unlink() : rename() :
Abre un archivo. Cierra un archivo. Escribe en el archivo. Lee el archivo. Detecta el final de archivo. Mide la longitud del registro del archivo. borra un archivo. La cambia nombre a un archivo.
9.3.2 Creación de un Archivo Un archivo debe crearse antes de ser procesado. Un archivo secuencial de datos puede crearse de dos formas distintas. Una es crear el archivo directamente, usando un procesador de textos o un editor. La otra es escribir un programa que introduzca información en la computadora y la escriba en un archivo. En este caso nos enfocaremos en el segundo caso, es decir, crearemos los archivos desde un programa y desde el programa introduciremos datos al archivo.
Los programas prog9-5.c y prog9-6.c son complementarios; el primero inserta datos en el archivo y el segundo los imprime en la pantalla. En el programa prog9-5.c podemos ver lo siguiente: 1. El nombre de la estructura (también se le dice nombre del registro) es alumno. 2. Las variables de la estructura alumno son: matricula, nombre[30], carrera[4];
3. ¡ADVERTENCIA!, Cuando inserte el nombre recuerde que no debe escribir mas de 29 caracteres porque lenguaje C necesita el último espacio para un carácter de control. Si no respeta esto se producirá un error en el programa. Lo mismo sucede con carrera, puede escribir las cerreras de la siguiente forma. IAS, IEC, ICC, IMA etc. sólo tres caracteres. 4. El nombre de la variable tipo registro es fime. 5. La variable apuntador al archivo se llama fpt. 6. fpt=fopen("c:datos.dat","w") con esta instrucción se abre el archivo, donde c: es el disco donde se va a grabar el archivo. datos.dat es el nombre del archivo y “ w” significa que el archivo se abre para sólo escritura. 7. fwrite(&fime,sizeof(alumno),1,fpt). Con esta instrucción estamos escribiendo en el archivo, donde con &fime estamos accesando la dirección de la variable tipo registro. Con sizeof(alumno) se indica el tamaño del bloque que será escrito en el archivo, en este caso el tamaño del bloque será igual a la longitud de alumno . El # 1 significa que se escribirá sólo un bloque en el archivo y con ftp estamos diciendo que se escriba el archivo datos.dat. 8. La función strset() se utilizó para limpiar los valores anteriores de las variables de cadena de caracteres.
/* prog9-5.c */ #include #include #include /* programa de almacena datos en un archivo de datos */ typedef struct { long int matricula; char nombre[30]; char carrera[4]; } alumno; /* nombre de la estructura */ /* apuntador al archivo */ FILE *fpt; main() { char OPCION[2]; /* declaracion de la variable tipo registro */ alumno fime; /* abrir el archivo */ fpt=fopen("c:datos.dat","w"); do{ printf("dame la matricula : "); scanf("%ld",&fime.matricula); printf("dame el nombre : "); scanf(" %[^\n]",fime.nombre); printf("dame la carrera : "); scanf("%s",fime.carrera); /* escribir en el archivo */ fwrite(&fime,sizeof(alumno),1,fpt); strset(fime.nombre,' '); strset(fime.carrera,' '); printf("¿Deseas continuar insertando datos al archivo? \n"); printf("Pulsa la letra 'S' para continuar o cualquier otra para terminar\n"); scanf(" %[^\n]",OPCION); }while(!strcmp(OPCION,"S") || !strcmp(OPCION,"s")); /* cerrar el archivo */ fclose(fpt); } /* fin de la funcion main() */
Los datos que insertamos con el programa prog9-5.c, podrán ser vistos en el monitor con el programa prog9-6.c. Con este programa destacaremos lo siguiente: 1. fpt=fopen("c:datos.dat","r"), con esta instrucción se abre el archivo para sólo lectura 2. fread(&fime,sizeof(alumno),1,fpt), con esta instrucción se lee el archivo, donde &fime es la dirección de la variable tipo registro, sizeof(alumno) indica el tamaño del bloque que se leerá del disco, en este caso el tamaño del bloques será igual a la longitud de alumno, el # 1 significa que se lee un solo bloque y fpt es el apuntador al archivo. 3. do{…}while(!feof(fpt)); este ciclo indica que se lea el archivo hasta que se terminen los registros. El significado de feof() es “End Of File”, o sea, final de archivo. Entre paréntesis se escribe la variable que apunta al archivo.
/* prog9-6.c */ #include #include #include /* Imprime los datos almacenados en un archivos de datos */ typedef struct { long int matricula; char nombre[30]; char carrera[4]; } alumno; FILE *fpt; main() { int linea; /* declaracion de la variable tipo registro */ alumno fime; /* abir el archivo */ fpt=fopen("c:datos.dat","r"); printf("Matricula Nombre linea=6; /* leer el archivo */ fread(&fime,sizeof(alumno),1,fpt); do{ printf("%ld",fime.matricula); printf("%s",fime.nombre); printf("%s",fime.carrera); linea=linea+1; /* leer el archivo */ fread(&fime,sizeof(alumno),1,fpt); }while(!feof(fpt)); getche(); /* cerrar el archivo */ fclose(fpt); } /* fin de la función main()*/
Carrera\n");
Capítulo #10 Aplicación de los Archivos de Datos. La intención de este último capítulo es presentar a detalle algunas aplicaciones de los archivos de datos. Este capítulo está compuesto por tres partes: 1. En la primera parte haremos programas sencillos que involucren archivos de datos. 2. En la segunda parte haremos programa de corte de control. 3. En la tercer parte haremos, primero, un sencillo programa de altas y consultas, y finalmente se dará el código de un programa de Altas, Bajas y Cambios.
10.1 PROGRAMAS QUE INVOLUCRAN ARCHIVOS DE DATOS. Problema 10.1: Realice un programa que genere un archivo de salida a partir de un archivo de entrada el cual contiene: Archivo de Entrada: Matricula, Nombre del Estudiante, Calificación del Primer Parcial y Calificación del Segundo Parcial
Archivo de Salida: Matricula, Nombre del Estudiante, Calificación del Primer Parcial, Calificación del Segundo Parcial y Promedio. Ejemplo:
Archivo de Entrada Matricula
Nombre
Primer Parcial
Segundo Parcial
595689
Ana Sánchez
90
50
897831
Saul Rodríguez 100
70
859645
Carmen Salas
70
80
985656
Gloria Zamora
50
60
917845
Sonia Mejía
80
90
Archivo de Salida Matricula
Nombre
Primer Parcial
Segundo Parcial Promedio
595689
Ana Sánchez
90
50
70
897831
Saúl Rodríguez 100
70
85
859645
Carmen Salas
70
80
75
985656
Gloria Zamora
50
60
55
917845
Sonia Mejía
80
90
85
/* prog10-1.c */ #include #include /* calcula el promedio de alumnos, programa que usa archivos */ de entada*/
/* estructura del archivo
typedef struct{ long int matricula_e; char nombre_e[30]; int primer_p_e; int segundo_p_e; } calificacion; /* nombre del registro de salida*/ /* esctructura del archivo de salida */ typedef struct{ long int matricula_s; char nombre_s[30]; int primer_p_s; int segundo_p_s; int promedio_s; } promedio; /* nombre del registro de salida */ /* punteros al archivo de entrada y de salida */ FILE *fentrada,*fsalida; calificacion entrada; /* variable tipo registro del archivo de entrada */ promedio salida; /* variable tipo registro del archivo de salida */ main() { /* declaracion de funciones */ void menu(); void iniciar(); void altas(calificacion entrada); void reporte(calificacion entrada, promedio salida); void imprime(promedio salida); /* llamada a la funcion menu() */ menu(); } /* fin de la funcion main */ /* ---------------------------------------- */ void menu() { int opcion; do{ printf("M E N U P R I N C I P A L\n"); printf("1.-I N I C I A R \n"); printf("2.-A L T A S \n"); printf("3.-R E P O R T E \n"); ;printf("4.-S A L I D A \n"); printf("cual opcion deseas? : "); scanf("%d",&opcion); switch(opcion) { case 1:
/* borra el archivo de entrada anterior, si se desea */ iniciar(); break; case 2: /* altas de registros */ altas(entrada); break; case 3: /* da el resultado del proceso */ reporte(entrada, salida); break; } /* fin switch */ }while(opcion>0 && opcion<4); } /* fin fin de la funcion menu() */ /* ---------------------------------------- */ void iniciar() { int op; printf("I N I C I A R\n"); printf("esta rutina borar el archivo de entrada anterior\n"); printf("deseas borrarlo? 1.-si; 2.-no : "); scanf("%d",&op); if(op==1) { /* abrir archivo de entrada */ fentrada=fopen("c:califica.dat","r"); if(fentrada==NULL) { printf("No puedo borrar el archivo porque NO existe \n"); getche(); } else { fclose(fentrada); /* borra archivo */ unlink("c:califica.dat"); } /* fin del if(fentrada==NULL) */ } /* fin del if(op==1) */ } /* fin de la funcion iniciar() */ /* ---------------------------------------- */ void altas(calificacion entrada) { int op; /* abrir archivo de entrada */ fentrada=fopen("c:califica.dat","a+"); if(fentrada==NULL) { printf("El archivo de entrada NO existe ; favor de revisar su proceso \n"); } /* fin if */ if(fentrada!=NULL) { do{ printf("A L T A S \n"); printf("dame la matricula : "); scanf("%ld",&entrada.matricula_e); printf("dame el nombre : "); scanf(" %[^\n]",entrada.nombre_e); printf("dame la califiacion del primer parcial : "); scanf("%d",&entrada.primer_p_e); printf("dame la calificacion del segundo parcial : "); scanf("%d",&entrada.segundo_p_e); /* escribe en el archivo de entrada */ fwrite(&entrada,sizeof(calificacion),1,fentrada); printf("deseas continuar 1.-si; 2.-no : ");
scanf("%d",&op);
}while(op==1); } /* fin del if(fentrada!=NULL) */ fclose(fentrada); } /* fin de la funcion altas() */ /* ---------------------------------------- */ void reporte(calificacion entrada, promedio salida) { int promedio_w; fentrada=fopen("c:califica.dat","r"); /* abrir archivo de entrada */ fsalida=fopen("c:promedio.sal","w"); /* abrir archivo de entrada */ if(fentrada==NULL) { printf("El archivo de entrada NO existe; favor de revisar su proceso \n"); } /* fin if */ if(fentrada!=NULL) { /* leer archivo de entrada */ fread(&entrada,sizeof(calificacion),1,fentrada); do{ promedio_w=(entrada.primer_p_e+entrada.segundo_p_e)/2; /* pasar los valores de las variables de entrada y trabajo a las variables de salida */ salida.matricula_s=entrada.matricula_e; strcpy(salida.nombre_s,entrada.nombre_e); salida.primer_p_s=entrada.primer_p_e; salida.segundo_p_s=entrada.segundo_p_e; salida.promedio_s=promedio_w; /* escribir en el archivo de salida */ fwrite(&salida,sizeof(promedio),1,fsalida); /* leer archivo de entrada */ fread(&entrada,sizeof(calificacion),1,fentrada); }while(!feof(fentrada)); fclose(fentrada); fclose(fsalida); imprime(salida); } /* fin del if(fentrada!=NULL) */ printf("\nPulse cualquier tecla para continuar \n"); getche(); } /* fin de la funcion reporte() */ /* ---------------------------------------- */ void imprime(promedio salida) { int linea; fsalida=fopen("c:promedio.sal","r"); /* abrir archivo de entrada */ if(fsalida==NULL) { printf("no puedo abrir archivo; favor de revisar su proceso \n"); } /* fin if */ /* poner encabezados */ printf("Matricula Nombre 1er Parcial linea=3; /* leer archivo de salida */ fread(&salida,sizeof(promedio),1,fsalida); do{ printf("%ld ",salida.matricula_s); printf("%s ",salida.nombre_s); printf("%d ",salida.primer_p_s); printf("%d ",salida.segundo_p_s); printf("%d ",salida.promedio_s); linea++; /* leer archivo de salida */ fread(&salida,sizeof(promedio),1,fsalida);
2do Parcial Promedio\n");
}while(!feof(fsalida)); fclose(fsalida); } /* fin de la funcion imprime */
Problema 10.2: Realice un programa que genere un archivo de salida a partir de un archivo de entrada el cual contiene:
Archivo de Entrada: Nombre del Empleado, Horas Trabajadas y Tarifa por hora Archivo de Salida: Nombre del Empleado, Pago Bruto, IMSS y Pago Neto Notas. a) Pago Bruto =(Horas Trabajadas)*(tarifa por hora) b) IMSS = 4.8% del Pago bruto c) Pago Neto = (Pago Bruto)-(IMSS) Ejemplo: Archivo de Entrada Nombre del Empleado JUAN MOLINA DORA VELEZ SARA CASTRO SAUL HIDALGO
Horas Trabajadas 30 40 45 39
Tarifa por Hora $4.50 $3.90 $4.70 $3.50
CLARA MORA
46
$4.20
Nombre del Empleado JUAN MOLINA DORA VELEZ SARA CASTRO SAUL HIDALGO CLARA MORA
Archivo de Salida Pago Bruto IMSS $135 $6.48 $156 $7.48 $211.5 $10.15 $136.5 $6.55 $193.20 $9.27
Pago Neto $128.52 $148.52 $201.35 $129.95 $183.93
********************************************************************
Problema 10.3: Realice un programa que genere un archivo de salida a partir de un archivo de entrada el cual contiene:
Archivo de Entrada: Número de Factura, Nombre del cliente e Importe de venta Archivo de Salida: Número de Factura, Nombre del Cliente, Importe de Venta, Porcentaje de descuento y el Importe de descuento neto Notas: a) Si el importe de Venta excede de $100 pesos se dará un 3% de Descuento, si el importe de
Venta es menor o igual $100 pesos se dará un 2% de Descuento b) Importe de descuento = (Importe de venta)%(Porcentaje de descuento) c) Importe de descuento neto=(importe de Venta)-(importe de descuento)
Ejemplo: Num.Factura 1596 1852 1956 1784 2106 Num.Factura 1596 1852 1956 1784 2106
Archivo de Entrada Nombre RAFAEL SOSA PERLA VELA ROSA MENDEZ RAUL ZAVALA LAURA VAZQUEZ Archivo de Salida Nombre RAFAEL SOSA PERLA VELA ROSA MENDEZ RAUL ZAVALA LAURA VAZQUEZ
Venta $350 $90 $260 $55 $195 Venta $350 $90 $260 $55 $195
%Descuento 3 2 3 2 3
Impte.Dto.Neto $339.50 $ 88.20 $252.20 $ 53.90 $189.15
***********************************************************************
Problema 10.4: Realice un programa que genere un archivo de salida a partir de un archivo de entrada el cual contiene:
Archivo de Entrada: Nombre del Estudiante, Número de créditos Archivo de Salida: Nombre del estudiante, Número de créditos y Colegiatura Nota.- Si un estudiante toma 12 créditos o menos la colegiatura es de $15 pesos por cada crédito, si toma más de 12 créditos la colegiatura es de $150 pesos
Ejemplo:
Archivo de Entrada Nombre del Estudiante Créditos GLORIA MEJIA 15 CARLOS PEDRAJA 10 SONIA LOPEZ 12 SANTIAGO ZAPATA 11 CARMEN SALAS 13 Archivo de Salida Nombre del Estudiante Créditos Colegiatura GLORIA MEJIA 15 $150 CARLOS PEDRAJA 10 $150 SONIA LOPEZ 12 $180 SANTIAGO ZAPATA 11 $165 CARMEN SALAS 13 $150 *******************************************************************************
Problema 10.5: Realice un programa que genere un archivo de salida a partir de un archivo de entrada el cual contiene:
Archivo de Entrada. Nombre del Empleado, Horas Trabajadas y Tarifa por hora Archivo de Salida.- Nombre del Empleado y el sueldo Notas.a) Sueldo = (Horas normales)*(tarifa por hora)+(horas extra)*(3.5) b) Las horas extra son aquellas que pasan de 40
Ejemplo: Archivo de Entrada Nombre del Empleado JUAN MOLINA DORA VELEZ SARA CASTRO SAUL HIDALGO CLARA MORA Archivo de Salida Nombre del Empleado JUAN MOLINA DORA VELEZ SARA CASTRO SAUL HIDALGO CLARA MORA
Horas Trabajadas 30 40 45 39 46
Tarifa por Hora $4.50 $3.90 $4.70 $3.50 $4.20
Sueldo $135 $156 $205.50 $136.50 $189
************************************************************************
Problema 10.6: Realice un programa que genere un archivo de salida a partir de un archivo de entrada, el cual contiene:
Archivo de Entrada.- Nombre del empleado, Código (1.-Salario, 2.-Sueldo, 3.-Comisión), Importe 1 e importe 2
Archivo de Salida.- Nombre del empleado y el importe de lo ganado Notas a) Si es salario, multiplique el importe 1 por el importe 2 para obtener el importe de lo ganado b) Si es sueldo, el importe de lo ganada es igual al importe 1 c) Si es comisión, multiplique el importe 1 por el importe 2 y agregue un 8% adicional para obtener el importe de lo ganado Ejemplo: Archivo de Entrada Nombre del Empleado Código RAUL GARZA 2 AIDA SANCHEZ 1 HILDA IBARRA 3 YAZMIN IGLESIAS 2 EDGAR PEREZ 3 Archivo de Salida Nombre del Empleado RAUL GARZA AIDA SANCHEZ HILDA IBARRA YAZMIN IGLESIAS EDGAR PEREZ
Importe 1 $530 $50 $45 $630 $30
Importe 2 $150 $15 $10 $20 $25
Impte Ganado $530 $750 $486 $630 $810
10.2 PROGRAMAS DE CORTE DE CONTROL Muchas son las situaciones de la vida cotidiana que manejamos a través de corte de control, por ejemplo, los recibos de teléfono, de luz, de agua, el estado de cuenta bancario, una factura etc. todos ellos, computacionalmente hablando, son cortes de control. Por eso, vamos en estos momentos a plantear problemas y a resolverlos por este método.
Problema 10.8: CORTE01.C Realice un programa que genere un archivo de salida a partir de un archivo de entrada la cual contiene: Archivo de Entrada.- Número de Cuenta, Nombre del cliente e Importe Archivo de Salida.- Número de Cuenta, Nombre del cliente e Importe total Nota.- El archivo de entrada está completamente validado y clasificado en forma ascendente por grupos de número de cuenta. Ejemplo:
Archivo de Entrada Número de cuenta Nombre del cliente 595689 KARLA GARZA 595689 KARLA GARZA 595689 KARLA GARZA 615849 IRMA ORTIZ 615849 IRMA ORTIZ 658912 JAVIER GALICIA 658912 JAVIER GALICIA 658912 JAVIER GALICIA 658912 JAVIER GALICIA
Importe $590 $750 $150 $965 $540 $170 $395 $980 $425
Archivo de Salida Número de Cuenta Nombre del Cliente 595689 KARLA GARZA 615849 IRMA ORTIZ 658912 JAVIER GALICIA
Importe Total $1,490 $1,505 $1,970
Advertencia: La solución a este problema está en el programa corte01.c. Cuando inserte los datos debe insertarlos en forma ordenada tal como se muestra en el ejemplo, de lo contrario el programa no funcionará adecuadamente /* corte01.c */ #include #include /*programa de corte de control #1 */ /* formato del archivo de entada*/ typedef struct{ long int cuenta_e; long int impte_e; } cuenta; /* nombre del registro de salida*/ /* formato del archivo de salida */ typedef struct{ long int cuenta_s; long int total_s; } total; /* nombre del registro de salida */ /* punteros al archivo de entrada y de salida */ FILE *fentrada,*fsalida; cuenta entrada; /* variable tipo registro del archivo de entrada */ total salida; /* variable tipo registro del archivo de salida */ main() { /* declaracion de funciones */ void menu(); void iniciar(); void altas(cuenta entrada); void reporte(cuenta entrada, total salida); void imprime(total salida); /* llamada a la funcion menu() */ menu(); } /* fin de la funcion main */ /* ---------------------------------------- */ void menu() { int opcion; do{ printf("M E N U P R I N C I P A L\n"); printf("1.-I N I C I A R \n"); printf("2.-A L T A S \n"); printf("3.-R E P O R T E \n"); printf("4.-S A L I D A \n"); printf("cual opcion deseas? : "); scanf("%d",&opcion); switch(opcion) { case 1: /* borra el archivo de entrada anterior, si se desea */
iniciar(); break; case 2: /* altas de registros */ altas(entrada); break; case 3: /* da el resultado del proceso */ reporte(entrada, salida); break; } /* fin switch */ }while(opcion>0 && opcion<4); } /* fin fin de la funcion menu() */ /* ---------------------------------------- */ void iniciar() { int op; printf("I N I C I A R\n"); printf("esta rutina borar el archivo de entrada anterior\n"); printf("deseas borrarlo? 1.-si; 2.-no : "); scanf("%d",&op); if(op==1) { fentrada=fopen("c:importe.dat","r"); /* abrir archivo de entrada */ if(fentrada==NULL) { printf("No puedo borrar el archivo porque NO existe \n"); printf("Pulse cualquier tecla para continuar \n"); getche(); } else { fclose(fentrada); /* borra archivo */ unlink("c:importe.dat"); } /* fin del if(fentrada==NULL) */ } /* fin if */ } /* fin de la funcion iniciar() */ /* ---------------------------------------- */ void altas(cuenta entrada) { int op; /* abrir archivo de entrada */ fentrada=fopen("c:importe.dat","a+"); if(fentrada==NULL) { printf("El archivo de entrada NO existe ; favor de revisar su proceso \n"); } /* fin if */ if(fentrada!=NULL) { do{ printf("A L T A S \n"); printf("dame el numero de cuenta : "); scanf("%ld",&entrada.cuenta_e); printf("dame el importe : "); scanf("%ld",&entrada.impte_e); fwrite(&entrada,sizeof(cuenta),1,fentrada); printf("deseas continuar 1.-si; 2.-no : "); scanf("%d",&op); }while(op==1); } /* fin del if(fentrada!=NULL) */ fclose(fentrada); } /* fin de la funcion altas() */ /* ---------------------------------------- */ void reporte(cuenta entrada, total salida)
{ long int cuenta_w,total_w=0; fentrada=fopen("c:importe.dat","r"); /* abrir archivo de entrada */ fsalida=fopen("c:importe.sal","w"); /* abrir archivo de entrada */ if(fentrada==NULL) { printf("El archivo de entrada NO existe; favor de revisar su proceso \n"); } /* fin if */ if(fentrada!=NULL) { /* leer archivo de entrada */ fread(&entrada,sizeof(cuenta),1,fentrada); cuenta_w=entrada.cuenta_e; do{ if(cuenta_w==entrada.cuenta_e) { total_w=total_w+entrada.impte_e; /* leer archivo de entrada */ fread(&entrada,sizeof(cuenta),1,fentrada); } else { /* se realiza el corte de control */ /* pasar los valores de la variables de trabajo a las variable de salida */ salida.cuenta_s=cuenta_w; salida.total_s=total_w; /* escribir en el archivo de salida */ fwrite(&salida,sizeof(total),1,fsalida); /* re-inicializar las variables de trabajo */ cuenta_w=entrada.cuenta_e; total_w=0; } /* fin if */ }while(!feof(fentrada)); /* se realiza el ultimo corte de control */ /* pasar los valores de la variables de trabajo a las variable de salida */ salida.cuenta_s=cuenta_w; salida.total_s=total_w; /* escribir en el archivo de salida */ fwrite(&salida,sizeof(total),1,fsalida); fclose(fentrada); fclose(fsalida); imprime(salida); } /* fin del if */ printf("\nPulse cualquier tecla para continuar \n"); getche(); } /* fin de la funcion reporte() */ /* ---------------------------------------- */ void imprime(total salida) { int linea; /* abrir archivo de entrada */ fsalida=fopen("c:importe.sal","r"); if(fsalida==NULL) { printf("no puedo abrir archivo; favor de revisar su proceso \n"); } /* fin if(fsalida==NULL) */ /* poner encabezados */ printf("numero de cuenta importe total\n"); linea=3; /* leer archivo de salida */ fread(&salida,sizeof(total),1,fsalida); do{ printf("%ld ",salida.cuenta_s); printf("%ld ",salida.total_s);
linea++; /* leer archivo de salida */ fread(&salida,sizeof(total),1,fsalida); }while(!feof(fsalida)); fclose(fsalida); } /* fin de la funcion imprime() */
*****************************************************************************
Problema 10.9 : CORTE02.C Realice un programa que genere un archivo de salida a partir de un archivo de entrada la cual contiene: Archivo de Entrada.- Número de vendedor, nombre del vendedor e importe de venta Archivo de Salida.- Número de vendedor, nombre del vendedor y sueldo Si el importe de venta es menor a $1,000, la comisión es del 5%; Si es mayor o igual a $1,000 y menor que $3,000, la comisión es del 7% y Si es mayor o igual a $3,000, la comisión es del 10%. Nota.- El archivo de entrada está completamente validado y clasificado en forma ascendente por grupos de número de vendedor Ejemplo:
Archivo de Entrada Número de vendedor Nombre del Vendedor 119 ARTURO SOTO 119 ARTURO SOTO 119 ARTURO SOTO 673 AIDA MATA 673 AIDA MATA 673 AIDA MATA
Importe de Venta $3,200 $1,100 $ 900 $5,100 $2,500 $1,200
673 710 710
AIDA MATA SAUL MOLINA SAUL MOLINA
$1,000 $1,500 $2,100
Archivo de Salida Número de Vendedor Nombre del Vendedor 119 ARTURO SOTO $442 673 AIDA MATA 710 SAUL MOLINA
Sueldo $815 $252
**************************************************************************************** Problema 10.10: CORTE03.C Realice un programa que genere un archivo de salida a partir de un archivo de entrada la cual contiene:
Archivo de Entrada: Número de Factura, Descripción del producto, cantidad y precio unitario Archivo de Salida: Número de Factura y Pago Nota.- El archivo de entrada está completamente validado y clasificado en forma ascendente por grupos de número de factura Ejemplo:
Archivo de entrada Num.Factura 523 523 523 558 558 591 591 591 591
Descripción PUNTILLAS LIBRETA SCRIBE APLIQUE FOX PRO MAPA MTY PLUMAS BIC PC WORLD PETER NORTON LIBRETA SCRIBE ACCESS FACIL 1
Archivo de Salida Num. Factura 523 558 591
Pago $166.90 $ 60.00 $306.80
Cantidad 2 3 1 1 4 1 1 2 $120
Precio unitario $4.60 $5.90 $140 $50 $2.50 $25 $150 $5.90
10.3 PROGRAMAS DE ALTAS, BAJAS Y CAMBIOS. Problema 10.11: Realice un programa que haga una agenda telefónica para guardar los datos en un archivo. La solución la puede encontrar en el programa prog10-3.c, cuando haga altas se borrará todos los teléfonos anteriores. Si no desea que esto suceda, abra el archivo, dentro de la función altas de la manera: fpt=fopen("C:phones.bin","a+"); /* prog10-3.c */ #include #include #include /* programa de agenda telefonica con archivo de datos */ typedef struct { long int telefono; char nombre[30]; } amigo; /* nombre del regisrto */ FILE *fpt;
/* puntero a un archivo */
amigo fime; /* nombre del registro (amigo) y variable tipo registro (fime) */ /* declaracion de la funciones */ void menu(); void altas(amigo fime); void ver_telefonos(amigo fime); main() { menu(); /* llamar a la funcion */ } /* fin de la funcion main() */ /* --------------------------------------- */ void menu() { int opcion; do{ printf("DIRECTORIO TELEFONICO\n"); printf("1.-A L T A S\n"); printf("2.-VER TELEFONOS\n"); printf("3.-SALIDA\n"); do{ printf("cual opcion deseas ? : "); scanf("%d",&opcion); }while(opcion<1 || opcion>3); switch(opcion) { case 1: altas(fime); break; case 2: ver_telefonos(fime); break; case 3:
printf("hasta luego, muchas gracias\n"); getche(); break; } /* fin switch */ } while(opcion>0 && opcion<3); } /* fin de la funcion menu */ /* --------------------------------------- */ void altas(amigo fime) { int opcion; fpt=fopen("C:phones.bin","w"); do{ printf("dame el telefono : "); scanf("%ld",&fime.telefono); printf("dame el nombre : "); scanf(" %[^\n]",fime.nombre); /* escribir en el archivo */ fwrite(&fime,sizeof(amigo),1,fpt); strset(fime.nombre,' '); do{ printf("continuar en altas; 1.-si, 2.-no\n"); scanf("%d",&opcion); if(opcion<1 || opcion>2) { printf("opcion invalida; favor de esperar"); printf(" } /* fin if */ }while(opcion<1 || opcion>2); }while(opcion==1); fclose(fpt); } /* fin altas */
");
/* --------------------------------------- */ void ver_telefonos(amigo fime) { int seguir; fpt=fopen("C:phones.bin","r"); if(fpt==NULL) { printf("No puedo mostrar los telefonos porque el archivo NO existe \n"); printf("Pulse cualquier tecla para continuar \n"); getche(); } /* fin del if(fpt==NULL) */ if(fpt!=NULL) { /* leer archivo */ fread(&fime,sizeof(amigo),1,fpt); do{ printf("telefono : %ld ",fime.telefono); printf("nombre : %s\n",fime.nombre); fread(&fime,sizeof(amigo),1,fpt); }while(!feof(fpt)); printf("Pulse cualquier tecla para continuar \n"); getche(); fclose(fpt); } /* fin del if(fpt!=NULL */ } /* fin de la funcion ver_telfonos() */
La mayoría de las aplicaciones requieren que se altere el archivo cuando se procesa. Por ejemplo, en aplicaciones que impliquen el procesado de registros de clientes, se puede desear añadir nuevos registros al archivo (ya sea al final o entre los registros existentes), o para reordenar los registros. Estos requerimientos sugieren varias estrategias computacionales distintas. Por ejemplo, considerar el problema de actualizar los registros dentro de un archivo de datos. Hay varios enfoques de este problema. Quizá el más obvio es leer cada registro de un archivo, actualizar el registro y después escribir el registro actualizado al mismo archivo. Sin embargo, hay algunos problemas con esta estrategia. En particular, es difícil leer y escribir datos con formato al mismo archivo sin alterar la ordenación de los elementos dentro del archivo. Además, el conjunto original de registros puede volverse inaccesible si algo funciona mal durante la ejecución del programa. Otro enfoque es trabajar con dos archivos diferentes: un archivo antiguo (fuente) y otro nuevo. Se lee cada registro dentro del archivo antiguo, se actualiza y se escribe el nuevo archivo. Cuando se han actualizado todos los registros, se borra o se almacena el archivo antiguo y se renombra el archivo nuevo. Esta última estrategia es la que se utiliza en el siguiente programa ABC.C. ________________________________________________________________________________________ /* ABC.C */ /* programa de Altas, Bajas y Cambios con archivos de datos */ #include #include #include #include #define CIERTO 1 #define FALSO 0 /* formato del archivo */ typedef struct {
char matricula[8]; char nombre[30]; char carrera[4]; }alumno; /* nombre del registro */ FILE *fpt; /* puntero al archivo */ alumno fime; /* variable tipo registro */ main() { /* declaracion de funciones */ void menu(); void iniciar(); alumno altas(alumno fime); alumno bajas(alumno fime); alumno cambios(alumno fime); int buscar(char mat[7]); int buscar_pantalla(char mat[8]); void borrar_registro(char mat[8]); void cambiar_registro(alumno fime,char mat[8]); int validar_matricula(char mat[8]); char cambiar_letras(alumno fime,char variable[30]); void imprime(alumno fime); /* llamada a la funcion */ menu(); imprime(fime); } /* fin de la funcion main() */
/* definicion de funciones */ /* --------------------------------------------- */ void menu() { int opcion; do{ printf("M E N U P R I N C I P A L\n"); printf("1.-I N I C I A R\n"); printf("2.-A L T A S\n"); printf("3.-B A J A S\n"); printf("4.-C A M B I O S\n"); printf("5.-S A L I R\n"); printf("cual opcion deseas ? :"); scanf("%d",&opcion); switch(opcion) { case 1: /* borra el archivo anterior, si se desea*/ iniciar(); break; case 2: /* altas de alumnos */ altas(fime); break; case 3: /* bajas de alumnos */ bajas(fime); break; case 4: /* cambios de alumnos */ cambios(fime); break; } /* fin switch */ }while(opcion>0 && opcion<5); } /* fin de la funcion menu() */ /* --------------------------------------------- */ void iniciar() {
int op;
}
printf("I N I C I A R\n"); printf("esta rutina borra el archivo de datos anterior\n"); printf("desea borrarlo? 1.-si,2.-no: " ); scanf("%d",&op); if(op==1) { fpt=fopen("c:abc.bin","w"); /* abrir archvo, se pierde el anterior */ fclose(fpt); /* cerrar archivo */ }/* fin if(op==1) */ /* fin de la funcion iniciar() */
/* --------------------------------------------- */ alumno altas(alumno fime) { int i,op,no_valido,encontrado; /* encontrado=1 verdadero ; encontardo=0 falso*/ int longitud; char mat[8],nom[30],car[4]; /* variable mat para buscar en el archivo */ fpt=fopen("c:abc.bin","a+"); /* abrir archivo */ do{ do{ printf("A L T A S\n"); printf("dame la matricula : "); scanf("%s",mat); no_valido=validar_matricula(mat); }while(no_valido==CIERTO); encontrado=buscar(mat); /* llamada a la funcion buscar */ /* busqueda secuencial de un registro */ if(encontrado) { printf("M A T R I C U L A E X I S T E N T E\n"); printf("pulse cualquier tecla para continuar \n"); getche(); /* borrar las lineas anteriores */ printf(" \n"); printf(" \n"); } else { strcpy(fime.matricula,mat); printf("dame el nombre : "); scanf(" %[^\n]",fime.nombre); /* cambiar letras a mayusculas */ longitud=strlen(fime.nombre); for(i=0;i
} /* fin de la funcion altas() */ /* --------------------------------------------- */ int buscar(char matri[8]) { /* busqueda secuencial de un registro */ int buscado; buscado=0; rewind(fpt); /* poner puntero al principio del archivo */ do{ fread(&fime,sizeof(alumno),1,fpt); /* leer archivo */ if(!strcmp(fime.matricula,matri)) { buscado=1; /* si lo encontro se asigna 1 a buscado */ break; } /* fin if */ }while(!feof(fpt)); /* se repite hasta fin de archivo */ return(buscado); } /* fin de la funcion buscar() */ /* --------------------------------------------- */ alumno bajas(alumno fime) { int op,no_valido,encontrado; /* encontrado=1 verdadero ; encontrado=0 falso*/ char mat[8]; /* variable mat para buscar en el archivo */ fpt=fopen("c:abc.bin","r"); /* abrir archivo solo lectura*/ if(fpt==NULL) { printf("no puedo abrir el archivo \n"); } /* fin if */ do{ do{
}
printf("B A J A S\n"); printf("dame la matricula : "); scanf("%s",mat); no_valido=validar_matricula(mat); }while(no_valido==CIERTO); encontrado=buscar_pantalla(mat); /* llamada a la funcion buscar */ /* busqueda secuencial de un registro */ if(!encontrado) { /* la matricula buscada no existe */ printf("M A T R I C U L A I N E X I S T E N T E\n"); printf("Pulse cualquier tecla para continuar\n"); getche(); /* borrar las lineas anteriores */ printf(" \n"); printf(" \n"); } else { /* la matricula buscada si existe */ printf("deseas dar de baja este registro 1.-si, 2.-no : "); scanf("%d",&op); /* borrar la linea anterior */ printf(" "); if(op==1) { borrar_registro(mat); } /* fin op==1 */ } /* fin if encontrado */ printf("deseas continuar 1.-si, 2.-no : "); scanf("%d",&op); }while(op==1); fclose(fpt); /* cerrar archivo */ return(fime); /* fin bajas */
/* --------------------------------------------- */
void borrar_registro(char matri[8]) { /* copiado secuencial de registros un archivo a otro */ /* baja fisica de un registro */ FILE *fregistro; rewind(fpt); /* poner puntero al principio del archivo */ fregistro=fopen("c:abc.new","w"); /* abrir archivo nuevo */ fread(&fime,sizeof(alumno),1,fpt); /* leer registro */ do{ if(strcmp(fime.matricula,matri)) { fwrite(&fime,sizeof(alumno),1,fregistro); } /* fin if */ fread(&fime,sizeof(alumno),1,fpt); /* leer archivo */ }while(!feof(fpt)); /* se repite hasta fin de archivo */ fclose(fregistro); fclose(fpt); unlink("c:abc.bin"); rename("c:abc.new","c:abc.bin"); fpt=fopen("c:abc.bin","r"); /* abrir archivo solo lectura*/ } /* finde la funcion borrar_registros() */ /* --------------------------------------------- */ alumno cambios(alumno fime) { int op,no_valido,encontrado; /* encontrado=1 verdadero ; encontrado=0 falso*/ char mat[8]; /* variable mat para buscar en el archivo */ fpt=fopen("c:abc.bin","r"); /* abrir archivo solo lectura*/ if(fpt==NULL) { printf("no puedo abrir el archivo \n"); } /* fin if */ do{ do{
}
printf("C A M B I O S\n"); printf("dame la matricula : "); scanf("%s",mat); no_valido=validar_matricula(mat); }while(no_valido==CIERTO); encontrado=buscar_pantalla(mat); /* llamada a la funcion buscar */ /* busqueda secuencial de un registro */ if(!encontrado) { /* la matricula buscada no existe */ printf("M A T R I C U L A I N E X I S T E N T E\n"); printf("Pulse cualquier tecla para continuar\n"); getche(); /* borrar las lineas anteriores */ printf(" \n"); printf(" \n"); } else { /* la matricula buscada si existe */ printf("deseas cambiar este registro 1.-si, 2.-no : "); scanf("%d",&op); /* borrar la linea anterior */ printf(" "); if(op==1) { cambiar_registro(fime,mat); } /* fin if op==1 */ } /* fin if encontrado */ printf("deseas continuar 1.-si, 2.-no : "); scanf("%d",&op); }while(op==1); fclose(fpt); /* cerrar archivo */ return(fime); /* fin de la funcion cambios() */
/* ------------------------------------------------- */ void cambiar_registro(alumno fime,char matri[8]) { /* copiado secuencial de registros de un archivo a otro */ /* baja fisica de un registro */ int op,longitud,i; char opc; FILE *fregistro; /* se inicia el proceso de pasar todos los registros a otro archivo */ rewind(fpt); /* poner puntero al principio del archivo */ fregistro=fopen("c:abc.new","w"); /* abrir archivo nuevo */ fread(&fime,sizeof(alumno),1,fpt); /* leer archivo */ do{ if(strcmp(fime.matricula,matri)) { fwrite(&fime,sizeof(alumno),1,fregistro); } else { printf("dame el nuevo nombre : "); scanf(" %[^\n]",fime.nombre); printf(" "); /* cambiar letras a mayusculas */ longitud=strlen(fime.nombre); for(i=0;i
}
printf(" "); printf("dame la nueva carrera : "); scanf("%s",fime.carrera); printf(" "); /* cambiar letras a mayusculas */ longitud=strlen(fime.carrera); for(i=0;i
/* --------------------------------------------- */ int buscar_pantalla(char matri[8]) { /* busqueda secuencial de un registro */ int buscado; buscado=0; rewind(fpt); /* poner puntero al principio del archivo */ do{ fread(&fime,sizeof(alumno),1,fpt); /* leer archivo */ if(!strcmp(fime.matricula,matri)) { buscado=1; /* si lo encontro se asigna 1 a buscado */ printf("nombre : %s",fime.nombre); printf("carrera : %s",fime.carrera); break; } /* fin if */ }while(!feof(fpt)); /* se repite hasta fin de archivo */
}
return(buscado); /* fin buscar_pantalla */
/* --------------------------------------------- */ int validar_matricula(char matri[8]) { int longitud,i,caracter,valido; caracter=FALSO; longitud=strlen(matri); for(i=0;i