Está en la página 1de 153
SEGUNDA EDICION EL LENGUAJE DE PROGRAMACION EDICION EN INGLES UNIX es una marca repistrada AT & T EL LENGUAJE DE PROGRAMACION ‘Traducido de la segunda edicién en inglés de: ‘THE C PROGRAMMING LANGUAGE ba sepretuccion total o parcial de sta bra pe culauer medio o mitodo DERECHOS RESERVADOS © 1991 respecto a la segunda edicibn en espaftol por PRENTICE-HALL HISPANOAMERICANA, S.A. Allscomlco Nim. $00:5° Pito Col, Industral Atoto 53519, Naucalpan de Jusrez, Edo. de México Miemiro de la Camara Nacional de la Industria Editorial, Reg. Nim. 1524 ISBN 968.280-208.0 Original English language edition published Copyright © MCMLXXXVIII by Prentice H All Rights Reserved ISBN 0-13-110362-8 IMPRESO EN MEXICO / PRINTED IN MEXICO. Prefacio Prefacio a ta primera sdicibn Introduceién Variables y expresiones aritméticas La propesitin for Constantes simbélicas Entrada y valida de caracteres ‘Arreglos Funciones Argumentos—Ilamada por valor Arreglos de caracteres 10 Variables externas y aleance Capitulo 2, Tipos, operadores y expresiones Nombres de variables ‘Tipos y tamatios de datos 7 Conversion: de tipo Operadores de inctemento y decremento Operadores para manejo de bits ny expresiones Expresiones condicionales Precedeneia y orden de evaluacion while y for 1s—do-while CONTENIDO & 73.7 Break y cor = 3.8 Goto y etiq. 2 CCapitute 4, Funcionsy ta estructura det programa 3s Canceptos basicos de funciones 5 js gue regresan valores noenteros, » Ejemplo—ura implementacioa de fopen y gete externas 2 Ejemplo—lisiato de directorios Reglas de aleance 88 7 Ejemplo—asignador de memoria Archivos header 2 ie ancal de referencia % 34 95 ” 1 El preprocesador de © ‘AG Conversiones Copies Apmaatones segs Apuntadores y direcciones 32. Aberntarss Sarewoeto:de faces 53 Apuntadores ¥ arreglos 5.4 Aritmética de direeciones Antadie 8, Bitte Entrada y sa 12 Procbs de canto de Garactees: 183 Funciones para cadenas: tidimensionales 5.10 Argumentos en la linea de comandos 3.11 Apuntadores a funclones 5.12 Declaraciones complicadas 4 ceataa Bs Capitulo 6, Estructuras B6 Diagnésticos: 6.1 Conceptos basicor sobre estructuras B7 les: 6.2 Estracturas y funciones BS - 6.3 Arreglos de estructuras Bo, > 64 Apuntadores 0 estructuras B10 6.5 Estructuras autorreferenciadss BLT Limites definides en ta implantacién: 6.6 Bisqueda en tablas 67 Typedet 6.8 Uniones 6.9 Campos de bits Apéuitice C. Resumen de modificaciones Indice Capitulo 7. Entrada y salida 7.1 Entrada y mato—print jumentos de longitud variable 7.9 Manejo de errores—stderr y exit Prefacio EI mundo de la computacién ha sufrido una revolucién desde la publicacién, en 1978, de El lengucje de programacion C. Las grandes computadoras son aho- ra mucho més grands, y las computadoras personales tienen capacidades que ri biado en ese tiempo, aunque sélo en forma modesia, y se ha extendido mas alla de lo que fueron sus origenes como el lenguaje del ‘tivo UNIX. La creciente popalaridad de C, los cambios en el lenguaje a lo largo de los i sen su disco, se tos eran prod dependiente de la maquina” culdando la conservacion de su espiri lenguaje C. jon de cadenas y comportamiento de caracteristicas que no se mencionaron en la defini nal, y al mismo tiempo establece explicitamente cuales aspectos tienen ain dependencia de maquina, Esta segunda edicion de Et lenguaje de programaciéin C lo describe tal como lo definié el estandar ANSI. (En el momento de escribir esta edicidn, el estandar se encontraba en a etapa final de revisién; se experaba su aprobacién a finales de 1988. Las diferendas entre lo que se ha descrito aqui y la forma final deberin ser minimas.) Aunque hemos hecho anotaciones en los lugares donde el lenguaje Hemos tratado de mantener la brevedad de la primera edicion. El no es grande, y no le esta bien un gran libro. Hemos mejorado la exposi ccaracteristicas eriticas, como los apuntadores, que son parte central en la progra- macién con C. Hemos redefinido los ejemplos ori je nuevos en varios capitulos. Por ejemplo, se aument6 el intencién fue trasladar la esen hecho con el nimo de que props madores, pero mo c« ladores —ese pay indar a un espaci jone una fic comprensién para los progra- Con ‘0 le ayude a aprender el -onocimiento hacia los amigos que nos ayudaron a ., Doug Mellroy, Peter cada pagina del bo- Tondo y Peter Weinberger. Dave Prosser respondid muchas preguntas detalladas acerca del esidndar ANSI. Utilizamos extensivamente el intérprete de C+ + de Bjame Stroustrup, para la prueba local de nuestros programas, y Dave Krisiol para las pruzbas finales. Rich Drechsler nos: Prefacio a la primera edicién ‘Ces un lenguaje de programacién de propdsito general que ofrece como ven- tajas economia de exoresién, control de flujo y estructuras de datos modernos ‘yun rico conjunto de operadores. Ademas, C noes un lenguaje d . ¥ no estd especi Pero su ausencia de restricciones y su generalidad lo hacen més conveniente y ‘0 para muchas tareas que otros lenguajes supuestamente més poderosos. lment dorde C y esencialmeate todos los programas de aplicacién de UNIX (incluyendo todo el sofware utilizado para preparar este libro) estén escritos en C. También existen compiladores >ara la produccién en otras maquinas, incluyendo la [BM Sysiem/370, la Honeywell 6000 y la Interdata 8/32. El lenguaje C no est aningin hardware o sistema en particular y ¢s facil escribir programas que corre- ran sin cambios en ctaiquier maquina que maneje C, La finalidad de ese libro es ayudar al lector a aprender cémo programar en ©. Contiene sien lo mas pronto posi tante y un manual de re los ejemplos son programas reales y completos, no 9s alstados. Todos los ejemplos han sido probados directamente a partir el cual esta'en forma legible para la maquina. Ademas de demostrar un uso efectivo del lenguaje, donde ha sido posible, tratamos de ilus- 0s itles y principios de buen estilo y diseRo. ‘0 no ¢5 un Manual de introduccion a la programacién; se supone en él familiaridad con los conceptos bésicos de programacién, como variables, propo- Siciones de asignacién, ciclos y funciones. No obstante, un programador novato dleber ser capaz de lee: y obtener los conceptos del lenguaje, aunque le ayudaria |e cooperacién de un colega més experimentado, Deacuerdo con muestra experiencia, C ha demostrado ser un lengu: bie. expresivo y versitl para una amplia variedad de programas. der y se obtienen mejores on él, Deseamos que est xii PREFACIO ALA PRIMERA EDICION Las criticas y sugerencias de muchos amigos y colegas han aumentado much tun placer escribitlo. En particular n tro agradecimiento a , Jim Blue, Stu Feldman, Doug Mellroy, y Larry Rosier que leyeron cuidadosamente las numerosas . ‘agradecemos Al Aho, St:ve Bourne, Dan Drorak, Chuck Haley, Debbie Haley, Marion Harrris, Rick Holt, Steve Johnson, John Mashey, Bob Mite, Ralph Muha, Peter Nelson, Ellice Pinson, Bill Plauger, Jerry Spi- vack, Ken Thompson y Peter Weinberger por sus valiosos comentarios a través, de varias etapas; a Mike Lesk y Joe Ossanna, por su invaluable ayuda en la im- Brian W. Kernighan Introduccion Ces un Lenguaje ce programacion de propésito general que ha sido estrecha- mente asoriado con e! sistema UNIX en donde fue desarrollado puesto que tanto elsistema como los programas que corten en dl embargo, este lenguaje no esta ligado a ningin sistema operative maquina, y aunque se le llama “Lenguaje de programacidn de sistemas” de ‘au utilidad para escribir compiladores y sistemas operativos, se eficacia para escribir importantes programas en diversas di - Muchas de las idces importantes de C provienen del lenguaje BCPL, desarro- lado por Martin Richards. La influencia de BCPL sobre C se continué indirecta- mentea través del lensuaje B, el cual fue eserito por Ken Thompson en 1970 para cl primer sistema UNIX de BCPL y B son lerguajes “‘carentes dk una variedad di ymimeros de pi € proporciona ipos fundamentales son caracteres, enteras de endiente de la maquina. C proporciona las construcciones fundamentales de control de flujo que se re- quieren en programas bien estructurados: azrupacién de proposiciones, oma de jones pueden regresar valores di © apuntadores. Cualquier fun no puede estar anidada, pero las vari fr declarades en una modalidad estructurada por bloques. Las fu es de un programa enC pueden exist en archivos fuente separados, que se com- de manera separada. Las variables pueden ser internas a una funci6n, =sinas pero conccidess6lo dentro de un archivo fuente, 0 visibles al programa completo. 2 wwmopuccton Un paso de preprocesar programa, inclusion de otros archivos fuente y compilacion condicional ‘Ces un lenguaje de relative “bajo nivel". Esia caracterizacién no es peyora~ implemente significa que C trata con el mismo tipo de ot Jas computadoras, Iimense caracteres, niimeros ¥ pueden ser combinados y cambiados de sitio con os operadores aritméticos y 1b- ‘gicos implantados por mag) pueden copiarse como una asignacién de almacenamiento que no sea la de definicién est trada/salida; no hay proposiciones ‘acceso a archivos. Todlos esos mecanismos de altonivel deben ser proporcionados por funciones llamadas explicitamente. De manera semejante, C solamente ofrece un control de flujo franco, y grave deficiencia rar dos cadenas de caracteres? tiene beneficios reales. Puesto que Ces r lenguaje de un samente pequefio, se puede describir al estindar ANSI 0 -speraba fuera aprobada a fines de mayoria de las earac- | estandar ya se encuentran soportadas por compiladores que la mayoria de los programas ex nos, que los compiladores pudieran producir mensajes de advertencia acerca del Para la mayoria de los programadores, el caibio mas importante es una nue- va sintaxis para declarar y definir funciones. Una declaracion de funcién ahora 1a descripeién de los argumentos de la funcidn; axis de la informac én extra permite que los compi- res causaloy por argumentos que no coin al lenguaje. FL LENGUAME DE PROGRAMACIONE 3 Existen otros cambios de menor escala en el lenguae. La asignacién de estruc- ado ampliamente dispor de punto floiante pueden jas. El preprocesador es mi esos cambios slo endriin efectos s madores Una segunda contilbucién sig actividades se- n iar proporcionan un declaraciones de funciones y tipos de dates. Los programas Debido a que los tpos de datos y estructuras de control provi manejadas directamerte por In mayoria de ejecucién (run uefa. Las funciones ce la biblioteca estandar tnicamente se llaman en forma ex- ‘a, de manera quese pueden evitar cuando no se necesitan, La mayor parte Duede escribirse en C, y excepto por detalles ocultos del sistema operativo, ellas ‘mas portitiles, esto es, programas que puedan correr: de miquines. El estandar explica los problema ibe un conjunto de constantes que c tael programa. ‘noes un lenguajefuertement a direccién, Los compiladores advertiran de la mayoria de los res de tipo, y no de tipos de datos incompatibles. basica de que los programados i estdin haciendo; silo requiere que establezean sus int Como cualquier otro lenguaie, C tiene sus defecos. Algunos de Testuenen la precedench equivocad dou unas tiene mejores. A pesar de todo, C ha probado ser un lenguaje extremadamente efectivo yy expresivo para una amplia variedad de programas de aplicacién, duccién orien- tada ala parte central de C. El propdsito es hacer quc el lector se inicie tan pronto puesto que creemos firmemente que la forma de aprender tun nuevo Lenguaje ¢s escribir programas en él. La introducién supone un conoci- mitento préctico de los elementos basicos de la programacién; no hay una explica- uutadoras, de compitacion, ni del significado de una expresidn como y mis formaimente de to que se hace en el capit fen los ejemplos de programas completos, mas que en fragmentos aislados. El ca- pitulo 2 trata de los tipos basicos de datos, operaciones y expresiones. El capitulo 2 trata sobre control de flujo: it-elee, switch, while, for, etc. En el capitulo 4 juctura de un programa —variables externas, reglas les ¥ otros aspectos— y también abarca al pre- sobre apuntadonss y aritmética de direeciones. ‘se cubren funciones y la , salida y otros secesos al sistema operativo se in cambios. gramas que la usen para ent puedan transportar de un sistema a ot capitulo 8 describe una interfaz ¢ unas en Cy el sistema /0 UNIX, concentriindose en entrada/salida, d sistema de archivos y la asi naciéa de memoria, Aunque algo de este capitulo es especifico de sistemas UNIX, los programadores que usen otros sistemas de todas maneras encontrarin aqui material de utilidad, incluyendo alguna comprension acerca de como esta implan- tada una versién de la biblioteca estindar, asi como sugerencias para obtener un ¢ un manual de consulta del lenguaje. El informe oficial joa de C es en siel isa y sin el mismo El apéndice B es un resumen dar, de nuevo ms pera unuarios que para implantadores. El apén- ice C es un breve resumen de los cambios del Lenguaje original. Aunque, en caso de dda, el estandar y el compilador en uso quedan como las autoridades finales capitulo 1: Introduccién general sonicentrarnos en las bases: variables y mética, control de flujo. funciones y los rudimentos de entrada y iejado intencionalmente fuera de este capi ir programas adores, estructuras, la mayor parte del ias proposiciones para control de flujo y ta ios ejemptos tes como podi En cualquier caso, los programadon extrapolar del material cue se encue de programacién. Los pi lo como un marce de referencia sobre el cual as idas que comienzan en el capi 1.1 Comencemos 1 nguajes: Imprima las palabras hola, mundo 6 INTRODUCCION GENERAL enrrTutoy Este 5 el gran obsticul rear el texto del programa de alguna cl programa para escribir #include main( ) ppriti*hola, mundo\n®): do. Como un ejemplo especifico, en en un archivo cuyo nombre termine ect lo con In orden ce hola.e Si no se ha cometido algiin error, como la omisin de un cardcter o escribir algo fen forma incorrect 10 ejecutable llamado a.out, Si se cjecuta a.out escribiendo la orden aout se eseribira hola, mundo En otros sistemas, las reglas seran diferentes, consultelo con un exper cualquiera que sea su tamafo, consta de funcionssy variables . Una funcién tiene proposiciones que especifican las operaciones de cdlculo que se van a las variables almacenan los valores utilizacos durante los céleulos. Las sy funciones de Fortrar ro ejemplo es una funcié: iene la libertad de dar cualquier nombre que se todo programa debe tener un main en algtin sit Por lo comin main llamard 2 otras funciones que ayuden a realizar su que usted ya escribid, y otras de bibliotecas escritas previamente. La primera linea del programa. include indie al compitador que seccionn.t coMENErMOS 7 Un método para Jama proporciona uné lista de valores, llamados argument. 5 es que la funcion que id funcion que esd icado por ta lista # include Inelure informacion acerca de ta maint ) define una urcion llamada mai que no recibe valores de argumentos { los proposiciones de main estén encerradas entre Haves prini(*hala, mundo\n"); main lama a la funcion de biblioteca print. ! para escribir sta secuencia de coracteres; \n representa el cardcter nueva Tinea El primer programa en © tan encerradas entre Haves { }, La fun main s6lo conticxe una proposicion, Print (“bola, mando\n" idor de C producira un mensaje de error. 8 xTRONUCCION GENERAL printf nunca proporciona una nueva linea autométicamente, de manera que se pueden utilizar varias llamadas para construir una linea de salida en etapas, Nuestro primer programa también pudo haber sido escrito de la si lade lista completa en la seccién 2,3. Ejereco 1-1. Ejecute el programa “hola, mundo" a su sistema. Experimente con Ja omisién de partes del programa, para ver qué mensajes de error se obtienen. Ejercicio 1-2, Experimente el descubrir qué pasa cuando la cadena de printf contiene \c, en donde ¢ es algiin cardcter no puesto en mente, 0 1.2. Variables y expresiones aritméticas El siguiente programa utiliza la férmula °C = (5/9) (°F=32) para imy sss equivalentes ceatigrados 0 secon \YARIADLES VEXPRESIOMES ARITMETICAS 9 icidn de una Unica funcidn Hamada “hola, mundo’, pero no es complicado. ido comentarios, declaraciones, variables, silida con formato, + imprme la tabla Fahrenheit Celsius ara lahr = 0 20, ..., 300 +/ main (} 1 ‘nt fabr, celsius, int lower, upper, as dos lineas /+ imprine le tabla Fehvenhett Celsus pata fahr = 0,20, .., 300 » son un comentario, que en este caso explica brevemente Lo que hace el programa. Cua eres enite /+ y «/ son ignorados por el compilador, y pueden yemente para hacer a un programa mas facil de entender. Los co- lugar donde puede colocarse un espacio juncién y antes de cualquier proposicidn ejecutable. Una declara- Propiedades de una variable; consta de un nombre de tipo ¥ una de variables, como it fabr, celsius; tat lower, upper, step: 10 INTRODUCCION GENERAL eartrutos char cardcter —un solo byte short entero conto long entero largo double punto flotante de doble precisién Los tama de estos objetos también dependen de la méquina. También existen arreglo, estructurasy unianes de esos ipos bisices, apuntadores a ellos y funciones {que regresan valores con esos tipos, todo lo cual se verd en el momento oportuno. Los cdlculos en el programa de conversién de temperaturas principian con las proposiciones de asignacién. lower = 0; suppor ~ 200; step = 2; fahr = lower; ‘que asignan a las variables sus valores iniciales. Las proposiciones individuales se terminan con punto y coma. Cada linea de la tabla se calcula de Ia misma manera por lo que se utiliza una iteracibn que se repite une vez por cada linea de salida; este es el propdsito del ciclo while while (ahr <= upper) { } El ciclo while funciona de la siguiente manera: se prucba la condicién entre pa- réntesis. De ser verdadera (fahr es menor o igua’ que upper), el cuerpo del ciclo (las tres proposiciones entre llaves) se ejecuta, Luego la condicién se prueba nue- ‘cuerpo se ejecuta de nuevo. Cuando la prueba resul- ta falsa (fahr excede upper) la iteracidn termina, y la ejecucidn continia en la das entre aves, El cuerpo de un while puede tener una o mas proposiciones ence Haves, como en el convertidor de temperaturas, © una sola proposicién como en ido en donde uno de ido. yen qué forma print{("¥%d\(%d\n", lahr, celsius): hace que los valores delos dos enteros fahr y celeiue sean eseritos, con una tabu. lacién (\t) entre ellos. Cada construecién % en el primer argumento de printf esta asociada c: correspondiente segundo argumento, tercero, etc., ¥ deben carresponder piadamente en mimero y tipo, o se tendriin soluciones incorrectas. ‘esio, print! no es luna entrada o salida definida en C. lades deben ser las mismas en cualquier compilador que se apegue a él Para concentramosen C, no hablaremos mucho acerca de la entrada y la sali da hasta el capitulo 7. En particular, pospondremos e! tema de ‘mato hasta entonces. Si 9€ 1 do lee de ta entraca en lugar de escribir a la salida: Fl problema mis grave es que debido a quesse ha utilizado aritmética de en- ‘eros, las temperaturas Celsius no son muy predsas; por ejemplo, 0*F es en rear lidad aproximadamente —17.8°C, no —17. Para obtener soluciones mas preci- sas, se debe utilizar aritmética de punto flotanteen lugar de entera, Esto requiere de algunos cambios en el programa. Aqui estd una segunda versién: # include /> imprime 1a tabla Fahrenheit-Colsius para fahr = 0, 20, ..., 300; versién de punto flota Limite superior de la tabla de temperaturas «/ Uimite superior « printf("%3.0f 9¢6.18\n", fabr, celaus); fabr = fahr + step; SECON 12 VARIABLES VEXPRESIONRS ARITMETICAS. 13, por lo que 5.0/9.0 no se trunca debido a que es una reiacion de dos valores de purto flotante. Si in operador arismético tiene operandos enteros, se ejecuta una operacién entera, Si un operador numérico tiene un operando de punto flotante y otro ente- este tkimo sera cenvertido a punto flotante antes de hacer la operacidn. Si intes de punto flotante c: nes enteros, destaca su nar jores humanos. \ detalladas de cuindo los enteros se convierten a punto flotante se encuentran en el capitulo 2, Por ahora, nétese que la asignacién fobs = lower; y | prueba cn It forma natural —cl int se convierte a float antes de efec- mnversion %3.01 del printf indica que se (en este caso fahr) por lo menos con tres ancho, sin punto decimal y sin digitos fraccionarios; 96.1 describe 2 otro mimero (celsius) que ie escribira en una amplitud de por fo menos 6 caracteres, con 1 ‘La amplitud y la precisién pueden omitirse de una espe %6F indica que el nlimero es por lo menos de seis earacteres de ancho; %.21 indica dos caracteres después del punto dedmal, pero el ancho no esti restringido; y ¥%6! inicamente indica escribir el mimero como punto flotante. ta eseribe como entero decimal 6d eseribe como entero decimal, por lo menos con 6 caracteres de arplitud om evaibe come punto Morante et esaribe como punto flotante, por lo menos con 6 caracteres de amplitud 14 ieRoDUccIONGENERAL wat «scribe como punto flotante, con 2 caracieres después del punto decimal 946.2 escribe como punto flotante, per lo menos con 6 caracte ancho y 2 después del al Entre otros, prinif también reconoce 960 para o:tal, para caricter, 48 para cadena de earacteres y %6% para % en si, Ejercicio 1-3. Modifique el programa de conversiGn de temperaturas de modo que escriba un encabezado sobre Ia tabla, 0 Escriba un programa que imprimala tabla correspondiente Celsius 1.3. La proposicién for ten suficientes formas distintas dle escribir un programa para una tarea en particular. Intentemos una variacion del programa de conversiOn de temperaturas, include ow fae = Este produce los mismos resultados, pero ciertamente se ve diferente. Un cambio importante es Ia eliminacién de la mayoria de las variables; s6lo permanece fahr y la hemos hecho int. Los limites inferior y superor y el tamafio del avance s6lo parecen como constantes dentro de la proposicién for, que es una nueva construceién, y la expresién que calcula la temperatura Celsius ahora aparece acién sepa- como el tercer argumento de printi en vez de una proposicién de rada, 10 cambio ejemplifica una regla general —en cualquier contexto en valor de una variable de alg - tuna expresion mas complicada de ese tipo. Puesto que el tercer argumento de print! debe ser un valor de punto flotante pare coincidir con %6.1f, cualquier ex- resion de punto flotante puede estar alli. La proposicién for ¢s un ciclo, una forma genenizada del while, on el while anterior, su operacién debe ser clara. Dentro de los park tres seeciones, separadas por punto y coma. La primera, la ini fahr = 0 seccion14 CONSTANTESIMBOLICAS IS ce ejecuta una vez, antes de entrar propiamente al ciclo. La segunda seccién es |a condieién o prueba que controla el ple printf) se ejecuta. fahr = fahr + 20 «se cjecuta y la condicién se vuelve a evaluar. El a. Tal como con el while, el cuerpo es encerradas entre Ilaves. La remento pueden ser cualquier expresiOn. y se basa en aquello que parezca to que es mas compactoque el while y mantiene reunidas en un lugar a las propo- ies que controlan al ciclo. 5. Modifique el programa de conversién de temperaturas de manera la tabla en orden inverso, esto es, desde 300 grados hasta 0. 0 1.4 Constantes simbélicas Una observacion final antes de dejar de de temperaturas. Es une mala practica poner en un programa, ya que proporcionan muy poca inform: leerel programa, y son difiiles de modificar en un forma sistemética, Una mane- ‘a de tratar a esos nlimzros mégicos es darles nombres signifiativos. Una linea ‘#deline define un nombre simbélico 0 constante simbolica como una cadena de caracteres especi nombre (que no esté ¢ rd por el texto de remy ser cualquier secuencia de caracteres: no est include fdeline LOWER 0 ‘#detine UPPER 300 ‘define STEP 20 mite superior +/ [+ tamato del increment «/ 16 wrropuccionceNnRAL, Js tmprime la tabla Fahrenbet!-Celsius + main( ) { st fae; for (fahr = LOWER; fahr <= UPPER; fuhr = fahr + STEP) printl("963d 66. fahr, (5.0/9.0) « (fahe~32); ' Las cantidades LOWER, UPPER y STEP son constentes simbdlicas, no va por lo que no aparecen enire las declaraciones. Los nombres de simbolieas, por convencin, se escriben con letras maytisculas, de mo puedan distinguir Fécilmente delos nombres de variables esc Nétese que no hay punto y coma 1.5 Entrada y salida de caracteres Ahora vamos a conside lia de programas relacionados para el pro- cesamiento de datos de tipo cardcter. Se encontrari que muchos programas sélo son versiones ampliadas de los prototipos que se :rat de cero o mas caracteres seguidos de un cardcter# de hacer que cada see modelo; el programador de C que La biblioteca estndar proporciona varias funciones para leer o escribir un ccardcter a la vez, de las cuales getchar y putchar son las mis lor. Esto es, después de © = getchar() la variable c contiene el siguiente caricter de entreda. Los caracteres provienen Rormalmente del teclado; la entrada de archivos s trata en el capi La funcién putchar escribe un cardcter cada vez que se invo putchar(c) eseribe el contenido de la variable entera c como un caricier, generalmente en ta pamtalia, Las llamadas a putchar y a printf pueden estar alternadas; la salida ‘parecer en el orden en que se realicen las llamaias. seecionns ENTRADA YSALIDADECARACTERES 17 1.5.1 Copia de archivos Con getchar y putchar se puede eseribir una c; ‘acerca de entrada y la entrada en la id sorprendente de cédigo lo més sencitlo es un (cardcter no es indicator de fin de archivo) inda ala salida el earicier recién leido Jee un earicier Al convertir esto en C se obtiene include Jo copia la entrada a la salida; 1a, versién «/ El operador de relacién != significa *‘no igual a". Lo que aparece como un cardcter en el teclado o en la pantalla es, por supues- como cualquier otra cosa, almacenado internamente como un patron de bits. ipo char tiene la funcibn especifica de almacenar ese tipo de dato, pero tam- bign puede ser usado cualquier tipo de entero. Usames int por una sutil pero im= portante razon. Elproblema es distingnir el fin de la entrada de tos datos vilidos. La solucién fs que gotchar devuelve un valor ‘0 cuando no hay més a la entrada, un valor que no puede ser coxfundido con ningan oiro cardcter. Este valor se llama de ai Sta lo suficientemente grande para almacenar cualquier valor que le regrese get- char. No se puede utilizar char puesto que e debe ser sufi te grande ‘como para mantener a EOF ademds de cualquier otro caracter. Por lo tanto, se emplea int. EOF es un entero defisido en , pero el valor numérico especifico po importa mientras que no sea el misino que ningin valor tipo char. Uti constante simbdlica, hemos asegurado que nada en el programa depende del lor numérica especifico 18 IwrRoDLCCION GENERAL caprTutor Pinclude Ia ont lo = getchar putchar(c); - EOF) jgna ac, y entonces prueba si De no serlo, el cuerpo cel while se cject ¢ el while, Luego, cuando se aleanza el final de la entra- iambién lo hace main, fa entrada —ahora hay slo una referencia a getchar— Esta version central tuna yee gue se 6 posible dese mos de reprimir, Los paréntesis que estin alrededor de la asignscién dentro de la cor neves a precedencia de! = ta en ausencia de paréntesis la prueba de relacin != se realizaria antes de la asigna- cidn =. De esta manera, la proposicién © = getchar( ) = EOF es equivalente a © = (getchax{ ) != EOF) ne el efecto indeseable de hacer que © sea0 9 char enconts6 fin de archivo. (En el api el valor de EOF, 0 seecioN as ENTRADAW SALIDA DECAMACTERES 19 1 cuenta caractetes y es semejante al programa que copia, b> trade; La. versiéa «/ long ne: ne = 0; while (geichay() |= EOF) printi(Y6ld\n’, ne); La proposicién + +20; ia un nuevo operator, + +, que signitica incrementa en uno, Es posible = ne + 1, pero + +ne.esmas conciso y muchas veces mas eficiente. adoptaremos la forma de prefijo. El programa para cortar caracteres acumnula su cuenta en una variable long en lugar de una int. Los enteros long son por lo menos de 32 bits. Aunque en algunas maquinas int y long son del mismo tamafio, en otras un int ¢s de 16 bits, con un valor maximo de 22767, ivamente poca lectura a la entrada para desbordar un contador int. La especificacion de conversion %ld indica a Para demostrar otra forma de escribir el #include la los carectores de la entrada; 2a. versién «/ double ae; for (no ~ 0; geteher() |= EOF) + +20) print{("36.0f\n", nc); 20 INTRODUCCION GENERAL carrmuto1 printf utiliza 9f tanto para float como para double; %.0f suprime la impresion el punto decimal y de la parte fraccionaria, que es cero. El cuerpo de este ciclo for esté vacio, debido a que todo el trabajo se realiza en las secciones de prucka ¢ incremento. Pero lasreglas gramaticales de C requie- ren que una proposicion for tenga un cuerpo. E! punto y coma aislado se liana proposicin nula, y es:é aqui para satisfacer este requisito. Lo colocamos en una Tinea aparte para que sea visible ‘Antes de abandonar el programa para contar caracteres, obsérvese que si la entrada no contiene caracteres, la prueba del while o del for no tiene éxito desde la primera llamada a geickar. y el programa produce cero, el resultado correcto. Esto es importante, Uno de los aspectos agradables acerca del while y del for es quehacen la prueba al inicio de ciclo, antes de proceder con el cuerpo. Si no hay nada que hacer, nada se hace, aun si ello signitcs no pasar a través del cuerpo dol ciclo, Las programas deben actuar en forma inteligente cuando se les da una entrada de longitud cero. Las proposiciones while y for ayudan a asegurar que los programas realizan cosas razonables con condiciones de fronter. 1.53 Conteo de lineas El siguiente programa cuenta lineas a la entrada, Como se mencioné anterior andar asegura que una secuencia de texto de entrada pa- saricter nueva linea. feres nueva linea: , El cuerpo del while consiste ahora en un if, el cual a su vez controla el incre- ‘mento + +nl. La proposicién if prucba la condi rentesisy, sila condicidn es verdadera, ejecuta i proposicién (0 grupo de propo- sicfones entre Waves) que le sigue. Hemos sangrado nuevamente para mostrar lo que conirola cada clemento, El doble signo de igualdad = = es la notacion de C para expresar "igual a” (como el = simple de Pascal 0 e! EQ. de Fortran). Este simbolo se emplea para SECON [ENTRADA YSALIDADECARACTERES 21 lad del = simple que utiliza C para la asignacion, \cipiantes de C ocasionalmente eseriben = cuando ‘Como se veri en el capitulo 2, el resultado es por Un mensaje de alerta: los p en realidad deben usar el conjunto de caracteres de la maquina, Esto se llama ice, atunque s6lo es otra forma de escribir un pequeno ente- en el conjunto ASCII de fl ual cs 10 en codigo ASCLL Se debe nolar culdadosaments que *\n es un cardeter simple, y en expresiones es s6lo un entero; por otro lado,""\n" es una constante cadena que contiene slo un cardeter. En el capitulo 2 se trata el tema versus caracteres, Escriba un programa que copie su entrada a la salida, reemplazando cada cadena de uno 0 mas blancos por un solo blanco. Escribaun programa que copie su entrada a la sali \\: Esto hace que las tebulaciones y los espacios sean visibles sin confusiones. 1.8.4 Conteo de palabras Fl cuarto en nuestrs serie de programas iitles cuenta las lineas, palabras y ea racteres, usando la definicién de que una palabra ¢s cualquier secuencia de carac- {eres que no contiene espacio en blanco ni tabulacion ni nueva tinea. Esta es una version reducida del programa we de UNIX. include #detine IN 1 /+ on ana palabra «/ #dotine OUT © + fuera de una palabra «/ J+ cuania lineas, palabras, y caracteres de la entrada «/ { int c, nl, aw, nc, state; 22 INTRODUCCION GENERAL tate = OUT; al = aw = ne = = getchar( t= EOF) print! (*9d %6d 96d\n", nl, aw, ac); } Cada vez que el programa encuentra el primer cardcter de una palabra, conta- biliza una palabra mas. La variable state registra si actualmente el programa esta © no sobre una palabra; ali asigna el valor OUT. Es preferible usar las constantes simbdlicas IN y OUT que los valores literales 1 y 0, porque hacen el programa mas legible. En un programa tan pequefio como éste i famas mis grandes «1 incremento en claridad bien vale el esfuerzo extra que se haya realizado para «escribir de esta manera desde el principio, Tambien se descubrird que es mas fécil hacer cambios extensivos en programas donde los mimeros magicos aparecen s6lo como constantes simbslicas. La linea al = aw = ne = 0; liza a las tres variables en cero. Este no es un caso especial sino una conse suencia del hecho de que una asignacién es una expresion con un valor, y que las asignaciones se asocian de derecha a izquierda. Es como si se hubiese escrito e== tabulador". (Recuerde que una representacién visible del cardcter tabulador.) ¢ operador && part AND; su precedencia es mas alta ue la de ||. Las expresiones conectadas por && o {| se evaldan de izquierda a la secuencia de esca © falsedad. Si ces un blanco, no hay necesidad de probar si es una nue- "8 0 un tabulador, de modo que esas pruebas no se hacen, Esto no es de SECCION 16 ARREGLOS 23 caso, pero es significative en situaciones mas com- das, como se vera mas adelante smplo muestra también un else, el cual especifica una accién alternativa a condicién de una proposicién if es falsa. La forma general es if (expresin) proposicin ele proposicién, icién,. Cada propesicion puede ser una prop\ ves. Fn el programa para contar palabras, la que esti d cl programa para contar palabras? (Qué clase ‘més conveniente para descubrir errores si éstos existen? ea), y de todos los lustrar varios aspectos de ‘Cen un programa. Existen doce categorias de entrada, por lo que es conveniente utilizar un arre- i en lugar de tener diez include (+ cuenta digios, espacios blancos, y ottos +/ main{ ) 24 wrrooucctow GENERAL carmmuvo1 ==. 4a, otrae = %d\n", white, nothex); I La salida de este programa al ejecutarto sobre si Aigitos = 93.0.0000001, espacios blancos = 123, otros = 345 La declaracién ‘nt ndigit [10]; declara ndigit como un arreglo de 10 enter comienzan en cero, por lo que Ios elementos Esto se refleja en los ciclos for qu Un subindice puede ser cualquier expresién enter: nteras como i, ¥ constantes enteras, Este programa en particular se basa en las propiedades de la representacin {de los digits como caracteres. Por ejemplo, la prueba W(e>=0 Sie <='9) el caracter en es un digito, Si lo 2s, el valor numérico del digito es En C, los subindices de arreglos to que incluye a variables SeCCION 16 AaRcaLos 25 leo (c= =" + + nwhile: leo + trother alse smo seha mostrado; larga secuencia de de- es podria rebasar el margen derecho de la pagina. Gn switeh, que: 0 3, propery larmente apropiada cuando ta 's determinar si alguna expr ra 0 de cardcter corresponde con latin miembro de un cenjunto de constantes. Para contrastar, se preseniard una Sersidn de este programa, usando switeh, en la seccidn 3.4, wprama dle las frecuen- lo entrada. 26 INTRODUCCIONGENERAL cartrutor 1.7, Funciones En lenguaje C, una furcién es el equivalente 4 una subrutina o funcién en Fortran, © a un procedimiento o funcién en Pascal. Una funcién proporciona tuna forma conveniente de encapsular algunos céleulos, que se pueden emplear después sin preocuparse de su implantacién. Con fanciones disefiadas adecuada- ‘mente, es posible ignorar cémo se realiza un trabsjo; es suficiente saber qué se hace. El lenguaje Chace que el uso de funciones sta facil, conveniente y eficien- te; es comiin ver una funcion corta definida y empleada una sola vez, anicamente porque eso esclarece alguna parte del codigo. Hasta ahora sélo se han utilizado funciones como printf, getshar y putcher, ‘que nos han sido proporeionadas; ya es et momento de escribir unas pocas no- otros mismos. Dado que C no posee un operador ce exponk de Fortran, ilustremos el mecanismo de la definicién de una funcional esc funcién pewer(m,n), que eleva un entero ma una potencia entera yp Esto 65, el valor de power(2,8) es 32. Esta funcién no es una rutina de expon ciacion prictica, puesto que solo maneja potencias positivas de enteros pe- quotios. pero es suficiente para ilustracién (la bi Funcida pow(x,y) que calcula 2%). ‘A continuacion se presenta la funcidn power y un programa main para utili zarla, de modo que se vea la estructura completa de una vez. ‘include int power(int m, Snt 2); ba ls funcién power «/ 3,0); return 0; power: eleva la base a la n-dsime potencia; n >= 0 +/ power(int base, iat n) int, pe can: +4i) pm P+ base: return i seCCIONI runcionss 27 jén de funcidn tiene te form: Una de siguiente: 1ipo-de-retorno nombre-de.funcion (declaracién de parimetros, si los hay) ‘ declaraciones ‘proposiciones mes de funcién pueden aparever en cualquier orden y en uno 0 varios fuente, pero una funcidn no puede separarse en archivos diferentes. Si a programa fuente aparece en varios archivos, tal vez se tengan que especificar nds cosas al compilar y cargerlo que si esta fe Se pone formato y se impr como lo son Z ¢ 4. (No todhs las funciones producen u ten el capitulo 4.) La primera linea de la funcién power, Int power(in base, iat n) declara los tipos y nombres de los pardmetros, la funcién devuelve. Los nombres que emplea cles a la funciOn y son iis iaalguno. Esto tamt variables i y p:la ide pow 1¢ nada que ver con la jente usaremes pardmetro ‘eal se empl El valor que cal Por medio de la proposicion re- ier expresi6n: cual le puede seg Una funcién no necesita regresar un valor; una proposicién return sin expresion hace que el control regreseal programa, pero no devuelve alain valor de utilidad, inal’ de una funcidn al aleanzar la lave derecha de incién que llama puede ignorar el valor que regress jente haya notado que hay una propos Puesto que main es una funcién como cualqui Valor a quien la invoca, que es en efecto el medio arn ‘en el que el programa 28 INTRODUCCIONGENERAL earrmuto idad, se han omitido hasta ahora las propo- es main, pero se incuirdn mds adelante, como un recordatorio de que los programas deben regresar su estado final a su medio am- biente. La deviaracion int power(iat m, int 2); indica que power es una funcién que espera dos ar- gumentos int y regresa un int. Esta declaracién, a la cual se le llama funcién pro- ‘otipo, debe coincidir con | i0n y uso de power. Es un error el que la defi- nicién cién 0 cualquier uso que de ellz se haga no corresponda con su prot Los nombres de los pardimetros no necesitan c vosen el prototipo de una funcién, de modo que pi escrito precisamente antes de mai de hecho, son pudo int power(in No obstante, unos nombres bien seleccionados seni una buena documentacién, por lo que se empleardn frecuentemente. Una nota histériea: La mayor modificacién entie ANSI C y las versiones ante- riores es cémo estén declaradas y definidas las funciones. En la definiciOn origi- nal de C, la funcién power se pudo haber escritc de la siguiente manera: J+ power lz base a n-ésima potencia; n >= 0 */ / (versién en estilo antiguo) +/ poner(base, 1) It base, n; { ' a la anterior.) jo del programa pudo haberse visto como sigue: revisar con facilided que power fuera llamada correctamente. De hecho, puesto SECON La ARGUMENTOS-LLAMADA FOR VALOR 29 ‘La nueva sintaxis de 0s prototipos de funciones permite que sea mucho mas facil para el compilador detectar errores en 1 numero o tipo de argumentos. El viejo estilo de deciaracién y definicién atin funciona en ANSI C, al menos por ida ampliamente que se utilice la nueva maneje. pilador que jo 1-48. Escriba ce nuevo ef programa de conversién de temperatura de ja sexcidn 1.2, de modo que ulice una funcién para la conversion. 1.8 Argumentos—llamadas por valor Hay un aspecto de lai funciones de C que puede parecer poco familiar a los programadores acostumtrados a otros lenguajes, particularmente Fortran. En C, {odos los argumentos de una funcién se pasan “por valor", Esto significa que la funcién que se invoca tecibe los valores de sus argumentos en variables tempo- rales y no en las original . esto conduce a eaborar programas mas compactos con pocas variables debido a que los pardmetros se tratan en la funcidn invocada como va Tiables locales convenientemente inicializadas. Por ejemplo, he aqui una version de power que utiliza ests propiedad. ‘+ power: eleva la base a la n-ésima potencia; n>=0; version 2 «/ Int power(int base, int x) { tat pi for (p = 1: 2 > 0;—n) $e bebe: return pi smporsl, y se decrementa (uy cero} ya no es necesaria lav de power no tiene efecto sobre Imente power. Cualquier cosa qi ‘mento con el que s 30 wrnoDUCCION GENERAL cariruLoy Cuando sea necesario, es posible hacer que una funcién modifique una va~ je dentro de una rutina invocada. La funcién que llama debe proporcionar ireccidn de la variable que ser cambiada ((éenicemente un apuntador a la var rable), y la funcion que se invoca debe declarar quel pardmetro sea un apun dor y tenga acceso a la variable indirectamente a través de él. Los apuntador se tratardn en el capitulo $. La historia es diferente con los arreglos. Cuando el nombre de un arreglo se igo es bastante simp! hile (hay otra tinea) larga que fa ancerior mds larga) ‘sudrdata ‘guarda su longitud imprime la lisee rds lrg Este pseudocddigo deja en claro que el programa s: divide naturalmente en par- tes. Una trae una nueva linea, otra la prueba y el resto controla el proceso, 1n-de las partes es muy fina, lo correcto sera esct ANREGLOS DE-CARACTERES 31 /+impnime la linea de entrada mas larga «/ main( ) ( it len; Js Jongitud actual de Ia linea »/ int max; (+ dxima longitud vista hasta el momento «/ char line[MAXLINE]; + linea de entrada actual «/ Ja linea mie larga se guarda aul «/ copy: copia ‘from’ en ‘copy(char tol], char i ypone que fo es ruficientemente grande «/ ) 1= 0 while trmlil) = ‘\0') 32. IeTRODUECION GENERAL eaprutos Las funciones getline y copy estan declaradas al principio del programa, q getline se comunican a través de un par de argumentos y un valor de retorno. En getline los argumentos se declaran por la linea tnt getline(char el], int lim) que especifica que el primer argumento, s, es un arreglo, y el segundo, lim, es un entero, El propésito de proporcionar cl tamaiio de un aiteglo es dealmacenamiento contiguo. La longitud del arreglo sno es necesaria en getlin puesto que su tamafo se fija en main. En getline se util un valor @ quién lo llama, tal como hizo la funcién power. Esta linea también declara que getline regresa un int; puesto que int es el valor de retorno por omi sin, puede suprimirse. Algunas funciones regresan un valor itil: oiras, como copy, se emplean i camente por su efecto y no regresan un valor. El tipo de retorno de copy €s void, cf cual esiablece explicitamente que ningun vaor se regresa, En gelline se coloca el caricter ‘\O' (candcter nulo, cuyo valor es cero) al final delarreplo que esti creando, para marear el fin dela cadena de caracteres. Esta con- vercidn también se utiliza por ol Ienguaje C: cuando una consiante de caracter como “hela\n” aparece en un programa en C, se almacena como wn arreglo que 16 105 caracteres de la cadena y termina con un ‘\Q' para marcar el fi. ble,’ ]-[wlo La especificacién de formato %s dentro de printf espera que el argumento co- rrespondiente sea una cadena representada de este modo; copy también se basa ‘enel hecho de que su argumento de entrada se termina con ‘\O', y copia este ca- rdcter dentro del argumento de salida. (Todo esto implica que “\O’, no es parte deun texto normal.) Es itil mencionar de paso que aun un programa tan pequefio como éste pre senta algunos problemas de diseito. Por ejemplo, gqué debe hacer main si en- ‘cuentra una linea que és mayor que sy limite? getline trabaja en forma segura, en ese caso detiene la recopilacién cuando el erreglo est cuentre el cardcter nueva linea, Probando la longitud y ¢! to, maia puede deierminar sila linea fue demasiado larga, y tratamiento que se desee. Por brevedad, hemos ignorado el asunto. Para un usuario de getline no existe forma de saber con anticipacién eudin » por lo que getline revisa ble desbor- ). Por otto lado, el usuario de copy ya conoce (0 10 puede averiguar) cual es el tamato de la cadena, por lo que decidimos no agregar comprobacién de errores en ella. SSECCION 108 VARIABLES EXTERNAS VALCANCE 33 Ejercicio 1-16, Corria la rutina principal del programa de la linea més larga de ‘modo que imprima ccrrectamente la longitud de lineas de entrada arbitrariamen- largas, y tanto texo como sea posible. Ejercicio 1-17. Escrita un programa que imprima todas las lineas de entrada que sean mayores de 80 caracteres. Ejercicio 1-18. Escriba un programa que elimine fos blancos y tos tabuladores que estén al final de cada linea de entrada, y que borre completamente las lineas, en blanco. © Fjercicio 1-19. Escrita una funcidn reverse( res s. Usela para escrbir un programa que invierta su entrada, linea a linea. © 1.10. Variables externas y alcance les que estén en maia, tal como line, longest, etc., son privadas . Debido a que son declaradas dentro de ion puede tener acceso directo a ellas, Lo mis slo cuando se lama 3 ta funcion, y desaparece cuando la funci6n por lo que tales variables son conocidas como variables auto ia terminologia de otros lenguajes. Aqui se izadas explicitamente en cada entrada. De no hacerlo, cont Como una alternativa a las variables automiticas, es pe que son exiernas a tocas las Funciones, esto es, Puede tener acceso por su nombre. (Este m de Fortran o a las vari do a que es pos! as pueden ser Usadas en lugar de lisias de argumentos para comunicar datos entre funciones. ‘Ademis, puesto que as variables externas se mantienen permanentemente en . en lugar de aparecer y desaparecer cuando se llaman y terminan las , Mantienen sus valores aun después de que regresa la funcién que los unci6n; esto fija un espacio de almacenamiento para ella. La var cbe declararse en caca funcidn que desee tener acceso a el de la variable. La deslaravion debe ser una prope puede estar impiicita en el contexto. Para concretar la 34 1NeTRODUCEION GENERAL cariTuLo programa de la linea mas larga con line, longest y max como variables externas, Esto requiere cambiar las llamadas, declaraciores y cuerpos de las tres funciones. ‘#include ‘#doline MAXLINE 1000 _/+ maximo tamato de una linea de entrada «/ st max; /+ méxine longitud vista hasia el momento «/ cchar line/MAXLINE]}; (nea de entrada actual +/ char longest{MAXLINE]; /s la Iinoa nds larga se quarda aqui +/ int getline( voi void copy(void); /* imprime la linea de entrada més larga; versién especializada “/ {nt en; extom int max: exter char longest}; max = 0; while (len = getline( )) > 0) M{ (max > 0) [+ huubo une linea +/ print(°%s", longest); retum 0; SECCION 110 VARIABLES EXTERNAS YALCANCE 35 ae J+ copy: versiés especializada »/ void copy(void) { int ‘extern chat ine{], longest{); i=; while (longest = +i non ! Las variables externas de main, getline y copy estén definidas en las primeras ineas del ejemplo anterior, lo que establece su tipo y causa que se les asigne expa- cio de almaccnamiento. Desde el punto de vista sintéctico, las definiciones exter- has son exactamente como les definiciones de variables locales, pero puesto que ‘ocurren fuera de las funciones, las variables son externas. Antes de que una fun- pueda usar una veriable externa, se debe hacer saber el nombre de la variable funciéa, Una forma de hacer esto ¢s escribir una declaraciOn extern dentro 4e la funcion; le declaracién es la misma que antes, excepto por la palabra reser- vada extern. Bajo siertas circun:tancias, la declaracién extern se puede omitir. Sila defini- ign de una variable externa ocurre dentro del archivo fuente antes de su uso por ‘una funeién en particular, entonces no es necesario el uso de una declaracién ex- tem dentro de la funcibn. La declaraci6n extora en main, gelline y copy es, por tanto, redundante. De hecho, una préctica comin, es poner las definiciones «te todas las variables externas al principio del archivo fuente y después of das las declaraciones extern. Sil programa estiten varios archivos fuente y una v ‘liza en archivo? y archivo3, entonces se neces ‘en archivo2 y archivos para conectar las ocurrencias de la variable. La prictica ‘Comin es reunir declaraciones extern de variables y funciones en un arc Failo, llamado histéricamente header, que es incluido por #includ y con- Fjercicio 2-1. Escriba us programa para determinar los rangos de variables char, long, tanto signed como unsigne valores apr: termine los rangos de los varios tipos de punto flotante, 2.3 Constantes dentro de un int también sera « se eseriben con wna wo U, terminal y el sufjo ul o UL indica unsigned tambiéx pueden ser seguidas por L para convertirlas en long y s unsigned: OXFUL es una constante unsigned long con valor de aciones numéricas tal como cualesquier ot Miinmente en comparadones con otros caracteres. Ciertos caracteres pueden ser representados en constante de carter y Por medio de secuencias de escape como \n (nueva linea); esas secuencias se ver 42, T1POS, OPERADORES YEXPRESIONES caprruLoa como dos caracteres, pero represenian solo uno, Ademas, un patron de bits ar- bitrario de tamano de un byte puede ser especificado por “\eoo" en donde ooo son de uno a tres digitos octales (0..7) 0 por ‘\ahat en donde hh son uno o mas digitos hexadecimales (0...9, a...f, A...F). Asi podria #daline VIAB‘\013"—_/s tab vertical ASCII «/ #deline BELL ‘\007 ——/» cardcier campana ASCII «/ 0, en hexadecimal, ‘#doline VTAB"\zh’—_/+ tab vortical ASCIL -/ #éeline BELL "\x? + cardcter campana ASCII «/ El conjunto completo de secuencias de escape es \acardeter de alarma (campans) \\. diagonal invertida \e retroceso \?inietrogacion \tavance de hoja \n nueva tinea \Fregreso de carro \ttabulador horizontal \W tabulador vertical nstane de cardicier_ “\O" representa el caracter con valor cero, el cardicter ‘\O" a menudo se escribe en ver de 0 pa de algunas expresiones, pero el valor numérico ¢s pr Una expresién constante es una expresidn que solo inmiscuye constantes. Ta- esiones pueden ser evaluadas durante la compilacién en vez de que se haga ipo de ejecucidn, y por tar que pueda encontrarse una coi ‘#detine MAXLINE 1000 char line [MAXLINE + 1}; \ehh numero hexadecimal la #define LEAP 1 _/+ on afos bisinstos+/ ‘nt days [91 +-28+ LEAP +31+20+91+30+ 91 +31 +90+31+90+31); stone de cadena o cadena literal, es una secuencia de cero o mis ca es encerrados entre comillas, como en "Soy una cadena’ "Ye la cadena vacia «/ SECoION23 CONSTANTS 43 Las comillas no son Farte de la cadena, sélo sirven pare delimitarla, Las mismas secuencias de escape utilizadas en constantes de caracter se aplican en cadena; \"" representa el carater comillas. Las constantes de cadena pueden ser con hiadas en tiem es equivatente a “ola, mando" estandar regresa la longitud de su argumento s de tipo cadena de caracteres, ex- cluyendo of ‘\O' terminal. Aqui est4 nuestra version: (* strlen: regrosa bt longitud de s */ = 40) de emuneracién. Una enumeracion eros constantes, como en ‘enum boolean (UO, YES}; El primer nombre en un enum tiene valor 0, el siguiente 1, y asf sucesivamente, ‘@ menos que sean especificados valores expl i no todos los valores son es- 44. “Tos. OPERADORES YENPRESIONES caprTuto2 pecificados, los valores 20 especificados continian la progresisn a partir del iltimo valor que si Io fue, como en el segundo de esos ejemp ‘enum escapes { BELL = “\a', RETROCESO = ‘\b', TAB ~ *\ NVALIN = ‘\n, VIAB = ‘\v, RETURN = ‘\r}, ‘enum months {ENE = 1, FEB, MAR, ABR, MAY, JUN, IL, AGO, SEP, OCT, NOV, DIC}; [+ FEB 6s 2, MAR es 3, etc. */ Los nombres que estan en enumeraciones diferentes deben ser ser distintos dentro de la misma enumer dad de revisarlus y depurador puede ser capaz de impri- mir los valores de variables de enumeracién en su forma simbélica, 2.4 Declaraciones ‘Todas las variables deben ser declaraclas antes de su uso, aunque ciertas decla- raciones pueden ser hechas en forma implicita por el contexto. Una declaracion specifica un tipo, y cantiene una lista de una o mis variables de ese tipo, como en Las variables pueden se distribuides entre las devlaraciones en cualquier forma; la lista de arriba podria igualmente ser escrita como char line{1000); Esta altima forma ocupa més espacio, pero es convenionte para agregar un co- mentario a cada deckacién 0 para modificaciones subsecuentes. Una variable también puede ser inicializada en su declaracidn. Si el nombre «5 seguido por un sigao de igual y una expresin, la expres sializador, como en seecion2s OPERADORESARITMETIOOS 45 flost spa = 1.02-5; Sila variable en cuestién no es automatica, izacién es efectuada sélo ‘una vez, conceptualmente antes de que el programa inicie su ejecueién, y el inicia- lizador debe ser una expresién constante. Una variable auromatica expliitamente la cada vez que se entra a la funcién o bloque en que const char migl] = “precauci La declaracion const también se puede utilizar con argumentos de tipo arreglo, i que la funsion no cambia ese arreglo: int strien(const cha Si se efectiia un intentode cambiar un const, el resultado estd definido por ta implantacién. 2.5 Operadores aritméticos Los operadores aritnéticos binarios son +, —, +, /, y el operador modulo %, La divisién entera trunca cualquier parte fraccionaria, La expresion x%y produce el residuo cuando x es: de a x exactamente. Por ejemplo, un afo es no entre 100, excepto aquellos afios que son di tos, Por lo tanto ((yoar 96 4 == 0 G5 year % 100 I~ 0) jj yoar % 400 ~ ~ 0) ‘printi(‘Sed os un ano bisiesto\n", year); alse rint{("96d no os un aflo bisiesto\n", year); por lo que es cero cuando y divi- El operador % no puece aplicarse a operandos float o dou! truncamiento para / y elsigno del resultado de % son depen maquina para operandos negatives, asi como la accidn que se toma en caso de sobreflujo, 0 subflujo. 46 1105, PERADORES Y EXPRESIONES ‘eaerTuto2 Los operadores binarios + y ~ tienen la misma precedencia, la cual es menor de *, /, y %, que a su vez esmenor que + y ~ unarios, Los s se asocian de izquierda a derecha. ‘La tabla 2-1 que se encuentra al final de este capitulo, resume la precedencia ¥ asociatividad para todos los operadores, 2.6 Qperadores de relacién y légicos: Los operadores de relacién son ‘Todos ellos tienen la misma precedencia. Precisumente bajo ellos en precedencia estdn los operadores de igualdad: == I= or que los operadores Los operadores de rela: “1 setoma como i < (lim-I miéticos, asi que una expresion come i < ‘como se esperaria. No & c != EOF; +41) lim=1 86 (c= gotchar{ de leer un nuevo cardcter es nevesario verificar que hay espacio para alma- snelarreglo 3, asi que la prucba i < lim debe hacerse primero. Ade. sia prucba falla, no debemos seguir y leer otro cardcter. ‘De manera seme desafortunado sie fuese probada contra EOF antes de que se llame a getchar; por lo tanto, la llamada y In asignacién deben ocurrit antes de gue se pruebe el cardcter ©. La precedencia de && es més alta que la de jj, y ambas son menores que los operadores de relacién y de asignaci6n, asi que expresiones como iclim—1 && (c = gotchar{)) != ‘\a' G& ¢ != EOF no requieren de paréntesis nales. Pero puesto que la precedencia de ! = es superior que la asignacién, los paréntesis se necesitan en (e = getchar( )) != “\n! para obtener el resultado deseado de asignacion a c y después comparacion con An. s#0C10N27 CONVERSIONES DE TIPO 47 Por definicida, el valor numérico de una expresién de relacion o logica es 1 sila relacidn es verdadera, y 0 si la relacién es falsa, El operador unario de negacién | convierte a un operando que no e¢ cero en 0, ¥ 4 un operando ce‘o en 1. Un uso comin de ! es en consirucciones como (\vélido) en lugar de if (valid = = 0) de cual es la mejor, Construcciones como Ivalido se no es valido"), pero otras mas complicadas pueden ser dificiles de entender Ejercicio 2-2. Escriba un ciclo equivalente a Ia iteracién for anterior sin usar && o 2.7 Conversiones de tipo Cuando un operador tiene operandos de tipos diferente: comin de acterdo con un reducido numero ro a punto flotante en una expresién como { + i, Las expré sentido, como utilizar un float como subi nes que podrian perder informacién, como asignar un tipo mayor de punto flotante a un entero, pueden producir una advertencia, pero en ciertas clases de transformacién de caracteres. Una es ejemplificada con esta in- genua implantacion dela funcidn atoi, que convierte una cadena de digitos en su equivalente numérico, [> alos: convierte s en entero «/ int atoi(char s{]) 4 sats, 9; nag for (1 = 0; ah] >= 0 &é&s| n= lea + (ch return 3; <=) +4) 48, T1P0s, OPERADORNS Y EXPRESIONES carrito ‘Tal como se discutié en el capitulo 1, la expresion da el valor numérico del cardcter almacenado en ,, forman una secuencia ascenderte contigua. ‘0 ejemplo de conversién de char a intes lz funcion lower, que con caricter sencilla a mimiscula para el conjunto de caracteres ASCII. Si el cardcter no es una letra mayiscula, lower lo regresa six cambio, jerle © a mindscula; solamente ASCH |. debido a que los valores (eo >= 'W S&e c= 2) return © + ‘a! —/A; else return ci } Esto funciona para ASCII debido a que las correspondientes letras mayisculas y miniisculas estin a una distancia fija como valores auméricos y cada alfabeto 5 contiguo —no hay sino letras entre Ay Z. Sin embarg 1a obse ‘la para el conjunto de caracteres EBCDIC, asi que este codigo: algo mis que sblo letras en ERCDIC. en el apéndice B, define una a independientes de el valor de la mplar la transportable para la funcion lower prueba. e>= USE <= puede reemplazarse por diate) Nosotros utilizaremos las funciones de en adelante. Existe un sutil punto acerca de la conversi6n de caracteres a enteros: El len ‘guaje no especifica si las variables de tipo char son valores con o sin signo. Cuan- do .un char se convierte a int, ;puede producit alguna vez un entero negativo? Larenpsers vara de una mdquine aot, sfonde diferencia nl arqulecti aracter que estt en el conjunto rracteres de impresion de la maquina sera 0, de modo que i 15 expresiones. Pero hay jue pueden sece1ona CONVERSIONES DE TIPO 49) 0s en algunas maquinas, aunque sean positivos en otras. dad, se debe especiticar signed o unsigned si se van a almace- fe no son raracteres en variables tipo char. fas expresiones de relacién como i > j y las expresiones légicas conectadas por &é ¥ |) estan definidas para tener un valor de I siendo verdaderas, y 0 al ser falsas. De este modo, la asignacién d=e>= Ubic<= 9 hace Ia d sic ¢5 un digito, y 0 si no toes. Sin embargo, las funciones como isdi- ‘ueden regresar euslquier valor diferente de cero como verdadero. Ent la parte de-validacién de if, wh le, for, etc., “verdadero” es slo diferente de cero”, por Jo que esto no hace diferencia, Las conversiones avitméticas implicitas trabajan como se espera. En general, siiun operador como + 0 + que toma dos onerandos (operador binat operandos de diferentes tipos, el tipo “menor” es promovido al tipo “superi antes de que la operaciin proceda. El resultado es el del tipo mayor. La seccién 6 del apéndice A establece las reglas de conversion en forma precisa. Si no hay operandos unsigned, sin embargo, el siguiente conjunto informal de reglas bas- tard parecer como ne transport Si cualquier operando es long double, conviértase el otro a long double. De otra manera, si cualquier operando ¢s double, conviértase el otro a do De otra manera, si cualquier operando es float, conviértase el otro a float. De otra manera, conviértase char y short a int. Después, si cuelquier operando es long, conviértase ef otro a long. Notese que los float que estan en una expresibn no se convierten automatica- mente a double; esto «s ua cambio de la de! ginal. En general, las fun- iones mateméticas como las de utilizarin doble precision, La razén cipal para usar float es ahorrar espacio de almacenamiento en arreglos gran con menor freaiencia, ahorrar tiempo en maquinas en donde la aritme- jue las comparaciones de val jentes de ia miquina, debido a que dependen de los a , supdngase que int es de . Entonces -1L < 1U, que 10, que es w Sigoad long: Pero1L > 1UL, debide aque Les prom parece ser un grin niimero positive, ‘a unsigned long ‘50 TIPO, OPERADORESY EXPRESIONES caprrutoa Las conversiones también tienen lugar en las asignaciones; ¢! valor del lado, derecho es convertido al tipo de la izquierda, el cual es el tipo del resultado Un cardcter es converuido a un entero, tenga o no extensién de signo, como se describié anteriormente. Losenteros mas largos son convertidos a cortos 0 a char desechiando el exceso de bits de mas alto orden. Asi en int i; char e: «1 valor de © no cambia. Esto es verdadero ya sea que se inmiscuya 0 no la ex. tension de signo. Sin embargo, el invertir el orden de las asignaciones podria producir pérdida de informacién. Sixesiloat ¢1 es int, entonces x = i¢i = xproducirin conversiones; de float 2 int provoca el truncamiento de cualquier parte fraccionaria. Cuando double se convierte a float, el que se redondee o trunque el valor es dependiente de la i plantacion, Puesto que un argumento de llamada a una funcién es una exoresion, tam- y double, Finalmente, la conversién explicita de tipa puede ser forzada (‘‘coacciona- da’) en cualquier expresién, con un operacor unario llamado cast, En la construccién (nombre-de-tipo) expresin la expresién es convertida al tipo nombrado, por las reglas de conversion anterio- res. El -adoprecisode un cast es como si a expresién fuera asignada a ‘variable del tipo especificado, que ye utiliza entonces en lugar de ta const ion completa. Por ejemplo, la rutina de biblicteca sqrt espera un argumento de doble precisién y producira resultados sin sertido si maneja inadvertidamente algo diferente. (sqrt esti declarado en nesun entero, pode- mos usar sart((doubl para convertir el valor dena doble siGn forzosa produce el valor 10 aropiado; n en si no se altera. operador cas’ tiene la misma alta precedencia que otros operadores unarios, co- no se resume en la tabla del final de este capitulo, ») pasirlo.a sqrt. Notese que la conver- se0C10N 24 ‘OPERADORES DE INCREMENTO Y DEERENENTO. 1 icin declara argumenios, como debe ser normalmente, argumentos cuando do el prototipo de la funcign sae Facion prod incién es Hamada. Asi double sqrt(double); lamada raie2 = sqrt(2); obliga al entero 2 a ser el valor double 2. a biblioteca esténdar incluye una implat unsigned long int next = 1; (+ rand: regresi un entero psaudoaleatorio en 0,,32767 +/ int rand(void) 1 next ~ next + 1109919245 + 12345; return (ansigned int)(next/65836) 96 32768; ) J+ srand: fija la somilla para sand() «/ vold srand(unsigted int seed) { Ejercicio 2-3. Escriba la funcién hoi hhexadecimales leme. Los next = seed: ia optativa) en su valor entero equiva permitidos son del Oal 9, delaaa laf, ydela Aa la F. 2.8 Operadores de incremento y deeremento El ienguaje C properciona dos operadores poco comunes para incrementar y decrementar variables. 3I operador de aumento + + agrega 1 a su operando, en ‘tanto que el operador de disminucion ~~ le resta 1. Hemos usado frecuentemen- te ++ para incrementar variables, como en file == \n) +4nl; 52. IPOS, OPERADORES V EXPRESIONES. capmutos después de que su valor se ha empleado. Es o significa que en un contexto don- deel valor esta siendo utilizado, y nosolo el efecto, + +n y n+ +son diferentes, Sia es 5, entonces xentt: asigna 5 a x, pero x= ttn; hace que x:sea 6. En ambos casos, n se hace 6, Los operadores de incremento, y decremento sélo pueden aplicarse a variatles; una expresion como (i+)) + + 5 ilegal. Dentro de un contexto en donde no se desea ningin valor, sino solo el efecto de incremento, como en prefljos y postfijos son iguales. Pero existen situaciones en donde se requiere es- pecificamente uno u otro, Por ejemplo, considérese la funcién squeeze(s.c), que todas las ocurrencias del cardcter © de una cadena s. sat 2) = Nop i+ 4) Cada vez que se encuentra un valor diferente de ©, éte se copia en Ia posicién actual j, y slo entoncesj es incrementada para prepararla para el siguiente carac- ter, Esto es exactamente equivalente a ‘Otro ciemplo de construccién semejante viene de la funcién getline que eseri- bimos en el capitulo 1, en donde podemos teemplazar we==% SeCCIONZY OPERADONES PARA MANEIODEIS $3 por algo més comprcto como w(e== let] =e: ‘Como un tercer 2jemplo, considérese que la funcién estindar « (+ atrcat: concatona t void strcat(char 1=\0) + encuentra a! fin de +) = ht +p = 00 Como cada cardcter se copia de t as, el + + pos para estar seguro; de que ambos estan en posi mismo trabajo pero regresa un apuntador a la posicion encontrads.) 0 9 Operadores para manejo de bits ! OR inclusive de bits ’ OR esclusive do bits << cortinionto a le iequierda >> cortiniento a le derecha ‘complomento a uno (unario) S4__TIPOS, OPERADORES YEXPRESIONES carrruLoz jor AND de bits & a menudo es usado para enmascarar algin con- por ejemplo, 2 = 8 80177; hace cero todos los bits de n, menos los 7 de menor orden. EL operador OR de bits | es empleado para encender bits: x = x| SET_ON; fija en uno a todos los bits de x que son uno en SET_ON. EL operador OR exclusive ~ pone un uno en cada posicidn en donde sus ope- randos tienen bits diferentes, y cero en donde son iguales. los operadores de bits & y | de los operadores lbgicos 8 uierda a derecha de un valor de verdad. Por ejemplo, six es I yy es 2, entonces x & y es cero en t Los operadores de corrimiento << y > > real rando que esti a la izquic nes de bits dado por el operando de la derecha, el cual debe ser positivo. Ast x << 2desplaza e} valor de x 2 a la derecha una cantidad signada llenard con bits de signo i inas y con bits 0 (“corrimiento logic io ~ da el complemento ¢ uno de un entero; esto es, con- viveversa. Por «i 0177700, que supone que x ¢s una cantidad de 16 bits. La forma transportable ‘no involucra un costo extra, puesto que “O77 esuna expresion constante que pue- de ser evaluada en tiempo de compi ion de algunos de los opercdores de bits, considere la fun- x,p.n) que regresa el campo de n bits de x (ajustado a la derecha) tres bits que estan en la J. gotbits: obliene n bite desde la posicién p +/ unsigned getbits(u i return (x >> (p+1 1 cortiendo a bits Fasia ta zquicrda con “O< Be} Si expr, y expr, son expresiones, entonces expr, op= expr 66 equivalente a 9pm, = (exon ex ¢ los paréniesis alrededor mando que expr, se ca xezytl significa xexeGe) xexeytl bits en Ten su argu- 6 TIPOS.OPERADORES Y EXPRESIONES ‘cavrruvoz x >>= 1) ) yyeallyypelp3+ 4] + yypvipl+p2]] += 2 Loperador de asignacion hace al e6digo mis féci de entender, puesto que el lee icat arduamente que dos exptesiones muy largas son en reali- © preguntarse por qué no lo son, y un operador de asignacién puede sompilador a producir ebdigo més eficiente, ‘Ya hiemos visto que la proposicién de asignacion tiene un valor y puede estar dentro de expresiones; e ejemplo mas comin es while ((c = get EOF) LLos otros operadores de asignacion (+ =,~=, de expresiones, aunque esto es menos frecuent En todas esas expresi ipo de una expresin de asignaciGn es el tipo de su operando del lado izqu ysu valor es el valor después de la asignacién. Ejercicio 2-9. En un sistema de niimeros de complemento a dos, x & = (x=1) bo- tral bit 1 dems la derecha en x. Explique el porque. Utilice esta observac ata escribir una version mas répida de bitcount. () también pueden estar dentro CCIOND. PRECEDENCIAY ORDEN DEEVALUACION 87 wéximo de a y b. La expresidn condicional, eserita con el opera proporciona una forma altemativa para escribir ésta y otras En la expresin expr, 2 expry expr, la expresion expr, es evalsada primero. Si es diferente de cero (verdadero), en es un int, entonces la expresién (> O?tsn 6 de tipo float sea n postivo 0 no, son necesarios alrededor de ta primera expt i yb separada por un blanco, y con cada linea (in nueva linea Rjercielo 2-10. Reescriba ta funci6i + que converte letras mayusculas © mlateclas, con una exprsioa condical en vex de un tbebe. G 2.42 Precedencia y orden de evaluacién La tabla 2-1 resume las reglas de presedencia y asociatividad de todos los ope: Fadores, Jo aquelos que atin no se han tratado. Los operadores que ‘tan en la misma linea tieen la misma precedencia; los renglones estin en orden ‘88 TIFOS, OPERADORES ¥ EXPRESIONES ‘eaprreLo2 de prevedeneia deereci cedencia, la cual es mds alta quela de + y ~ binarios. EL )serefiere ala llamada a una funcién. Los operadores —> y.. son utilizados para tener acce- os en el sizeof (x & MASK) = = 0) deben ser completamente colocedas entre parér! piados. is para dar los resultados apro- TAILA 241, PRECEDENCIA ¥ ASOCIATIVIDAD DE OPERADORES OvERADORES Asociarivinan Tequierda a derecha += 8 (apo) siz00! Los +, —,y # unatios, tienen mayor precedenda que las formas binarias. Como muchos lenguajes, C no especifica el orden en e! cual los operandos de SECCION2 2 PRECEDENCIAY ORDEN DE EVALUACION $9 De manera semejan n no esti expec fi printi(*96d %6d\n", + +n, powe ede producir res tos compiladores, dependiendo de es inerementada antes de que se llame a power. La solucién, por supuesto, es escribir /+ EQUIVOCADO «/ printi('%8d Yed\a", 2, power( ss dependencias all = i++; s compiladores respuestas de. in especifica: tun cédigo que dependa de! orden de evaluacién es la préctica de programacién en cualquier lenguaje. Naturalmente, es nece- 10 si no sabe como se hacen las cosas en varias caprtutas Control de flujo control de flujo en ejemolos anteriores; agui completaremos el conjunto, y sere- mos mas precisos acerca de las discutidas con anteriorided. 3:1 Proposiciones y bioques Una expresion como x = 061+ + 0 printi(...) se convierte cn una propos! cidn cuando va seguida de un punto y coma, como en. x= 0; is pil ( En C, el punto y coma «s un terminador de proposicién, en lugar de un separa- dor, como 10 es en un L:nguaje tipo Pascal. Las llaves { y } se emolean para agrupar declaraciones y proposiciones dentro ie juesta 0 blogue, de modo que son icamente & encierran las propos Proposiciones miltiples después de un if, else, while o for. (Pueden declararse ‘variables dentro de ewalguier bloque: esto se expondra en el capitulo 4.) No hay Punto y coma después ¢e la Have derecha que termina un Bloque, 3.2 Itelse La proposicion if-else se Sintaxis es a para expresar decisiones. Formalmente, a if (expresin) proposicién, che proposicion; o 62 CONTROL DE FLUIO ‘eaprruLos vordadera (esto. en lugar de Mf [expresion != 0) Algunas veces esto es claro y natt Debido a que e else de cuando un else se omite de \ el else con el if anterior sin else mas cercaro. Por ejemplo, en tin > 0) it(a>b) ne rab; el else va con el if mas interno, como se muestra con el sangrado. Si eso no lo que se desea, se deben utilizar llaves para forzar la asociacién correct z= b; La ambigtiedad es especialmente perniciosa en situaciones como esta a inequivoca lo que | else con el if mi tar es anidados, seCCI0N}3 HSE 63 A propésito, nétexe que hay un punto y coma después de z = @ en >» one a=b to se debe a que gramaticalmente alle sigue una propesicicn, yuna expresion eon npre se termina con punto y coma, 3.3. Else-it La construccién if (expresin) proposiciin ‘proposicién s§ se evaliian en orden; si cualquier exprest jada con ella se ejecuta, y esto termina toda ta cadena. Co- grupo deniro La parte del cuando ringuna de las of S05 no hay una accion expl else proposicisr el Final puede ot ede utiizarse para deteccién de errores al atrapar ion de tres vias, se muestra una mn de bisqueda bi- Tara que decide si ur valor particular de x se encuentra en el arreglo ordenado ¥. Los elementos de vdeben estar en orden ascendente. La funcidn regrexala po- sicién (un mimero enize 0 y n=l) six estd en v, y ~1 si n0 €s as ‘La busqueda bina‘ia primero compara el valor de entrada x con el elemento a bisqueda se enfoca fad superior medio de 64 CONTROLDEFLUIO ‘eaprruLoa 1ad seleccionada. Este proceso de dividir en dos continia hasta que se en- lor o ya no binsearch: anc int Binsearch(in i eel] <=... <=vio int low, high, mid; low = 0; high = n-1; while (low <= hich) { mid = (low+ high) /2; Wo < vimial) high = mid ~ ele if (x > v [+ no se enconiré =/ retara “1; Ladecisién fundamental es six es menor que, mayor que o igual al elemento me- dio v{mid] en cada paso; esto es un [else-i) natural. Bjerciclo 3-1, Nuestra busqueda binaria realiza dos pruebas dentro del cicloy cuando una podria ser suficiente (al precio de mis pruebas en el exterior) Esc tuna version con sélo una prueba dentro del ciclo y mida la diferencia en tiempo. de ejecucién. 3.4 Switch La proposicién switch ¢s una decisién multiple que prueba si una expresigr coincide con uno de un niimero de valores constantes enteros, y traslada el cor trol adecuadamente. (expresién) { case exp-const: proposiciones ‘cate exp-const: proposiciones detault: proposiciones |. Todas las expr default sec) swiTcH 65 SECCION.4 acelin alga: las ocurrencias de cada ido una secuencia de printf ed", nai printf", espacios blancos ="%6d, otros = %d\n", ) La proposicién break provoca una salida inmediata del switch. Puesto que los [Case] sirven sdlo como etiquetas, después de que se tino, la ejecucion pasa Pa lun switch son break y re- Inmediata de los ciclos waile, for y do, como se vera mas adelante en este capit 66 CONTROL DERLWIO caprmuto3 en parte bueno y en parte no. Por et lado positive, simple, como con los 3.5 Ciclos—while y tor Ya hemos encontrado 10s ciclos while y for. En la expresion se evalita, Si es diferente de cero, ie ejecuta la proposicién y se reeva liia la expresidn. Este cielo continua hasta que la expresin se hace cero, punto ar después de la propasicion proposicion exe=pto por el comportamiento de continue que se describe en la seccibn 3.7. mente, las tres componentes de un ciclo for son expresiones, Por Jo comun, expr, y expr, son asignaciones o llamadas a funcién y expr, es uma eX presién de relacion. Cualquiera de las tres partes se puede omitir, aunque deben permanecer los punto y coma. Si expr, 0 expr, se omite, slo se desecha de lt SECCIONIS CICLOS-WLEYFOR 67 expansi6n. Si la prueta expr, no esti presente, se toma como permanentemente rdadera, asi que ', que presumiblemente sera interrumpida por otros ‘medios, como un breek o un return. El usar while o for es principalmente cuestién de preferencia personal. Por ejemplo, en while (c = getchar( e=="\ Js ignora caractores expaciadores ==40 no hay inicializacion o reinicializacién, por lo que el while es més natural. El forse prefiere cuando existe una ini incrementos, pa {que mantiene las propesiciones de control del ciclo juntas y visi del mismo. Esto es mas obvio en for = O.4< mitt) que es la forma caracteristica de procesar lox en C, lo analogo al cicle DO de Fortran: sia no es perfecta puesio que tanto el te, considere que es un izacibn e incremento opera: van para acciones de cor aqui esta in| de ato para convertir Esta es ligeramente més general que Ia del ‘en blanco previos al niimero, y los signos que realiza la misma conversion para nume- Como un ejemplo mas amy luna cadena a su equivatente num capitulo 2; trata tambien los esp 0s de punto flotante.) La estruetura del programa ref la forma de la entrada: a parte entra y conviériela Cada paso realiea su SECCIONIS cactos-WiLEY FOR 69 68 CONTROLDERLUIO, earrrucos que llega a cero. El ciclo intermedio recorre los elementos. El ciclo mas interno. compara cada pareja de elementos que esta separada por el espacio gap einvierte ie estén desordenadas. Puesto que gap finalmente se reduce a uno, todos {os elementos se ordenan correctamente. Nétese cémo la generalidad del for hace que él ciclo mas exterao coincida con la forma de los otros, aun cuando no es tuna progresion aritmé.ica. Un titimo operador de C es la coma ‘*,"", que frecuentemente encuentra uso ena proposicién for. Una pareja de expresiones separadas por una coma se eva. hula de izquierda a derecha, y el tipo y valor del resultado son e! tipo y valor del operando derecho. Asi, en una proposicidn for es posible colocar expresiones lesen las diferentes partes, por ejemplo, para procesar dos indices en para- to se ilustra en \a funcién rovorso(s), que invierte a la cadena s en el mis mo lugar, #include a entero; versién 2 +/ Js tgnora espacio en blanco «/ J+ quora el signo «/ Hiaclade return sign +n; |+ reverse: invisrte la cadena s on el mismo lugar +/ void reverse(cha: cca estindar proporciona una funciSn mais elaborada, striol, para conversion de cadenas a enteros largos; véase la seccién 5 del apéndice B. ‘Las comas que separana los argumentos de una funcién, las variables en declara- ciones, ete., ma son operadores coma, y no garantizan evaluacién de izquierda 8 derecha, Los operadores cona deberin utilizarse poco. Los usos mas adecuados son en construcciones fuertemente relacionadas una con la otra, como en el ciclo for de reverse, y en macros en donde un célculo de paso miltiple debe ser una expre- sién simple. Una expresién coma podria también ser apropiada para el intercam- bio de elementos en reverse, donde el intercambio puede ser a través de una operacion simple: for( J+ shollgort:ordene vi0}..vin-I void shellsort(int vi), { int oa, 3, 1, temp; for (gap = w/2; gap > 0; gap /= for (1 = gap} i ’s Desire! El trabajo se ajusta ordenadamente en tres partes: while (hay otra tinea) (le tinea contiene el porrin) ¢s getline, funzion que ya escribimos en e que alguien ya nos proporcioné. Esto signi rutina para deddir sila linea contiene una ocurren- cia del patron. Podemos resolver ese problema escribiendo una funcién strindex(s,t), que re~ aresa la posicién o indice en la cadena s en donde comienza Ia cadena t, 0 ~1 si 8 no contiene t. Debido a que los arreglos en C pr 10s indices seran cero 0 positives, y as{ un va.or negati para sefialar una falla. Cuando posteriormente se necesite una isefto,Hlenar los detalles del programa es simple. , de modo que se puede ver eémo las piezas quedan: pauron que se buscard es ume cadena literal, lo cual no mecanismo mas general. Regresaremos ex breve a una discusién sobre como. iializar arreglos de caracteres, y en el captulo S mostraremos cémo hacer que patron de caracteres sea un pardmetro fijado cuando se ejecuta el programs. eramente diferente de getline, que se podré compa rar con ki del capitulo SteCION 4 CONCEPTOS BASICOS DE FUNCIONES 17 # include ‘#deline MAXILINE 1000 + longitud maxima por linea de entrada +/ tnt gelline(char line], int mex); int strindex(cher sourcel), char searchior{}); char patiors J+ patrén por buscar +/ Jvencwentra to¢as las linaas que coincidan con el patron +/ main () { ‘char line[MAXLINE}; int found = 0; while (gotlino(line, MAXLINE) > 0) if (stnndex(line, pattern) > = 0) { ‘printi("%68", line); found ++; 1 roturn foud; } (> getline: trae linea y la pone en s, regres su longitud «/ {nt galline(char af], iat lim) { fiat ©, i= 0; ‘while (im > 0 && (e=getchar) != EOF && ¢ !="\n) ali tess (+ strindex: reyresa el fadice de t ea #,~1 a1 no existe +/ ‘nt strindex(char s{ , char t{ 1) 78 FUNCIONES VLA ESTRUCTURA DEI PROGRAMA canttuto ¢ (ke > 0 6 tik] ==) rotara {: ) seturn “1; ) Cada definicién de fi tipo-regresodo nombrevde-funcidn(declaraciones de argumentos) ( ) declaraciones y propasiciones Varias partes pueden omitirse; una furcién minima es es algunas: i para reservar lugar al desarrollar un programa. Si el tipo que regresa 5 se supone int, rograma es solo un conjunto de det icin entre funciones ¢s por argumentosy valores regresados por las f clones, y através de variables externas. Las funciones pueden presentarse en ct uier orden dentro del archivo fuente, y el programa fuente se puede dividir varios archivos, mientras {as funciones no se dividan, Laproposicién raturn es el mecanismo para que la funcién que se llama se un valor a su invocador. Al return lc puede seguir cualquier expré retum expresién La expresién se convertiré al tipo de retorno de ta funcién si es necesario. Frecuencia se utilizan paréat fa encerrar la expresidn, pero son optative ‘La funcién que llama tiene la libertad de ignorar el valor regresado. Inch no hay necesidad de una expresién después de rotu jones de variables y funciones, la funci lemente un signo de protlemas, lor desde un lugar y ninguno desde otro. En cualquier caso, regresa explicitamente un valor, su ‘velor” es ciertamente basur El programa de biisqueda del patrOnregresa un estado desde main, el nmero de coincidencias encontradas. Este valor esta disponible para ser empleado el medio ambiente que llamé al programa. Ei mecanismo de cémo compilar y cérgar un programa en C que reside en va archivos fuente varia de un sistema 2 otro, En el Ja orden ce mencionada en el capi sreciow 42 PUNCIONES QUE REGRESAN VALORES NO-ENTEROS 79 {res funciones se clmacenan en tres archivos Hamados main.c, geiline.c, y strin- dex.c. Entonces @ orden cc main.c gelline.c strindex.c sitdia el cédigo objeto re 0, y después los carge fe en Los archives compila los tres archivos, ols aie un error, digamos en main.c, ese archivo pue- ismo y el resultado cargado con los archivos ob- " contra ".0” para distinguir los archivos fuente de que regresa la posicién de la ocu- Ejersicio 4-1, Escriba la funcién strrindo: no hay alguna. rrencia de més ala derecha de t 4.2. Funciones que regresan valores no enteros Hi de funciones han regresado 0 ningin valor (void) funcién debe regresar alzo de otro tipo? Muchas ciones numéricascomo aqrt, ain y eos regresan double; otras funciones especial zaclas regresan tipos diferentes. Para ilustrar e6mo tratar con esto, eserib ‘wemos la funcicn atof(e), que convierte la cadena s a su valor equivale panto flotante de dot La funcién atof es una extensién de 1a ahora ‘os ejempl 2Qué pasa si Primero, atofpor si misma debe deciarar el tipo del valor que regresa, puesto . E] nombre del tipo precede al nombre de la funcién: #include cadens # a double +/ double val, power: fat 3, sign for (1 = 0; isspace(siil}: ++) /* ignora espacios blancos +/ sign = (i) <= 7D

También podría gustarte