You are on page 1of 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,

You might also like