Está en la página 1de 153
_ LENGUAJE DE / PROGRAMACION EDICION EN INGLES UNIX es una marca repistrada AT & T ENGUAJE DE PROGRAMACION © ‘Traducido de la segunda edicion en inglés de: ‘THE C PROGRAMMING LANGUAGE 1.0 parcial de esta obra, por cualquier medio o método sin autorizacion escrita del editor DERECHOS RESERVADOS © 1991 respecto a la segunda edicion en espaol por PRENTICE-HALL HISPANOAMERICANA, S.A. Alacornulco Nim, 500-5? Piso Col Industrial Atowo 53519, Naucalpan de Jur, Edo. de México Miembro de Ia Camara Nacional de la Industria Editovial, Reg. Nim, 1524 ISBN 968-880-205-0 ISBN 0-13-110362-8 IMPRESO EN MEXICO / PRINTED IN MEXICO Prefacio Prefacio a ta primera edicion Introduccién lo 1, Introduceiin general ‘Comencemss Variables y expresiones aritméticas La proposiién for CConstantes simbdlicas Entrada y salida de caracteres Arreglos Funciones ‘Argumento;—llamada por valor 9 Arreplos de caracteres 10 Variables externas y alcance Capi 1 1 1 1 1 1 1 1 1 Capitulo 2, Tipos, operadores y expresiones 2 Nomibres de variables 22 Tipos y tamaiios de datos 23 Constanes 214 Dectaraciones 2S. Operadores aitméticos 26 Operadores de relacion y Wgicos 2.7 Conversions de tipo 28 Operadores de incremento y decremento 39. Operadores para manejo de bits 2.10 Operadores de asignacion y expresiones 2.11 Expresiones condiconales 212 Precedencia y orden de evaluacign lo 3. Control de flujo 3.1 Proposiciones y bloques CONTENIDO ix 3.7. Break y continue 3.8 Goto y etiquetas lo 4. Funciones y ta estructura del programa 4.1. Conceptos basicos de funciones 42 alores no-enteros 43 44 4.11 EI preprocesador de C Capitulo 5. Apuntadores y arreglos 5.1 Apuntadores y direcciones 5.2. Apuntadores y argumentos de funciones 5.3. Apuntadores y arreglos 5.4 Ariumética de direcciones 5.5 Apuntadores a caracteres y funciones 5.6 Arreglos de apuntadores; apuntadores a apuntadores 5.7. Arreglos multidimensionales 5.8 Inicializacion de arreglos de apuntadores 5.9 Apuntadores vs. arreglos multidimensional 5.10 Argumentos en la linea de comandos 5.11 Apuntadores a funciones 5.12 Declaraciones complicadas 5. Estructuras Conceptos basicos sobre estructuras Estructuras y funciones Arreglos de estructuras Apuntadores 0 estructuras Estructuras ferenciadas Buisqueda en tabl Typedet Uniones ‘Campos de bits 105 de longitud variable to—seanf 7.6 Manejo de errores—stderr y exit Alcance y ligadura Preprocesamiento Gramatica 9 Senales: Funciones de fecha y hora: Apéndice C. Resumen de nodificaciones Prefacio El mundo de la computacién ha suftido una revolucién desde la publicacién, en 1978, de £! lenguaje de programacién C. Las grandes computadoras son aho- ra mucho mas grandes, y las computadoras personales tienen capacidades que ri- valizan con los me cambiado en ese La creciente popularidad de C, los cambios en el lenguaje a lo largo de los aios, y la creacién de compiladores por grupos no involucrados en su diseito, se combinaron para demostrar la necesidad de una definicidn del lenguaje mas pre- cisa y contempordnea que la que proporcioné la primera edicién de este libro. En 1983, el Americas National Standards Institute (ANSI) estableci6 un cor ‘cuyos propésitos eran producit “una definicion no ambigua del lenguaje Cc, dependiente de la maquina’, cuidando la conservacion de su es do es el estandar ANSI para el lenguaje C i pero no descritas en la primera cedicion, particularmente la asigna nal, y al mismo tiempo establece expliciamente cuales aspectos del lenguaje tienen aim dependensia de maquina. Esta segunda edicion de El lenguaje de programacién C lo describe tal como lo defini6 el estandar ANSI. (En el momento de escribir esta edicidn, el esténdar se encontraba en la eta: 3¢ esperaba su aprobacién a finales Tenguaje forma. En gene- isible es la nueva jodernos compiladores ma- ral esto no hace una forma de declaras nejan ya la may! x PREFACIO Hemos tratado de mantener la brevedad de lz primera edicién. Bl lenguaje C no es grande, y no le esta bien un gran libro. Hemos mejorado la exposicion de ccaracteristicas criticas, como los apuntadores, que son parte central en la progra- macién con C. Hemos redefinido los ejemplos criginales y agregamos ejemplos nuevos en varios capitulos. Por ejemplo, se aumexté el tratamiento de declarac nes complicadas con programas que convierten ceclaraciones en palabras y vice- versa, Como antes, todos los ejemplos se han probado directamente a partir del texto, el cual estd diseniado de manera que lo pueda leer la maquina. EI ape ‘manual de referencia, no es el estandar, sino que nuestra rencidn fue trasladar la esencia del esténdar a un espacio més pequeiio. Esté hecho con el dnimo de que proporcione una facl comprensién para los progra- adores, pero no como una definicidn del lenguaje para quienes escriben compi- ladores —ese papel proj es un resumen de las pos tiene el pro- pésito de ser una referencia para programadores, no para implantadores. En el apéndice C se offece un resumen de los cambios de la versién original. ‘Como mencionamos en el prefacio a la primera edicién, C “se lleva bien, en cen que aumenta m una década mas de expe ain lo sentimos asi. Descamos que ro le ayude a aprender et enguaje C y también c6 ‘Tenemos un profundo reconocimiento hacia los amigos que nos ayudaron a producir esta segunda edicidn. Jon Bentley, Doug Gwyn, Doug Mcllroy, Peter Nelson y Rob Pike nos dieron valiosos comentarias sobre casi cada pagina del bo- rrador de este manuscrito, Estamos agradecidos por la cuidadosa lectura de Al Aho, Dennis Allison, Joe Campbell, G. R. Emin, Karen Fortgang, Allen Ho- lub, Andrew Hume, Dave Kristol, John Linderman, Dave Prosser, Gene Spat- ford, y Chris Van Wyk. También recibimos tities sugerencias de Bill Cheswick, Mark Kernighan, Andy Koening, Robin Lake, Tom London, Jim Reeds, Clovis Tondo y Peter Weinberger. Dave Prosser respondi6 muchas preguntas detalladas acerca del estandar ANSI. Utilizamos extensivamente el intérprete de C++ de Bjarne Stroustrup, para la prueba local de nuestros programas, y Dave Kristol nos ofrecid un compilador ANSI C para las prucbas finales. Rich Drechsler nos la Brian W. Kernighan Dennis M. Ritchie Prefacio a la primera edicion Ces un lenguaje de programacién de propésito general que ofrece como ven- tajas economia de expresiGn, control de flujo y estructuras de datos modernos conjunto de operadores. Ademas, C no es un lenguaje de “muy alt “grande’’, y no est especializado en alguna érea especial de aplicacién, Pero su ausencia de restricciones y su generalidad lo hacen mas conveniente y cfectivo para muchas tareas que otros lenguajes supuestamente mas poderosos. Originalmente, C fue disefiado para el sistema operativo UNIX y Dennis Ritchie Jo implanté sobre el mismo en la DEC PDP-11, El sistema operativo, el compila- dor de Cy esencialmeate todos los programas de aplicacién de UNIX Gincluyendo todo el sofware utilizado para preparar este libro) estan escritos en C. También cxisten compiladores para la produccién en otras méquinas, incluyendo la IBM System/370, la Honeywell 6000 y la Interdata 8/32. El lenguaje C no esta ligado € ningin hardware o sistema en particulary es fécil eseribir programas que corre- sin cambios en evalquier maquina que mangje C. 1a finalidad de este libro es ayudar al lector a aprender cémo programat . Contiene una introduccién general para hacer que los nuevos usuarios se in cien lo mas pronto posible, capitulos separados sobre cada caracteristica impor- tante y un manual de referencia. La mayoria de las exposiciones estén basadas ‘nla lectura, escrituray revisién de ejemplos, mas que en el simple establecimien- to de reglas. En su mayoria, los ejemplos son programas reales y completos, no fragmentos aislados. Todos los ejemplos han sido probados directamente a partir del texto, el cual esta en forma legible para la maquina. Ademas de demostrar ‘c6mo hacer un uso efectivo del lenguaje, donde ha sido posible, tratamos de ilus- trar algoritmos utiles y principios de buen estilo y disefio. El libro no es un manual de introduccién a la programacién; se supone en él familiaridad con los conceptos basicos de programacidn, como variables, propo- siciones de asignaci6n, ciclos y funciones. No obstante, un programador novato deber ser capaz de leer y obtener los conceptos del lenguaje, aunque le ayudaria la cooperacién de un colega més experimentado, De acuerdo con nusstra experiencia, C ha demostrado ser un lenguaje agrada- ble, expresivo y versatil para una amplia variedad de programas. Es facil de apren- Aer y se obtienen mejores resultados a medida que aumenta nuestra experiencia on él. Deseamos que este libro le ayude al lector a usarlo correctamente n xii PREFACIO A LA PRIMERA EDICION Las criticas y sugerencias de muchos amigos y colegas han aumentado much simo los conceptos de este libro y ha sido un placer escribirlo. En par tro agradecimiento a Mike Bianchi, Jim Blue, Stu Feldman, Doug Mellroy, Roome, Bob Rosin y Larry Rosler que leyeron cuidadosamente las numerosas versiones. También agradecemos Al Aho, Steve Bourne, Dan Dvorak, Chuck Haley, Debbie Haley, Marion Harrris, Rick Holt, Steve Johnson, John Mashey, Bob Mize, Ralph Muha, Peter Nelson, Elliot 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- presién, Brian W. Kernighan Introduccién Ces un lenguaje de programacién de propésito general que ha sido estrecha- ‘mente asociado con el sistema UNIX en donde fue desarrollado puesto que tat el sistema como los programas que corren en él estan escritos en lenguaje C. Sin embargo, este lenguae no esté ligado a ningin sistema operativo ni a ninguna maquina, y aunque ima “lenguaje de programacién d su utilidad para escribir compiladores y sistemas operativos, se cficacia para escribir importantes programas en diversas di ‘Muchas de las ideas importantes de C provienen del lenguaje BCPL, desarro- llado por Martin Richards. La influencia de BCPL sobre C se continué indirecta- mente a través del lenguaje B, el cual fue escrito por Ken Thompson en 1970 para cl primer sistema UNIX de la DEC PDP-7, una variedad di yntimeros de punto fiotante de varios tamafios. Ademés, existe una jerarqufa de tipos de datos derivados, creados con apuntadores, arreglos, estructuras y unio- roposicién. Los apuntadores proporcionan una aritmética de direcciones inde- Pendiente de la maquina C proporciona las tonstrucciones fundamentales de control de flujo que se re- guieren en programas bien estructurados: azrupacién de proposicione: lecciOn de un caso entre un conjunto de ell while, for) 0 en la pat estructuras, uniones ivamente. Las va- ymalmente ‘*automaticas”, o creadas de nuevo con cad idn de una funcién no puede estar anidada, pero las variables wadas en una modalidad estructurada por bloques. Las funcio- es de un programa enC pueden existir en archivos fuente separados, que se com- ‘an de manera separada, Las variables pueden ser internas a una funcién, ‘temas pero conocides s6lo dentro de un archivo fuente, o visibles al programa completo, 2 INTRODUCCION Un paso de preprocesamiento realiza substitucién de macros en el texto del programa, inclusién de otros archivos fuente y compilacién condicional.. Ces un lenguaje de relativo “bajo nivel ". Esta caracterizacién no es peyora- tiva, simplemente significa que C trata con el miso tipo de objetos que la mayo- ria de las computadoras, Ilamense caracteres, mimeros y direcciones. Estos pueden ser combinados y cambiados de sitio con !os operadores aritméticos y 16- gicos implantados por maquinas reales. CC no proporciona operaciones para tratar directamente con objetos compues- tas 0 arreglos, No existen ope inque las estructuras pueden copiarse como una unidad. El lenguaje no define ninguna facilidad para de almacenamiento que no sea la de definicién estatica y la disciplina de pilas provista por las variables locales de func’ no emplea heap ni re- colector de basura. Finalmente, C en si mismo no proporciona capacidades de en- trada/salida; no hay proposiciones READ 0 WRITE, ni métodos propios de acceso a archi por funciones De manera semejante, C solamente ofrece un control de flujo franco, y lin condiciones, ciclos, agrupamientos y subprogramas, pero no multiprogramacién, operaciones paralelas, sincronizacion ni corn ‘Aunque la ausencia de alguna de esas capacidades puede parecer como una rave deficiencia (“significa que se tiene que llamar a una funeién para compa rar dos cadenas de caracteres?”), el mantener al lenguaje de un tamafto modesto tiene beneficios reales. Puesto que C es relativamente pequefto, se puede deseribir -. Un programador puede razo- izar en verdad la totalidad del nguaje Por muchos alos, Ia definicién de C fue el manual de referencia de la primera edicion de E1 lenguaje in C. En 1683, el American National Stan- dards Institute (ANSW) establecio moderna ¥ compret in resultante, el estandar ANSI 0 le definicion de C. La defi “ANSI C”, se esperaba fuera aprobada a fines d: 1988. La mayoria de las carac~ teristicas del estandar ya se encuentran soportadas por compiladores modernos. El estdndar esta basado en el manual de referencia original. El lenguaje ha ‘cambiado relativamente poco; uno de los propésitos det estandar fue asegurar que la mayoria de los programas existentes pudiesen permanever validos o, al me- nos, que los compiladores pudieran producir mensajes de advertencia acerea del nuevo comportamiento. Para la mayorfa de los programadores, el cambio ms para declarar y definir funciones. Usa declaracién de funcién ahora \eluir una descripeién de los argumentos de la funcién; la sintaxis de la n cambia para coincidir. Esta informacion extra permite que los compi- ladores detecten mas facilmente los errores causados por argumentos que no coin- ciden; de acuerdo con nuestra experiencia, es una adicion muy dil al Lenguaje, importante es una nue- LENGUAJE DE PROGRAMACIONC 3 Existen otros cambios de menor escala en el lenguaje. La asignacién de estr turas y enums n sencilla, Las propiedades de la aritmé signo, estin esclarecidas. El preprocesador es laborado. La mayor parte de esos cambios solo endran efectos secundarios para la mayoria de los progra madores. ‘Una segunda contribuci6n significativa dei estindar es la definicién de una bi- blioteca que acompaie a C. Esta especifica funciones para tener acceso al sistema ‘operativo (por ejemplo, leer de archivos y escribir en ellos), entrada y salida con Formato, asignacién de memoria, manipulacién de cadenas y otras actividades se- mejantes. Una coleccion de encabezadores (headers) estandar proporcionan un acceso uniforme a las declaraciones de funciones y tipos de datos. Los programas que utilizan esta biblioteca para interactuar con un sistema anfitri6n estan asegu- rados de un comportamiento compatible, La mayor parte de estrechamente modelada con base en la “biblioteca E/S idan otros sistemas. De nuevo, la mayoria de los pr dores no notaran mucho el cambio. Debido a que los tipos de datos y estructuras de control provistas por C son manejadas directamente por la mayoria de las computadora jecucion (run-time) requerida para implantar programas autoco 0s es pe- queha. Las funciones ce la biblioteca estndar Unicamente se llaman en forma ex: de manera que se pueden evitar cuando no se necesitan. La mayor parte Puede eseribirse en C, y excepto por detalles ocultos del sistema operativo, ellas ‘mismas son portdtiles Aunque C coincidecon las capacidades de muchas computadoras, es indepen- diente de cualquier arquitectura. Con un poco de cuidado es Facil escribir progra- ‘mas portatiles, esto es, programas que puedan correr sin cambios en tna variedad de méquinas. El estandar explica los problemas de la tran tun conjunto de constantes que caracterizan a la maquina en la programa, Cno cs un lenguajefuertemente tipificado, sino que, cacién de tipos ha side reforzada, La definicién original de C desaprob ermitid, el intercambio de apuntadores y enteros; esto se ha dar ahora requiere la edecuada declaraciGn y la conversién explicita que ya ha sido obligada por los buenos compiladores. La nueva declaracién de funciones £$ otro paso en esta direccién. Los compiladores advertirin de la mayoria de los Ettores de tipo, y no hay conversién automatica de tipos de datos incompatibles. Sin embargo, C mantiene la filosofia basica de que los programadores saben lo ue estan haciendo; silo requiere que establezcan sus intenciones en forn 10 cualquier otro lenguaje, C tiene sus defectos. Algunos de los operado- 1en Ja precedencis equivocada; algunos elementos de la sintaxis pueden ser 4 wwtropuccion mejores. A pesar de todo, yy expresivo para una ampl ha probado ser un lenguaje extremadamente efectivo variedad de programas de aplicacién El libro esta organizado como sigue. El capitulo 1 ¢s una introduccién orien- tada a la parte central de C. El propésito es hacer que el lector se inicie tan pronto como le sea posible, puesto que creemos firmemeate que la forma de aprender ‘un muevo lenguaje es escribir programas en él. La introduccién supone un conoci- ‘miento prctico de los elementos basicos de la pros 19 hay una explica- in de computadoras, de compi ficado de una expresién como n=n-+1. Aunque hemos donde fue posibl estructuras de datos y al cién, nos hemos conee En los capit pectos de C en mayor detalle y mas formalmente de lo que se hace en el ‘aunque el énfasis esté aim fn los ejemplos de programas completos, més queen fragmentos aislados. El tulo 2 trata de los tipos basicos de datos, operaciones y expresiones. El capi ructura de un programa —variables externas, reglas de alcance les y otros aspecios— y también abarca al pre~ ocesador. El capitulo 5 discute sobre apumtadores y aritmética de direcciones. pitulo 6 cubre estructuras y uniones. se cubren funciones y la rativo UNIX, concentrandose en entrada/saida, el sistema de archivos y la nacién de memoria. Aunque algo de este capitulo es especifico de sistemas UNIX, los programadores que usen otros sistemas de todas maneras encontrarén aqui de utilidad, incluyendo alguna comprension acerca de como esta implan- aver as{ como sugerencias para obtener un. cédigo portat El apéndice A contiene un manual de consulta del lenguaje. El informe oficial de la sinta embargo, esti ‘manual de const sta. El apéndice B es un resumen de la blioteca estandar, de nuevo mas para usuarios que para implantadores. El apén- dice C es un breve resumen de los cambios del lenguaje original. Aunque, en caso de duda, el estandar y el compilador en uso quedan como las autoridades finales sobre el lengt capitu.o 1: Introduccion general rapido como sea posible al punto en donde pueda escribir programas para hacerlo tenemos que concentrarnos en las bases: variables y constantes, a mmética, control de flujo, funciones y los rudimentos de entrada y salida, Hemos fuera de este capitulo las cara -as de C que son importantes para escribir programas més grandes, Esas caracteristicas incluyen intadores, estructuras, la mayor parte del rico conjunto de operadores de C, ias proposiciones para control de flujo y la bil Este enfoque tiene sis inconvenientes. Lo En cualquier caso, los programadores con experie ‘apolar del material que se encuentra en. rogramacién. Los principiantes deben complementatlo Programas semejantes a los aqui expuestos. Ambos grupos pueden utilizar e: lo como un marco de referencia sobre el cual asociar las descripciones mis idas que comienzen en el capitulo 2. Comencemos in nuevo lenguaje de programaci rograma por escribir ¢s el mismo para todos habilidad de crear el texto lo, ejecutarlo y des- nevanicos, 16do lo Este ¢s el gran obstaculo; para librarlo debe tener del programa de alguna manera, compi cubrira donde Con el dor demas es relativ En C, el programa para escribir “hola, mundo" es #include rmain( ) { priatl("hola, mando\n"); ' La forma de ejecutar este programa depende del sistema que se esté utilizan- do, Como un ejemplo especi ,0 UNIX se debe crear el programa en un archivo cuyo nombre termine con “.c"”, como hola.c, y después larlo con la orden ce hola. Sino se ha cometido algiin error, como la omisiin de un eardcter o escribir algo en forma incorrecta, la compilacién se hard sin emitir mensaje alguno, y creard un archivo ejecutable Hamado a.out. Si se ejecuta a.out escribiendo la orden a.out se eseribira hola, mundo En otros sistemas, las reglas seran diferentes, constltelo con un experto. Ahora algunas explicaciones acerca del programa en si. Un programa en C, cualquiera que sea su tama, consta de funciones y variables . Una funcién c¢ tiene proposiciones que especifican las operaciones de célculo que se van a re zar, ¥las variables almacenan los valores utilizados durante los cdlculos, Las fun- ciones de C son semejantes a las subrutinas y funciones de Fortran 0 a los procedimientos y funciones de Pascal. Nuestro ejemplo es una funcién llamada main. Normalmente se tiene la'libertad de dar cualquier nombre que se desee, pero ‘‘main’” es especial —el programa comienza a ejecutarse al principio de main. Esto significa que todo programa debe tener un main en algtin sitio. Por lo comin main llamara a otras funciones que ayuden a realizar su traba- jo, algunas que usted ya escribié, y otras de bibliotecas escritas previamente. La primera linea del programa. Wsnclade indica al compilador que debe incluir informacion acerca de la bibl dar de entrada/salida; esta linea aparece al principio de muchos archivos fuente de C. La biblioteca estindar estd deserita en el capitulo 7 y en el apéndice B. Un método para comunicar datos entre las funciones es que la llama proporciona une lista de valores, llamados argumenios, a ta invocando. Los parériesis que estan después del nombre de la fun ala lista de argumentos. En este ejemplo, main esta definido para ser que no espera argumentos, lo cual esti indicado por la lista vacia ( ). # include incluye informacion acerca de la biblioteca estindar main( ) define una funcion llamada main que 10 recibe valores de argumentos ( as proposiciones de main esti encerradas entre ilaves “hola, mundo\n"); ‘main tlama a la funcién de biblioteca print. t ara escribir esta seewencia de caracteres; \a representa el cardeter nueva linea EI primer programa en C _ Las proposiciones de una funcién estiin encerradas er cién main sélo contiene una proposici ola, mundo\n") réntesis; de esta maneca se est “hola, mundo\n"’, prntf es una funcidn de biblioteca que eve este caso la cadena de caracteres que se encuentra entre comil A una secuencia de caracteres entre co 1 cadena dle caracteres © constante de cade luso de cadenas de caracteres serd como argumentos para print! y otras fui La secuencia \n en la cadena representa el caracter nueva linea e! de C, y hace avanzar la impresién al margen izquierdo de la siguiente linea. S: Sc omite el \n (un experimento que vale la pena), encontrar que no hay avance le linea después de la impresion. Se debe utilizar \n para incluir un carcter nuue= ¥a linea en el argumerio de printf; sise intenta algo como “hola, mundo pri ” 6! compilador de C producicé un mensaje de error ULOL printf nunca proporciona una nueva linea automét se pueden utilizar varias llamadas para construir una Nuestro primer programa también pudo haber sido escrit imente, de manera que ea de salida en etapas, de la siguiente manera. include -produciéndose una salida idéntica, [Notese que \n representa un solo cardecter. Una secwencia de escape como \n proporciona un mecanismo general y extensible para representar caracteres in de escribir. Entre otros que C proporciona estén \t para tabula- in, \b para retroceso, \” para comillas,y \\ para la diagonal invertida, Hay una lista completa en la seccién 2.3. Ejercicio 1-1. Ejecute el programa “hola, mundo" en su sistema, Experimente con Ia omisidn de partes del programa, para ver qué mensajes de error se obtienen. Cr Experimente el descubrir qué pasa cuando la cadena del argumento i contiene \e, en donde c es algtin cardcter no puesto en lista anterior mente, O 1.2. Variables y expresiones aritméticas El iente programa utiliza la férmula °C = (5/9) (°P-32) para imprimir wiente tabla de temperaturas Fahrenheit y sus equivalentes c Is: SB2SR° 140 60 160 71 180 82 200 23 220 104 SECCION 12 VARIABLES V EXPRESIONES ARITMETICAS 240 115 ° int ahr, celsius; int lower, upper, step) lower = 0; J+ limite inferior de upper = 300; / limite superior step = 20; J+ tamano del incremento «/ abe while Las dos lineas Js imprime la tabla Fahrenhei para fahr = 0,20, ..., 300 +/ son un comentario, que en este caso expli Cualesquier caracteres entre /. brevemente que hace el programa. / son ignorados por el compilador, y pueden ados libremente para hacer a un programa mas entender. Los co- irios pueden aparecer en cualquier lugar donde puede colocarse un espacio en blanco, un tabulador o nueva linea, En C, se deben declarar todas las variables antes de su uso, generalmente al Drincipio de la funcién y antes de cualquier proposicién ejecutable. Una declara- idn notifica las propiedades de una variable; consta de un nombre de tipo y una ‘a de variables, como int fabr, celsius; int lower, upper, step; 10 INTRODUCCION GENERAL carrruto1 EI tipo int significa que las variables de la lista so1 enteros, en contraste con float, a punto fotante, esto es, mimeros que pueden tener una parte fraccio- por lo menos con seis digitos significativos y ura magnitud generalmente entre 10 y 10°*. ‘Ademds de int y loat, C proporciona varios tipos de datos basicos, incluyendo: char ccardcter —un solo bute short entero corto long entero largo double punto flotante de doble precisien Los tamafis de estos objetos también dependen de la mquina. También existen arreglos, estructuras y uniones de estos tipos basicos, apuntadores a ellos y funciones {que regresan valores con esos tipos, todo lo cual « verd en el momento oportuno. Los caleulos en el programa de conversién de temperaturas principian con las, proposiciones de asignacién, lower = 0; supper = 300; step = 20; fabr = 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 la misma manera por lo que se utiliza una iteracién que se repite una vez por cada linea de salida; este es el propésito del ciclo while while (fahr <= upper) { , El ciclo while funciona de la siguiente manera: se prueba la condicién entre pa- réntesis, De ser verdadera (fahr es menor o igual que upper), el cuerpo del ciclo (las tres proposiciones entre llaves) se ejecuta. Luego la condicién se prueba nue- vamente, y sies verdadera, el cuerpo se ejecuta de nuevo. Cuando la prueba resul- ta falsa (lahr excede a upper) la iteracién termina, y la ejecucién continiia en la proposicién que sigue al ciclo. No existe ningunaotra proposicion en este progra- ma, de modo que termina, El cuerpo de un while puede tener una o mas proposiciones encerradas entre Hlaves, como en el convertidor de temperaturas, ¢ una sola proposicién sin Haves, como en wb 1+ imprime la tabla Fahrenheit-Celsius para fakr = 0, 20, ..., 300; versién de punto flotante «/ main( ) { float far, celsius; iahr~22.0); fahr, celaue); fabs = fahr + step; SECCION \VARIABLES Y EXPRESIONES ARITMETICAS 13 Estoes dos como No pudimos truncaria a cero, Sin embargo, un punto decimal en una constante indica que ésta es de punto flotante, por lo que 5.0/9.0 no se trunca debido a que es una relacién de dos valores de punto flotante. ‘ene operandos enteros, se ejecuta una operacién ‘un operador numérico tiene un operando de punto flotante y otro ente- libimo sera cenvertido a punto flotante antes de hac Las reglas detalladas de cuindo los enteros se convierten a punto flotante se encuentran en el capitulo 2, Por ahora, nétese que la asignacién 1 = lower; y la prueba while hr <= upper) umbién trabajan en la forma natural —el int se convierte a float antes de efec- tuarse la operacién. La especificaciOn de conversion %3.0f del printf indica que se escribiré un iimero de punto flotente (en este caso fahr) por lo menos con tres caracteres de ancho, sin punto dedmal y sin digitos fraccionarios; %6.1f describe a otro ‘iimero (celsius) que se eseribird en una amplitud de por lo menos 6 caracteres, con 1 digito después del punto decimal. La salida se vera como sigue: 0 -178 202-67 40 44 amplitud y la precision pueden omitise de una espe n: 966f indica que Lmimero es por lo menos de seis earacteres de ancho; %.2{ indica dos caracteres, después del punto decimal, pero el ancho no esta restringido; y % indica escribir el mimero como punto flotante. Sa 66d et 688 14. INTRODUCCION GENERAL caprruLo+ wat scribe como punto flotante, can 2 caracteres después del punto decimal %96.2i —_escribe como punto flotante, per lo menos con 6 earacteres de aancho y 2 después del punto des mbién reconoce 9%o para octal, %x para hexadecimal, %e para cardcter, %s para cadena de caracteres y %% para % en si 1.3. Modifique el programa de conversion de temperaturas de modo iba un encabezado sobre la tabla. Ejercicio 1-4, Escriba un programa que imprima la tabla correspondiente Celsius a Fahrenheit. 1.3. La proposicién for Existen suficientes formas particular. Intentemos una vari tas de escribir un programa para una tarea en del programa de conversién de temperaturas, include int fahr, for (fahr = 0; fahr <= 300; fahr = fakr + 20) rint("$63d %6.16/n", far, (6.0/9.0)+(fahr 32); acdos, pero ciertamente se ve dil de la mayoria de las variables; s6lo permanece fahr y la hemos hecho ites inferior y superor y el tamafto del avance slo ‘aparecen como constantes dentro de la proposicién for, que es una nueva construccién, y la expresién que calcula la temperatura Celsius ahora aparece como el tercer argumento de printf en ver de una proposicién de asignacién sepa- rada. Este tltimo cambio ejemplifica una regla general —en cualquier contexto en cl que se flotante puede estar all uuna forma generslizada del wu operacién debe ser clara. Dentro de los paréntesis existen -ciones, separadas por punto y coma. La primera, la inicializacion fahr = 0 La propo con el seccION.4 CONSTANTESSIMBOLICAS. 15, se cjecuta una vez, antes de entrar propiamente al ciclo. La segunda seccién es la condicién 0 prueba que controla el fahr <= 300 Esta condicién se evahiz; sies verdadera, el cuerpo del ciclo (en este caso un sim- ple printf) se ejecuta. Después el ineremento de avance hr = fabs + 20 se ejecuta y la condicién se vuelve a evaluar. El ciclo termina sila condicién se hace alsa, Tal como con el while, el cuerpo del ciclo puede ser sencilla 0 un grupo de proposiciones encerradas entre llaves. La incremerto pueden ser cualquier expresién. mn entre while y for es arbitraria, y se basa en aquello que pi for es por lo general apropiado para ciclos en los que la ini més claro. cidn y el inererhento son proposiciones sencillas y Idgicamente rel to que es mas compactoque el while y mantiene reunidas en un lugar @ las propo- siciones que controlan al ciclo, Ejercicio 1-8. Modifique el programa de conversién de temperaturas de manera que escriba la tabla en orden inverso, esto es, desde 300 grados hasta 0. 0 1.4 Constantes simbélicas Una observacién final antes de dejar definitivamente el tema de la conversién. de temperaturas. Es una mala prictica poner ‘“nimeros magicos”” como 300 y 20 en un programa, ya que proporcionan muy poca informacién a quien tenga que leer el programa, y son cificiles de modificar en un forma sistem: ra de tratar a esos mimeros 1 nombre tiene la misma forma que un nombre de variable: una secuen- ras y digitos que comienza con una I texto de reemplazo puede Ser cualquier secuencia de caracteres; no esté limitado a niimeros. include 16 xTRODUCCION GENERAL J+ imprime la tabla Fahrenheit-Colsius + main() { int far; for (lahr = LOWER; printi("%43d %66 tidades LOWER, UPPER y STEP son constantes simbdlicas, no variables, Jue no aparecen entre las declaraciones. Los nombres de constantes encién, se escriben con waytisculas, de modo que se iimente de los nombres de variables escritos con mindsculas. [Nétese que no hay punto y coma al final de una linca #define. 1.5. Entrada y salida de caracteres Ahora vamos a considerar una familia de progrzmas relacionados para el pr. 10 cardcter. Se encontrar que muchos programas s6lo es ampliadas de los prototipos que se ‘ratan agus simple. La entrada y sal importar dénde fue originada 0 hacia donde se dirige, se tr ijos (streams) de caracteres. Un fi de caracteres divididos entre lineas, cada una de las cuales consta de cero 0 més caracteres seguidos de un cardcter nueva responsable de hacer que cada secuencia de entrada o salida e roporciona varias funciones para leer o escribir un getchar y putchar son las mas simples. Cada vez liente cardcter de enirada de una secuencia de tex- sde cardcter a la vez, de las eu getchar lee el 10 y lo devuelve como su valor. Esto es, d © = geichar( la variable c con! jente cardcter de entrada. Los caracteres provienen normalmente del teclado; la entrada de archivos se trata en el capitulo 7. La funcién putchar escribe un cardcter cada vez que se invoca: putchar(e) contenido de la variable entera c Las llamadas a putchar y a printi pueden estar alternadas; mo un caracter, generalmente en salida SECCION S| ENTRADA YSALIDADECARACTERES 17 4.5.1 Copia de archivos Con getchar y putchar se puede escribir una cantidad sorprendente de eédigo itil sin saber nada més acerca de entrada y salida. El ejemplo més sencillo es un programa que copia la entrada en la salida, un cardcter a la vez: lee un cardeter while (cardcter no es indicador de fin de archivo) ‘manda a ta salds el cardcter recién leido lee un cardctor Al convertir esto en C se obtiene include J+ copla la entrada a la salida; 1a, versién «/ main() into; como tn cardcter en otra cosa, almacenado bien puede ser usado cualquier tipo de entero. Usamos int por una sutil pero im- portante razén, EL problema es distinguir el fin de la entrada de los datos vilidos. La solucién 8 que getchar devuelve un valor distintivo cuando no hay mas a la entrada, un valor que no puede ser confundido con ningiin otro cardcter. Es EOF, por ‘end of file (fin de archivo)". Se debe declarar ¢ ino sea lo suficientemente grande para almacenar cualquier valor que le regrese get- char. No se puede utilizar char puesto que c debe ser suficientemente grande como para mantener a EOF ademas de cualquier otro caracter. Por lo imbélica, hemos asegurado que nada en el programa depende del valor numérico especifico 18 INTRODUCCION GENERAL carmuto1 EI programa para copiar podria escribirse de modo més conciso por progra- ‘madores experimentados de C. En lenguaje C, cualquier asignacién, tal como c= getchar() in puede aparecer cono pari cardcter a ¢ se coloca dent 16 while, el programa que copia puede es:ribirse de include J+ copia la entrada a la salida; 2a. versién «/ while (c = getchar putchar(c); = FOF) } El while obtiene un cardcter, lo asigna a e, y entonces prueba si el cardcter fue la sefial de fin de archivo. De no serlo, el cuerpo del while se cjecuta, escribiendo (¢ el while, Luego, cuando se alcanza el final de la entra- termina y también lo hace main. Esta versién centraliza la entrada —ahora hay solo una referencia a getchar— ante es mas compacto y mas facil de leer 4 seguido este s que estan alrededor de la de! = cs, ‘en ausencia de paréntesis la prueba de cin =. De esta manera, la proposicién © = gelchar( )!= EOF jdn != se realizaria antes de la asigna- s equivalente a © = (getchax( )! EOF) Esto tiene el efecto indeseable de hacer que c sea0 mada de getchar encontré fin de ar mas detall Ejer Ejercicio 1-7. Escriba un programa que imprima el valor de BOF. © dependiendo de si la 2 se trata este tema vio 1-6. Verifique que la expresién getchar ()!= EOF es 001. 0 ENTRADA YSALIDA DECARACTERES. 19 1.5.2 Conteo de caracteres El siguiente programs cuenta caracteres y es semejante al programa que copia, include / cuenta los care main() { s do la entrada; La. version «/ Jong ne; ac = 0; while (getch: 1= EOF) iene = me + 1, pero + +nees mas conciso y muchas veces més elieiente opetador correspondiente ~ para disminuir en 1. Los operadores ++ y jos (+ +-ne) como postfijos (n+ +); esas eites valores dentro de las expresiones, como se de- 102, pero ambos ++ne y ne-+ + incrementan a nc. Por el momento adoptaremo: la forma de prefijo. El programa para cortar caracteres acumula su cuenta en una variable long en lugar de una int. Los enteros long son por Jo menos de 32 Aunque en algunas méquinas int y long son del mismo tamano, en otras un int es de 16 con un valor maximo de 32767, y tomaria ivamente poca lectura a la entrada para desbordar un contador int. La especificacién de conversién %ld indica @ jorrespondiente es un entero long. para demostrar otra forma de escribir el #include J» cuenta los caracteres de la entrada; 2a. version «/ smain( ) { double ne; for (nc = 0; getchar( ) != EOF; + +nc) 4 '%.08\n’, ne); 20. metRODUCCION GENERAL carrruto joat como para double; %.0f suprime la impresion del punto decimal y de la parte fraccionaria, que ¢s cero. El cuerpo de este ciclo for estd vacio, debido a que todo cn las secciones de prueba ¢ incremento. Pero las reglas gramaticales de C requic- ren que una proposicién for tenga un cuerpo. Ei punto y coma aislado se llama proposicién nula, y esta aqui para satisfacer este requisito. Lo colocamos en una -a aparte para que sea visible. ‘Antes de abandonar el programa para contar caracteres, obsérvese que si la prueba del while o del for no tiene éxito desde programa produce cero, Esto es importante. Uno de los aspectos agradables acerca, y del for es que hacen la prueba al inicio del ciclo, antes de proceder con el cuerpo. Sino hay nada que hacer, nada se hace, aun si ello significa no pasar a través del cuerpo del ciclo. Los programas deben actuar en form: snte 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 frontera. printf utiliza %f tanto pare trabajo se realiza 1.5.3 Conteo de El siguiente programa cuenta lineas a la entrada. Como se meneioné anterior teca estandar asegura que una secuencia de texto de entrada pa- rezca una secuencia de ‘ada una terminada por un caracter nueva linea. ar caracteres nueva linea: include J+ cuenta las lineas de Ia entrada +/ El cuerpo del while con: mento + +nl. La proposic rentesis c que cont El de id = = es la notacin de C para expresar “igual a’ (como el = simple de Pascal o el .EQ. de Fortran). Este simbolo se emplea para SECCION 1 ENTRADA YSALIDA DECARACTERES 21 distingui uueba de igualdad del = simple liza C para la asignacion, Un mensaje de alerta: los principiantes de C ocasionalmente escriben = cuando cen realidad deben usar = =. Como se verd en el capitulo 2, el resultado es por neral una expresidn legal, de modo que no se obiendra ninguna advertencia, Un cardcter escrito entre apéstrofos representa un valor entero igual al valor numérico del cardcter en el conjunto de caracteres de la maquina, Esto se llama tuna constante de cardcier, aunque s6lo es otra forma de escribir un pequeno ente- ro. Asi, por ejemplo ‘A’ es una constante de cardcter; en el conjunto ASCII de car -est0 es, la representacidn interna del caracter A. Por su- puesto ‘A’ es preferible que 65: su significado es obvio, y es independiente de un conjunto de caracteres en particular. es de cadena tambien son le: simple, y en ex constante cadena que contiene s6lo un cardcter. En el capi de cadenas versus caracteres. Ejercicio 1-8. Eser y nuevas lineas. 6 Ejercicio 1.9. Escriba un programa que copie su entrada a la salida, reemplazando cada cadena de uno o més blancos por un solo blanco. 5 tun programa que cuente espacios en blanco, tabuladores Ejercicio 1-10, Escriba un programa que copie su entrada ala sal do cada tabulacién por \t, cada retroceso por \b y cada di \. Esto hace que las tabulaciones y los espacios sean visibles sin confusiones. 0) 1.5.4 Conteo de palabras El cuarto en nuestre serie de programas tities cuenta las lineas, palabras y ca- racteres, usando la definicién de que una palabra es cualquier secuencia de carac- teres que no contiene espacio en blanco ni tabulacién nj nueva linea. Esta es una versién reducida del programa we de UNIX. include define IN 1 /+ en una palabr define OUTO —_/ fuera de una palabra «/ J» cuenta lineas, palabras, y caracteres de la entrada «/ main() { int, al, nw, ne, state; 22. INTRODUCCION GENERAL eaprTuto1 state = OUT; al = nw = ne = 0; while ((c = getchar( )) != EOF) ( if(e == \n) rintf ("96d 9d d\n", nl, nw, ne); , Cada vez que el programa encuentra el primer cardcter de una palabra, conta- biliza una palabra més. La variable state registra si actualmente el programa est © no sobre una palabra; al iniciar es "*no esta sobre una palabra”, por lo que se asigna el valor OUT. Es preferible usar las constantes simbélicas IN y OUT que los valores literales 1 y 0, porque hacen el programa mas legible. En un programa inima, pero en programas mas grandes cl esfuerzo extra que se haya realizado para escribir de esta manera desde el io. También se descubrira que es més Facil hacer cambios extensivos en programas donde los mimeros magicos aparecen sélo como constantes simbélicas. La linea al = nw = ne = 0; inicializa a las tres variables en cero. Este noes un caso especial sino una conse- cueneia del hecho de que una asignacién es una expresi6n con un val las asignaciones se asocian de derecha a izquierda. Es como si se hul al = (nw = (nc = ‘sic ¢s un blanco 0 ¢ es nueva linea o ¢ es un tabuladoi secuencia de escape \t es una representacién vis se evaltan de izquierda a derecha, y se garantiza que la evaluacién terminard tan pronto como se conozca la verdad o falsedad. Si c ¢s un blanco, no hay necesidad de probar sies una nue- va linea o un tabulador, de modo que esas pruebas no se hacen. Esto no es de SECCION 6 ARREGLOS 23 particular importaneia en este caso, pero es significativo en situaciones mas com- das, como se Yerd mas adelante. .jemplo muestra también un else, el cual especifica una accién alternativa sila condicién de ina proposicién if es falsa. La forma general es it (expresicn) proposicién, else roposicién, én puede ser una proposi el programa para contar palabras, la que estd d que controla dos proposiciones entre laves, iCémo probaria el programa para contar palabras? {Qué clase més conveniente para descubrir errores si éstos existen? 0 Ejercicio 1-12, Escriba un programa que imprima su entrada una palabra por linea. 0 1.6 Arreglos F de caracteres espaciadores ‘otros caracteres. Esto es Cen un programa. Existen doce categorias de entrada, por lo que es conveniente utilizar un arre- slo para mantener el mimero de ocurrencias de cada digito, en lugar de tener diez variables individuales. Esta es una versin del program: deo, lancos, tabuladores, nueva linea), y de todos los icioso, pero nos permite ilustrar varios aspectos de include + cuenia digios, espacios blancos, y otros */ rain( ) 9, nother; 24 TRODUCCION GENERAL caprTuLoy while ((c = getchar( )) 1= EOF) (ce >= Uae <= 9) + +ndigitle~07;, ele if (¢ = = =e + +nwhite; else print for (= 0; 1 < 10; ++!) printi(* %d”, ndigitli); sppacios blances = %éd, otros = Séd\n", , nother); La salida de este programa al ejecutarlo soore si mismo es digitos = 93.000.0.0001, espacios blancos = 123, otros = 345, La declaracién int ndigit (10); declara ndigit como un arreglo de 10 enteros. En C, los subindices de arreglos snzan en cero, por lo que los elementos son ndigit{0], ndigit (1), ..., ndi- Esto se refleja en los ciclos for que inicializan ¢ imprimen el arreglo. Un subindice puede ser cualquier expresin entera, lo que incluye a variables ‘enteras como i, y constantes enteras. Este programa en particular se basa en las propiedades de la representacién de los digitos como caracteres. Por ejemplo, la prueba f(e>= Va&e <= 9) determina si el cardcter en ¢ es un digito. Si lo ¢s, el valor numérico del digito es °-0 Esto solo funciona si ‘9! tienen valores consecutivos ascendentes. Por fortuna, esto es asi en todos los conjuntos de caracteres.. Por definicién, los char son sélo pequetios enteros, por lo que las variables y las constantes char son idénticas a las int er expresiones aritméticas, Esto es natural y conveniente; por ejemplo, ¢~’0' es una expresién entera con un valor entre 0 y 9, correspondiente a los caracteres °C’ a °9" almacenados en ¢, por lo ue es un subindice valido para el atreglo ndigit. La devisin de si un caracter es digito, espado en blanco u otra cosa se realiza con la secuencia We >= 0 8&e <= 9) + +ndigit(o~ SECCION Ls ARREGLOS 25 ==) El patron sf (condicién,) ropesicién, lee if (condicisn) also proposicién, frecuentemente en programas como una forma de expresar una deci le. Las condiciones se evalian en orden desde el principio hasta que se satisface alguna coniticién; en ese punto se ejecuta la proposicién correspon- varias proposiciones entre Cuando se como se hizo en el programa para con- Puede haber cualquier mimero de 3, proporciona of larmente apropiada cuando la Qn ¢s determinarsi alguna expresidn entera o de cardcter corresponde con miembro de un ccnjunto de constantes. Para contrastar, se presentara un version de este programa, usando switch, en la seccidn 3.4, ygrama de las frecuen- da. 26 INTRODUCCION GENERAL carrtuto1 1.7 Funciones En Ienguaje C, una furién es el equivalente a una subrutina o funcién en Fortran, 0 a un procedimiento 0 funcién en Pascal. Una funcién proporciona tuna forma conveniente de encapsular algunos célculos, que se pueden emplear después sin preocuparse de su implantacién. Con funciones diseadas adecuada- mente, es posible ignorar como se realiza un trabsjo; es suliciente saber qué se hace. El lenguaje C hace que el uso de funciones s conveniente y eficien- te; es comiin ver una funci6n corta definida y empleada una sola vez, inicamente porque eso esclarece alguna Hasta ahora ‘m,n), que eleva un entero m a una potencia entera y post Esto cs, el valor de power(2,6) es 32. Esta funcion no es una rutina de exponen- ‘ica, puesto que sdlo maneja potencias positivas de enteros pe- ustios, pero es funcidn pow(x,y) que cale ‘A continuacion se presenta la funci6n power y un programa main para util zarla, de modo que se vea la estructura completa de una vez. include int power(int m, int 2); ‘ prusba la funcién power «/ main( ) J+ power: eleva la base a la n-dsima potencia; n >= 0 «/ int power(int base, int n) { sECCION 17 FuNciones 27 Una definicién de funciéa tiene la forma siguiente: tipo-de-retorno nomre-de-funcién (declaracién de pardmetres, si los hay) { declaraciones roposiciones jones de funcién pueden aparecer en cualquier orden y en uno 0 pero una funcién no puede separarse en archivos diferent pareve en varios archi ‘vez se tengan que especificar mas cosas al compilar y carg: Fa en uno solo, pero es0 es cosa del sistema operativo, no un atributo del lenguaje. Por ahora supondremos que ambas funciones estén en :1 mismo archivo y cualquier cosa que se haya aprendi- do acerea de cOmo ejecutar programas en C, alin funcionaran a funcién power se invoca dos veces por main, en la linea ‘bd %d Mala", pasa dos formato y rl c mai que se por inea de la funcién power, int power(in base, iat 2) is rutinas pueden Lutilizar los mismos nombres sin que exista problema alguno. Esto también es cier- 0 para las variables i y p: la i de power no tiene nada que ver con la i de main. Generalmente usaremos pardmetro para una variable nombrada en la lista en- re parémtesis de la definicén de una funcion, y a do al hacer la llamada de la funcién. Los términos return expresion Una funcién no necesita regresar un valor; una propo: fa al “‘caer al final’ de una funcién al alcanzar la llave derecha de ién. Ademés, la funcién que llama puede ignorar el valor que regresa Probablemente haya notado que hay una proposicién return al final de main, Puesto que main es una furcién como cualquier otra, también puede regresar un valor a quien la invoca, qu: es en efecto el medio ambiente en el que el programa 28 INTRODUCCION GENERAL capituto se ejecuta, Tipicamente, un valor de regreso cero implica una terminacién nor- mal; los valores diferentes de cero indican condiciones de terminacién no comu- nes 0 erréneas. Para buscar la simplicidad, se han cmitido hasta ahora las propo- siciones return de las funciones main, sn mas adelante, como un recordatorio de que los programas deben regresar su estado final a su medio am- biente La detlaracién int power(int m, int 0); totipo, debe coincidir con la definicién y uso de power. Es un error el que la defi- nicién de una funcién o cualquier uso que de elle se haga no corresponda con su prototipo. Los nombres de los parémetros no necesitan caincidir; de hecho, son optat vos en el prototipo de una funcién, de modo que para el prototipo se pudo haber escrito {int power(in No obstante, unos nombres bien seleccionados son! una buena documentacién, por lo que se emplearan frecuentemente. Una nota histérica: La mayor modificacién entre ANSI C y las versiones ante- ses c&mo estn declaradas y definidas las funciones. En la definicién origi- nal de C, la funcién power se pudo haber escrito de la siguiente manera: J+ power: olova la baco a n-teima potencia; n >= 0 +/ h (versién en estilo antiguo) +! power(base, 1) int base, { Pp for(i = ji <= a; ++) P= ps base; return pi los paréntesis y sus tipos se declaran antes de anterior.) del programa pudo haberse visto como sigue: uerpo de la funcién es igual a de power; No se permitié ninguna lista de parémetros, de modo que el compilador no pudo revisar con facilidad que power fuera llamada correctamente. De hecho, puesto SECCION 1 |ARUMENTOS—LLAMADA POR VALOR 29 que por omisién se podia suponer que power regresaba un entero, toda la decla~ racion podria haberse onitido. La nueva sintaxis de ‘os prototipos de funciones permite que sea mucho més para el compilador detectar errores en el niimero 0 tipo de argumentos. El estilo de declaracién y definicin ain funciona en ANSI C, al menos por 1.8 Argumentos—llamadas por valor Hay un aspecto de las funciones de C que puede parecer poco familiar a los progratiadores acostumbrados a otros lenguajes, par § argumentos de una funcidn se pasan “‘por val fica que funcidn que se invoca recibe los valores de sus argumentos en variables tempo- nales. Esto conduce a algunas propiedades diferentes a las umadias por referencia" como Fortran o con paré- (0s varen Pascal, en donde la rutina que se invoca tiene acceso al argumento iginal, to a una copia local. La diferencia principel ¢s que en C Ia funcién que se invoca no puede alterar fectamente una variable de la funcidn que hace la llamada; s6lo puede moi car su copia privada y temporal llamada por valor es una ventaja, no una desventaja. Por lo ‘a eaborar programas més compactos con pocas variables lizadas. Por ejemplo, he aqui una versién de power que utiliza este propiedad. J+ power: eleva la base a la n-6sima potoncia; n> =0; versién 2 +/ int power(int base, int n) { int p; for (p = 1; 2 > 0; —-n) pa peb temporal, y se decrementa (un ue se ejecuta hacia “ga a cero; ya no es necesaria la variable 4, Cualquier cosa que se Ie haga a n dentro de power no tiene efecto sobre el argu: mento con el que s¢ Ilam6 originalmente power. 30 1NTRODUCCION GENERAL caprTuto es posible hacer que una funcién modifique una va- ‘ina invocada. La funcién que llama debe proporcionar lun apuntador a la va- invoca debe declarar que el parametro sea un apuni le indirectamente a través de él. Los apuntador La historia es diferente con los arreglos. Cuando el nombre de un arreglo se emplea como argumento, el valor que se pasa a la funcién es la localizacién o rreglo —no hay copia de los elementos del arrealo. lor, la funcién puede tener acceso y alterar cual- es el tema de la siguiente seccién. digo es bastante simp bile (hay otf i (es mds larga que fa anterior més larga) udrdata ‘guarda su longitud Jimprime ta linea més larga Este pseudocddigo deja en claro que el programa szdivide naturalmente en par- tes. Una trae una nueva linea, otra el proceso. lad deberd retornar la lor 10. Cero es un regreso de id de linea valida. Cada linea de texto yea que séle contenga un cardcter nueva do a que nunca es una lor menos un cardeter; incluso una spccioN 19 ARREGLOS DECARACTERES 31 include (J+ imprime la Kea ds entrada mds larga «/ rain( ) { int len; /+ Tongitud actual de la linea -/ Int max; J + Axima longitud vista hasta el momento +/ ‘char line(MAXLINE]; linea de entrada actual «/ ‘char longest(MAXLINE]; \nea més larga se guarda aqut +/ J» ubo una linea «/ longest , regresa ou longitud / =EOF && ol="\n'; + +3) 32. INTRODUCCION GENERAL carro: Las funciones getline y copy estn declaradas al principio del programa, que se supone esta contenido en un archivo. ‘main y getline se comunican a través de un par de argumentos y un valor de retorno. En getline los argumentos se declaraa por I Int gatline(char im) que especifica que el primer argumento, s, es un arreglo, y el segundo, lim, es un entero. El propésito de proporcionar 1 regresa un int; puesto que iat es el valor de retorno por omi- sidn, puede suprimirse ‘Algunas funciones regresan un valor itl; otras, como copy, se emplean éini- ccamiente por su efecto y no regresan un valor. El tipo de retorno de copy es void, cl cual establece explicitamente que ningtin valor se regresa. En getline se coloca el cardcter “\O’ (cardeter nulo, cuyo valor es cero) al final del arreglo que estd creando, para marcar el fin de la cadena de caracteres. Esta con- ion también se utiliza por el lnguaje C: cuando una constante de cardcter como “hola aparece en un programa en C, se almacena como un arre ccaracteres de la cadena y termi La especificacién de formato %s dentro de print espera que rrespondiente sea una cadena represemtada de «ste modo; copy también se basa en el hecho de que su argumento de entrada se termina con '\0’, y copia este ca- rdcter dentro del argumento de salida. (Todo ica que ‘\0', no es parte de un texto normal.) Es ttl mencionar de paso que aun un programa tan pequeno como éste pre- senta algunos problemas de diseito. Por ejemplo, ;qué debe hacer main si en- cuentra una linea que es mayor que sy ine trabaja en forma segura, en ese caso detiene la recopilacién cuando el arreglo 7 argumento co- iar) cual es el tamafio de la cadena, por lo que decidimos no agregar comprobacién de errores en ella VARIABLES EXTERNASYALCANCE 33 modo que imprima ccrrectamente la longitud de lineas de entrada arbitrariamen- largas, y tanto texto como sea posible. Fjereieo 1-17, Escrita un programa que imprima todas ls lineas de entrada que sean mayores de 80 caracteres. 0 jercicio 1-18, Escriba un programa que elimine los blancos y los tabuladores aque estén al final de cada linea de entrada, y que borre completamente las lineas en blanco. © Ejercicio 1-19, Escriba una funcin reverse(s) que invigrta la cadena de caracte- +. Usela para escribir un programa que invierta su entrada, linea a linea. © funcién, y desaparece cuando la fun por lo que tales variables son conocidas como variables automét inologia de otros lenguajes. Aqui se utilizard en adelante ‘mético para hacer referencia a esas variables locales. (En el cay categoria de almacenamiento estética, en la que las variables locales si eo vvan sus valores entre llamadas.) Debido a que las variables locales aparecen y desaparecen con la invocacién de ‘que son externas a tocas las funciones, esto es, variables a las 4) Puede tener acceso por stu nombre. (Este mecanismo es parecido al COMMON de Fortran o a las varicbles de Pascal declaradas en el bloque mas exterior.) Debi- do a que es posible tener acceso global a las variables externas, éstas pueden ser sadas en lugar de listas de argumentos para comunicar datos entre funcioncs. Ademés, puesto que ‘as variables externas se mantienen permanentemente en cia, en lugar de aparecer y desaparecer cuando se laman y terminan las inciones, mantienen sus valores aun después de que regresa la funcién que los sup Variable externa debe denise, exactamente una vez, fuera de cualquler luncién; es 34 INTRODUCCION GENERAL ‘carr programa de la linea més larga con line, longest y max como variables externas, Esto requiere cat #include smano de una linea de entrada «. ‘#doline MAXLINE 1000 /+ maxim .axima longitud vista hasta el momento «/ 1a de entrada actual « larga se guarda aqui +/ le entrada més larga; versién especializada */ exten int max; extern char long ft ois extern char line(]; for (i = 0; 1 < MAI 6 (c= getchar( )) != EOF 8c != “\n'; + +i) jar las Hamadas, declaraciores y cuetpos de las tres funciones. SECCION 110 YVARIABLESEXTERNAS YALCANCE 35 Iineli] = 0% retum j } (+ copy: versiée especializada +/ void copy(void) { int cextem char line(], longest{]; } as son exactamente como las definiciones de variables locales, pero puesto que ‘curren fuera de las funciones, las variables son externas. Antes de que una fun- \6n pueda usar una variable externa, se debe hacer saber el nombre de la variable la funeién. Una forma de hacer esto es escribir una declaracién extern dentro la funcién; la declaracién es la misma que antes, excepto por la palabra reser- vada extern, Bajo ciertas circunstancias, la declaracién se puede omitir. Si la defini- \6n de una variable externa ocurre dentro del archivo fuente antes de su uso por ina funcién en particular, entonces comiin, es poner ternas al principio del archivo fuente y después omit tern. junciones en un archivo sepa- sader, que es incluido por #include al principio de cada archivo fuente, El sufijo .h se usa por convei ‘ers. Las funciones de la biblioteca estindar, por ejem| 'eaders como . Este tema se trata ampliamente en el capitulo 4, y la foteca en el capitulo 7 y en el apéndice B. 36 TRODUCCION GENERAL ‘caprrutoy Puesto que las versiones especializaclas de getline y copy no tienen argumen- tos, la I6gica sugeriria que sus prototipos al principio del archivo deben ser getli- y copy( ). Pero por compatibilidad con programas de C anteriores, cl estan~ dar toma a una lista vacia como una declaracién al viejo estilo, y suspende toda revision de listas de argumentos; para una lista explicitamente vacia debe emplearse la palabra void. Esto se discutird en el capituio 4. Se debe notar que empleamos cuidadosamente las palabras definicién y decla- racién cuando nos referimos a variables externes en esta seccién. La palabra ‘de- ” se refiere al lugar donde se crea la variable 0 se le asigna un lugar de almacenami ‘declaracién"’ se reflere al lugar donde se establece la naturale- za de la variable pero no se le asigna espacio. ‘A proposit una tendencia a convertir todo en variables extern, debido a que aparentement las comunicaciones —Ias listas de argumentos son cortas y las variables existen siempre, cuando se les requiere. Pero las variables ‘externas existen siempre, aun cuando no hacen falta. Descansar fuertemente so- bre variables externas e5 peligroso, puesto que lleva a programas cuyas cone- xiones entre datos no son completamente obvias —las variables pueden cambiar- se en forma inesperada ¢ inadvertida, y el programa es dificil de modificar. La segunda versién del programa de la linea mayo: es inferior a la primera, en parte por las anteriores razones y en parte porque destruye la generalidad de dos titles funciones, introduciendo en ellas los nombres de las variables que manipula. Hasta este punto hemos descrito lo que podria lamarse los fundamentos con- vencionales de C. Con estos fundamentos, es posible escribir programas itiles de tamafio considerable, y probablemente seria uma buena idea hacer una pausa sufi- cientemente grande para realizarlos. Estos ejercicios sugieren programas de com- plejidad algo mayor que los anteriores del cari Ejercicio 1-20. Escriba un programa detab que reemplace tabul trada con el nimero apropiado de blancos para espaciar hasta el de tabulacién. Considere un conjunto fijo de paros de tabulacién, digamos cada zn columnas. ;Debe ser n una variable o un parémetro simbslico? 0 Ejercicio 1-21. Escriba un programa entab que reemplace cadenas de blancos por el minimo niimero de tabuladores y blancos para obtener el mismo espaciado. re los paros de tabulacién de igual manera que para detab. Cuando un tabulador 0 un simple espacio en blanco fuese suficiente para aleanzar un paro de tabulacidn, ja cudl se le debe dar preferencia? 0 ‘doblar"” lineas grandes de entrada en \ocardcter no blanco que ocurra an- ina de entrada. Aseguirese de que su programa se comporte ymente con lineas muy largas, y de cue no hay blancos o tabuladores antes de la columna especificada. 0 Ejercicio 1-23. Escriba un programa para elirtinar todos los comentarios de un programa en C. No olvide manejar apropiadamente las cadenas entre comillas y las constantes de cardcier. Los comentarios de C no se anidan. SECCION 0 YARIABLESEXTERNAS VALCANCE 37 jercicio 1-24. Escriba un programa para revisar los errores de rudimen- ineados. No comentarios, capituLo 2: Tipos, operadores y expresiones Las variables y las constantes son los objetos de datos basicos que se manipu- un programa. Las declaraciones muestran las variables que se van izar y establecen el tienen y algunas veces cuales son sus valores i ciales. Los operadores especifican lo que se hard con las variables. nes combinan variables y constantes para producir nuevos valores. El ‘objeto determina el coajunto de valores que puede tener y qué operaciones se pue- den realizar sobre él. Estos son los temas de este capitulo. El estindar ANSI ha hecho muchos pequeflos cambios y agregados a los ti- pos basicos y a las expresiones. Ahora hay formas signed y unsigned de todos los tipos enteros, y notaciones para constantes sin signo y constantes de cardcter hhexadecimales. Las op:raciones de punto flotante pueden hacerse en precision sen- la; también hay un tipo long dout mn extendida. Las constantes de cadena pueden concatenarse a pendiente por mucho impide que cambien. ipos aritméticos se aumentaron pa- ipos. ra manejar el ahora mas rico conjunto d 2.1 Nombres de variables Aunque no lo mensionamas en el capit los nombre de las vat 1, existen algunas restrieciones en s y de las constantes simbi + Puesto que las rutinas de bi as may(isculas y mintisculas son 40 1170S, OPERADORES Y EXPRESIONES caprrutoz ‘Al menos los primeras 31 caracteres de un nombre interno son si para nombres de funciones y variables externa ‘0 puede sei 31, puesto que los nombres externos los pueden usar los ensambladores y los ear~ sgadores, sobi iene control, Para nombres externos, el es- anda sminiscul se pueden uti rmimisculas. Es conveniente elegir nombres que izar nombres corios para variables locales, especialmente indices de jomibres mas largos para variables externas. 2.2 Tipos y tamafios de datos Hay unos cuantos tipos de datos basicos en C: char um solo byte, eapaz de contener un cardcter del conjunto de local int tun entero, normalmente del tama natural de fos enteros en la rmiquina en la que se ejecuta. float punto flotante de precsién normal double punto flotante de doble precisién. Ademés, existen algunos calificadores que se aplican a estos tipos basicos. short y long se aplican a enteros: short int sh; long int counter; Lapalabra int puede omitirse de tales declaraciones, lo que tipicamente se hace. jencién es que short y long puedan proporcionar diferentes longitudes ée enteros donde sea préctico; int ser normalnente el tamafo natural para una ‘miquina en particular. A menudo short es de16 bits y long de 32; int es de 16 ‘ode 32 bits. Cada compilador puede seleccionar libremente los tamafios apropia~ su propio hardware, sujeto slo a la restriccién de que los shorts e ints son, por Io menos de 16 bits, los longs son por lo menos de 32 bits y el short no, ‘a su vez no es mayer que long. ‘ex tanto que las variables signed char tienen valores entre ~128 y 127 (en una ndquina de complemento a dos). El hecho de que los chars ordinarios sean con seccioN.3 CONSTANTES. 41 a, pero los cat fes que se pueden impri especifica punto flotante de precision extendida. Igual los tamafios de objetos de punto flotante se definen en la double y long double pueden representar uno, dos o tres ta- ba us programa para determinar los rangos de variables char, nto signed como unsigned, imprimiendo los val 10s de punto flotante. termine los rangos de los varios 2.3. Constantes centera como 1234 ¢s un int. Una constante long se escribe con somo en 123456789L; un entero demasiado grande para también seré tomado como long. Las co ie 10 se escriben con una uo U, terminal y el sufijo ul o UL indica unsigned long, Las constantes de punto flotante contienen un punto decimal ponente (1e~2) 0 ambos; su ‘a menos que tengan jos {0 F indican una constant El valor de un entero puede especiti gar de decimal. Un 0 (cero) al princi -a hexadecimal. Por ejem y Oxlf 6 OXIF en hexadeci ibiéa pueden ser seguidas por L para conver U para haverlas unsigned: OXFUL es una constante unsigned long con valor de 15 en decimal. 1o L indiean un long double. ccardcter en el conjunto ée caracteres de la maquina. Por ejemplo, en el de caracteres ASCII el cardcter constante ‘0' tiene el valor de 48, el cual no esta relacionado con el valor 1umérico 0. Si escribimos ‘0’ en vez de un valor numérico como 48 que depende conjunto de caracteres, el programa es independiente ‘como cualesquier otros enteros, au ‘mtinmente en comparaciones con ot Ce 42. _T1P0s, OPERADORES Y EXPRESIONES caprruoa como dos caracteres, pero representan s6lo uno. Ademas, un patron de bits ar~ bitrario de tamafo de un byte puede ser espesificado por Nove! en donde o00 son de uno a tres digitos octales (0...7) 0 por "hat en donde Ad son uno o mas digitos hexadecimales (0...9, a...f, A...F). Asi podria- ‘mos escribir #doline VTAB \O13'—_/+ tab vertical ASCII «/ ‘#deline BELL \007 + cardcter campana A‘ ©, en hexadecimal, #dofine VIAB ‘\xb' + tab vertical ASCI ‘Pdefine BELL \x7" J+ cardcter campana ASCII «/ El conjunto completo de secuencias de escape es \a_ cardcter de alarma (campana) \\ diagonal invertida Yb retroceso \E avance de hoja \n nueva linea \r-_regreto de carro Mt tabulador ado er ‘\O" representa el caracter con val ibe en vez de 0 para anfati e algunas expresiones, pero el valor numérice es precisamente 0. Una expresién constante es una expresién que s6l 1ye constantes. Ta- les expresiones pueden ser evaluadas durante la compilacién en vez de que se haga fen tiempo de ejecucién, y por tanto pueden se- utilizadas en cualquier Iugar en que pueda encontrarse una constante, como en ‘#dofine MAXLINE 1000 cchar line [MAXLINE + 1); ‘#deline LEAP 1+ en afios bisiestoss/ int days (31+28+LEAP +31 +30+31 + 90+31+31+30+31+30+31); Una constante de cadena o cadena literal, es una secuencia de cero 0 mas ca- racteres encerrados entre comillas, como en "Soy una cadona”” ‘js Ta cadena vacia «/ secci0n23 CCONSTANTES 43, Las comillas no son parte de Ia cadena, sélo sirven para delimitarla. Las mismas clas de escape utilizadas en constantes de caracter se aplican en cadenas; \ representa el car las. Las constantes de cadena pueden ser concate nadas en tiempo de compi “hola,” mundo” es equivalence a “hola, mundo” lo ‘\0 al final, de modo que $ uno mas del niimero de caracteres escritos significa que no hay limite en cuanto a los programas deben estdndar regresa la I cluyendo el ‘\O' terminal. Aqui esta nuestra versién: ="0) strlen y otras funciones para cadenas estan declaradas en el header estindar . Se debe ser cuidadoso al distinguir entre una vor te de cardcter y una cadena lerucién. Una enumeracion a de valores enteros constantes, como en ‘enum boolean (110, YES}; El primer nombre en un enum tiene valor 0, el siguiente 1, y asi sucesivamente, ‘4 menos que sean especificados valores explicitos. Si no todos los valores son es- 44 1170s, oPERADORESY EXPRESIONES carcruio 5 no especificados continiian io fue, como en el segunclo de eso: enum escapes { BELL = ‘\e', RETROCESO = ‘\b', TAB = "\!, NVALIN = ‘\n’, VIAB = ‘\v, RETURN = ‘\r}, a partir det enum months {ENE = 1, FEB, MAR, ABR, MAY, JUN, FEB es 2, MAR es 3, Los nombres que estén en enumeraciones diferentes deben ser distintos, Los va- lores no necesitan ser di Las enumeraciones proporcionan una manera conveniente de asociar valores constantes con nombres, un menudo mejor que #de! depurador puede ser mir los valores de variables de enumeracién en su forma simb 2.4 Declaraciones Todas las variables deben ser declaradas antes de su uso, aunque ciertas decla- raciones pueden ser hechas en forma implicita por el contexto. Una declaracién ‘specifica un tipo, y contiene una lista de una o mis variables de ese tipo, como en int lower, upper, step: char ¢, line (10; fas entre las declaraciones en cualquier forma; ta de arriba podria igvalmente ser escrita como har line (000); ‘ima forma ocepa mas espacio, pero es conveniente para agregar un co- io cada declaracién © para modificaciones subsecuentes Una variable tamtién puede ser inicializada en su declara ¢s seguido por um signo de igual y una expresin la expresion sirve como un ador, como en secciona.s OPERADORES ARITMETICOS. 48 ese = WV i=G; limit = MAXLINE+1; dda cada vez que se entra a la funcién o bloque en dor puede ser cualquier expresion. Las vari eas y externas son para las que no hay unis basura. -ador const puede aplicarse a la declaracién de cualquier variable pa: ‘ar que su valor no sera cambiado. Para un arreglo, el calificador efectiia un intentode cambiar un const, el resultado est definido por la implantacién. 2.5 Operadores aritméticos Los operadores aritméticos binarios son +, ~, «, /, vel operador médulo %. La divisidn entera trunca cualquier parte fraccionaria. La expr x%y produce el residuo cuando x es dividido entre y, por lo que es cero cuando y divi- de a x exactamente, Por ejemplo, un afio es bisiesto si es divisible entre 4 pero no entre 100, excepto aquellos afios que son divisibles entre 400, qui bisies- 105, Por lo tanto if (Gear % 4 == 0.88 year % 100 != printf("%d os un ano bisiesto\n, else printi("%éd no os un afio Disiosto\ year % 400 = = 0) “ yoar); El operador % no puede aplicarse a operandos truncamiento para / y elsigno del resultado de % si para operandos negatives, asi como la accién que se toma en caso de sobreflujo © subflujo. 46 1170s, OPERADORES Y EXPRESIONES. carrruto2 s + y— tienen la misma precedencia, la cual es menor 'y %, que a su vez esmenor que + ¥ ~ unarios, Los sha Los operadores binat que la precedencia de ‘operadores aritméticos se asocian de izquierda a der La tabla 2-1 que se encuentra al final de este capi y asociatividad para todos los operadores. resume la precedencia 2.6 Operadores de relacién y ldgicos Los operadores de relacién son > >e= n= lens return a; <= 9) +49) Tal como se discutié en el capitulo 1, la expresién da el valor numérico del cardcter almacenado en s[i], debido a que los valores etc., forman una secuencia ascenderte contigua. ejemplo de conversion de chara intes le f lower, que cor a miniiscula para el conjunto de caracteres ASCIT. Si el cardcter mayiscula, lower lo regresa sin cambio. convierte ¢ a miniscule; solamente ASCII «/ int lower(int ¢) { if(e >= /A' 880 <= 7) return © + 'a!— else return ' Esto funciona para ASCII debido a que las co-respondientes letras mayusculas y minisculas estin a una distancia fija como valores numéricos y cada alfabeto es contiguo ino letras entre A y Z. Sin embargo, esta altima observa- cidn no es cierta para el conjunto de caracteres EBCDIC, asi que este codigo eo= Uae c= puede reemplazarse por indigit(c) Nosotros utilizaremos las funciones de en adelante. Existe un sutil punto acerca de la conversiéa de caracteres a enters: El len- ‘guaje no especifica si las variables de tipo char son valores con o sin signo. Cuan- do un char se convi La respuesta varia de una maquina a oti ra. Bn algunas méquinas un char cuyo iza que ningiin caract {andar de caracteres de impresion de la es siempre seran cani esté en el conjunto ive, de modo que secc10n27 CONVERSIONES DE TIPO. 49, parecer como negativos en algunas maquinas, aunque sean positivos en otras. sransporiabilidad, se debe especi mned o unsigned si se van a almace- 1 datos que no son caracteres en variables tipo char. Las expresiones de relacién como i > j y las expresiones légicas conectadas por && y || estén definidas para tener un valor de 1 siendo verdaderas, y 0 al ser falsas. De este modo, la asignacién dsc>=USbcc= 9 y0si no lo es. Sin embargo, las funciones como isdi- rrente de cero como verdadero. En la parte "es sélo “diferente de cero”, por hace ladsicesun deval Jo que esto no hace Las conversiones ait un operador como + 0 + ai operandos de diferentes tipos, el tipo '*menor’” es promo’ antes de que la operacén proceda. El resultado es el del tipo mayor. La seccién 6 del apéndice A estatleve las reglas de conversién en forma precisa. Si no hay operandos unsigned, sin embargo, el siguiente conjunto informal de reglas bas- tard: Si cualquier operando es long double, conviértase el otro a long double. De otra manera, si cualquier operando es double, conviértase el otro a double. De otra manera, si cualquier operando es float, conviértase cl otro a float. De otra manera, conviértase char y short a Después, si cualquier operando es long, conviértase el otro a long. Nétese que los float que estan en una expresién no se convierten automética- to ¢s un cambio de la definiciGn original. En general, las fun- de utilizardn doble precisién. La razon horrar espacio de almacenamiento en arreglos gran- suencia, ahorrar tiempo en méquinas en donde la aritme- a de doble preci particularmente costosa. Las realas de conversion son més complicadas signed. El problema es que las comparaciones de valores con signo y sin signo nt dependientes de Ia maquina, debido a que dependen de los tamaiios de varios tipos de entsros. Por ejemplo, supdngase que int es de 16 bits y long de 32, Entonces ~1L < 1U, debido a que 1U, que es un int, es promovido a yned long. Pero-1L > 1UL, debido a que ~1L es promovido @ unsigned long Y asi parece ser un gran niimero positive. des 0, con menor ‘50 TIPOS, OPERADORES Y EXPRESIONES carrruLo2 jen Tugar en las asignaciones; el valor det lado 0 de Ia izquierda, el cual es el tipo del resultado. jo a un entero, tenga o no extensién de signo, como, Las conversiones tam! derecho es convertido al Un cardcter es conver se describié anteriormente. Los enteros mis largos son convertidos a cottos o a char desechando el exceso. de bits de mas alto orden. Asi en int i; char ¢; l 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. Sixes float e ies int, entonces x = iei = xproducirdn conversiones; de float 2 int provoca el truncamiento de cualquier part: fraccionaria, Cuando double se convierte a float, el que se redondee o trunque el valor es dependiente de la im- plantacién. Puesto que un argumento de la lamada a una funcién es una expresion, tam- bien suceden conversiones de tipo cuando se pasan argumentos a func ausencia del ipo de una funcién, char y short pasan asser int, y hace doble, Esta es la razn por la que hemos declarado los arguimentos a funcio- nes como int y double, aun cuando la funcidn se llama con char y float. Finalmente, 1a conversin explicita de tipo 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 conversién anterio- - -adoprecisode un cast es como si a expresién fuera asignada a una variable del tipo especificado, que se utiliza entonces en lugar de la construc- i (eca sqrt espera un argumento de jo si maneja inadvertidamente es un entero, pode- sqrt(double) 1) el valor den a doble antes de pasarlo a sqrt. Notese que la conver- duce el valor de n en el tipo apropiado; nen si no se altera. El ia que otros operadores unarios, co- SeCCION2 (OPERADORES DEINCREMENTOYDECREMENTO $1 double sqri(dout llamada aie = sqrt(2) obliga al entero 2 a ser el valor double 2.0 sin necesidad de ningin cast. La biblioteca estindar incluye una implantacidn transportable de un genera- dor de niumeros pseudoaleatorios, y una funcion para inicializar la semilla; lo mero ilustra un cast: ‘unsigned long int next = 1; Js rand: regress un entero psoudoaleatorio en 0.22767 +/ rand(void) next = next + 1109515245 + 12345; rolurn (unsigned int)(nex/65536) % 32768; : + srands void srand(unsigied int seed) { Ja semilla para rand() «/ next = seed; ; jercicio 2-3. Escriba a funcién htoi(s), que convierte una cadena de di hhexadecimales (incluyendo Ox 6 OX en forma optativa) en su valor entero equiva ie. Los digitos permitidos son del 0 al 9, de laa ala, y dela A ala F, O 2.8 Operadores de incremento y decremento El ienguaje C proporciona dos operadores poco comunes para inerementar y decrementar variables. 5! operador de aumento + + agrega 1 a su operando, en tO que el operador dz disminucién ~~ le resta 1. Hemos usado frecuentemen- ++ para inerementar variables, como en if(e == \n) + +n; El aspecto poco comin es que + + y ~~ pueden ser utilizado como pr s de la variable, como en + +n), 0 como pos + +). En ambos casos, el efecto es incrementar n. Pero la expresion + + "menta a n antes de que su valor se utilice, en tanto que n+ + incrementa a 52. TIPOS, OPERADORES V EXPRESIONES carrrunos to don- a desptés de ques valor se ha empleado. Eso significa que en un eon jo utilizado, y no sélo el clecto, + +n y n+ +son Sines 5, entonces xentty asigna 5 a x, pero hace que x sea 6. En ambos casos, n se hace 6. Los operadores de increment ¥y decremento s6lo pueden aplicarse a variables; una expresién como (i+})+ + es de un contexto en donde no se desea ningin valor, sino solo el efecto jos y postfijos son iguales. Pero existen situaciones en donde se requicre umente uno u otro. Por ejemplo, considérese la funcién squeeze jina todas las ocurrencias del cardcter ¢ de una cadena s. = NOt +) ++] = lily sli] = NO , Cada ver que se encuentra un valor diferente de ¢, éste se copia en la posicion actual j, y s6lo entonces j es inerementada para prepararla para el siguiente cardc- Otro ejemplo de construceién semejante viene de la funcién getline que eseri- bimos en el capitulo 1, en donde podemos reemplazar seccion29 OPERADORESPARAMANEJODE BITS $3 por algo mas compacto como J+ encuentra ol fin de s «/ while ((l:+ +1 = t+ +)) 120) f+ copia t of } Como cada cardcter se copia de t a s, el ++ postfijo se aplica tam ma de squeeze(sl,s2) eardcter de la eadena # Fjereicio 2-8. Escrita la funcién any(sl,s2), que regresa la Ja cadena sl en donde se encuentre cualquier cardcier de la cadena #2, 0 ~1 sl no contiene caracteres de 62. (La funcién de biblioteca estandar strpbrk hace €l mismo trabajo pe‘o regresa un apuntador a la posicién encontrada.) © ccomplemento a uno (natio) ‘S4_“1P0S, OPERADORES Y EXPRESIONES carruto2 El operador AND de bits & a menudo es usado para enmascarar algiin con- junto de bits; por ejempl a= 2.80177; hace cero todos los bits de m, 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 exclusivo * pone un uno en cada posicién en donde sus ope- iemplo, six es 1 y y es 2, entonces x & y es cero en tanto que x && y Los operadores de corrimiento << y >> realizan corrimientos a la izquier- derecha de su operando que esta a la izquierda, ‘dado por el operando de la derecha, el cual debe << 2 desplaza el valor de x a la izquierda dos po unsigned siempre 's Vacantes con cero, El correr lad signada llenara con bits de signo (‘‘corrimiento aritmé- en algunas maquinas y con El operador nario ~ da el complemento 2 uno de un ent te cada bit I en un bit O y viceversa. Por eiemplo, x= x07 de algunos de los operedores de cidn getbits(x,p,n) que regresa el campo de a bits de x (ajustado a la derecha) que principia en la posicién p. Se supone que la posicién del bit 0 esta en el borde derecho y que n y por sositivos adecuados. Por ejemplo, g regresa los tres bits que estan en la posicion 4 3 y 2, ajustados a la de Ja posicién p «/ ‘unsigned getbits(unsigned x, int p, { rotum (x >> (p+1-n)) &°(0 < > (p+ 1—n) mueve el campo deseado al borde derecho de la pa- SECCION2 10 OPERADORES DE ASIGNACIONYEXPRESIONES 85 Ejercieio 2-6. Escriba una funci que principian en la posicion p iguales a cambio. O ,Pyn,y) que regresa x con los n bits sa la derecha de y, deja 1 cambiado a0 y viceversa), dejando Ejereicio 2-8. Es in rightrot(x,n) que rearesa el valor del entero x rotado a la derecha 1 posiciones de bits. 2.10 Operadores de asignacién y expresiones Las expresiones tales como iaiee cen las que la variable del lado izquierdo se repite inmediatamente en el derecho, pueden ser escritas en ‘a forma compacta ite? Bl operador + = se llama operador de asignacién. La mayoria de los operadores binarios (operadores como + que tienen un coperando izquierdo y otto derecho) tienen un correspondiente operador de asig- nacién op=, en donde op es uno de Foi > BT! expr) y expr; son exsresiones, entonces expr, op= expr 6s equivalente @ expr, = (expr) op (expr) ;pluando que expr, se c en su argu- 56 TIPOS, OPERADORES V EXPRESIONES carrruLo2 cuenta bite Len x +/ [+ bitcount: int b; for (b = 0; x!= 0;x>>= 1) if & 0) bests i Declarar al argumento x como unsigned asegura que cuando se corre a la dere cha, los bits vacantes se llenardn con ceros, no con bits de signo, sin importar Ja méquina en la que se ejecute el programa, Muy aparte de su concisién, los operadores de asignacién tienen bs ventaja de después pon el r icai= i+ 2, Ademas, para una, yyvallyypvlp3+p4] + yypelpl+p2]] += 2 el operador de asignacién hace al cédigo més faci: de entender, puesto que el tor no tiene que verificar arduamente que dos expresiones muy largas son en reali dad iguales, o preguntarse por qué no lo son, y un operador de asignacién puede incluso ayudar al compilador a producir eédigo mas eficiente. ‘Ya hemos visto que la proposicién de asignacion tiene un valor y puede estar dentro de expresion jemplo mas comiin es while ((¢ = getchax( )) != EOF) Los otros operadores de asignaci6n (+ =,— =, etc.) también pueden estar dentro de expresiones, aunque esto es menos frecuente. En todas esas expresiones, el tipo de una expresién de asignacién es el tipo de su operando del lado izquierdo, y su valor es elvalor después de la asignacién, Ejercicio 2-9. En un sistema de nimeros de complemento a dos, x 6&= (x-1) bo- rra el bit | de més a la derecha en x. Explique el Forqué. Utilice esta observacién para escribir una versién mas répida de bitcount. 1] 2.11. Expresiones condicionales Las proposiciones (a> b) else : a=b PRECEDENCIA YORDENDEEVALUACION ST jonal, escrita con el opera- fa para escribir ésta y otras dor ternario " sciones semejantes. En la expresién expr, 2 expry : expry za (@>btark fez = max(a, Se debe notar que la expresién condicional es en si una expresién, y se puede cs de tipo # Los parénté presidn condicional, pueso que la precedencia de ?: es de la asignacién. De cualquier modo son recomendables, puesto que hacen mas La expresion condicioral frecuentemente lleva a un c6digo conciso. Por ejem= plo, este ciclo imprime m elementos de un arreglo, 10 por linea, con cada columna separada por un blanco, y con cada linea (incluida la ditima) terminada por una nueva linea, después de ‘imo. Todos los otros clementos son seguidos por cure, pero es mas Lo buen ejemplo es Ejercicio 2-10. Reescriba la fu ‘mimisculas, con una expresién con 2.12 Precedencia y orden de evalu resume las reglas de precedencia y asociatividad de todos los ope- los que ain no se han tratado. Los operadores que caprruto2 ‘58 IPOS, OPERADORESY EXPRESIONES ntador) y & (direct la precedencia de los operadores de bits &, = = y |=. Esto implica que las expresiones de prueba de bi ((x & MASK) == 0) deben ser completamente colocadas entre parértesis para dar los resultados apro- piadas. ‘TABLA 21, PRECEDENCIA Y ASOCIATIVIDAD DE OPERADORES ‘ASOCIATIVIDAD, izquierda a derecha derecha a inquierda iequierda a derecha inquierda a derecha ' inquierda a derecha 8a igquierda a derecha inquierda a derecha 2 derecha a izquierda Ste ce ee [ee eos f= <= pee | derecha a izquierda iquierda a derecha Los +,-.¥ snen mayor precedencia ‘Como muchos lenguajes, C no especifica el orden en el cual srin evaluados. (Las excepciones son &&, en proposiciones como SECCION2.22 PRECEDENCIA Y ORDEN DEEVALUACION 59 Js EQUIVOCADO « puede produ tos compiladores, dependiendo de sin es incrementada antes de que se llame a power. La solucién, por supuesto, cs escribir print cma Mala", Las llamadas a funciones, proposiciones de asignacién anidadas, y los opera dores de ineremento y decremento provocan a fectos colaterales" —alguna varia- ble es modificada como producto de la evaluacién de una expresin. En cualquier involucra efectos colaterales, pueclen exi s dependencias pr puesto que el mejor orden depende grandemente de la arquitectura de la maquina. «printf mostrada anteriormente.) moraleja es que escribir un cédigo que depencda del orden de evaluacién es lenguaje. Naturalmer capituco 3; Control de flujo rden et gue se realiza de las construcciones de control de flujo en ejemalos anteriores; aqui completaremos el conjunto, y sere: ‘mos mas precisos aceree de las discutidas con anterioridad. 3.1. Proposiciones y bloques Una expresin como x = 061+ + o printi(...) se convierte en una proposi- cin cuando va seguida de un punto y coma, como en x=0; printl (5 En C, el punto y coma ¢s un terminador de proposicién, en lugar de un separa- dor, como lo es en un lenguaje tipo Pascal. laves { y } se emalean para agrupar declaraciones y proposiciones dentro de una propasicidn compuesta 0 bloque, de modo que son sintaeticamente equi: valentes a una proposic On laves que encierran las proposiciones de una funcién son un e-emplo obvio; otros ejemplos son | proposiciones milltiples después de un if, else, while o for. variables dentro de cwalquier bloque; esto se expondra en el capi Dunto y coma después ce la Have derecha que termina un bloque lo 4.) No hay 3.2 Itelse La proposicion if-else se sintaxis es para expresar decisions. Formalmente 1 (expresién) roposicién, ole proposiciéns a © CONTROL DE FLUO caprtutoa Puesto que un if simplemente prueba el valor numérico de una expresién, son posibles ciertas abreviaciones de cédigo. Lo mas obvio es escribir if (expresion) cen lugar de if (expresion |= 0) Algunas veces esto es claro y natural; ot Debido a que la parte else de un if-else 2s optai cuando un else se omite de una secuencia if anidada, Esto se resuelve al asociar terior sin else mas cereara. Por ejemplo, en z=b; el else va con el if més interno, como se muestra con el sangrado. Si eso no lo que se desea, se deben utilizar Ilaves para forzar la asociacién correcta: f(a > 0) (a> b) else Je MAL + ror ~~ n es negativo \n"); El sangrado muestra en forma inequivoca lo que se desea, pero el compilador no | mensaje y asocia el else con el if mas interno. Puede ser dificil encom tar esta clase de errores; es una buena idea utilizar Haves cuando hay varios if anidados, secc10ns.3 ELSEIF 63 A propésito, nétese que hay un punto y coma después de z = a en (a> b) else nab; debe a que gramaticalmente alfiile sigue una proposicién, y una expresion, " siempre se termina con punto y coma. La construccién if (expresién) propasicion lee if (expresién) roposicion (expresién) proposicion else proposicion ccurre de modo tan f-ecuente que bien vale una pequefia discusién aparte. Es secuencia de proposiciones if es la forma mas general de escribir una deci le. Las expresicnes se evaliian en orden; si cualquier expresidn es verdade- ra, la proposicién asociada con ella se ejecuta, y esto termina toda la cadena. Co- in es una proposicidn simple 0 un grupo dentro rte del maneja Pe jon cuando ninguna de las otras condiciones se satisface. En algunos ca 0s no hay una accidr explicita para la omisiOn; en ese caso el else proposicisr 2, 0 puede utilizarse para deteccién de errores al atrapar ‘ion de tres vias, se muestra una Tuncidn de busqueda bi- aria que decide si un valor particular de x se encuentra en el arreglo ordenado ¥. Los elementos de vdeben estar en orden ascendente. La funcién regresa la po- sicién (un niimero en:re 0 y nl) si x esté en v, y ~ La busqueda binaria primero compara el valor de Medio del x es menor que el valor del medio, la biisqueda se enfoca bla; de otra manera lo hace nte paso es comparar a x con el 64 CONTROL DEFLUIO caprrutos Ja mitad seleccionada, Este proceso de dividir en dos continiia hasta que se en- cuentra el valor o ya no hay elementos. * binsearch: encuentra xen v[0] <= y[l] <=... <= vin—I]*/ nt binsearch(int x, in int low, high, mids low = 0; high = 2-1; while (low <= man ) La decisi6n fundamental dio v{mid] en cada pa es menor que, mayor que o igual al elemento me- sto es un else natural. Ejercicio 3-1. Nuestra busqueda binaria realiza dos pruebas dentro del cicl podria ser suficiente (al precio de mis pruebas en el exterior). Escriba on solo una prueba dentro del cico y mida l diferencia en tiempo de ejecucién. 3.4 Switch La proposicién switch es una decisién miltiple que prueba si una expresién ide con uno de un nimero de valores constantes enteros, y traslada el con- 1 adecuadamente, switch (expresién) { case exp-const: proposiciones case exp-const: proposiciones default: proposiciones ) Cada Ease] se etiqueta con uno 0 mas valores zonstantes enteros o expresiones id un programa para contar las ocurrencias de cada dos los demas caracteres, usando una secuencia de std el mismo programa con un switch: include main) /+ cuenia digitos, espacios blancos, y otros” { int c, i, nwhile, nother, ndigit 1H white = nother = 0; for (1 = 0; 1 < 10; i+ +) 0; = cotchar( )) != EOF) { sncos ='%d, otros = %6d\n", ! 66 CONTROL DEFLUIO caprmutos sece1ons.s cictosWiteYFOR 67 Pasar a través d parte buene y en parte no. Por el lado positivo, expansidn. Si la prueba expr, no esta presente, se toma como permanentemente verdadera, asi que { for ' y emplear comer break despues del es una iteracién “‘infinita”, que presumiblemente sera interrumpida por otros medios, como un break 0 un return. E] usar while o for es principalmen ejemplo, en ‘Como formalidad, cologue default) aun si es [case] al final, esta practica de programacién defensiva lo salvara. agregue otro cuestién de preferencia personal, Por while (Cc = getchar( )) = 1 fe ignors caracteres espaciadores «/ copia la cadena t a s. Utilice un switch. Escriba también una funcién para la di- reccién inversa, convirtiendo secuencias de escape en caracteres reales. () no hay iniializacion o reincializacion, Elforse prefiere cuando existe una ini que mantiene las propesiciones de control del ciclo juntas y visibles al principio del mismo. Bsto es més obvio en 3.5. Ciclos—while y for epee Sear ay Ya hemos encontrado los os while y for. En que es la forma caracteristica de procesar los primeros n elementos de un arreglo ‘en C, lo andlogo al cicle DO de Fortran o al for de Pascal. Sin embargo, la anal sia no es perfecta puesto que tanto el indice como cl pueden ser alterados deste dentro del ciclo, y la variable del indice iretiene su valor uando las iteraciones terminan por cualquier raz6n. Debido a que las componen- tes del for son expresiones arbitrarias, sus ciclos no estan restringidos a progres nes aritméticas. Por otra parte, considere que es un mal estilo ineluir en las secciones de inicializacién incremento operaciones no relacionadas con esas ac tividades, que mas bier se reservan para acciones de control del ciclo. Como un ejemplo rds amplio, aqui esta otra version de atoi para conver cadena a su equivalente numérico. Esta es ligeramente mas general que la del 2; trata también los espacios en blanco previos al nimero, y los signos + 0-. (Elcapitulo 4 muestra atof, que realiza la misma conversién para niime- 10s de punto flotante.) La estructura del programa refleja la forma de la entrada wile (expresion) roposicion la expresion se evalita, Si es diferente de cero, se ejecuta la proposicion y se reeva- lia la expresidn. Este ciclo continua hasta que la expresién se hace cero, punto en el cual se suspende la ejecucion para cont nuar después de la propasicién. La proposicién for for (expr; exprss expr) proposicién cs cquivalente a expr: hile (expr) ( w expacios en blanco, silos hay toma et signa, si hay excepto por el comportamiento de continue que se describe en la seccién 3.7. ‘oma ta parte entera y conviérela Gramaticalmente, las tres componentes de un ciclo for son expresiones. Por Jo comuin, expr; y expr, son asignaciones o Hlamadas a funciOn y expr, es una eX presidn de relacién. Cualquiera de las tres paites se puede omitir, aunque deben permanecer los punto y coma. Si expr, © expr; se omite, slo se desecha de la Cada paso realiza su parte, y deja las cosas en forma clara para el siguiente. La ‘alidad del proceso termina con el primer cardcter que no pueda ser parte de Un numero. 68 CONTROL DEFLUIO carrTutog include sign for (; = 0; isspace(s[il); i+ +) /+ ignora espacio en blanco « Jo gnora ol signo «/ ye en forma gr cfectivamente un mé int gap, 5, j, emp; for (gap = n/2; gap > 0; gap /= 2 for (1 = gap; i < mj 1+ +) for (j=i-gap; i> =0 84 viil>vli+gapl: I-=9ap) { } Existen tres ciclos anidados. El mas externo controla el espacio entre los elemet tos comparados, reduciéndolo desde n/2 por un factor de dos en cada paso ha sECCIONS.S clcLos_WiLEYFOR 69 que llega a cero. El intermedio recorre los elementos. El ciclo mas interno compara cada pareja de elementos que esta separada por el espacio gap e invierte lo mas externo coincida con Ia forma de los otros, aun cuando no es tuna progresién aritméica, Un tltimo operador de C es la coma **,”, que frecuentemente encuentra uso en la proposicién for. Una pareja de expresiones separadas por una coma se eva- hia de izquierda a derecha, y el tipo y valor del resultado son el tipo y valor del operando derecho. Asi, en una proposicién for es posible colocar expresiones ies en las diferentes partes, por ejemplo, para procesar dos indices en para- te a la cadena s en el mis- mo lugar. include Js reverse: invierte la cadena s en el mismo lugar +/ void reversa(cha: Las comas que separana los argumentos de una funcién, las variables en declara- ciones, etc., 20 son operadores coma, y no garantizan evaluacién de izquierda a derecha, Los operadores coma deberdn utilizarse poco. Los usos mis adecuados son en construcciones fuertemente relacionadas una con la otra, como en el ciclo for de reverse, y en macros en donde un céleulo de paso multiple 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 operacién simple: hittin) Ejereicio 3-3, Escriba la funcién expand(sl,22) que expande notacién abreviada noa~z, que viene en la cadena sl, en equivalente completa abe...x¥2, en 82, Permita letras maylisculas y Para manejar casos como a-b-e y a~20-9 y ~a~2. Haga que los guiones al ‘nicio 0 al final se tomen literalmente. 0 70 CONTROL DE FLUJO capirutoa 3.6 Ciclos—do-while ‘Como ya se expuso en el capitulo 1, I la condicién de término. En contrast al final después de realizar cada paso a ta siempre por lo menos una vez. La sintaxis del do es y for verifican al principio prueba el cual se ejecu- do roposicién while (expresién); La proposiciOn se ejecuta y después se evalia la expresién. Si es verdadera, la proposicién se cvalia de nuevo, y asi sucesivamente. Cuando la expresién se hace falsa, el ciclo termina. Excepto por el sentido de la prueba, el do-while es equiva- lente a la proposicién repeat-until de Pasc La experiencia demuestra que el do-while es mucho menos I for. Aunque de cuando en cuando es valioso, como fierte un nimero a una cena de caracteres (lo inverso de. rabajo es ligeramente ms complicado de lo que podria pensarse en un. debido a que los métodos fécil itos los generan en if ((sign = 2) < 0) 1 vuelve a n positivo «/ i=0; J+ genera digitos en orden inverso */ 2% 10 +0; /+ toma al siguiente digito «/ while ((2 /= 10) > 0); 1+ borralo «/ El do-whilo es necesario, o al menos conveniente, puesto que por lo menos be instalar un cardcter en el arreglo s, aun sin es cero. También empleamos llaves alrededor de la proposicién simple que hace el cuerpo del do-whi inmecesarias, y asi el lector apresurado no confandira la seccién del while con el principio de un ciclo whil En una representacién de niimeros en complemento a di joa no maneja el niimero negativo mas grande, esto es, el valor de nuestra | secc10N3.7 BREAKYCONTINUE 71 . Escriba una version defitoa) que acepte tres argumen tercer argumerto es un ancho minimo de campo; n agregar blancos a la izquierda fe ancho. 3.7 Break y continue Algunas veces es conveniente tener la posibilidad de abandonar un tra manera que no sea probando al inicio o al final. La proposicién bre porciona una salida y do, tal como lo hace el cas al final de una cadena, utilizando un break p: se encuentra el no-blanco, no-tabulador 0 no-nuevs =~ 1=°\¢ 88 sfn] != x) slat] = \0" return 2; } mada con el break, pero se utiliza menos lo for, while o do que la de whilo y do, esto significa que la parte de la prueba se ejecuta 'nmediatamente; en el for, el control se traslada al paso de incremento. La propo- 72 CONTROL DEFLUIO ‘caprtutoa sicion continue se aplica solamente a ciclos, no a switch. Un continue dentro de lun switch que esta a su vez en un ciclo, provoca la siguiente iteracién del ciclo, Como un ejemplo, el siguiente fragmento procesa s6lo los elementos no_ negativos que estan en el arreglo a; los valores negativos son ignorados. bemiteyd <0) /+ ignora elementos negatives +/ ‘continue; Js trabaja con elementos postves «/ La proposicién continue se emplea a menudo cuando la parte del ciclo que sigue es complicada, de modo que invertir Ia prueba y sangrar otro nivel podria anidar profundamente el programa. 3.8 Goto y etiquetas C proporciona la infinitamente abusable proposicién goto, y etiquetas pi saltar hacia ellas. Formalmente, el goto nunca es necesario, y en la préctica casi siempre mds facil escribir cédigo sin éL. En este libro no se ha usado alguno. ‘Sin embargo, hay dlgunas situaciones donde los goto pueden encontrar un I gar. La més comnin es abandonar el procesamiento en alguna estructura proft damente anidada, tal como salir de dos 0 mas ciclos a la vez. La proposici break no se puede utilizar directamente, puesto que solo sale del ciclo mas no. Asi: for(...) for vu (desastre) carregla ef desorden los Esta organizacién es itil si el eédigo de mansjo de error no es trivial y res pueden ocurrir en varios lugares. Una etiqueta tiene la misma forma que un nombre de variable y es seg por dos puntos. Puede ser adherida a cualquier proposicién de la misma funci de determinar si dos a lidad es yb, tienen un elemento en comin. Una pe SECCIONS coro vEniQueras 73 goto encontrado; J+ no se encontré ningin elemento en comin « ‘encontrado: /*setiene wo: ali] = = El c6digo que involucra un goto siempre puede escribirse si ver al precio de algunas pruebas repetidas 0 variables extra. Por ejemp! queda en los arreglos quedaré ‘encontrado = 1; f (encontrado) 1+ 60 tone uno: ali] = = bli} «/ else J+ no s» encontré algun elemento en comin +! Con pocas excepeiones, como las codigo que se basa en pro- posiciones goto es generalmente mas dificil de entender y de mantener que el e6di- go sin ellas, Aunque no somos dogmaticos acerca del asunto, se ve que las proposiciones goto deben ser utilizadas raramente, si acaso. captuto 4: Funciones y la estructura del programa Las funciones dividen tareas grandes de com nen varias mas pequenas, sobre lo que otros y: en lugar de comenzar deste cero. Las funciones apropiadas ocultan los detalles de on de las partes del programa que no necesitan saber acerca de le s6lo algunas grandes. Un programa puede residir en uno o més archi- vos fuente, los cuales pueden compilarse por separado y cargarse junto con f ciones de biblioteca previamente compiladas. No trataremos aqut tales procesos, puesto que los detalles varian de un sistema a otro. La declaraci6n y definicién de funciones es el area donde el estindar ANSI ha hecho los cambios mas visibles a C. Tal como mencionamos en cl capitulo ahora es posible declarar los tipos de los argumentos cuando se declara una fi cidn, La sintaxis de la definicién de funciones también cambia, de modo que las, dcclaraciones y las definiciones coincidan. Esto hace posi pueda detectar muchos més errores de 1o que podia ant 's argumentos se declaran con propiedad, se real El preprocesador de C tambi Procesador incluyen un con; 4.1 Conceptos bésicos de funciones Para comenzar, disefiemos y escribamos un programa que imprima cada linea de su entrada que contenga un “patron” o cadena de caracteres en particular. 8

También podría gustarte