Академический Документы
Профессиональный Документы
Культура Документы
Mar a Lizbeth Gallardo L opez y Pedro Lara Vel azquez junio - 2013
Con afecto para todo aquel estudiante que desea tener un primer acercamiento al paradigma de programaci on estructurada.
II
Introducci on
Desde nales de 1953, cuando John Backus propuso el lenguaje FORTRAN como una alternativa m as pr actica a la programaci on en lenguaje Ensamblador (muy cercano al lenguaje m aquina), se han desarrollado una innidad de lenguajes de programaci on, as como dialectos de los mismos. Estos programas nos sirven para desarrollar algoritmos de soluci on para resolver problemas de programaci on concretos. A los algoritmos de soluci on para un problema espec co se les llama programas. Un algoritmo se puede comparar a una receta de cocina, donde el conjunto de instrucciones ordenadas se denen una sola vez y despu es puede ser repetido por otras personas. As , un algoritmo se propone una sola vez y despu es puede ser traducido a varios lenguajes. En la actualidad existen distintos paradigmas de programaci on: imperativo, funcional, orientado a objetos y l ogico por mencionar solo algunos. La programaci on imperativa estructurada la dene Edsger Dijkstra como ((una losof a para la implementaci on de algoritmos a trav es de un conjunto nito de estructuras bien organizadas)). Dicho en otras palabras, la programaci on estructurada parte un gran problema en pedazos m as peque nos, de tal forma que el programa nal es el resultado de resolver cada subproblema de una manera m as sencilla. En estos apuntes se utiliza el lenguaje de programaci on estructurada C. Dentro de los lenguajes imperativos estructurados, C es el lenguaje m as utilizado en la actualidad por su versatilidad y por la gran cantidad de bibliotecas disponibles para los programadores. Una biblioteca contiene un conjunto funciones que pueden reutilizarse en soluciones a problemas espec cos, por ejemplo: integraci on y derivaci on de funciones matem aticas, generadores de interfaces de usuario. En contraste con el lenguaje ensamblador, el cual es considerado de bajo nivel porque todo se desarrolla muy cerca del lenguaje de m aquina, C es considerado un lenguaje de nivel intermedio, ya que permite realizar aplicaciones ocultando al programador los detalles de la arquitectura de hardware; pero si el programador lo requiere, C le permite comunicarse con ella. Estas notas se dividen de la siguiente forma: los cap tulos 1 proporciona una
III
IV
introducci on a la arquitectura actual de una computadora; el cap tulo 2 presenta el concepto de algoritmo y su representaci on gr aca, empleando diagramas de ujo; el cap tulo 3 aborda el lenguaje C; en el cap tulo 4 presenta las estructuras de selecci on; el cap tulo 5 presenta el concepto de funci on, el cual es indispensable en el paradigma de programaci on estructurada; el cap tulo 6 muestra las estructuras iterativas; el cap tulo 7 presenta el concepto de tipos de datos estructurados; el cap tulo 8 presenta el tipo de dato estructurado registro; el cap tulo 9 muestra el manejo de archivos de texto; y nalmente, el cap tulo 10 presenta el sistema operativo UNIX.
Indice general
1. Arquitectura de computadoras 1.1. Modelo actual de la Computadora . . . . . . . . 1.1.1. Unidad central de procesamiento . . . . . 1.1.2. Memoria . . . . . . . . . . . . . . . . . 1.1.3. Dispositivos de entrada y salida de datos . 1.2. Software de base y software de aplicaci on . . . . 2. Algoritmos 2.1. Algoritmo . . . . . . . . . 2.2. Programaci on . . . . . . . 2.3. Programaci on estructurada 2.4. Diagramas de ujo . . . . 1 1 2 4 5 6 9 9 10 11 12 15 15 16 16 17 23 23 25 27 30 33 37 37 38 38
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
3. Lenguaje C 3.1. Origen del lenguaje C . . . . . 3.1.1. Tipos de datos . . . . 3.1.2. Variables y constantes 3.1.3. Operadores . . . . . . 4. Estructuras de decisi on 4.1. Decisi on simple . . . 4.2. Decisi on binaria . . . 4.3. Decisi on encadenada 4.4. Decisi on anidada . . 4.5. Decisi on m ultiple . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
5. Funciones 5.1. Importancia de dividir un problema . . . . . . . . . . . . . . . . . 5.2. Reglas b asicas para denir funciones . . . . . . . . . . . . . . . . 5.2.1. Declarar la funci on . . . . . . . . . . . . . . . . . . . . .
V
VI
INDICE GENERAL 5.2.2. Denir la funci on . . . . . 5.2.3. Llamar a la funci on . . . . 5.3. Paso de par ametros por valor . . . 5.4. Paso de par ametros por referencia . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 39 41 42 47 47 53 55 61 61 64 73 77 83 83 84 87 91 91 91 107 107 109 110 110 113 114 116 116 117 119 120
6. Estructuras repetitivas 6.1. Estructura repetitiva durante (for) . . . . . . . . . . . . . . . . . . 6.2. Estructura repetitiva mientras (while) . . . . . . . . . . . . . . . . 6.3. Estructura repetitiva haz - mientras (do-while) . . . . . . . . . . . 7. Tipos de datos estructurados 7.1. Arreglos unidimensionales . . . . . . . 7.2. Arreglos unidimensionales y funciones. 7.3. Arreglos bidimensionales . . . . . . . . 7.4. Cadenas . . . . . . . . . . . . . . . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
. . . .
8. Registros 8.1. Denici on de variables de tipo registro. . . . . . . . . . . . . . . 8.2. Denici on de un registro empleando alias. . . . . . . . . . . . . . 8.3. Representaci on de los registros en la memoria . . . . . . . . . . . 9. Archivos 9.1. Conceptos b asicos . . . . . . . . . . . . . . . . . . . . . . . . . . 9.2. Funciones usuales para el manejo de archivos . . . . . . . . . . . 10. Introducci on al sistema operativo UNIX 10.1. Acceder al sistema operativo . . . . . . . . . . . . . . . 10.2. Comandos b asicos . . . . . . . . . . . . . . . . . . . . 10.2.1. Mostrar el directorio actual de trabajo pwd . . 10.2.2. Listar el contenido de un directorio - ls . . . . . 10.2.3. Conocer qui en est a conectado al servidor - who . 10.2.4. Cambiar de directorio cd . . . . . . . . . . . . 10.2.5. Crear un nuevo directorio - mkdir . . . . . . . . 10.2.6. Eliminar un archivo - rm . . . . . . . . . . . . . 10.2.7. Renombrar o mover archivos mv . . . . . . . . 10.2.8. Copiar archivos - cp . . . . . . . . . . . . . . . 10.2.9. Mostrar el manual de comandos de UNIX man
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
. . . . . . . . . . .
Cap tulo 1
Arquitectura de computadoras
1.1. Modelo actual de la Computadora
Una computadora est a formada por: hardware y software. 1) Hardware: es la parte f sica o tangible de la computadora y est a formada por varios elementos, a saber: Unidad central de procesamiento, monitor, disco duro, entre otros. 2) Software: es la parte no tangible de la computadora y se clasica en software de base o de sistema y software de aplicaci on. En la secci on 1.2 explicaremos esta clasicaci on; ahora nos enfocaremos al hardware. La arquitectura de hardware de las computadoras (gura 1.1) que empleamos hoy en d a se atribuye a John von Neumann y otros investigadores. Los principales componentes de la computadora son: la unidad central de procesamiento, la memoria y los dispositivos de entrada y salida de datos.
1.1.1.
La unidad central de procesamiento (CPU acr onimo ingl es para Central Process Unit) se encarga de realizar las operaciones aritm etico-l ogicas con los datos, la forman: la unidad arim etico l ogica, la unidad de control y un conjunto de registros. Unidad aritm etico-l ogica La unidad aritm etico-l ogica (ALU acr onimo ingl es para Aritmetic Logic Unit) est a encargada de realizar las operaciones aritm eticas y l ogicas. Dentro de las operaciones aritm eticas, distinguimos entre las unarias: incremento y decremento; y las binarias: suma (+), resta (), multiplicaci on (), divisi on (/) y m odulo ( %)1 . La forma de expresar las operaciones binarias es: A <operador>B = C. Las operaciones l ogicas son: NOT, AND, OR y XOR. Con excepci on de la operaci on de negaci on que es una operaci on unaria, el resto son binarias. Por ejemplo, p=llueve afuera y q=hay sol son dos proposiciones, la tabla 1.1 muestra el resultado de aplicar operaciones l ogicas sobre ellas. Diagrama Operaci on l ogica NOT p Llueve afuera y hay sol p AND q Llueve afuera o hay sol p OR q hay sol Llueve afuera o (uno de los dos) Resultado No llueve afuera
p XOR q
1 El
La unidad de control (CU acr onimo ingl es para Control Unit) es responsable de seleccionar las operaciones aritm etico-l ogicas. Esto se logra a partir de varias l neas de control que pueden estar activas o inactivas. Por ejemplo, para una ALU simple con 10 operaciones diferentes se necesitan cuatro l neas de control, las cuales 4 pueden denir 16 (2 ) situaciones diferentes, diez de las cuales pueden usarse para las operaciones aritm etico-l ogicas y el resto para otros prop ositos. La tabla 1.2 muestra algunos ejemplos sobre el c odigo binario de algunas operaciones. C odigo 0000 0001 0010 0011 Operaci on Neutro (no hay operaci on por hacer) Suma Resta Multiplicaci on
Registros Los registros son celdas de almacenamiento, propias de la CPU, que guardan temporalmente tanto los datos de entrada que ser an procesados por la ALU como el resultado del procesamiento. Distinguimos tres tipos: registros de entrada, registros de instrucci on y el contador de programa. Registros de entrada. En el pasado las computadoras solo ten an un registro de entrada para alojar, por turnos, uno de los datos de entrada (el otro dato de entrada ven a directamente de la memoria). Actualmente las computadoras utilizan docenas de registros para acelerar las operaciones, las cuales son cada vez m as complejas y requieren de varios registros para mantener los resultados intermedios. Registros de instrucci on. El CPU es el responsable de buscar las instrucciones en la memoria, una a una; luego debe almacenarlas en el registro de instrucci on, interpretarlas y ejecutarlas. Contador de programa. Hace un seguimiento de la instrucci on que se ejecuta actualmente; concluida la ejecuci on, el contador se incrementa para apuntar a la direcci on (de memoria) de la siguiente instrucci on o dato.
1.1.2.
Memoria
Es una colecci on de celdas de almacenamiento. Cada celda tiene un identi nico conocido como ((direcci cador u on)). Los datos se transeren hacia y desde la memoria en grupos de bits llamados palabras. Un bit es la unidad m nima de alma ste f cenamiento en una computadora; e sicamente es un condensador (gura 1.2): si est a cargado, entonces representa 1 (verdadero); si no est a cargado, entonces representa 0 (falso).
Una palabra puede estar formada por un patr on de 8 bits (ejemplo 10100100) y hasta 64 bits en computadoras recientes. La gura 1.3 representa una memoria con 8 celdas; donde cada celda est a formada por un patr on de 8 bits. Cada una tiene asignada una direcci on expresada, de igual manera, en binario. Las direcciones est an designadas por un n umero consecutivo que inicia con la direcci on 0.
La cantidad de celdas que contienen las memorias de las m aquinas es variable: de cientos (un horno de microondas) a miles de millones (computadoras actuales). El tama no la memoria principal suele medirse en las siguientes unidades: Kilobytes, Megabytes, Gigabytes y Terabytes; estas unidades corresponden a los valores de la tabla 1.3:
1.1. MODELO ACTUAL DE LA COMPUTADORA Potencia 210 220 230 240 Bytes 1, 024 1, 048, 576 1, 073, 741, 824 1,099511628x1012 Equivalencia 1,024 bytes 1,024 Kb 1,024 Mb 1,024 Gb Unidad 1 kilobyte (Kb) 1 Megabyte (Mb) 1 Gigaabyte (Gb) 1 Terabyte (Tb)
Por ejemplo una computadora cuya memoria tiene 4MB y el tama no de palabra es igual a 16 bits tiene 4 1, 048, 576 = 4, 192, 304 celdas, cada una con un tama no de 2 byte. Todas con su direcci on correspondiente: 0, 1, 2, ... , 4, 192, 303 (pero expresado en binario). Existen varios tipos de memoria, de los cuales distinguiremos: 1) la memoria de acceso aleatorio y 2) la memoria de solo lectura. Memoria de acceso aleatorio (RAM acr onimo ingl es para Random Access Memory). Es la memoria principal de una computadora. Un usuario puede leer y escribir en la RAM mientras la m aquina est e encendida. La informaci on es autom aticamente borrada si deja de alimentarse de energ a el ectrica a la computadora. Por esta caracter stica, a la RAM tambi en se le llama memoria vol atil. Memoria de solo lectura (ROM acr onimo ingl es para Read Only Memory). El contenido de esta memoria es grabada por el fabricante. De la informaci on contenida en esta memoria podemos citar: datos del fabricante, modelo de la computadora, tipo de procesador, capacidad de almacenamiento, la fecha, entre otros. Tambi en contiene un programa llamado sistema b asico de entrada y salida (BIOS acr onimo ingl es para Basic Input-Output System) el cual ((arranca)) o inicia el funcionamiento de la computadora.
1.1.3.
CAPITULO 1. ARQUITECTURA DE COMPUTADORAS posterior. Ejemplo: disco duro2 , Memorias USB3 , Discos compactos CD4 , ptico de almacenamiento de datos DVD5 , Memorias SD6 , entre otros. disco o
1.2.
Al encender la computadora se ejecuta el programa llamado sistema b asico de entrada y salida (BIOS), el cual est a guardado en la ROM. El BIOS revisa todos los dispositivos conectados a la computadora y se encarga de buscar al sistema operativo en el disco duro, para luego ((cargarlo)) (guardarlo) a la RAM. El software de base esta formado por un conjunto de programas que nos permite comunicar y controlar el hardware de la computadora. Ejemplos de software de base son: controladores de dispositivos, cargadores, ligadores y compiladores de programas, entre otros. El software de aplicaci on est a enfocado a automatimatizar tareas de un usuario, tales como: c alculos matem aticos, dise no de im agenes, entre otros; ejemplos de sofware de aplicaci on son: hoja de c alculo, editores de im agenes, manejadores contables, entre otros. La gura 1.4 muestra como el software de base se encuentra entre el hardware y el software de aplicaci on.
acr onimo ingl es para Hard Disc. acr onimo ingl es para Universal Serial Bus. 4 CD acr onimo ingl es para Compact Disc. 5 DVD acr onimo ingl es para Digital Versatile Disc. 6 SD acr onimo ingl es para Secure Digital. 7 Un programa de aplicaci on es distinto a un software de aplicaci on, principalmente porque el
3 USB
da uno ser a escrito en lenguaje C; luego, el programa ser a traducido por un compilador a lenguaje m aquina (lenguaje binario 0 apagado y 1 encendido); despu es, nuestro programa en lenguaje de m aquina ser a ligado con otros programas propios del lenguaje C; y nalmente, este conjunto de programas ser a llevado a memoria pricipal (RAM) para que se inicie su ejecuci on, ver gura 1.5.
Compilador: Es un programa (o conjunto de programas) encargado de traducir de un programa fuente, escrito en lenguaje de alto nivel8 , a un programa objeto, escrito en lenguje m aquina. Un compilador realiza las siguientes operaciones: an alisis l exico, pre-procesamiento, an alisis sint actico, an alisis sem antico, generaci on de c odigo y optimizaci on de c odigo. Un enlazador es un programa que toma los archivos: 1) del c odigo objeto generados en el proceso de compilaci on y 2) el c odigo objeto de las funciones empleadas por el programador en su programa de aplicaci on (las cuales forman parte de una biblioteca proporcionada por el lenguaje de alto nivel); nalmente, enlaza ambos tipos de c odigos objeto produciendo un programa ejecutable. Un cargador es el responsable de llevar el contenido del archivo ejecutable (programa ejecutable) a la memoria principal (RAM) para iniciar su ejecuci on a solicitud del usuario.
software se dene como el conjunto de programas y su documentaci on. Esta documentaci on sirve para comprender el dise no, el funcionamiento, y los detalles t ecnicos de los programas que forman parte del software. En este curso de programaci on estructurada, aprenderemos a dise nar e implementar soluciones de problemas sencillos, para los cuales no se generar a la documentaci on. 8 Entenderemos el t ermino ((lenguaje de alto nivel)) aquel que comprende el ser humano y que instruye a la computadora para resolver un problema.
Cap tulo 2
Algoritmos
2.1. Algoritmo
Un algoritmo es un conjunto de pasos precisos y ordenados, que permiten alcanzar un resultado, o bien resolver un problema. Las caracter sticas de un algoritmo son: precisi on, nitud y determinismo. Precisi on. El algoritmo debe evitar, en la medida de lo posible, la ambig uedad. Finitud. Independientemente de la complejidad (dicultad) del algoritmo, el conjunto de pasos debe ser nito. Determinismo. Para un mismo conjunto de datos entrada, el algoritmo siempre debe arrojar el mismo conjunto de resultados. Las etapas principales de un algoritmo (gura 2.1) son: 1) la recepci on de los datos de entrada, 2) el procesamiento de los datos y 3) la impresi on de los resultados.
A continuaci on se presenta un ejemplo de un algoritmo que permite darse de alta en la aplicaci on ((aula virtual)): 1. Acceder a la direcci on de aula virtual 9
10
CAPITULO 2. ALGORITMOS 2. Acceder a la r ubrica ((Ciencias B asicas e Ingenier a)) 3. Seleccionar la UEA ((Programaci on Estructurada)) del profesor 4. Leer instrucciones para el registro 5. Realizar el registro a) Escribir matr cula b) Escribir fecha de nacimiento c) Escribir datos generales 6. Acceder a aula virtual 7. Escribir matr cula y contrase na 8. Est as dentro!
Las etapas para crear un algoritmo que resuelva un problema espec co son: 1) an alisis del problema, 2) construcci on de un algoritmo y 3) vericaci on del algoritmo. El an alisis del problema nos permite determinar su naturaleza, e identicar su causa; para luego, dividir el problema en subproblemas. En la construcci on del algoritmo elaboramos escenarios, dise namos una soluci on para cada subproblema, y luego las integramos para as resolver el problema inicial; este proceso tambi en incluye mejorar el algoritmo. La vericaci on del algoritmo consiste en ejecutar (o realizar) cada paso se nalado en el algoritmo, con datos de entrada para los cuales conocemos los resultados.
2.2.
Programaci on
Programar es concebir un algoritmo que permita a una computadora resolver un problema. El algoritmo debe escribirse en un lenguaje claro, estricto y universal, a saber: pseudoc odigo. Posteriormente, ese algoritmo expresado en pseudoc odigo podr a ser traducido a cualquier lenguaje de programaci on, en nuestro caso a lenguaje C. La codicaci on consiste en traducir el algoritmo a un lenguaje de programaci on, para as obtener un programa fuente. Un programa, concepto desarrollado por von Neumann en 1946, es un conjunto de instrucciones que sigue una computadora para alcanzar un resultado espec co. El programa se escribe en un lenguaje de programaci on, a partir de un diagrama de ujo o de un algoritmo expresado en pseudoc odigo.
11
Un lenguaje de programaci on est a constituido por un conjunto de reglas sint acticas y sem anticas. Las reglas sint acticas especican la correcta formaci on de palabras y oraciones en un lenguaje. Las reglas sem anticas especican el sentido o signicado de un s mbolo, una palabra o una oraci on.
2.3.
Programaci on estructurada
La programaci on estructurada es una losof a para la implementaci on de algoritmos a trav es de un conjunto nito de estructuras debidamente organizadas. Fu e propuesto, en 1965, por Edgser Dijkstra, en la Universidad de Hainover. El Teorema de la estructura, propuesto por Bohn y Jacopini se nala que son necesarias tres estructuras b asicas para construir cualquier programa, a saber: 1. Una estructura de secuencia, donde las instrucciones se ejecutan una tras otra. 2. Una estructua de selecci on o decisi on, donde un bloque de instrucciones se ejecuta s olo si se cumple una condici on. 3. Una estructura de repetici on, donde un bloque de instrucciones se ejecuta varias veces en funci on de una condici on. Estas estructuras se presentan en la tabla 2.1 y tienen una sintaxis espec ca en el lenguaje de programaci on C; la denici on y la sint axis de cada una de ellas, las abordaremos en las secciones 4 y 6. Secuencia Decisi on Repetici on
12
CAPITULO 2. ALGORITMOS
2.4.
Diagramas de ujo
Un diagrama de ujo es la representaci on gr aca de un algoritmo; la construc ste es muy importante porque nos permite escribir un programa ci on correcta de e en cualquier lenguaje de programaci on estructurada. La tabla 2.2 presenta los principales s mbolos para representar a un algoritmo. S mbolo Descripci on Marca el inicio y el n de un programa Entrada de datos. Expresa lectura Representa operaciones que se realizan en secuencia: asignaciones, operaciones aritm eticas, etc. Representa una toma de decisi on; el ujo del programa sigue uno de los dos caminos alternativos Representa una toma de decisi on m ultiple; el ujo del programa sigue uno de los caminos alternativos Representa la estructura repetitiva for donde se conoce el n umero de iteraciones sobre un conjunto de instrucciones Representa la impresi on de resultados en la pantalla de la computadora. Expresa escritura Marcan la direcci on del ujo del programa Representa conexi on del ujo del programa en la misma p agina Representa conexi on del ujo del programa entre dos p aginas Representa el llamado a una funci on (subprograma)
Tabla 2.2 S mbolos para el diagrama de ujo
2.4. DIAGRAMAS DE FLUJO 1. Todo diagrama de ujo debe tener un inicio y un n 2. Las l neas de direcci on deben ser rectas
13
3. Las l neas de direcci on deben estar conectadas a un s mbolo que exprese lectura, proceso, decisi on, escritura, conexi on o n del programa 4. Un diagrama de ujo debe construirse de arriba hacia abajo y de izquierda a derecha 5. La notaci on utilizada en el diagrama de ujo debe ser independiente del lenguaje de programaci on 6. Al realizar una tarea compleja, es conveniente poner comentarios que ayuden a entenderla 7. Si la construcci on de un diagrama de ujo requiere m as de una hoja, debemos emplear los conectores adecuados y enumerar las p aginas. 8. No es posible que a un s mbolo determinado llegue m as de una l nea de direcci on.
14
CAPITULO 2. ALGORITMOS
Cap tulo 3
Lenguaje C
3.1. Origen del lenguaje C
C es un lenguaje de programaci on inventado por Dennis M. Ritchie y Kenneth L. Thompson entre 1969 y 1973 en los laboratorios Bell de New Jersey. C es un lenguaje estructurado, el cual ofrece algunas ventajas: 1) control de ujo, 2) manejo de variables simples y estructuradas, 3) simplicaci on en la expresi on de operaciones y 4) un conjunto de operadores. Originalmente C fue dise nado para construir el sistema operativo UNIX; sin embargo, el n ucleo (kernel)1 Linux fue desarrollado por Linus Torvals utilizando tambi en el lenguaje C. Actualmente, C se emplea para construir programas de aplicaci on. En 1989, la American National Standards Institute establece una especicaci on est andar para C, llamada ANSI X3.159-1989 ((Programming Language C)), mejor conocida como ANSI C. Posteriormente, en 1990, fue raticado como est andar por la International Organization for Standardization, llamada (ISO/IEC 9899:1990). C es especialmente poderoso, principalmente porque se apega a la arquitectura del hardware de la computadora. Gracias a estas caracter sticas, se han propuesto varias versiones del lenguaje C, que operan sobre sistemas operativos y arquitecturas de computadoras diferentes. Sin embargo, los programas escritos bajo el ANSI C son portables a distintos sistemas operativos y distintas arquitecturas. Algunos ejemplos de versiones del lenguaje C son: Compilador GCC es parte del proyecto GNU2 , funciona para plataformas
kernel concentra todas las funcionalidades posibles de un sistema operativo, a saber: planicaci on, manejo del sistema de archivos, manejo de redes, controladores de dispositivos, gesti on de memoria, entre otras. 2 GNU acr onimo recursivo que signica GNU is Not Unix, cuya losof a est a enfocada a com1 Un
15
16 GNU-Linux.
CAPITULO 3. LENGUAJE C
Compilador MinGW3 es una implementaci on del compilador GCC para la plataforma Win32; es decir, para entornos Windows. Compilador Turbo C4 funciona para entornos MS-DOS5 .
3.1.1.
Tipos de datos
Los tipos de datos que procesa una computadora se clasican en: b asicos y estructurados. Los b asicos, constituyen un solo valor que puede ser: entero, real, entero caracter. largo, real de doble precisi on o Los estructurados que hacen referencia a un grupo de valores. Los tipos de datos estructurados se clasican en: Arreglos (vectores y matrices): Todos los valores del arreglo son de un solo tipo b asico. Cadenas: Es un vector que guarda valores de tipo caracter Registros: Hacen referencia a un grupo de valores, donde cada uno de ellos puede ser de un tipo b asico; inclusive puede incluir tipos de datos estructurados (arreglos, cadenas o registros)
3.1.2.
Variables y constantes
Identicadores. Es el nombre que identica a una o varias celdas de memoria, las cuales contendr an datos simples o estructurados. Un identicador se forma por medio de letras, d gitos y el caracter gui on bajo ( ). Un identicador siempre comienza con una letra. C distingue entre min usculas y may usculas, por ejemplo: los identicadores Aux y aux son diferentes. La longitud m axima m as com un de un identicador, no excede los 7 caracteres. Existe un conjunto de palabras reservadas del lenguaje que no deben emplearse como identicadores, ver tabla 3.1.
partir el software libremente; este movimiento es encabezado por Richard Matthew Stallman. 3 MinGW acr onimo ingl es para Minimalist GNU for Windows, creado por Colin Peters. 4 Turbo C fue propuesto por Borland Software Corporation. 5 MS-DOS acr onimo ingl es para MicroSoft Disk Operating System.
3.1. ORIGEN DEL LENGUAJE C auto break case char const continue default do double else enum extern oat for int short signed sizeof static struct switch typedef union unsigned void volatile while goto if long register return main
17
Variables. Empleamos un identicador para nombrar a una variable, la cual designa un conjunto de celdas, que guardar an un valor temporalmente; es decir que el valor cambiar a durante el tiempo de ejecuci on del programa. En C declaramos una variable, de los tipos mencionados en la secci on 3.1.1. Ejemplos:
int valor1; float valor2=5.4; //se asigna un valor inicial a la variable //El signo de igual (=) significa, en lenguaje C, asignacion. El valor de la derecha del signo se asigna a la variable o constante de la izquierda.
Constantes. Empleamos un identicador para nombrar a una constante, la cual designa un conjunto de celdas, que guardar an un valor que no cambia durante el tiempo de ejecuci on del programa.
#$define PI 3.14169 //se declara enseguida de las bibliotecas const float PI=3.14169; //se declara en el cuerpo de una funcion
3.1.3.
Operadores
Distinguiremos tres tipos de operadores: 1) aritm eticos, 2) relacionales y 3) l ogicos. Tambi en analizaremos los operadores simplicados, los operadores de incremento-decremento y el operador coma (,). Operadores aritm eticos. Suponga que declaramos dos variables (v y x) una de tipo real y otra de tipo entera: float v; int x; ver operaciones en la tabla 3.2
CAPITULO 3. LENGUAJE C Operaci on x=4.5+3 v=4.5+3 x=4.5 - 3 v=4.5 - 3 x=4.5 * 3 v=4.5*3 v=4*3 x= 4 / 3 x=4.0 / 3.0 v=4 / 3 v=4.0 / 3 v=(oat) 4 / 3 v=((oat) 5+3) / 6 x=15 %2 v=(15 %2)/2 v=((oat)(15 %2))/2 Resultado x=7 v=7.5 x=1 v=1.5 x=12 v=13.5 v=12.0 x=1 x=1 v=1.0 v=1.33 v=1.33 v=1.33 x=1 v=0.0 v=0.5
Divisi on
M odulo
Al evaluar expresiones aritm eticas debemos respetar la jerarqu a de los operadores y aplicarlos de izquierda a derecha, la tabla 3.3 muestra la prioridad entre los operadores aritm eticos. Prioridad Mayor Menor Operadores (), *, /, % +, -
Operadores aritm eticos simplicados. Nos permiten realizar la misma operaci on utilizando una notaci on m as compacta (tabla 3.4). Operador += -= *= /= %= Operaci on larga x=x+5 y=y-2 x=x*y x=x/y x=x %y Operaci on simplicada x+=5 y-=2 x*=y x/=y x %=y
19
Operadores de incremento y decremento. Se pueden utilizar antes o despu es de la variable, pero los resultados son diferentes. Suponga que declaramos las variables x y y como enteras y x=7, los resultados de operar con estas variables se pueden observar en la tabla 3.5 Operaci on y=x++ y=++x y=x y= Resultado y=7 x=8 y=8 x=8 y=7 x=6 y=6 x=6
Expresiones l ogicas o booleanas. Est an formadas por n umeros, constantes, variables y operadores l ogicos y relacionales. El valor que pueden tomar estas ex 0 (falso). Las expresiones l presiones al ser evaluadas, es 1 (verdaderas) o ogicas se utilizan frecuentemente en estructuras de decisi on y en estructuras repetitivas. Operadores relacionales. Se utilizan para comparar dos operandos, los cuales pueden ser: n umeros, caracteres, cadenas, constantes o variables, ver tabla 3.6. Operadores l ogicos. Permiten formular condiciones compuestas a partir de varias condiciones simples, ver tabla 3.7.
Descripci on igual a diferente de menor que mayor que menor o igual que mayor o igual que
La tabla de verdad 3.8 muestra el comportamiento de los operadores l ogicos NOT (!), AND (&&) y OR (||) P 1 1 0 0 Q 1 0 1 0 !P 0 0 1 1 !Q 0 1 0 1 P||Q 1 1 1 0 P&&Q 1 0 0 0
Otro ejemplo:
int x, y, z, v; x=(y=(15>10), z=(2>=y), y&&z); Ejecutamos las operaciones de izquierda a derecha: y=(15 > 10) entonces y = 1 (verdadero) z=(2 >= y) entonces z = 1 x=(y && z) entonces x=1
Prioridades de los operadores. Las expresiones se eval uan de izquierda a derecha, pero los operadores se aplican seg un su prioridad, tal y como se observa en la tabla 3.9.
3.1. ORIGEN DEL LENGUAJE C Prioridad (+) Operadores () !, ++, , /, % +, ==, ! =, <, >, <=, >= &&, || + =, =, =, / =, % = ,
21
(-)
22
CAPITULO 3. LENGUAJE C
Cap tulo 4
Estructuras de decisi on
Las estructuras de decisi on se utilizan en la soluci on de un problema cuando debemos elegir entre dos o m as opciones. Esta estructura determinar a el ujo que seguir a el programa que estamos construyendo. La toma de una decisi on se basa en la evaluaci on de una o m as condiciones. Distinguimos cinco tipos de estructuras de decisi on: 1. Estructura de decisi on simple (if) 2. Estructura de decisi on binaria (if-else) 3. Estructura de decisi on encadenada (if-else, if-else) 4. Estructura de decisi on anidada 5. Estructura de decisi on m ultiple (switch)
4.1.
Decisi on simple
Al llegar a una estructura de decisi on durante la ejecuci on de un programa, se eval ua la condici on; si es verdadera entonces se ejecuta un bloque de instrucciones espec co; pero si la condici on es falsa entonces este bloque es ignorado y se contin ua con el ujo normal del programa, ver gura 4.1. 23
24
if(condicion){ bloque_V; } :
condicion puede estar formada por una o varias condiciones que al ser evaluadas nos proporcionan un valor l ogico (V-verdadero F-falso) o bloque V denota un conjunto de instruc nicamente cuando el ciones que se ejecuta u resultado de la condici on es verdadera Los dos puntos signican el ujo secuencial del programa
menores de 12 anos. Programa 4.1: Descuento en dulces para los ninos En vido de tener utilidades a costa de una mayor la tienda de Don Pascual, siempre a cantidad de diab eticos infantiles, tiene una promoci on que consiste en otorgar el 20 % de descuento solo para ni nos menores de 12 a nos, cuya compra sea mayor o igual a 100 pesos. Realice un programa para que de manera autom atica, Don Pascual no tenga que utilizar su calculadora cada que atienda a un ni no con dichas caracter sticas.
Especicaci on El programa debe dar como entrada la cantidad a pagar (valor 1 si el real) y un valor entero: 0 si el ni no que compra es mayor o igual a 12 a nos, o ni no que compra es menor de 12 a nos. El programa calcula el precio de la compra nicamente dos decimales. La tabla 4.1 muestra dos ejemplos de (valor real), con u entrada-salida.
25
NOTA: 1. En este programa es importante que el usuario introduzca los valores con el formato correcto. 2. Recordemos que en C, el operador relacional igual que es ==; en contraste con el operador asignaci on, que es =. 3. No olvidemos que los corchetes delimitan el inicio y n de cualquier estructura de control, en este caso la estructura if. 4. El c odigo de impresi on esta limitado a 128 caracteres, en los programas en C no se pueden imprimir acentos ni ((e nes)).
4.2.
Decisi on binaria
En la estructura de decisi on binaria tenemos dos bloques alternativos de instrucciones, los cuales son independientes uno de otro; en el punto de la toma de una decisi on solo se ejecutar a uno de ellos, dependiendo del valor l ogico que resulte al evaluar la condici on, ver gura 4.2.
26
condicion puede estar compuesta por una o varias condiciones que al ser evaluadas nos proporcionan un valor l ogico (V-verdadero F-falso). o bloque V denota un conjunto de instruc nicamente cuando el ciones que se ejecutar au resultado de la condici on es verdadero bloque F denota un conjunto de instruc nicamente cuando la ciones que se ejecutar au condici on es falsa
Programa 4.2: Ra ces de un polinomio de segundo grado. Hacer un algoritmo que encuentre las ra ces de un polinomio de segundo grado. El algoritmo debe proporcionar las ra ces imaginarias, si ese fuera el caso. Ver la ecuaci on 4.1 b + b2 4ac x= 2a
(4.1)
Especicaci on: Las variables de entrada son tres valores reales, y como sal dos n ida pueden ser dos n umeros reales, o umeros imaginarios. Cuando el determinante es cero, la ra z est a degenerada y se imprime dos veces. La tabla 4.2 proporciona algunos datos de entrada y salida esperados.
ENCADENADA 4.3. DECISION Entrada 1.0 2.5 3.0 -1.5 2.0 3.5 Salida -1.25 + 1.198958 i -1.25 - 1.198958 i -1 0.666667
27
#include <stdio.h> #include <math.h> int main(void){ float a, b, c, det, aux; printf("Dame los 3 coeficientes de la ecuaci de segundo grado:"); printf("ax2+bx+c=0 :"); scanf(" %f %f %f",&a,&b,&c); det=(b*b-4*a*c); aux=-b/(2*a); if(det < 0){ printf("x1 = %f + %f i \n",aux,pow(-det,.5)/(2*a)); printf("x2 = %f - %f i",aux,pow(-det,.5)/(2*a)); } else { printf("x1 = %f \nx2 = %f",aux+pow(det,.5)/(2*a),aux-pow(det,.5)/(2* a)); } return 0; }
4.3.
Decisi on encadenada
Cuando una condici on que es falsa nos lleva a evaluar una nueva condici on, decimos que las estructuras de decisi on est an encadenadas. Cada condici on se eval ua siguiendo el orden, el bloque de instrucciones del otro caso (else) solo se ejecutar a cuando ninguna de las condiciones anteriores se ha cumplido. Observe que las estructuras encadenadas mantienen independencia una de otra, por lo tanto es m as sencillo manipularlas durante la soluci on de un problema. Ver la gura 4.3.
28
if(condicion1){ bloque1_V; } else if(condicion2){ bloque2_V; } else if(condicion3){ bloque3_V; } else{ bloque3_F; }
condicion puede estar compuesta por una o varias condiciones que al ser evaluadas nos proporcionan un valor l ogico F-falso). (V-verdadero o bloque V denota un conjunto de in nicamente strucciones que se ejecutar au cuando el resultado de la condici on es verdadero El bloque F denota un conjunto de nicainstrucciones que se ejecutar a u mente cuando ninguna de las condiciones previas se hayan cumplido
Programa 4.3: Pirinola digital. Construir un programa que simule el juego de la pirinola, tambi en llamada perinola o peonza. Hay siete valores que se pueden asociar a un n umero aleatorio entre 0 y 6; o bien, en un intervalo (depende del generador de n umeros aleatorios del lenguaje de programaci on). Especicaci on: En este problema no hay una entrada por parte del usuario; el programa debe generar un valor aleatorio, correspondiente a los lados de la pirinola, para luego indicar la acci on que los jugadores deben realizar. La tabla 4.3
ENCADENADA 4.3. DECISION determina el valor y la acci on asociada. Valor 0 1 2 3 4 5 6 Acci on Pon uno Pon dos Toma uno Toma dos Toma todo Todos ponen Pierdes todo
29
Programa 4.4: Funci on denida por intervalos. Construya un algoritmo que calcule el resultado de la funci on f(y) denida en los siguientes intervalos:
30
3y + 36 y2 10 f (y) = 3 y + y2 1 0
Especicaci on:
Los valores de entrada y salida son otantes. Entrada 3 44.4 Salida 45.0 89498.75
#include<stdio.h> #include<math.h> int main(void){ float x=0.0, y=0.0; printf("Introduce el valor de y: "); scanf(" %f", &y); if(y>0.0 && y<=11.0) printf("x = %.2f", 3*y+36); else if(y>11.0 && y<=33.0) printf("x = %.2f", pow(y,2)+10); else if (y>33.0 && y<=64.0) printf("x= %.2f", pow(y,3)+pow(y,2)-1); else printf ("x= %.2f", x); return 0; }
4.4.
Decisi on anidada
En t erminos generales, una estructura de decisi on puede contener a otras estructuras, por ejemplo: una estructura de proceso, una estructura de repetici on e incluso una nueva estructura de decisi on. En particular, cuando una condici on que es verdadera nos lleva a evaluar una nueva condici on, decimos que las estructuras selectivas est an anidadas. En una estructura anidada se debe tener cuidado de no olvidar cerrar las llaves correspondientes a cada una de las estructuras; y tambi en, se debe tener cuidado de cerrarlas en el lugar adecuado (ver gura 4.4).
31
Figura 4.4 Estructura de decisi on encadenada if(condicion1){ if(condicion2){ if(condicion3){ bloque3_V; } else{ bloque3_F; } } else{ bloque2_F; } } else{ bloque1_F; }
condicion puede estar compuesta por una o varias condiciones que al ser evaluadas nos proporcionan un valor l ogico (V F-falso). verdadero o bloque3 V solo se ejecutar a cuando las condiciones 1,2 y 3 sean verdaderas nicaUno de los bloque F se ejecutar au mente cuando la condici on respectiva no se haya cumplido
Programa 4.5: Juego de piedra-papel-tijera. El programa simula ser un oponenete que elige al azar una de las tres opciones: piedra, papel o tijera, y la compara con la que elige el usuario. Especicaci on: Como entrada el usuario proporciona un de los siguientes n umeros, donde cada uno tendr a un signicado distinto: 1 signica piedra, 2 signica papel y 3 signica tijera. Como salida el programa deber a indicar el ganador
32
del juego. Es importante se nalar que para simular la tirada de la computadora, en el programa deber a seleccionarse uno de los tres valores de manera aleatoria, empleando la funci on que genere un n umero aleatorio del lenguaje de programaci on en que se desee codicar el algoritmo. La tabla 4.6 permite identicar los casos de gane y pierde para ambos jugadores (la computadora y el usuario). Las expresiones ((Gan e)), ((Ganaste)) y ((Empate)) provienen del jugador oponente simulado por la computadora. Algunos ejemplos de entrada salida se obsevan en la tabla 4.7
``` ```
Usuario
Entrada 1 2
Salida Tu opci on fue piedra, yo escog piedra Empatamos! Tu opci on fue papel, yo escog tijera Gan e!
Tabla 4.7 Piedra-papel-tijera
#include<stdio.h> #include<stdlib.h> #include<time.h> int main(void){ int num=0, opc=0; srand(time(NULL)); num=(rand() %3)+1; printf("1-Piedra 2-Papel 3-Tijera \n"); printf("Escoge una de las opciones anteriores: "); scanf(" %d",&opc); if(opc==1){ if(num==1) printf("Tu opcion fue Piedra, yo escogi Piedra - Empatamos!"); else if(num==2) printf("Tu opcion fue Piedra, yo escogi Papel - Gane!"); else if(num==3) printf("Tu opcion fue Piedra, yo escogi Tijera - Ganaste!"); } else if(opc==2){ if(num==1) printf("Tu opcion fue Papel, yo escogi Piedra - Ganaste!"); else if(num==2) printf("Tu opcion fue Papel, yo escogi Papel - Empatamos!"); else if(num==3)
33
fue Tijera, yo escogi Piedra - Gane!"); fue Tijera, yo escogi Papel - Ganaste!"); fue Tijera, yo escogi Tijera -Empatamos!");
4.5.
Decisi on multiple
En problemas que involucran tomar una decisi on entre m ultiples opciones conviene emplear la estructura switch (gura 4.5), en lugar de emplear estructuras condicionales encadenada. La estructura de decisi on m ultiple proporciona un c odigo m as claro para quienes lo leen; su uso m as com un es la construcci on de un men u de opciones para el usuario del programa.
34
CAPITULO 4. ESTRUCTURAS DE DECISION case permite que el programa decida sobre el bloque de instrucciones que deber a ejecutarse, seg un el valor de la variable selector; por ejemplo (si selector=2 entonces se ejecutar a el bloque de instrucciones denotado por case 2. selector solo puede tomar valores de tipo enteros o de tipo caracter. selector es la variable que se comparar a con el valor de cada case break indica el n del bloque de instrucciones en cada case default denota el conjunto de instrucciones que se ejecutar a cuando el valor de la variable selector no corresponda a ninguno de los case anteriores.
switch(selector){ case 1: bloque1; break; case 2: bloque2; break; case 3: bloque3; break; default: bloqueD; break; }
Programa 4.6: C alculo de sueldo. Dado el sueldo, la categor a y el costo por una hora extra de trabajo, calcular el sueldo total de un empleado con base en la tabla 4.8. Adem as, el programa debe considerar que si el empleado trabaja m as de 30 horas extras, solo se le pagar an las primeras 30.
Especicaci on: El usuario introduce la clave de la categor a, el sueldo y las horas extras; como resultado, el programa proporciona el sueldo neto del empleado; la tabla 4.9 muestra dos ejemplos Categor a 1 2 3 4 Precio por hora extra 30 38 50 70
35
#include <stdio.h> int main(void){ int categoria=0,hExtra=0; float sueldo=0.0,PHE=0.0; printf("CAT \t Precio HE \n"); printf(" 1 \t 30 \n 2 \t 38 \n 3 \t 50 \n 4 \t 70 \n"); printf("Categoria, sueldo, hrs extra: "); scanf(" %d %f %d", &categoria,&sueldo,&hExtra); if(hExtra > 30) hExtra=30; switch(categoria){ case 1: PHE = 30; break; case 2: PHE = 38; break; case 3: PHE = 50; break; case 4: PHE=70; break; default: PHE = 0; break; } printf("El sueldo total es de : %.2f", sueldo+PHE*hExtra); return 0; }
Programa 4.7: Pirinola con switch. Ahora vamos a retomar el problema de la pirinola, pero esta vez emplearemos la estructura de decisi on switch. Recordemos que para el juego tenemos siete posibilidades (tabla 4.10).
36
CAPITULO 4. ESTRUCTURAS DE DECISION Valor 0 1 2 3 4 5 6 Acci on Pon uno Pon dos Toma uno Toma dos Toma todo Todos ponen Pierdes todo
#include<stdio.h> #include<stdlib.h> #include<time.h> int main(void){ int num=0; srand(time(NULL)); printf("Pirinola/perinola/peonza digital \n\n"); num=rand() %7; switch(num){ case 0: printf("Pon uno \n"); break; case 1: printf("Pon dos \n"); break; case 2: printf("Toma uno \n"); break; case 3: printf("Toma dos \n"); break; case 4: printf("Toma todo \n"); break; case 5: printf("Todos ponen \n"); break; default: printf("Pierdes todo"); break; } return 0; }
Cap tulo 5
Funciones
Para resolver un problema de gran tama no es conveniente descomponerlo en subproblemas, de tal manera que cada uno de ellos pueda ser resuelto de una manera m as sencilla. El lenguaje C emplea el t ermino ((funci on)) para denotar el c odigo que resuelve un subproblema. Algunas ventajas de emplear funciones son: Facilita la escritura y lectura de los programas. Permite el trabajo en paralelo. Facilita la asignaci on de responsabilidades. El c odigo de la funci on se escribe una sola vez y se utiliza tantas veces como sea necesario. Facilita el mantenimiento de los programas.
5.1.
Sea L( p) la longitud de un programa cualquiera y sean l ( p1) y l ( p2) las longitudes de dos segmentos mutuamente excluyentes y complementarios del mismo programa p; de tal modo que la longitud del programa ser a: L( p) = l ( p1 ) + l ( p2 ) (5.1)
Donde p designa al programa completo y pi denota los subprogramas (c odigos) que conforman a p. Sean adem as E ( p), e( p1 ) y e( p2 ) los esfuerzos necesarios para obtener L( p), l ( p1 ) y l ( p2 ) respectivamente; en general se tendr a que: E ( p) > e( p1 ) + e( p2 ) 37 (5.2)
38
CAPITULO 5. FUNCIONES
Es decir, el esfuerzo para construir al programa p es estrictamente mayor al esfuerzo requerido para construir de forma independiente los programas p1 y p2 . Adem as, es m as f acil corregir errores y modicar el c odigo de un programa que es peque no que el de un programa que es grande; principalmente porque en un programa peque no est a enfocado a una tarea espec ca; por el contrario, un programa grande suele realizar varias tareas a la vez.
5.2.
5.2.1.
Declarar la funci on
Es indicar al compilador que una funci on forma parte del programa; a esta acci on tambi en se le conoce como especicaci on del prototipo de una funci on. Generalmente, el prototipo de una funci on se escribe despu es de incluir las bibliotecas y antes de iniciar la funci on main().
tipo_dato nombre_funcion(lista_parametros);
Donde: tipo dato indica el tipo de dato que devolver a la funci on al concluir su ejecuci on, por elemplo: int, float, char. lista parametros corresponde al conjunto de valores que recibir a de la funci on que la llam o. Los valores est an contenidos en variables, por lo tanto deber an recibirse estos valores en variables locales (propias de la funci on receptora). Una funci on no necesariamente devuelve un valor y no necesariamente recibe par ametros, en este caso se indica con la palabra reservada void.
5.2.2.
Denir la funci on
Signica especicar el conjunto de instrucciones que realizar an una tarea determinada dentro del programa.
tipo_dato nombre_funcion(lista_parametros){ declarar_variables;
39
Donde: declarar variables corresponden a variables locales que requerir a la funci on para realizar su tarea. bloque de instrucciones que determinan el comportamiento de la funci on. return marca el n de la funci on y devuelve, cuando as se requiera, un resultado (valor) cuyo tipo corresponde al denido en el prototipo de la funci on. Es importante que el prototipo de la funci on coincida exactamente con la cabecera de la funci on, en su denici on.
5.2.3.
Llamar a la funci on
desde cualquier otra funci Se realiza desde la funci on principal o on. Durante la ejecuci on del programa, el llamado a una funci on implica un ((salto)) hacia ella para ejecutar su conjunto de instrucciones; al terminar, se devuelve el control de la ejecuci on a la funci on que la llam o; en este caso a la funci on main(). Al hacer el llamado debe especicarse: El nombre de la funci on (nombre funcion) a la que se desea invocar. Los valores (lista de valores) que ser an enviados a la otra funci on. Generalmente, los valores est an contenidos en variables, las cuales se escriben dentro del par entesis, siguiendo el orden y respetando el tipo de dato (tipo dato) declarado en el prototipo.
int main(void){ : nombre_funcion(lista_de_valores); : return 0; }
Programa 5.1: Encontrar el mayor de tres numeros. Dados tres n umeros enteros a, b y c, encontrar al mayor de entre ellos.
40
CAPITULO 5. FUNCIONES
Especicaci on: La funci on recibe como param etros tres valores de tipo entero, y como salida muestra al mayor de entre ellos; la tabla 5.3 muestra dos ejemplos. Entrada 82 1 7 342 867 950 Salida 82 867
41
5.3.
Una manera de realizar la comunicaci on entre las funciones es a trav es del paso de par ametros por valor, donde la funci on receptora recibe como par ametros una copia de los valores contenidos en las variables originales (propias de la funci on que hace el llamado); por lo tanto, si una variable local (propia de la funci on receptora) sufre una alteraci on no afectar a a la variable original, porque la variable local solo tiene una copia del valor. Programa 5.2: Piedra-Papel-Tijera con funci on. Retomando el juego de piedrapapel-tijera, reformularemos el c odigo, empleando una funci on llamada ((referi)), la cual estar a encargada de determinar al ganador de la jugada. Especicaci on: La funci on recibe como par ametros: el valor de la tirada del usuario y el valor de la tirada de la computadora; la funci on env a el resultado a la pantalla de la computadora. La tabla 5.2 muestra dos ejemplos. Entrada 3 2 Salida Tu opci on fue Tijera, yo escog Piedra Ganaste! Tu opci on fue Papel, yo escog Papel Empatamos!
Tabla 5.2 Piedra-Papel-Tijera
#include<stdio.h> #include<stdlib.h> #include<time.h> void referi(int mine, int yours); int main(void){ int mine=0, yours=0; printf("Juguemos a piedra papel o tijera \n"); printf(" 1. Piedra \n 2. Papel \n 3. Tijera \n"); printf("Cual es tu tirada: "); scanf(" %d", &yours); printf("Mi tirada es: "); srand(time(NULL)); mine=rand() %3+1; printf(" %d \n",mine); referi(mine,yours); return 0; } void referi(int mine, int yours){ if(mine==yours) printf("Empate entre tu y yo \n"); else{
42
CAPITULO 5. FUNCIONES
switch(yours){ case 1: if(mine==2) printf("Gane !!!! \n"); else printf("Ganaste!!! \n"); break; case 2: if(mine==1) printf("Ganaste!!! \n"); else printf("Gane!!! \n"); break; case 3: if(mine==1) printf("Gane!!! \n"); else printf("Ganaste!!! \n"); break; default: printf("ERROR en tu tiro!!! \n"); break; } } return;
5.4.
El paso de par ametros por referencia es otra forma de comunicarnos con las funciones. Aqu los par ametros no son copias de los valores, sino las direcciones de las variables originales; por lo tanto, si un par ametro sufre una alteraci on en la funci on que lo recibe, la variable original tambi en se ve afectada. En el lenguaje C, el paso de par ametros por referencia se realiza mediante el concepto de ((apuntador)). Un apuntador es una direcci on de memoria (por ejemplo 0X 98 f 010 expresada en hexadecimal). Dado que debemos manipular una direcci on de memoria, se vuelve necesario declarar variables que puedan guardar direcciones; las cuales no corresponden a ninguno de los tipos de datos b asicos vistos hasta ahora (int, float, char, etc.). Por lo tanto, emplearemos una notaci on especial que nos permita denotar una variable de tipo apuntador; a saber, los operadores de: direcci on (&), declaraci on de variable tipo apuntador (*) e indirecci on (*). Programa 5.3: Manejo de una variable de tipo apuntador. Las variables x y z guardan dos valores n umeros enteros, y la variable y es de tipo ((apuntador a entero)). El programa muestra el uso de los operadores para el manejo de apuntadores.
43
Especicaci on: La funci on no recibe param etros, x = 3, y como salida se muestra la asignaci on z = (y); la tabla 5.3 muestra el ejemplo. Salida 3
Tabla 5.3 Manejo de una variable apuntador
#include<stdio.h> int main(void){ int x=0,z=0; int *y; //declaro y como una variable de tipo apuntador x=3; y=&x; //le asigno a y la direcci on de x, por lo tanto y apunta a x z=*y; //le asigno a z el valor de la variable a la cual apunta y printf("z= %d ",z); return 0; }
En tiempo de ejecuci on, el manejo de la memoria ser a como se muestra en la gura 5.1. La direcci on de x es 0x98 f 010 y su contenido es 3. En el paso 1 y guarda la direcci on de x, y en el paso 2, a la variable z se le asigna el valor de la variable a la que y apunta; es decir, el valor de x. Cuando se asigna la direcci on de x a y, es como si y se encontrara apuntando a x, tal y como lo muestra la gura 5.2.
Programa 5.4: Intercambio del valor de dos variables. Escribir un programa que realice el intercambio de valores entre dos variables, empleando paso de
CAPITULO 5. FUNCIONES
Especicaci on: Este programa debe estar formado por una funci on que permute los valores de dos variables a, b; esta funci on no devuelve ning un valor y debe recibir las direcciones de las tres variables; la tabla 5.4 muestra dos ejemplos. Entrada a=84 b=10 a=2 b=22 Salida a=10 b=84 a=22 b=2
Programa 5.5: De segundos a horas, minutos y segundos. Construya un programa en C que reciba un valor entero correspondiente a una cantidad en segundos; y luego, debe mostrar en pantalla su equivalente en horas, minutos y segundos restantes. Especicaci on: Escriba una funci on denominada convertir que reciba como par ametro, por valor, la cantidad de segundos; y los par ametros, por referencia hora min y seg. Las entradas y salidas son de tipo entero; la tabla 5.3 muestra dos ejemplos.
5.4. PASO DE PARAMETROS POR REFERENCIA Entrada 123456 67758 Salida 34h 17m 36s 18h 49m 18s
45
#include <stdio.h> void convertir (int,int*,int*,int*); int main(void){ int segundos,hora,min,seg; printf("Ingresa los segundos: "); scanf(" %d",&segundos); convertir(segundos,&hora,&min,&seg); printf(" %d h %d min %d seg",hora,min,seg); return 0; } void convertir (int *hora = segundos *min=(segundos % *seg=(segundos % return; } segundos,int* hora, int* min, int*seg){ /3600; 3600)/60; 3600) %60;
46
CAPITULO 5. FUNCIONES
Cap tulo 6
Estructuras repetitivas
En la soluci on de algunos problemas es com un requerir que un conjunto de instrucciones sea ejecutado varias veces. Al conjunto de instrucciones que se ejecuta repetidamente se le llama ciclo; si bien, las instrucciones son las mismas, los datos pueden variar. En una estructura repetitiva debe existir una condici on que detenga la ejecuci on del ciclo (suele llamarse condici on de paro). En cada iteraci on esta si debe detenerse. condici on de paro es evaluada para decidir si el ciclo contin ua o
6.1.
Generalmente, la estructura for (ver gura 6.1) se utiliza en soluciones donde se conoce el n umero de veces que deber a repetirse el ciclo. Por lo tanto, se establece decrementando en cada un contador inicial; este contador se va incrementando o m iteraci on, hasta alcanzar un valor m aximo o nimo; una vez alcanzado este valor, el ciclo termina y se contin ua con el ujo normal del programa.
47
48
CAPITULO 6. ESTRUCTURAS REPETITIVAS exp1 establece un valor inicial a un contador. exp2 corresponde a la condici on de paro donde se especica el valor m aximo o m nimo que podr a alcanzar el contador. decremento para el contador. exp3 corresponde al incremento o bloque V conjunto de instrucciones que se repetir a hasta que la condici on sea falsa. Cuando la condici on es falsa.
Programa 6.1: Numeros perfectos. Se dice que un n umero entero es perfecto si l mismo es igual al propio n la suma de sus divisores excepto e umero. Por ejemplo, seis es n umero perfecto porque 1 2 3 = 6 y 1 + 2 + 3 = 6. Escriba un programa que obtenga los n umeros perfectos comprendidos entre 1 y 10000. Especicaci on: El programa no recibe ning un valor por parte del usuario; en lugar de eso, genera una lista de n umeros en un rango de [1.,10000] y para cada uno de ellos, determina si es un n umero perfecto. La tabla 6.1 muestra los cuatro n umeros perfectos comprendidos en el rango antes mencionado. Salida 6 28 496 8128
Tabla 6.1 N umeros perfectos
#include <stdio.h> #define MAX 1e4 int main(void){ int num=0, sum=0, i=0; printf("Numeros perfectos \n\n"); for(num=1; num<=MAX; num++){ sum=0; for(i=1; i<=(num/2); i++) if(num %i==0) sum = sum+i; if(sum==num) printf (" %5d es numero perfecto \n", num); } return 0; }
49
Programa 6.2: Adivina el numero. Construir un programa que simule el juego de adivinar un n umero comprendido entre 1 y 100. El usuario tiene 7 oportunidades para lograrlo. El programa debe generar aleatoriamente el n umero y luego solicitar al usuario que lo adivine. Si el n umero del usuario es menor que el n umero aleatorio, se le indica ((mi n umero es mayor)); pero si el n umero del usuario es mayor que el n umero aleatorio, se le indica ((mi n umero es menor)); si el n umero del usuario es igual que el n umero aleatorio, se le indica ((acertaste)); si el usuario agota sus oportunidades, el programa avisa que el juego termini o y naliza. Especicaci on: Los n umeros de entrada son enteros y la salida es una cadena de texto que se imprime en pantalla. La tabla 6.2 proporciona un ejemplo. Entrada 50 25 12 17 21 20 40 60 80 90 88 86 Salida mi numero es menor mi numero es menor mi numero es mayor mi numero es mayor acertaste mi numero es mayor mi numero es mayor mi numero es mayor mi numero es mayor mi numero es menor mi numero es menor se acabaron tus intentos
// Programa que simula el juego de adivina el numero que estoy pensando #include<stdio.h> #include<stdlib.h> #include<time.h> int main(void){ int num=0, tuNum=0, i=0; srand(time(NULL)); printf("Programa adivina un nmero en 7 oportunidades o menos\n"); printf("\n Estoy pensando un numero, entre 1 y 100"); num=(rand() %100)+1; for(i=1; i<=7; i++){ printf("\n Intenta adivinar el numero: "); scanf(" %d", &tuNum); if(num < tuNum) printf("Mi numero es menor \n");
50
Programa 6.3: Numeros primos menores a cincuenta. Construir un programa que determine los n umeros primos menores a cincuenta. Un n umero es primo, si nicos divisores son e l mismo y la unidad. sus u Especicaci on: No hay entrada por parte del usuario; como salida se enlistan los n umeros primos con la siguiente leyenda: ((x es primo)). La tabla 6.3 muestra un ejemplo. Salida 2 es primo 3 es primo 5 es primo 7 es primo 11 es primo 13 es primo 17 es primo 19 es primo 23 es primo 29 es primo 31 es primo 37 es primo 41 es primo 43 es primo 47 es primo
Tabla 6.3 N umeros primos
#include <stdio.h> #define LIM 1e3
51
n! = n (n 1) (n 2) . . . 2 1
(6.1)
Especicaci on: Solicitar al usuario un n umero entero para obtener su factorial. Para la soluci on debe denir una funci on secundaria. La tabla 6.4 muestra dos ejemplos. Entrada 0 10 Salida 1 3628800
#include <stdio.h> int fact(int); void serie(int); void limite(int *n); int main(void){ int n; limite(&n); serie(n); return 0; }
52
void limite(int *n){ do{ printf("introduce un numero natural: "); scanf(" %d",n); }while((*n)<=0); return; } void serie(int n){ float termino=0.0, total=0.0; int i=0; for(i=1; i<=n; i++){ termino = (float)(2*i)/fact(2*i); printf(" %f ", termino); total+=termino; } printf("\n %f ", total); return; } int fact(int n){ int aux=1,x=0; for(x=1; x<=n; x++){ aux=aux*x; } return aux; }
53
6.2.
sta resulta verdadera La estructura while eval ua primero una condici on, si e entonces se ejecuta el bloque de instrucciones; de lo contrario, se contin ua con el ujo normal del programa. Generalmente, la estructura while se emplea en soluciones donde no se conoce previamente la cantidad de iteraciones que deben realizarse para obtener un resultado. Sin embargo, una estructura while puede emplearse en lugar de una estructura for en soluciones donde se conoce el n umero de iteraciones. Es importante se nalar que una estructura while, podr a no ejecutarse, si la condici on nunca se cumple.
while(condicion){ bloque_V; }
mientras la condicion sea verdadera, el ciclo contin ua en ejecuci on. La condici on de paro puede implicar varias condiciones unidas por los operadores l ogicos && y ||. bloque V es el conjunto de instrucciones que conformar an el ciclo. Programa 6.5: Serie alternante. Escriba un programa que empezando en el n umero dos, le suma cinco, al siguiente t ermino le suma tres; luego, al siguiente t ermino cinco, y al siguiente t ermino tres, y as alternadamente, hasta alcanzar el n umero 2500. Especicaci on: El programa no tiene una entrada espec ca del usuario; y la salida es la serie de n umeros que resultan de ir sumando alternadamente 5 y 3; la tabla 6.5 muestra un ejemplo.
54
#include <stdio.h> int main(void){ int serie=2, cambio=1; while(serie<=2500){ printf(" %d\t",serie); if(cambio==1){ serie+=5; cambio=0; } else { serie+=3; cambio=1; } } return 0; }
Programa 6.6: Suma y promedio de calicaciones. Escriba un programa que solicite calicaciones a un usuario. El programa debe aceptar calicaciones hasta que se introduce un valor fuera del rango. El programa debe mostrar la suma y el promedio de las calicaciones. Especicaci on: El usuario introduce las calicaciones en un rango de [0, 10]; y como salida se proporciona el promedio. Ambas variables deben ser declaradas como reales; la tabla 6.6 muestra dos ejemplos. Entrada 3 5 10 5.5 8.5 9.5 Salida 6.0 7.83
55
6.3.
A diferencia de las estructuras for y while, que analizan la condici on de paro al principio del ciclo, la estructura do-while comprueba la condici on al nal (gura 6.3). Esto signica que el bloque de instrucciones se ejecutar a al menos una vez. Generalmente, esta estructura se emplea para validar datos que se reciben desde el teclado; sin embargo, puede emplearse en cualquier otro tipo de soluci on que involucra iteraciones.
bloque V es el conjunto de instrucciones que se va a repetir mientras la condici on sea verdadera. Note que bloque V se ejecutar a por lo menos una vez, la primera vez que se ingresa a la estructura do-while.
56
CAPITULO 6. ESTRUCTURAS REPETITIVAS Haz bloque V mientras la condicion se cumpla. La condici on de paro puede implicar varias condiciones unidas por los operadores l ogicos && y ||.
Programa 6.7: Promedio de pares y promedio impares. Escribir un algoritmo que obtenga por una parte, el promedio de los n umeros pares, y por otra parte, el promedio de los impares. Los n umeros son enteros positivos que introduce el usuario. El programa se detiene cuando el usuario introduce cero o un valor negativo. Especicaci on: El usuario introduce uno a uno valores enteros, cuando se introduce un valor menor o igual que 0, entonces se le informa por un lado sobre el promedio de los valores pares y por otro lado, sobre el promedio de los impares. Los valores de entrada son enteros y los de salida son reales. La tabla 6.7 muestra dos ejemplos. Entrada 1234560 998876 Salida 4.0 3.0 7.33 8.33
57
Problema 6.8: Cortina de numeros. Escriba un programa que genere una cortina de n umeros en la pantalla. Especicaci on: El usuario introduce un n umero natural para denir el tama no de la cortina, con un tama no m aximo de 12 para que se muestre la cortina correctamente en la pantalla. El programa debe validar el dato de entrada; todo valor menor o igual que 0 terminar a el programa. Proponer una soluci on al problema empleando funciones. La tabla 6.8 muestra dos ejemplos. Entrada 3 Salida 123321 1221 11 1234554321 12344321 123321 1221 11
#include <stdio.h> int pideDato(void); void figura(int); int main(void){ int num=0; do{ num=pideDato(); }while(num<0); if(num>0) figura(num); else printf("\n Escogiste salir!!"); return 0; } int pideDato(void){ int num=0; printf("\n\n Cortina de numeros. Para salir introduce un 0, o bien"); printf("\n introduce un numero entero positivo menor a 14");
58
printf("\n\n N = "); scanf(" %d",&num); return(num); }
void figura(int num){ int i=0, j=0, k=0, aux=num; for(i=1; i<=num; i++){ //define n umero de renglones for(j=1; j<=aux; j++){ //primera serie de n umeros printf(" %3d",j); } for(k=1; k<=(2*i-1); k++){ //serie de espacios printf(" "); } for(j=aux; j>0; j--){ // serie en orden inverso printf(" %3d",j); } printf("\n"); aux--; // aux determina el l mite superior de ambas series } return; }
Problema 6.9: Numeros perfectos menores o iguales a n. Escriba un programa que muestre en pantalla todos los n umeros perfectos comprendidos en el rango de 1 a n, donde n es un n umero dado por el usuario. Especicaci on: El programa debe incluir una funci on. Si n = 0 el programa termina. Si n < 0 insiste con el usuario en solicitar un valor para n, el l mite de la serie. No se recomienda la b usqueda para valores m as grandes a 10, 000 por lo tardado que resulta encontrar el siguiente n umero perfecto, a saber: 33, 550, 336. Proponer una soluci on al problema empleando funciones; la tabla 6.9 muestra dos ejemplos. Entrada 100 10000 Salida 6, 28 6, 28, 496, 8128
59
60
Cap tulo 7
7.1.
Arreglos unidimensionales
Declarar un arreglo unidimensional es similar a declarar una variable, pero indicando su tama no, por ejemplo:
int vector[10]; //Corresponde a un arreglo llamado vector de tama no 10 y cuyos elementos deber an ser de tipo entero float num[40]; //Corresponde a un arreglo llamado num de tama no 40 y cuyos elementos deber an ser de tipo real
61
62
//Cuando se omite el tama no de un arreglo, debe inicializarse con valores, y su tama no corresponder a al n umero de valores de inicio
Se asigna un valor a cada celda. La asignaci on se hace en el orden en que aparecen los valores. En tiempo de ejecuci on, el arreglo vector se ver a, en la memoria principal, como se muestra en la gura 7.1: ndice vector 0 2.3 1 4.4 2 6.5 3 7.2 4 5.5 5 1.7 6 5.8 7 4.6
Todos los arreglos comienzan en con una posici on 0 (cero); por lo tanto, el ltima posici tama no de vector es 8, pero su u on es 7. En general, para un arreglo de ltima posici tama no n, su u on ser a n 1. l a trav Para acceder a cualquier elemento, nos referimos a e es de su posici on. En el ejemplo 7.1, para referirnos al elemento en la posici on 2, escribimos vector[2], es decir 6.5; para referirnos al elemento en la posici on 6, escribimos vector[6], es decir 5.8; el elemento del vector[2 + 3] es igual al vector[5], es decir 1.7. Problema 7.1 Imprimir en pantalla los valores de un vector. Construir un programa encargado de crear un vector con cinco elementos, el cual deber a imprimirse en la pantalla. Especicaci on: Denir un arreglo de 5 elementos enteros al que llamaremos vector. El programa recibe los valores enteros desde el teclado; cuando el arreglo est a completo deber a imprimirse cada elemento en la pantalla pero en el orden inverso en que fueron ingresados. Entrada 34195 6 28 49 68 12
#include<stdio.h> #include<stdlib.h> #include<time.h> #define MAX 5 int main(void){ int vector[MAX]={0}, i=0;
Salida 59143 12 68 49 28 6
63
printf("\nProporciona 5 valores enteros para un vector\n"); for (i=0;i<MAX;i++){ printf("\nvector[ %d] = ", i); scanf(" %d",&vector[i]); } printf("\nLos 5 valores del vector son, en el orden inverso son: \n\n") ; for (i=MAX-1;i>=0;i--){ printf(" %d ", vector[i]); } printf("\n"); return 0; }
Problema 7.2. Imprimir en pantalla los valores aleatorios de un vector. Construir un programa que genere valores aleatorios que se guardar an en un arreglo unidimensional; y posteriormente, el arreglo se imprimir a en la pantalla. Especicaci on: Denir un arreglo de 20 n umeros enteros. El programa debe generar los valores del arreglo de forma aleatoria, en un rango de [0.,9]; el programa deber a imprimir el vector en la pantalla, la tabla 7.2 muestra dos ejemplos de arreglos generados aleatoriamente. Salida 59143126849286735971 62849681259143126322
Tabla 7.2 Elementos de un vector
#include<stdio.h> #include<stdlib.h> #include<time.h> #define MAX 20 int main(void){ int enteros[MAX]={0}, i=0; printf("\nGenerando valores aleatiorios, en un rango de [0..9]"); printf("\npara un vector de 20 elementos llamado enteros \n\n"); for (i=0;i<MAX;i++){ enteros[i]=rand() %10; } printf("\nLos 20 valores del vector enteros son: \n\n"); for (i=0;i<MAX;i++){ printf(" %d ", enteros[i]); }
64
printf("\n"); return 0; }
7.2.
Cuando una funci on requiere pasar un arreglo (como par ametro) a otra funci on, ste pasa u nicamente por referencia. Por lo tanto, cualquier modicaci e on que se realice sobre el arreglo, en la funci on que lo recibe, afectar a al arreglo original que se localiza en la funci on que realiz o el llamado. Los c odigos 7.3 y 7.4 muestran dos notaciones, que podemos emplear en el lenguaje C, para manejar un arreglo que pasa como par ametro a una funci on. El resultado de ambos c odigos es el mismo; la diferencia entre los c odigos es que 7.4 muestra el paso de par ametro de un arreglo empleando la notaci on de apuntadores. Sin embargo, en ambos casos, el arreglo pasa a la funci on calcula por referencia. Problema 7.3: Mostrar el paso por referencia de un arreglo unidimensional. Construir un programa que dado un arreglo unidimensional con valores enteros, llame a la funci on calcular y reste 2 a cada elemento. El resultado debe imprimirse en la pantalla. Especicaci on: El programa debe tener dos funciones: calcular e imprimir los resultados. La tabla 7.3 muestra el resultado de restar 2 a cada elemento de un arreglo inicializado con los valores [1,2,3,4,5]. Primero, llama a la funcion calcular para realizar la resta, y segundo, llama a imprimir para observar el resultado en la pantalla. Salida -1 0 1 2 3
Tabla 7.3 Paso por referencia de un arreglo
#include<stdio.h> //Prototipos void calcular(int datos[], int n); void imprimir(int datos[], int n);
65
Problema 7.4: Mostrar el paso por referencia de un arreglo unidimensional, empleando la notaci on de apuntadores. Construir un programa que dado un arreglo unidimensional con valores enteros, llame a la funci on calcular y reste 2 a cada elemento. El resultado debe imprimirse en la pantalla. Especicaci on: El programa debe tener dos funciones: calcular e imprimir los resultados. La tabla 7.4 muestra el resultado de restar 2 a cada elemento de un arreglo inicializado con los valores [5,6,7,8,9]. Primero, llama a la funcion calcular para realizar la resta, y segundo, llama a imprimir para observar el resultado en la pantalla. Salida 3,4,5,6,7
Tabla 7.4 Paso por referencia de un arreglo (notaci on de apuntadores)
#include<stdio.h>
66
//Prototipos void calcular(int* datos, int n); void imprimir(int* datos, int n); int main(void){ int datos[]={5,6,7,8,9}; imprimir(datos,5); calcular(datos, 5); //Llamado a la funci on imprimir(datos,5); return 0; } //Definici on de la funci on calcular void calcular(int* datos, int n){ int i=0; for(i=0; i<n; i++) *(datos+i)= *(datos+i)-2; return; } //Definici on de la funci on imprimir void imprimir(int datos[], int n){ int i=0; for(i=0; i<n; i++) printf(" %d ",*(datos+i)); printf("\n\n"); return; }
Problema 7.5: Suma de dos vectores enteros. Construir un programa que calcule la suma de 2 arreglos unidimensionales de tipo entero. El resultado debe almacenarse en un tercer arreglo.
Especicaci on: El programa debe tener tres funciones: una que lea los datos, otra que haga la suma y nalmente otra que imprima los resultados. La tabla 7.5 muestra, como primer valor, el tama no de los arreglos; luego, dos vectores dados como entrada y el vector correspondiente con la suma de los valores de ambos.
7.2. ARREGLOS UNIDIMENSIONALES Y FUNCIONES. Entrada 3 123 468 4 3479 9845 Salida 5 8 11
67
12 12 11 14
#include <stdio.h> #define MAX 100 int tamVEC(void); void leeVEC(int X[],char nom,int n); void sumVEC(int A[],int B[],int C[],int n); void impVEC(int X[],char nom,int n); int main(void){ int A[MAX]={0}; int B[MAX]={0}; int C[MAX]={0}; int tam=0; tam=tamVEC(); leeVEC(A,A,tam); leeVEC(B,B,tam); sumVEC(A,B,C,tam); impVEC(A,A,tam); impVEC(B,B,tam); impVEC(C,C,tam); return 0; } int tamVEC(void){ int n=0; do{ printf("Dame el tama de los arreglos (1-100)"); scanf(" %d",&n); }while(n<=0 || n>=MAX); return (n); } void leeVEC(int X[], char nom, int n){ int i=0; printf("\nLectura del vector %c:\n",nom); for (i=0;i<n;i++){ printf("\n %c[ %d]=", nom, i); scanf(" %d",&X[i]); } return; } void sumVEC(int A[],int B[],int C[],int n){
68
} void impVEC(int X[], char nom, int n){ int i=0; printf("\n Vector %c: ", nom); for (i=0; i<n; i++){ printf(" %d ",X[i]); } return; }
Programa 7.6: Lanza treinta millones de dados. Construir un programa que simule el lanzar 3 dados, 1E 7 veces; para luego, obtener la frecuencia con la que se present o cada suma de caras en los lanzamientos. Especicaci on: No hay datos de entrada, la salida es un entero que indique la suma y la frecuencia es un porcentaje (otante menor que uno). La funci on debe tener tres funciones, una que haga la simulaci on de tirar los dados, otra que imprima la frecuencia. Opcionalmente, mediante valores ASCII1 se puede incluir una especie de histograma de frecuencias, tal y como se muestra en el ejemplo de la tabla 7.6
acr onimo ingl es para American Standard Code for Information InterchangeC odigo Est andar Estadounidense para el Intercambio de Informaci on. Este c odigo fue creado para representar un conjunto de caracteres a trav es de 7 bits.
1 ASCII
7.2. ARREGLOS UNIDIMENSIONALES Y FUNCIONES. Entrada 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Salida 0.004597 0.013925 0.027767 0.046234 0.069336 0.097385 0.115706 0.125015 0.125067 0.115598 0.097294 0.069457 0.046314 0.027788 0.013925 0.004593 0.004658 0.013884 0.027817 0.046329 0.069530 0.097008 0.115721 0.124956 0.125053 0.115827 0.097042 0.069504 0.046352 0.027833 0.013837 0.004649
69
* ** **** ****** ********* *********** ************ ************ *********** ********* ****** **** ** *
* ** **** ****** ********* *********** ************ ************ *********** ********* ****** **** ** *
70
#define ITERA 1.0e7
void tiraDados(int []); void imprimeRes(int []); void imprimeCad(int lim, char car); int main(void){ int cara[100]={0}; time_t tiempo1, tiempo2; srand(time(NULL)); time(&tiempo1); tiraDados(cara); imprimeRes(cara); time(&tiempo2); printf("\nEl tiempo de ejecucion es: %f \n", (float)(tiempo2-tiempo1)); return(0); } void tiraDados(int cara[]){ int i=0, j=0, suma=0; for(i=0; i<ITERA; i++){ suma=0; for(j=1; j<=NDADOS; j++){ suma+=(rand() %6)+1; } cara[suma]++; } return; } void imprimeRes(int cara[]){ int i=0; printf("Probabilidades para la suma de caras de %d dados son: \n",NDADOS) ; for(i=NDADOS; i<=NDADOS*6; i++){ printf(" %d \t %f \t ", i, cara[i]/ITERA); imprimeCad((int)((100*cara[i])/ITERA), *); printf("\n"); } return; } void imprimeCad(int lim, char car){ int i=0; for(i=1; i<=lim; i++) printf(" %c",car); return; }
Problema 7.7: Convierte un entro de base 10 a cualquier otra base. Construir un programa que permita recibir dos valores: 1) un valor entero positivo a convertir
71
a cualquier base num erica; y 2) un valor entero positivo correspondiente a la base para la conversi on. Es importante mencionar que el programa funcionar a bajo el siguiente criterio: si la base es 8 los d gitos utilizados ser an (0, 1, 2, . . . 7); si la base es 16 los d gitos usados ser an (0, 1, 2, . . . 15). Especicaci on: Como entrada se reciben: un valor entero (expresado en base decimal) y un valor entero que especica la base para la conversi on. Como salida, el programa imprimir a la secuencia de d gitos (correspondiente a la conversi on) separados por un espacio. El programa estar a limitado a 40 d gitos para imprimir la conversi on. Este l mite es lo sucientemente grande como para convertir cualquier entero largo decimal (del orden de 2E 9) a base binaria (siendo esta base la que requiere m as d gitos para su impresi on). Entrada 1048596 2 123456 5 Salida 100000000000000000000 12422311
#include <stdio.h> #define MAX 560 int main(void){ int decimal=0, base=0, i=0, conversion[MAX]={0}; printf("Programa que realiza la conversion entre bases"); printf("\n(de decimal a cualquier otra base) \n"); do{ printf("\nProporciona el valor a convertir (entero positivo)"); printf("\no cero para salir: "); scanf(" %d", &decimal); printf("\nProporciona la base numerica para la conversion: "); printf("\no cero para salir: "); scanf(" %d", &base); }while(decimal<0 && base<0); if(decimal>0 && base>0){ do{ conversion[i]=decimal %base; decimal=(int)(decimal/base); i++; }while(decimal!=0 && i<MAX); for(i=i-1; i>=0; i--) printf(" %d", conversion[i]); } return 0;
72
}
73
7.3.
Arreglos bidimensionales
matriz) consta de renglones Un arreglo bidimensional (tambi en llamado tabla o y columnas. Para acceder a un elemento debemos emplear dos ndices, el primero para denotar el rengl on y el segundo para denotar la columna donde se encuentra el elemento. Declarar un arreglo bidimensional es similar a declarar un arreglo unidimensional, pero indicando, adem as del n umero de renglones, el n umero de columnas, por ejemplo:
int matriz[3][4]; //Corresponde a un arreglo llamado matriz de 3 renglones y 4 columnas; por lo tanto su tama no es de 3x4=12 elementos, todos de tipo entero float num[5][5]; //Corresponde a un arreglo llamado valores de 5 renglones y 5 columnas; por lo tanto es una matriz cuadrada de 25 elementos de tipo real
Cuando declaramos un arreglo bidimensional, es posible darle valores iniciales, por ejemplo:
int matriz[3][4]={12,24,46,17,25,31,49,63,42,21,89,96}; //Se asignan los valores en el orden de aparici on, cubriendo cada rengl on int matriz [3][4]={{12,24,46,17},{25,31,49,63},{42,21,89,96}}; //Esta forma proporciona claridad a quien lee el c odigo int matriz[3][4]={0}; //incorrecto //Una arreglo bidimensional no puede inicializase con 0 (cero) de esta manera
En tiempo de ejecuci on, el arreglo matriz podr a representarse como se muestra en la tabla 7.8: r0 r1 r2 c0 12 25 42 c1 24 31 21 c2 46 49 89 c3 17 63 96
Observe que tambi en los arreglos bidimensionales comienzan con una posici on 0 (cero) tanto en los renglones como en las columnas; por lo tanto, el n umero
74
ltima posici de renglones matriz es 3, pero su u on es 2; mientras que el n umero ltima posici de columnas es de 4 pero su u on es 3, y el tama no de la matriz es de 3x4. En general, en tama no de una matriz est a determinado por el producto (nrenglones )x(mcolumnas ) correspondiente al n umero de elementos que puede albergar el arreglo bidimensional. l a trav Para acceder a cualquier elemento, nos referimos a e es de su posici on, por ejemplo: En el ejemplo 7.8 para referirnos al elemento en la posici on 2, 3, escribimos matriz[2][3], es decir 96; para referirnos al elemento en la posici on 0, 1, escribimos matriz[0][1], es decir 24. Problema 7.8: Traspuesta de una matriz. Construir un programa que dada una matriz, obtenga la matriz transpuesta. Especicaci on: Denir dos arreglos bidimensionales (matrices) de tama no nxm, donde el tama no m aximo es de 50x50 elementos de tipo real, para cada matriz. El programa recibe, desde el teclado, el tama no en renglones (n), el tama no en columnas (m) y los valores de cada matriz; el programa deber a obtener su traspuesta y guardarla en una nueva matriz. Finalmente, el programa deber a imprimir en la pantalla cada una de las matrices. Para este ejercicio debemos emplear funciones. La tabla 7.9 muestra dos ejemplos. Entrada 34 1234 5792 4767 23 1.2 3.4 5.6 7.8 8.9 0.1 Salida 154 277 396 427 1.2 7.8 3.4 8.9 5.6 0.1
#include <stdio.h> #define MAX 50 void leeMatriz(float MAT[][MAX], int* n, int* m); void traspuesta(float MAT1[][MAX],float MAT2[][MAX],int n, int m); void imprMatriz(float MAT[][MAX], int n, int m); int main(void){ float MAT1[MAX][MAX], MAT2[MAX][MAX];
75
Problema 7.9: La matriz es sim etrica? Escriba un programa que al recibir como dato un arreglo bidimensional (matriz) cuadrado, determine si el mismo es sim etrico.
76
Especicaci on: Denir un arreglo bidimensional (matriz) cuadrado de tama no m aximo 50x50 elementos de tipo entero. El programa recibe, desde el teclado, el tama no de renglones y columnas (n) y los valores de la matriz; el programa no. Finalmente, el programa dedeber a determinar si esta matriz es sim etrica o ber a imprimir en pantalla tanto la matriz y como la traspuesta. Para este ejercicio debemos emplear funciones. La tabla 7.10 muestra dos ejemplos. Entrada 3 123 456 789 4 3040 0124 4259 0493 Salida
NO
SI
#include <stdio.h> #define MAX 50 int leeMatriz(float[][MAX]); int simetrica(float[][MAX],int); int main(void){ float MAT[MAX][MAX]; int n=0,resp=0; n=leeMatriz(MAT); resp=simetrica(MAT,n); if (resp==0) printf("\nLa matriz es simetrica\n"); else printf("\nLa matriz no es simetrica\n"); return 0; } int leeMatriz(float MAT[][MAX]){ int i=0, j=0, n=0; printf("Cual es el tamanio de la matriz cuadrada: "); scanf(" %d",&n); for(i=0; i<n; i++){ for (j=0; j<n; j++){ printf("MAT[ %d, %d]= ",i,j); scanf(" %f",&MAT[i][j]); } printf("\n"); }
7.4. CADENAS
return n; } int simetrica(float MAT[][MAX],int n){ int i=0, j=0, flag=0; for (i=0; i<n; i++){ for (j=i+1; j<n; j++){ if (MAT[i][j]!=MAT[j][i]) flag=1; j=n; i=n; } } return flag; }
77
7.4.
Cadenas
Una cadena es un arreglo unidimensional empleado para guardar elementos de tipo caracter char. Una cadena se declara igual que los arreglos, por ejemplo:
char cad[10]; //corresponde a una cadena llamada cad de tama no 10 y cuyos elementos deber an ser de tipo caracter
En el leguaje C, todas las cadenas terminan con un caracter ((nulo)) denotado por una diagonal inversa y el n umero cero (\0); por lo tanto, al momento de denir el tama no de la cadena tenemos que contar la celda que ocupar a este caracter. El caracter \0 sirve para marcar el n de una cadena. Cuando declaramos una cadena, es posible darle valores iniciales, por ejemplo:
char cadena[5]={h,o,l,a,\0}; //Los valores se asignan a cadena en el orden en que aparecen char cad[5]=hola; //Otra forma v alida de inicializar a cad char cad[5]= ; //Todos elementos del arreglo tienen como valor inicial al caracter espacio char cad[]= hola; //El tama no del arreglo queda definido como 5
78
Observe que si bien el tama no de la palabra hola es 4, la cadena es declarada ltima posici como de tama no 5, donde el caracter \0 ocupa la u on en el arreglo, es decir la posici on 4. Al manipular una cadena se debe cuidar de no sustituir al caracter \0 con alg un otro valor. Los operadores de asignaci on (=) y los relacionales (==, ! =) no se emplean en el manejo de cadenas, salvo la asignaci on al declarar e inicializar una cadena; tal y como vimos en los ejemplos anteriores. Para manipular a las cadenas en un programa, debemos emplear un conjunto de funciones que encontramos en las bibliotecas: string.h, stdlib.h y ctype.h.
//Dos formas de ingresar caracteres: scanf( %c,&caracter); getc(caracter); //Dos formas de imprimir caracteres en la pantalla: printf( %c,caracter); putc(caracter);
//Dos formas de ingresar cadenas: scanf( %s,&cadena); gets(cadena); //Dos formas de imprimir cadenas en la pantalla: printf( %s,cadena); puts(cadena);
Cuando se desea leer una nueva cadena, debemos emplear la funci on fflush() para limpiar los buffer de entrada y salida, donde se guarda una cadena temporalmente. El llamado a la funci on para limpiar el buffer de entrada es: fflush(stdin) y el llamado a la funci on para limpiar el buffer de salida es: fflush(stdout). La tabla 7.12 muestra una serie de comandos b asicos para el manejo de cadenas en lenguaje C.
7.4. CADENAS
Comando strcpy(destino, origen). Copia el valor de cadena origen hacia la cadena destino. Precauciones No verica que la cadena destino sea lo bastante grande como para almacenar el valor de la cadena origen. Si limite se elige con cuidado, esta funci on es m as segura que la versi on strcpy. No verica que la cadena destino sea lo bastante grande como para almacenar el resultado de la concatenaci on. Si limite se elige con cuidado, esta funci on es m as segura que la versi on srtcat .
79
strncpy(destino, origen, limite). Igual que la funci on strcpy de dos argumentos, solo que se copian cuando mucho el l mite caracteres. strcat (destino, origen). Concatena el valor de cadena origen con el nal de la cadena destino. strncat (destino, origen, limite). Igual que la funci on strcat de dos argumentos, solo que se anexan cuando mucho l mite caracteres. strlen(origen). Devuelve un entero igual a la longitud de la cadena origen; el caracter nulo X no se cuenta en la longitud. strcmp(cadena1 , cadena2 ). Devuelve 0 si cadena1 y cadena2 son iguales. Devuelve un valor menor a 0 si cadena1 es menor que cadena2 . Devuelve un valor mayor a 0 si cadena1 es mayor que cadena2 . Por lo tanto, devuelve un valor distinto de cero si cadena1 y cadena2 son distintas. Cada caracter tiene un valor entero, seg un la tabla de ASCII . strncmp(cadena1 , cadena2 , limite). Igual que la funci on strcmp de dos argumentos, solo que se comparan cuando mucho limite caracteres.
Si cadena1 es igual a cadena2 esta funci on devuelve 0, lo que la convierte en falsa cuando se eval ua. Esto es lo inverso de lo que podr amos esperar dado que las cadenas son iguales. Tener cuidado con la l ogica que sigue esta funci on.
Si limite se elige con cuidado, esta funci on es m as segura que la funci on strcmp de dos argumentos
Programa 7.10: La cadena es Pal ndromo? Construir un programa que dada sta es una cadena pal una cadena, determine si e ndromo. Se dice que una cadena es pal ndromo si al invertir el orden de los caracteres (de derecha a izquierda) se lee igual. Especicaci on: Se debe emplear una funci on la cual devuelve uno si la cadena es pal ndromo y cero si no es pal ndromo. Considere una cadena sin espacios
80
entre las palabras; la tabla 7.13 Entrada AnitaLavaLatinA DammItImmaD LaminaElizaBeT Salida Si Si No
#include<stdio.h> #include<string.h> #define MAX 50 int palindrome(char cad[]); int main(void){ char cad[MAX]={\0}; int resp=0; printf("Ingresa la cadena a ser evaluada como palindrome,"); printf("\npero SIN ESPACIOS ENTRE LAS LETRAS:\n"); scanf(" %s",cad); printf("la cadena mide %i y contiene %s", strlen(cad), cad); resp=palindrome(cad); if (resp==0) printf("\nLa cadena no es palindrome\n"); else printf("\nLa cadena es palidrome\n"); return 0; } int palindrome(char cad[]){ int i=0, j=0, flag=1; for (i=0, j=strlen(cad)-1; i<strlen(cad)/2 && j>=strlen(cad)/2; i++, j --){ printf("\n %c %c", cad[i],cad[j]); if(cad[i]!=cad[j]){ flag=0; j=-1; i=strlen(cad)+1; } } return flag; }
Programa 7.11: Anagramas. Construir un programa que reciba desde el teclado el nombre del usuario; el programa debe iterar n veces con el prop osito de desordenar la cadena en cada iteraci on. El programa debe imprimir la cadena obtenida en cada iteraci on.
7.4. CADENAS
81
Especicaci on: El programa debe usar una funci on que reciba la cadena original y su tama no; esta funci on deber a desordenar la cadena n veces; donde n es el tama no de la cadena que ingres o el usuario. Esta misma funci on se encargar a de imprimir la cadena resultante de cada iteraci on; la tabla 7.14 muestra dos ejemplos de anagramas para sus respectivas cadenas. Entrada William Shakespeare Salida ep haileSreaiskmWla ai pleeerSWsikaalmh aihl lsmeaeWaSepirk ikaiaWrseeplalheS m i amaWeakishSpeller i lamkaearSemeaeahs mpilraS aaeikeelsWh Sepimli ehakWeslara salaieSWleepkhiarm eis ieklhWalrSpmaae eapWkaei Sishlalrem epmiashker WleilaaS elmkhWe eSraasipali eapmi lelshiSekaaWr iSpmhe sklileearaWa leeea ialWrikmhpaSs imeh laelakareSWpis lieeilaSsmapWharek sfool soo lofso fools olfso
lofos
82
} void desordena(char nom[]){ int i=0, j=0, esc=0; char aux=\0; for(j=1; j<=strlen(nom); j++ ){ for (i=0; i<strlen(nom); i++){ esc=rand() %(strlen(nom)-i)+i; aux=nom[i]; nom[i]=nom[esc]; nom[esc]=aux; } printf("\n"); printf(" %s ",nom); } return; }
Cap tulo 8
Registros
Es una colecci on nita y heterog enea de elementos. A cada uno de los elementos se les denomina ((campo)). Un campo debe ser declarado se nalando su tipo de dato; sea b asico: entero, real, caracter; o estructurado: arreglos, cadenas o registros. No es necesario establecer un orden entre los campos. En el lenguaje C, un registro se dene como se muestra enseguida:
struct registro{ tipo_dato campo_1; tipo_dato campo_2; tipo_dato campo_3; tipo_dato campo_4; };
Un registro dene un nuevo tipo de dato; es decir, podemos crear variables que tienen la forma del registro reci en denido. Todo registro debe ser denido antes de la funci on principal main() y despu es de incluir las bibliotecas que emplearemos en el programa.
8.1.
Cuando declaramos variables de tipo registro, la palabra struct debe preceder al nombre del registro . Observe que una vez denido el registro, declaramos variables locales, pertenecientes a la funci on main()
struct registro{ tipo_dato campo_1; tipo_dato campo_2; tipo_dato campo_3; tipo_dato campo_4; };
83
84
CAPITULO 8. REGISTROS
Es posible declarar variables globales que siguen a la denici on del registro, tal y como se muestra a continuaci on. Sin embargo, en el curso emplearemos variables locales solamente.
struct registro{ tipo_dato campo_1 tipo_dato campo_2 tipo_dato campo_3 tipo_dato campo_4 } reg_1, reg_2;
8.2.
La instrucci on typedef permite denir alias o sin onimos para los tipos de datos simples o estructurados. En el caso de los registros, resulta pr actico porque elimina la necesidad de escribir reiteradamente la palabra struct. Tenemos dos alternativas para emplear un alias: La primera alternativa, consiste en anteponer la palabra typedef a la palabra struct y colocar el nombre del registro antes del punto y coma, tal y como se muestra a continuaci on.
typedef struct{ tipo_dato campo_1; tipo_dato campo_2; tipo_dato campo_3; tipo_dato campo_4; }registro; int main(void){ registro reg_1, reg_2; : : return 0; }
La segunda alternativa, consiste en denir el registro y despu es del punto y coma, denir su alias, tal y como se muestra a continuaci on.
struct registro{
85
Para acceder a los campos de un registro empleamos dos operadores: Operador S mbolo Punto . Descripci on Lo empleamos cuando una variables es declarada del tipo registro Lo empleamos cuando una variable es declarada como de tipo apuntador a registro Ejemplo var registro.campo 1
Flecha
Programa 8.1: Registro de informaci on personal. Construir un programa que permita guardar los datos personales de dos personas en registro llamado persona, el cual incluya: nombre, edad, peso y fecha de nacimiento. La fecha de nacimiento de una persona deber a guardarse en un registro que incluya los campos de: a no, mes y dia.
Especicaci on: El programa debe tener dos registros: fecha, que incluye los campos anio, mes y dia, todos de tipo entero; y una registro persona que incluye los campos: nombre, edad, peso y nace.
86
Entrada Nombre: Susana Peso: 66.50 Dia de nacimiento: 13 Mes de nacimiento: 6 Anio de nacimiento: 1966 Nombre: Daniel Peso: 77.80 Dia de nacimiento: 19 Mes de nacimiento: 10 Anio de nacimiento: 1974
CAPITULO 8. REGISTROS
Salida Susana tiene un peso: 66.50 kg; su fecha de nacimiento es 13/6/1966
#include<stdio.h> typedef int int int }fecha; struct{ anio; mes; dia;
typedef struct{ char nombre[30]; float peso; fecha nace; }persona; void leerPersona(persona* una_persona); void imprPersona(persona una_persona); int main(void){ persona p1, p2; printf("Lectura de datos de dos personas \n"); leerPersona(&p1); leerPersona(&p2); imprPersona(p1); imprPersona(p2); return 0; } void leerPersona(persona* una_persona){ printf("----------------------------------"); printf("\nNombre: "); scanf(" %s", una_persona->nombre); fflush(stdin); printf("\nPeso: "); scanf(" %f", &una_persona->peso); printf("\nDia de su nacimiento: "); scanf(" %d", &una_persona->nace.dia); printf("\nMes de su nacimiento: "); scanf(" %d", &una_persona->nace.mes);
87
8.3.
En la memoria de la computadora el registro persona se ver a como lo muestra la gura 8.1, donde nace es una variable de tipo fecha, la cual a su vez es un registro.
Tal y como lo muestra el ejercicio anterior (denici on del registro persona) un registro puede incluir campos de tipo: 1) arreglo (como nombre), 2) registro (como nace); sin embargo, tambi en es posible denir arreglos de registros, lo cual til cuando se desea manipular numerosos registros de un mismo tipo. resulta u Observe que el paso de par ametros por valor y por referencia tambi en se aplica en el manejo de registros. En el paso de par ametros por referencia, empleamos los operadores: () para declarar una variable de tipo apuntador a registro; (&) para referirnos a la direcci on de una variable tipo registro; y () para referirnos al valor al cual apunta la variable apuntador a registro. Ver la secci on 5.4 para detalles del manejo de apuntadores.
88
CAPITULO 8. REGISTROS
La gura 8.2 muestra las combinaciones que podemos realizar entre arreglos y registros.
Registros con arreglos; es decir, al denir un registro uno m as campos pueden ser de tipo arreglo unidimensional, arreglo bidimensional o cadena.
Registros anidados; es decir, al denir un registro uno o m as de sus campos pueden ser de tipo registro.
Arreglos de registros; es decir, podemos declarar una o varias variables que son arreglos de tipo registro, tal y como lo har amos para denir un arreglo caracteres. de enteros, reales o
Problema 8.2: Base de datos de alumnos. Construir un programa donde se dena un arreglo unidimensional de personas, el programa debe leer los datos de las personas desde el teclado; posteriormente, deber a imprimir en pantalla el contenido de ese arreglo.
Especicaci on: Denir un arreglo de personas con 3 elementos. El programa deber a emplear dos funciones: una para leer el arreglo y la segunda para imprimir el contenido del arreglo en la pantalla; la tabla 8.3 muestra algunos ejemplos de los registros contenidos en un arreglo.
89
#include<stdio.h> #define MAX 3 typedef int int int }fecha; struct{ anio; mes; dia;
typedef struct{ char nombre[30]; float peso; fecha nace; }persona; void leerPersona(persona* alumnos); void imprPersona(persona* alumnos); int main(void){ persona alumnos[MAX]; printf("\nLectura de datos de un grupo de alumnos \n"); leerPersona(alumnos); printf("\n\nLos datos de los alumnos recien ingresados son: \n"); imprPersona(alumnos); return 0; } void leerPersona(persona* alumnos){ int i=0; for(i=0; i<MAX; i++){ printf("----------------------------------"); printf("\nNombre: ");
90
scanf(" %s", alumnos[i].nombre); fflush(stdin); printf("\nPeso: "); scanf(" %f", &alumnos[i].peso); printf("\nDia de nacimiento: "); scanf(" %d", &alumnos[i].nace.dia); printf("\nMes de nacimiento: "); scanf(" %d", &alumnos[i].nace.mes); printf("\nAnio de nacimiento: "); scanf(" %d", &alumnos[i].nace.anio); } return; }
CAPITULO 8. REGISTROS
void imprPersona(persona* alumnos){ int i=0; for(i=0; i<MAX; i++){ printf("----------------------------------"); printf("\n %s ", alumnos[i].nombre); printf("tiene un peso de %4.2f Kg; ", alumnos[i].peso); printf("la fecha de su nacimiento es %d/",alumnos[i].nace.dia); printf(" %d/ %d", alumnos[i].nace.mes, alumnos[i].nace.anio); printf("\n\n"); } return; }
En el programa 8.2 hemos denido un arreglo de tipo persona llamado alumnos. Observe tambi en que el acceso a los datos se realiza a trav es del operador punto (.) porque, todos los arreglos se manejan, por defecto, mediante memoria din amica y no es necesario expresarlo a trav es de la notaci on de apuntadores.
Cap tulo 9
Archivos
Las cosas se simplican cuando separamos el programa de los datos con los que opera, si los datos se mantienen en archivos aparte y los problemas vuelven a ser cortos y simples de leer. Tenemos varios tipos de archivos, aquellos que usaremos para consulta, otros que usaremos para poner la informaci on de una ejecuci on en el mismo, y tambi en archivos ya existentes donde se agregar an los datos reci en procesados.
9.1.
Conceptos b asicos
Un archivo es un conjunto de datos de distintos tipos: int, float, char etc., que se guardan juntos, bajo un nombre com un, en un dispositivo secundario, a saber: disco duro, memoria USB, etc. Por ejemplo ((texto.txt)) ser a un archivo de datos. Los nombres de los archivos son reconocidos por el sistema operativo a trav es de los comandos ls (Unix) y dir (DOS). Actualmente Unix y Windows (desde la versi on 95) aceptan 255 caracteres para nombrar un archivo. El contenido de un archivo perdura hasta que una persona o programa lo modica.
9.2.
Para manipular archivos, dentro de un programa escrito en lenguaje C, empleamos un conjunto de funciones, la cuales est an contenidas en la biblioteca stdio.h; la tabla 9.1 presenta una breve descripci on de estas funciones. 91
92 Funci on fopen() fclose() fputc() fgetc() fputs() fprintf() fscanf() feof() ferror() rewind() remove() fush()
CAPITULO 9. ARCHIVOS Descripci on Abrir un archivo Cerrar un archivo Escribir un caracter en el archivo Lee un caracter de un archivo Escribir una cadena en un archivo Imprimir a un archivo valores con un formato de dato determinado Leer de un archivo valores con un formato de dato determinado Devuelve verdadero cuando llega al n del archivo Devuelve verdadero si se ha producido un error Colocar el indicador de posici on de un archivo al principio del mismo Eliminar un archivo Vaciar el buffer que sirve para leer una cadena de un archivo
Tabla 9.1 Funciones b asicas de archivos
En el lenguaje C es necesario indicar la acci on que vamos a realizar sobre un archivo; a esto se le conoce como ((modo de apertura de un archivo)); la tabla 9.2 describe cada uno de estos modos de apertura. Modo r w a r+ Signicado read write append read and write Descripci on Abrir un archivo de texto para lectura l Abrir un archivo de texto para escribir en e l Abrir un archivo para agregar texto en e Abrir un archivo para lectura y escritura
exit(valor-entero) es una funci on que termina de inmediato la ejecuci on de un programa y forma parte de la biblioteca stdlib.h. Se puede usar cualquier valor entero, pero por convenci on se emplea: 1 para indicar que el programa terminar a porque durante su ejecuci on se incurri o en alg un error, previsto por el programador. 0 para indicar que el programa terminar a sin que esto cause alg un error.
93
Programa 9.1: Escribir un conjunto de caracteres en un archivo. Construir un programa que permita escribir un conjunto de caracteres en un archivo.
Especicaci on: Los caracteres deber an ser ingresados desde el teclado por el usuario. Al dar enter se guardar a el conjunto de caracteres en el archivo llamado ((texto.txt)); posteriormente, deber a cerrarse este archivo. La tabla 9.3 muestra dos ejemplos. Entrada del teclado Kings Lead Hat = Talking Heads Mr. Mojo Risin is Jim Morrison Salida al archivo texto.txt Kings Lead Hat = Talking Heads Mr. Mojo Risin is Jim Morrison
#include <stdio.h> int main(void){ char car; FILE *ap; printf("Escriba una cadena para ser guardada en un archivo"); printf("\n El fin de la cadena lo marca un <ENTER>\n"); ap=fopen("texto.txt","w"); if (ap!=NULL){ while ((car=getchar())!=\n){ fputc(car,ap); } fclose(ap); } else printf("No se puede abrir el archivo"); return 0; }
Programa 9.2: Leer el contenido de un archivo. Construir un programa que permita leer el contenido de un archivo. El contenido del archivo deber a desplegarse en la pantalla. Especicaci on: El programa debe abrir el archivo ((texto.txt)); luego, debe leer caracter a caracter y desplegar cada uno en pantalla del usuario; la tabla 9.4 muestra dos ejemplos.
94 Archivo de entrada ((texto.txt)) Because the wind is high it blows my mind Well you should see Polythene Pam, Shes so good-looking but she looks like a man.
CAPITULO 9. ARCHIVOS Salida en la pantalla Because the wind is high it blows my mind Well you should see Polythene Pam, Shes so good-looking but she looks like a man.
#include <stdio.h> int main(void){ char car; FILE *ap; if ((ap=fopen("prueba.txt","r"))!=NULL){ while (!feof(ap)){ car=fgetc(ap); putchar(car); } fclose (ap); } else printf("No se puede abrir el archivo"); printf("\n"); return 0; }
Programa 9.3: Codicar el contenido de un archivo de texto. Construir un programa que lea el contenido de un archivo de texto fuente y lo codique. Todos los caracteres codicados deber an guardarse en un nuevo archivo.
Especicaci on: El criterio para codicar cada caracter del archivo consiste en sumarle 2 al caracter ASCII correspondiente. El programa debe recibir desde el teclado, los nombres de los archivos fuente y destino. la tabla 9.1 muestra dos ejemplos de texto codicados.
9.2. FUNCIONES USUALES PARA EL MANEJO DE ARCHIVOS Archivo de entrada Because the sky is blue it makes me cry Because the world is round it turns me on Archivo de salida
Dgecwug"vjg"um{"ku"dnwg"kv"ocmgu"og"et{
95
Dgecwug"vjg"yqtnf"ku"tqwpf"kv"vwtpu"og"qp
#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[3]) { char mytext[80], encrtext[80]; FILE *ap1, *ap2; int i=0, desplaza=2; if(argc!=3){ printf("el numero de parametros es erroneo"); exit(1); //Termina el programa } else if((ap1=fopen(argv[1],"r"))!=NULL && (ap2=fopen(argv[2],"w"))!= NULL){ while(!feof(ap1)){ fflush(stdin); i=0; fgets(mytext, 79, ap1); while (mytext[i]!=\0) { encrtext[i]=mytext[i]+desplaza; i++; } encrtext[i]=\0; fputs(encrtext, ap2); } fclose(ap1); fclose(ap2); } else printf("No es posible abrir el archivo"); return 0; }
Programa 9.4: Decodicar el contenido de un archivo de texto. Construir un programa que lea el contenido de un archivo de texto codicado y lo decodique. Todos los caracteres decodicados deber an guardarse en un nuevo archivo.
96
CAPITULO 9. ARCHIVOS
Especicaci on: El criterio para decodicar cada caracter del archivo consiste en restarle 2 al caracter ASCII correspondiente. El programa debe recibir desde el teclado, los nombres de los archivos fuente y destino. La tabla 9.6 dos ejemplos de texto decodicado. Archivo de entrada
Ujqwnf"hkxg"rgtegpv"crrgct"vqq"uocnn. "Dg"jcpmhwn"K"fqp)v"vcmg"kv"cnn
Archivo de salida Should ve percent appear too small, be thankful I dont take it all You ask me for a contribution... Were doing what we can
[qw"cum"og"hqt"c"eqpvtkdwvkqp000"Yg) tg"fqkpi"yjcv"yg"ecp
Programa 9.5: Simular el juego de bola 8 m agica. Construir un programa que simule una ((bola 8 m agica)), la cual adivina el futuro del usuario a trav es de una
97
serie de preguntas por parte del usuario. Se trata de un juguete que parece una bola de billar; la cual se agita y en la parte de atr as, se puede leer una de 20 respuestas. La bola tiene un icosaedro sumergido en tinta negra con una respuesta en cada cara.
Especicaci on: El programa debe contar con dos funciones secundarias. Una de ellas debe encargarse de solicitar al usuario preguntas o la palabra n (que pone t ermino al juego). La otra funci on debe proporcionar una respuesta en la pantalla. La respuesta debe ser tomada al azar de un conjunto de respuestas previamente denidas en un archivo con extensi on .txt; considerar 10 respuestas armativas, 5 ambiguas y 5 negativas. Un un ejemplo de archivo, se muestra en la tabla 9.7. Dos ejemplos de entrada y salida del programa lo muestra la tabla 9.8.
Como lo veo... si Es seguro Decididamente si Es lo mas probable Positivamente Parece ser que si Sin lugar a dudas Si Si - denitivo Puedes conar en eso Respuesta ambigua... intente de nuevo Preguntame despues Mejor no te digo ahora No puedo predecirlo ahora Concentrate y vuelve a preguntar No cuentes con ello Mi respuesta es no Mis fuentes dicen que no No parece que pase Lo dudo mucho
Tabla 9.7 Archivo con respuestas de la bola 8 m agica
98 Entrada Pasar e el curso sin tener que estudiar? En verdad adivinas el futuro?
// Programa que simula una bola 8 magica #include<stdio.h> #include<string.h> #include<stdlib.h> #include<time.h> void leeArchivo(char resp[][50]); void generaPreg(char preg[]); void generaResp(char resp[][50]); int main(void){ char preg[100]={ }, resp[20][50]; srand(time(NULL)); printf("\n\n Este programa es magico, respondera a tus preguntas \n"); leeArchivo(resp); do{ generaPreg(preg); if(strcmp(preg,"fin") && strcmp(preg,"FIN")) generaResp(resp); }while(strcmp(preg,"fin") && strcmp(preg,"FIN")); return 0; } void generaPreg(char preg[]){ fflush(stdin); printf("\n Haz tu pregunta o la palabra \"fin\" para terminar: \n"); gets(preg); return; } void leeArchivo(char resp[][50]){ int i=0; FILE *arch; arch=fopen("magica.txt", "r"); if(arch!=NULL){ while(!feof(arch)){ fflush(stdin); fgets(resp[i], 49, arch); i++; } } return; } void generaResp(char resp[][50]){ int seleccion=0; seleccion=(rand() %20)+1;
99
Programa 9.6: Precios con IVA. Una papeler a necesita contar con un programa que le permita obtener la lista de sus precios con el Impuesto al Valor Agregado (IVA) correspondiente. El usuario deber a proporcionar el nombre del archivo donde se encuentran los precios originales en forma de lista; el programa debe calcular los nuevos precios con IVA y colocarlos en el archivo que le indique el usuario. Especicaci on: El programa tiene cuatro funciones: una de ellas pregunta el nombre del archivo origen, otra recupera la informaci on de este archivo en un arreglo, una tercera calcula el IVA y una cuarta guarda los nuevos valores con el IVA incluido en un archivo destino. La tabla 9.9 muestra una lista con los precios originales y los precios con el IVA incluido. Entrada 123 482.1 8.85 9.56 4758 Salida 141.45 554.415 10.1775 10.994 5471.7
100
total = calculaTotal(precios, tam-1); guardaDatos(precios, total, tam-1); return(0); }
CAPITULO 9. ARCHIVOS
void nombreArchivo(char tipo[], char nom[]){ printf("Cual es el nombre del archivo de %s: \n", tipo); gets(nom); return; } int cargaDatos(float precios[]){ int n=0; char nomArch[LON]; char aux1[LON]="entrada"; FILE *ap; nombreArchivo(aux1,nomArch); ap=fopen(nomArch, "r"); if(ap!=NULL){ while(!feof(ap)){ fscanf(ap, " %f", &precios[n]); n++; } fclose(ap); return(n); } else{ printf("\n no puede abrir el archivo"); exit(1); } } float calculaTotal(float precios[],int tam){ float total=0.0; int i=0; for(i=0; i<tam; i++){ precios[i]*= 1.15; total+=precios[i]; } return(total); } void guardaDatos(float precios[], float total, int tam){ int i=0; char nomArch[LON]; char aux1[LON]="salida"; FILE *ap; nombreArchivo(aux1,nomArch); ap=fopen(nomArch, "a+"); if(ap!=NULL){ fprintf(ap, "\n"); for(i=0; i<tam; i++){ fprintf(ap, "\n %.2f", precios[i]); } fprintf(ap, "\nSuma total de los precios con iva: %f\n", total); fclose(ap);
101
Programa 9.7: Guardar registros en un archivo Construir un programa que permita agregar, consultar y modicar los registros de varios alumnos, los cuales se encuentran almacenados en un archivo.
Especicaci on: El programa debe estar formado por: 1) una funci on que permita consultar los registros que est an guardados en un archivo; 2) una funci on que permita modicar alguno de los registros; y 3) una funci on que permita agregar un nuevo registro. El nombre del archivo lo proporciona el usuario. La tabla 9.10 muestra el archivo ((alumnos.txt)) y el men u que se espera proporcione el programa al usuario; la tabla 9.11 muestra dos ejemplos para las operaciones de ((agregar registro)) y ((consultar registro)).
Tabla 9.10 Archivo de entrada y men u de operaciones sobre la informaci on del archivo
CAPITULO 9. ARCHIVOS Salida Nombre: Luis Robles P erez Peso: 45.67 Dia nacimiento:4 Mes nacimiento:6 Anio nacimiento:1967 Ramiro Felix Reyes tiene un peso de 56.76 kg; su fecha de nacimiento es 7/12/1965 Luis Robles P erez tiene un peso de 45.67 kg; su fecha de nacimiento es 4/6/1967
2 (Consultar registros)
typedef struct{ char nombre[LON]; char paterno[LON]; char materno[LON]; float peso; fecha nace; }persona; char menu(void); void consultar(char* nom); void agregar(char* nom); void modificar(char* nom); int cargaDatos(persona* alumnos, char* void imprPersona(persona* alumnos, int void leerPersona(persona* alumnos, int void guardaDatos(persona* alumnos, int void nombreArchivo(char* nom); int main(void){ char opcion= , nom[LON];
103
char menu(void){ char opcion= ; printf("\n\n Registro de alumnos\n"); printf("\nA) Agregar registros de alumnos a un archivo.\n"); printf("\nB) Consultar los registros de alumnos de un archivo.\n"); printf("\nC) Modificar el registros de uno o varios alumnos.\n"); printf("\nEscoge una opcion (A, B, C) o Z para salir\n"); scanf(" %c",&opcion); fflush(stdin); return(opcion); } void consultar(char* nom){ int tam=0; persona alumnos[MAX]; tam=cargaDatos(alumnos, nom); printf("\nLos datos leidos son %d",tam); imprPersona(alumnos,tam); return; } void agregar(char* nom){ int tam=0, i=0; persona alumnos[MAX]; printf("Cuantos registros va a agregar no mas de %d: ", MAX); scanf(" %d", &tam); for(i=0; i<tam; i++){ leerPersona(alumnos,i); } guardaDatos(alumnos,tam,nom,TRUE); return; }
104
CAPITULO 9. ARCHIVOS
void modificar(char* nom){ int i=0, tam=0, res=1; persona alumnos[MAX]; tam=cargaDatos(alumnos, nom); while(res==1){ printf("\nQue registro desea modificar (0.. %d): ",(tam-1)); scanf(" %d",&i); if(i>=0 && i<tam) leerPersona(alumnos,i); else printf("\nError... ese registro no existe"); printf("\nDesea modificar otro registro (si-1 o no-0)? "); scanf(" %d",&res); } guardaDatos(alumnos,tam,nom,FALSE); return; } void leerPersona(persona* alumnos, int i){ printf("----------------------"); printf("\nNombre: "); scanf(" %s %s %s", alumnos[i].nombre, alumnos[i].paterno, alumnos[i].materno); fflush(stdin); printf("\nPeso: "); scanf(" %f", &alumnos[i].peso); printf("\nDia de su nacimiento: "); scanf(" %d", &alumnos[i].nace.dia); printf("\nMes de su nacimiento: "); scanf(" %d", &alumnos[i].nace.mes); printf("\nAnio de su nacimiento: "); scanf(" %d", &alumnos[i].nace.anio); return; } int cargaDatos(persona* alumnos, char* nom){ int i=0; FILE *ap; ap=fopen(nom, "r"); if(ap!=NULL){ while(!feof(ap)){ fscanf(ap, " %s %s %s", alumnos[i].nombre, alumnos[i].paterno, alumnos[i].materno); fflush(stdin); fscanf(ap, " %f", &alumnos[i].peso); fscanf(ap, " %d", &alumnos[i].nace.dia); fscanf(ap, " %d", &alumnos[i].nace.mes); fscanf(ap, " %d", &alumnos[i].nace.anio); i++; } fclose(ap); return(i); } else{ printf("\n no puede abrir el archivo"); exit(1); } }
105
void nombreArchivo(char* nom){ printf("Cual es el nombre del archivo: "); scanf(" %s",nom); fflush(stdin); fflush(stdout); return; } void imprPersona(persona* alumnos, int tam){ int i=0; for(i=0; i<tam; i++){ printf("----------------------"); printf("\n %s %s %s ", alumnos[i].nombre, alumnos[i].paterno, alumnos[i].materno); printf("tiene un peso: %4.2f Kg; ", alumnos[i].peso); printf("la fecha de su nacimiento: %d/", alumnos[i].nace.dia); printf(" %d/ %d", alumnos[i].nace.mes, alumnos[i].nace.anio); printf("\n\n"); } return; }
void guardaDatos(persona* alumnos, int tam, char* nom, int agrega){ int i=0; FILE *ap; if(agrega) ap=fopen(nom, "a+"); else ap=fopen(nom, "w+"); if(ap!=NULL){ for(i=0; i<tam; i++){ fflush(stdin); fprintf(ap, "\n %s %s %s", alumnos[i].nombre, alumnos[i].paterno, alumnos[i].materno); fprintf(ap, "\n %f", alumnos[i].peso); fprintf(ap, "\n %d", alumnos[i].nace.dia); fprintf(ap, "\n %d", alumnos[i].nace.mes); fprintf(ap, "\n %d", alumnos[i].nace.anio); } fclose(ap); return; } else{ printf("No puede abrir el archivo"); exit(1); } }
106
CAPITULO 9. ARCHIVOS
Cap tulo 10
10.1.
Para realizar una conexi on al servidor remoto debemos ejecutar un programa tal como el SSH-Security Shell, el cual debe existir previamente en nuestra com ste nos soliciputadora personal o en nuestra terminal. Luego de ejecutar el SSH, e tar a una clave del usuario, tal y como lo muestra el ejemplo de la tabla 10.1. Petici on login: annie Descripci on Primero me solicitar a el usuario con el cual fui registrado en el servidor A continuaci on me solicitara la contrasenia del mismo usuario
password: x32jh88a
107
108
La clave del usuario y la contrase na deben ser proporcionadas por el administrador del servidor. Ambos datos deben ser digitalizados exactamente como fueron proporcionados, respetando el orden y las letras may usculas y las min usculas. Cabe resaltar que, en general, un servidor proporciona tres oportunidades para introducir correctamente el usuario y la contrase na. Si ambos datos son correctos, el servidor enviar a un mensaje de bienvenida seguido de un s mbolo de dolar ($), al cual se le denomina Shell . El Shell es un int erprete de comandos para el sistema operativo UNIX, a partir del cual podemos escribir comandos y ejecutarlos con solo pulsar la tecla de enter. Cada usuario tiene asignado un espacio de trabajo en el servidor. Siempre que se inicia la sesi on de un usuario, se le sit ua en su rbol de directorios en UNIX, a directorio de conexi on. La gura 10.1 presenta un a partir del cual se propondr an ejemplos para la descripci on de los comandos b asicos de UNIX.
rbol: ruta Distinguimos dos tipos de rutas para acceder a un directorio del a absoluta y ruta relativa. rbol Ruta absoluta o completa: describe la ruta a seguir desde la ra z del a hasta el archivo o directorio al que deseamos referirnos en alg un comando. Ruta relativa: describe la ruta a seguir desde el directorio de trabajo donde nos encontramos hasta el archivo o directorio al que deseamos referirnos con
109
La tabla 10.2 muestra las rutas absoluta y relativa a partir del directorio profesores; para referirnos a la ruta actual (/users/profesores) empleamos ./; para referirnos a su ((hijo)) empleamos ./longjohn; para referirnos a su ((nieto)) empleamos ./longjohn/programas; para referirnos a su ((padre)) users, empleamos ../profesores, y para referirnos al directorio ((ra z)) del sta es siempre una ruta sistema de archivos de UNIX empleamos /; observe que e absoluta. Ruta relativa ./ ./longjohn longjohn/programas ../profesores/ Ruta absoluta o completa /users/profesores /users/profesores/longjohn /users/profesores/longjohn/programas /users /
La tabla 10.3 muestra las rutas absoluta y relativa a partir del directorio clase; la ruta actual es /users/profesores/longjohn/clase; para referirnos a su ((hermano)) empleamos ../programas; para referirnos a su ((abuelo)) empleamos ../../ (((el pap a de mi pap a))); para referirnos a su t o empleamos ../../annie (((el hijo del pap a de mi pap a))). Ruta relativa ../programas ../../ ../../annie Ruta absoluta o completa /home/longjohn/programas /home/longjohn/profesores /users/profesores/annie
10.2.
Comandos b asicos
Los comandos son los nombres de programas que se desean ejecutar. El formato general para ejecutar un comando es:
\$ comando [modificador...] [ruta|archivo|directorio] modificador: Determinan el modo como se ejecutar el comando x...: Indica uno o varios elementos ruta: Refiere a una ruta absoluta a una ruta relativa
110
archivo: Refiere a un archivo por su nombre y extensin directorio: Refiere a un directorio por su nombre [x]: Indica que el elemento x es opcional x|y: El elemento x o el elemento y
Los comandos b asicos que emplearemos en el curso se describen a las siguientes secciones:
10.2.1.
El comando pwd muestra en la pantalla el directorio actual de trabajo, ver ejemplos de la tabla 10.4, su notaci on general es:
$pwd
10.2.2.
Antes de mostrar algunos ejemplos, presentamos los atributos que caracterizan un archivo en UNIX. (a) rwxr-xr(b) 1 (c) longjohn (d ) profesores (e) 265 (f) Feb 13 (g) 10:47 (h) Pipati.c (i)
10.2. COMANDOS BASICOS Tipo d l Descripci on Archivos ordinarios, tales como los que creamos en lenguaje C Directorios Para indicar los enlaces simb olicos
Tabla 10.6 Tipo de archivos
111
(b) PERMISOS. Los derechos sobre un archivo se asignan a los roles: propietario, grupo y otros (ver tabla 10.7). Los derechos posibles sobre un archivo son: lectura (r-read), escritura (w-write) y ejecuci on (x-execute) Propietario rwx Todos los permisos Grupo rx Permiso de lectura y ejecuci on
Tabla 10.7 Roles y permisos
(c) ENLACES SIMBOLICOS. Indica el n umero de enlaces simb olicos que tiene un archivo. Un enlace simb olico corresponde a la referencia (o direcci on) de un archivo. (d) PROPIETARIO. Indica quien cre o el archivo. (e) GRUPO. Indica el grupo al cual pertenece el propietario en el momento de la creaci on del archivo. expresado en bytes del archivo. (f) TAMANO. ltima fecha en que fu (g) FECHA. Indica la u e modicado el archivo. ltima modicaci (h) HORA. Indica la hora de la u on del archivo. (i) NOMBRE DEL ARCHIVO. Indica el nombre del archivo o del directorio. En el ejemplo 1 de la tabla 10.8 el modicador l nos proporciona datos como: el tipo del archivo, los derechos, el propietario, el grupo asociado, la fecha ltima modicaci y hora de la u on el nombre del archivo. Los modicadores pueden emplearse en conjunto; la tabla 10.9 muestra otros modicadores para el comando ls. En el ejemplo 2 de la tabla 10.8 se solicita que muestre el contenido de los subdirectorios del directorio de trabajo actual, a saber: /users/profesores/longjohn.
112
Ejemplo 1 $ ls -l total 906 -rw-rr-x -rwxr-xr-x drwxr-xr-x drwxr-xr-x Ejemplo 2 $ ls -Rl total 906 -rw-rr -rwxr-xr-x -rw-rr -rwxr-xr-x ./programas: total 16 -rw-rr -rwxr-xr-x ./tareas: total 54 -rwxr-xr-x -rw-rr -rwxr-xr-x -rw-rr
1 1 2 2
1 1 1 1
1 1
longjohn longjohn
profesor profesor
503 6536
pirinola.c pirinola.exe
1 1 1 1
10.2. COMANDOS BASICOS Modicador -a -C -c -u -R -p Descripci on Muestra todas los archivos, incluyendo aquellos que son ocultos Muestra los nombres de archivos en columnas Muestra todos los archivos ordenados por fecha de creaci on Muestra todos los archivos ordenados por la ltimo acceso fecha del u Muestra el contenido de los subdirectorios de un directorio Distingue a los directorios de los archivos ordinarios a trav es de ((/)), colocado al nal del nombre
113
10.2.3.
El comando who permite conocer a los usuarios conectados en un momento determinado al servidor, su notaci on general es:
$who [am i]
El ejemplo 1 de la tabla 10.10 muestra la lista de los usuarios y la terminal de conexi on correspondiente a cada uno de ellos. El ejemplo 2 de la misma tabla 10.10 proporciona mi usuario y la terminal desde la cual me he conectado. Ejemplo 1 $ who ip-18-03 ip-16-18 cbrrn longjohn ip-20-13 ip-21-33 ip-9-02 Ejemplo 2 $ who am i longjohn
Feb 13 13:13 Feb 13 13:19 Feb 13 10:28 Feb 13 10:40 Feb 13 13:28 Feb 13 13:36 Feb 13 12:13
pts/15
Feb 13 10:40
(172.17.20.128)
114
10.2.4.
Cambiar de directorio cd
$cd [ruta|directorio]
El ejemplo 1 de la tabla 10.11 muestra como cambiar al directorio especicado. Observe que clase es un subdirectorio del directorio de trabajo longjohn; es decir, cuando estamos en un directorio espec co podemos acceder a sus subdirectorios (((hijos))). El ejemplo 2 de la tabla 10.11 muestra como cambiar al directorio especicado a trav es de una ruta absoluta. Observe que nos encontramos en el directorio clase (/users/profesores/longjohn/clase) y queremos situarnos en el directorio programas, el cual es ((hermano)) de clase, en este caso podemos emplear la ruta absoluta (/users/profesores/longjohn/programas). El ejemplo 3 de la tabla 10.11 muestra como cambiar a un directorio ((hermano)) evocando al ((padre)) con la ruta relativa (../programas); observe que en este ejemplo hacemos la misma acci on que el ejemplo 2. El ejemplo 4 muestra como cambiar al directorio ((padre)) longjohn con la ruta relativa (..). El ejemplo 5 de la tabla 10.11 muestra como cambiar al directorio ra z del sistema de archivos de UNIX. El ejemplo 6 de la tabla 10.11 muestra como cambiar al directorio asignado al usuario, al cual denominamos ((espacio de trabajo)) del usuario.
115
<longjohn@ce.azc.uam.mx> </users/profesores/longjohn> $ cd clase <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase> <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase> $ cd /users/profesores/longjohn/programas <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/programas> <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase> $ cd ../programas <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/programas> <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase> $ cd .. <longjohn@ce.azc.uam.mx> </users/profesores/longjohn> <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase> $ cd / <longjohn@ce.azc.uam.mx> </> <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase> $ cd <longjohn@ce.azc.uam.mx> </users/profesores/longjohn>
Tabla 10.11 Ejemplos del comando cd
D. actual
116
10.2.5.
El ejemplo 1 de la tabla 10.12 muestra como crear el directorio archivos como ((hijo)) del directorio de trabajo actual clase. El ejemplo 2 de la tabla 10.12 muestra como crear el directorio ciclos en el directorio clase que es ((padre)) del directorio de trabajo actual archivos (/users/profesores/longjohn/clase/archivos). El ejemplo 3 de la tabla 10.12 muestra como crear el directorio seleccion en el directorio clase, que es ((hijo)) del directorio de trabajo actual longjohn, (/users/profesores/longjohn) empleando la ruta absoluta /users/profesores/longjohn/clase/seleccion. Ejemplo 1 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase> $ mkdir archivos Ejemplo 2 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase/archivos> $ mkdir ../ciclos Ejemplo 3 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/> $ mkdir /users/profesores/longjohn/clase/seleccion
Tabla 10.12 Ejemplos del comando mkdir
10.2.6.
es:
Eliminar un archivo - rm
El ejemplo 1 de la tabla 10.13 muestra como eliminar el archivo calculadora.c del directorio de trabajo actual seleccion. El ejemplo 2 de la tabla 10.13 muestra como eliminar el directorio multiple del directorio de trabajo actual seleccion. Para que el directorio sea eliminado, debe estar vac o.
117
El ejemplo 3 de la tabla 10.13 muestra como eliminar recursivamente el contenido (archivos y directorios) del directorio seleccion; para lograrlo, se emplea el modicador r *. El ejemplo 4 de la tabla 10.13 muestra como eliminar todos los archivos con extensi on txt del directorio actual de trabajo archivos. El modicador i solicita conrmaci on de la eliminaci on de cada archivo. El ejemplo 5 de la tabla 10.13 muestra como eliminar el archivo fuente.txt que se encuentra en el directorio clase; pero nos encontramos en el directorio longjohn (/users/profesores/longjohn/); por lo tanto, empleamos la ruta relativa ./clase. Ejemplo 1 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase/seleccion> $ rm calculadora.c Ejemplo 2 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase/seleccion> $ rm multiple Ejemplo 4 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase/seleccion> $ rm -r * Ejemplo 5 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase/archivos> $ rm -i *.txt Ejemplo 4 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/> $ rm ./clase/fuente.txt
Tabla 10.13 Ejemplos del comando rm
10.2.7.
El comando mv permite cambiar de nombre a un archivo en el mismo directorio; adem as de permitir mover uno o varios archivos de un directorio a otro, su notaci on general es:
$mv [modificador...] ruta|archivo|directorio ruta|archivo|directorio
118
El ejemplo 1 de la tabla 10.14 muestra como cambiar de nombre al archivo oficio.txt por reporte.txt, el directorio de trabajo actual es archivos. El ejemplo 2 de la tabla 10.14 muestra como mover el archivo prueba.txt que se encuentra en el directorio de trabajo actual archivos al directorio seleccion, pero con el nombre datos.txt. Si se omite el segundo nombre, se copiar a con el mismo nombre. Cabe mencionar que es posible mover un archivo empleando una ruta absoluta o una ruta relativa tanto para el directorio fuente como para el directorio destino. El ejemplo 3 de la tabla 10.14 muestra como mover un conjunto de archivos que cumplen con el criterio if*, del directorio actual de trabajo clase al directorio seleccion, empleando la ruta relativa ./seleccion. En este caso, tambi en es posible mover un conjunto de archivos empleando una ruta absoluta o una ruta relativa tanto para el directorio fuente como para el directorio destino. El ejemplo 4 de la tabla 10.14 muestra como mover el directorio multiple al directorio seleccion. Observe que nos encontramos en el directorio longjohn; por lo tanto, empleamos las rutas relativas ./clase/multiple para el directorio fuente y ./clase/seleccion para el directorio destino.
Ejemplo 1 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase/archivos> $ mv ocio.txt reporte.txt Ejemplo 2 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase/archivos> $ mv prueba.txt ../seleccion/datos.txt Ejemplo 3 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase> $ mv if* ./seleccion Ejemplo 4 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/> $ mv ./clase/multiple ./clase/seleccion
Tabla 10.14 Ejemplos del comando mv
119
10.2.8.
Copiar archivos - cp
El comando cp permite copiar el contenido de un archivo a otro en el mismo directorio o en otro directorio, su notaci on general es:
El ejemplo 1 de la tabla 10.15 muestra como copiar el contenido del archivo reporte.txt al archivo reporte-ver01.txt en el directorio de trabajo actual archivos. El ejemplo 2 de la tabla 10.15 muestra como copiar el archivo prueba.txt que se encuentra en el directorio de trabajo actual seleccion al directorio archivos, conservando el mismo nombre. Si se desea copiar con otro nombre se especica al nal del comando. Cabe mencionar que es posible copiar un archivo empleando una ruta absoluta o una ruta relativa tanto para el directorio fuente como para el directorio destino. El ejemplo 3 de la tabla 10.15 muestra como copiar un conjunto de archivos que cumplen con el criterio *.c del directorio actual de trabajo clase al directorio seleccion empleando la ruta relativa (./seleccion). Cabe mencionar que es posible copiar un conjunto de archivos empleando una ruta absoluta o una ruta relativa tanto para el directorio fuente como para el directorio destino. El ejemplo 4 de la tabla 10.15 muestra como copiar el directorio juegos que se encuentra en el directorio el directorio archivos hacia su directorio ((padre)) clase. Por lo tanto, empleamos la ruta relativa (../). El modicador -R permite que se copien tambi en los subdirectorios.
120
AL SISTEMA OPERATIVO UNIX CAPITULO 10. INTRODUCCION Ejemplo 1 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase/archivos> $ cp reporte.txt reporte-ver01.txt Ejemplo 2 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase/seleccion> $ cp prueba.txt ../archivos Ejemplo 3 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase> $ cp *.c ./seleccion Ejemplo 4 <longjohn@ce.azc.uam.mx> </users/profesores/longjohn/clase/archivos> $ cp -R ./juegos ../
Tabla 10.15 Ejemplos del comando cp
10.2.9.
El comando man muestra la sintaxis de cualquier comando de UNIX as como los modicadores posibles, su notaci on se muestra a continuaci on y la tabla 10.16 muestra un ejemplo.
10.2. COMANDOS BASICOS $ man ps NAME ps - report process status SYNOPSIS ps [-aAcdefjlLPy] [-g grplist] [-n namelist] [-o format]... [-p proclist] [-s sidlist] [-t term] [-u uidlist] [U uidlist] [-G gidlist] DESCRIPTION The ps command prints information about active processes. Without options, ps prints information about processes that have the same effective user ID and the same controlling terminal as the invoker. The output contains only the process ID, terminal identier, cumulative execution time, and the command name. Otherwise, the information that is displayed is controlled by the options.
Tabla 10.16 Ejemplos del comando man
121
122
Bibliograf a
[1] Brian W. Kernighan and Dennis M. Ritchie, El lenguaje de programaci on C, segunda edici on, Prentice Hall. [2] Gary J. Bronson, C++ para ingenier a y ciencias, Internacional Thomson, 2007, editor colaborador G.J. Lehigh. [3] Osvaldo Cair o, Fundamentos de programaci on. Piensa en C, primera edici on, Pearson - Prentice Hall, 2006. [4] Walter Savitch, Resoluci on de problemas con C++, quinta edici on, Pearson - Addison Wesley, 2005. [5] Bjarne Stroustrup, The C++ programming language, AddisonWesley, 1991. [6] Stephen R. Davis, C++ for dummies, 5th edition, Wiley Publishing Inc., 2004. [7] J. Glenn Brookshear, Introducci on a las ciencias de la computaci on, cuarta edici on, Addison-Wesley, 1995. [8] Guillermo Levine Guti errez, Introduccion a la computaci on y la programaci on estructurada, McGraw-Hill, 1994. [9] Abdelmadjid Berlat, Jean-Franc ois Bouchaudy et Gilles Goubet, dition, Eyrolles, 2003. Unix utilisateur, seconde e
123
124
BIBLIOGRAFIA