Documentos de Académico
Documentos de Profesional
Documentos de Cultura
El Lenguaje de Programacion C (Ansi C) 2 Ed Kernighan - Ritchie Espaol Spanish
El Lenguaje de Programacion C (Ansi C) 2 Ed Kernighan - Ritchie Espaol Spanish
stropy: copia t hacia void strepy(char +s, char +t) ( sat J+ srcpy: copie t haota s; version 3 con apuntadores */ void elcopy(char +=, char #1) 4 while (+++ = +14 +) 1=0; 3 ‘while (al = ¢ fi) != 40) Sey } En contraste, agul esti una versién de strepy con apuntadores: ‘J+ steepy: copia | hacia 5; veraiéx 1 con spuntadores +/ ‘void strepy(char +3, char +t) { while (9 = +1) = “\0) [ atts tees ‘Aunque esto puede parecer mi ‘notacion es considerable, y debe ‘Srocuentemiente en programas de . En la biblioteca esténdar () strepy, devuelve la cadena objetivo ‘como el valor de la funcién, La segunda rutina que examinaremos es stromp(s,t), que compara las cadenas sy ty regresa un valor negativo, cero © positive si s es lexicoarafi- 1, huesto que se encor que # y tno coinciden, t ) Osta==t, 30 Puesto que los argumencos se pasan por valor, stropy puode urilizar Jos pad la forma que le parezca mejor. Aqui hay apuntadores convenie lzdos, que se desplazan a lo largo del arreglo un cardeter a la ‘\O’ con que termina 4 se ha copiado a 8, { En la practica, strepy no ve eseribiria como se mostr6 anteciormente. Los p agramadores expertos de C preferirian Js steopy: copia t hacia s; versién 2 con apuintadexes +/ ‘oid strepy(char 4s, char *!) { while ((se+ + = st4 4) 1= 40) + Esto traslads el incremento de s y de t hacia dentro de la parte de prueba clo. El vak 1a version con apuntadores de stremp: /* stomp: ragrasa t +f int stromp(char *6, char *)TI APUNEABORES ¥ ARREGLOS ‘carcteLo Puesto que ++ y ~~ son operadores prefljas o postfijos, se presentan ot vombinacionss de *, ++ ¥——, aunque con menos frecuencia, Por ejemplo, de traer el caracter al que punta. En efeeio, la pareja de oy sp++ = val: val = py + mete val en la pila */ saca el tope de Ia pila y lo pone en val */ ‘son expresiones idiométicas estindar para meter y sacar algo de una pila; Ia seecidn 4.3, con apuntadores de la funcidn streat que s ia cadena ¢ a] final des. = muestra en el capitulo 2: stroat(e,)) Ejercicio 5-4. Escriba la Funciéa strend| ) copia hasta n caracteres de * hacia s, En ‘apéndice B se exponen descripciones més completas, = 5-6, Reescriba los programas y ejercicios apropiados de los capitula leando apuntadores en ue, a diferencia de los enteros, no se pueden ot iple ope donde entran los arreglos de apuntadores. cordenar se almacenan juntas en un gran arreglo de caracter : fener acceso & cada Linea por medio de un apuntador 2 su primer cardcier. SEOCION 56 ARREGLOS DE APUNTADOKES; APUNTADORES A APUNTADORES 119) «i lado, [08 apuntaclores se pueden almacenar en un arregio. Dos Iineas se pueden Zomparar pasando sus apuntadores a stromp. Cuando clos fineas desordenadas Genen gue intercambiarse, se intercambian Jos apuntadores en el arreglo de apun- tadores, no [as lineas de texto. lee todas tas tineas de entrada ‘ordénatas inprimelas en arden es mejor dividir el programa e n momento el paso de ordenamiento, y concentrémonos en las ¢s- tructuras de datos y la entrada y salida, La rutina de entrada tiene que reunir y guardar los caracteres de cada linea, y coustruir un arreglo de apumadores hacia las Wneas, También debe cont ada, puesto que esa informacién se requiere para el orde- ebido a que Ia funcién de entrada sl iene que imprimir las lineas en el orden en que apare- en en el arreglo de apuntadores, include ‘include « ‘deline MAXLINES 8000 finde # do .0a8 por ordenar +! char +linopte[MAZLINES); _/+ apuntadares a lineas de texto */ ‘at readhines(char Voie waitelines(char ine eid geort(ohar inept | nt Jolt, nt sight); + oxdena Iineas de entrada */ ‘aain( )Br SPUNTADORES Y ARKEGLOS en int lines; /+ mimero de linees de entrada leidas «/ a que lineptr es un af tun apuntador @ char. Est i ((nlinee = readline ‘georilinepte, 0, lines ‘old wrilelines{chay slinept| |, lines) ( while (alines—~ > 0) line: lee lineas de entrad / imes(char “lineptl J, st maxtines) int len, nlines; char *p, line! MAXLEN), alin trabajard. lines = 0; white (Ven = getline(ine, MAXLEK}) > 0) Mf (lines >= maxing: | (p = alloc(len)) = = NULL) J+ qoort: ordena v vyoid qsori(char ett, int right) ‘\O% /* climina cardeter nueva tinea */ lineptr[olines+ +] = p; rota nbines; t J+ wsitelinoe: osoribe linees de salide */ ‘Void writelines(char slinepir{ |, int alines) { \a", lineptni); getline se traté en la seccién 1.9. ‘Tuevo elemento es la declaracién para inept: ‘lineptrMAXCINES] void snapichar “vf |,122 APUNTADORES Y ARAECLOS ceaprruny Puesto que cualquier elemento individual de v (alias Hnepte) es un apumtador cardcter, temp también debe serlo, de modo que uno pueda copiarse ai otro, Ejercicio 5-7, Reeseriba readlines para alimacenar lineas en un arreglo prop cionado por main, en lugar de llamar a alloc para obtener espacio de miento. ;Cudnto mas rapido es el programa? 5,7 Arreglos multidimensionales Lenguaje C proporciona arreglos multidimensionales rectangulares, en Ia practica se usan menos que los arreglos de apuntadores. En esta, ‘mostraremas algunas ée sus propiedades, Considérese el problema de la conversién de fechas, de dia del mes a dia. ano y vieeversa, Por ejemplo, ef 1 de marzo es el 60° dia de un ato que no bisiesto, y ol 61° dia de uno que sf los. Definamos dos funciones para hace : day-of-yeer coavierte mes y dia en el dia del ato, y mont (eel dia del ano en mes y dia. Pucsto que esta ltima funcién calcula valores, los argumentos de mes y dia deben ser apuntadores: month day(1968, 60, Sm, &d) hace m igual a 2 y d igual 8 29 (29 de febrero), ‘Ambas funciones necesitan siga, le pasa a feb urante los célculos. Fl arreglo y fas funciones que realizan las transform son como se muestra a continuacién: {0, 31, 28, 31, 30, del ato 8 partic de mes y ato +/ ‘month, int day) int 5, leap; secci0w 37 ‘thon de un arreglo de do ARKEGLOS MULTIDIMENSIONALES 123 oap = yoar¥d == 0 && yeer95100 != Cj year%4d00 = = 0; return day; j Je monthday: obtiens mes, y dia a ‘yoid month day(int year, it yearday, ico de una expresion loxica, come lade leap, ev cero fe emplearse como indice del arroglo daytab. jay, para que ambas pucdan utilizarlo, (imo de char para almacenar enteros pequefos que no son daytab es el primer arreglo de caracteres de dos dimensiones eon el que hemos tratado. En C, un arreglo de dos dimensiones es en realidad un arveglo unidimen- sional, cada uno de cuyos elementos es un arreglo. Por ello, los subindices se es- criben como days /+ [renglén} [columna] +! 5 de modo que los nimeros de mes pue- Puesio que el espacio no es apremiante bse inicia con una fo es més claro arreglo de dos dim en Ia fumeién debe la declaracion de pa iniimero de renglo-124 APUNTADORES ¥ ARREELaS carrot s1CciON 59 AVONTADORES V5. ARKEGLOS MULIIDIMENSIONALES 125 k rota (n <1 f'n > 12)? name(O] ; aame(al; ‘También podria ser Hint daytabt J 130) 1.) porque el nimero de renglones es irrelevante, o podria ser amel] $e almacena un apuntador a ellos. Puesto que ct ame no esté especificado, el compilador cuenta los inicializadores y completa ¢ aximero correcto. 3 un apuntador a 1mm arteglo de 13 entteros. Los (0 que los corchetes [| tienen mas alta preved 6.9 Apuntadores vs. arreglos multidimensionales 1evs ustarios de C algunas veces se contunden con la diferencia entre int tdaytab (13) 6 un arreglo de 13 apuntadores a entero. De modo més general, sélo la primer dimensién (subindice) de un arreglo queda abierta; todas las otras deben e3 carse, En la sevcitn $.12 se discute mas acerea de declaraciones complicadas, Ejercivio $-8. No existe deteccién de errores en day-of year ni en mont Soluclont:ntodefesto: asignade 200 locaidades de tamano de un int, y se emplea el cdlculo convencional de subindices rectangulares 20%rengién+columna para encontrar elemento 5.8 Inicializacién de arreglos de apuntadores Considérese el problema de escribir una funcién month name(n), que re tun apuntador a una cadena de caracteres que comiengan el nombre del n-Est mes. Esta es una aplicacién ideal para un arreglo static interno, mot contiene un arreglo reservado de cadenas de caracteres, y regresa un apur Ia cadena apropiada cuando se llama. Esta seccién muestra como se ese arreglo de nombres. La sintaxis es semejante a la de iniciaizaciones previas (08, otro a cincuenta y algin otro a ninguno. ingue hemos basado esta discusion en crminos de enceros, el uso mas fre- as de caracteres de + month name: —regresa él sombre del n-esimo mes +/ char “month nametint 2) char *naime| ] = { "Mos iegal’, “Ene, “Feb', "Mar" js nombre: ‘Mes legals}126 APUNTADOMES ¥ ARREGLOS con la de un arreglo bidimensional: char anamme| ) [15] = { "Mos ilegal”, "Ene", "Feb", "Mar" J; 0 Ejercicio 5-9. Reescriba las rutinas day_ot_year y month_day empleando apy tadores en lugar de indices. 0 5.10 Argumentos en la linea de ordenes Dentro de un medio ambiente que maneje C hay una forma de pasar ar mentos en a lines de érdenes ode parametrosa un programa cuando empieza ejecucion. Cuando se llama a main se le invoea eon dos arguments. El prime (llamado por convencion arge, por ars i inea de Ordenes con los que se invae6 el programa; el segundo (axgv, por vector) €s un apuntador a un arreglo de cadenas de caravteres qu ne los argumentos, uno por cadena, Se acostumbea utilizar niveles ra lar esas cadenas de caracteres. imprime ‘ola, mundo Por convencién, argv{0] es ef nombre con ‘que argc es por lo menos 1. Si arge es 1, entonce no hay argu después del nombre del programa. En el ejemplo anterior, argo es argv(l] y argv{2] son “echo”, y “mundo, respectivamente guimento optativo cs argv[i] y el ultimo es axgvlargo—]; ademas, e est ‘quiere que argv[arge] sea un apuntador nulo, ergy: seCC10N 510 ARGUMENTOS EN LA LINEA DE ComANDOS 127 La primera version de echo trata a axgy como un arreglo de apuntadores a ca acters: ‘include J+ eco do los argumentos de la linea de éidenes; Ie. versidn «/ main(int arge, char argv J) int 5 argv) 2" ‘Como argv es un apuntador a un arreglo de apuntadores, se pucden manipular al apuntador en Tugar de indexar al arreglo. Esta siguiente variacién se basa en Incrementar argv, que es un apuntador 2 un apuntador a char, en tanto se dis ‘minuye arge: #inolude los arguuisntos de la linea de érdenes; 2s, version +/ ‘argc, char “ar while (—arge > 0) "Shadée", +4 tangy, (argo > 1) 2": retam 0; ' Puesto que argv es vin apuntador al inicio del arreglo de cadenas de argumentos, Inerementarlo en | (+ + argv) lo hace apuntar hacia argv(1] en lugar de apuntar ‘4 argv[0]. Cada incremento sucesivo lo mucve al siguiente argumento; entonces “argy es el apuntador a ese argumento. Al mismo tiempo, arge disminuye; cuan: 4 lesa a cero, no quedan argumentos por imprimit. Ex forma alternativa, podemos escribir la proposicién print! como priatlarge > Esto demuestra que el argumento de formato del print! también puede ser una Soren es Como un segundo ejemplo, hagames algunas mejoras ‘On 4.1 que encuentra un patron. Si se recuer: del programa, un e-quema que obs del programa grep de UNIX, cambiemos el programa de moi FE patron que se debe encontrar se espeifique por el primer argummento en ka de ordenes. "es", ++ tara), programa de la sex12 APUNEABOKES y ARREGIOS Amncludo include ‘#deliae MAXLINE 1000) int qeiline(ehar vline, int max); (+ find: imprime Mneas que coincidien con el patrén del ler. arcumente main(int arge, char *argv! J) { har line[MAXLINE]; int found = 0; 4 (arge t= 2} pprial(*Uso: fad patsso\n"), ' Los arguments para opciones eben ser permitidos en cualquier orden; resto del programa debe ser independiente del numero de argumentos que ran presentes, Ademés, es conveniente para los usuarios que los argument Jas opciones puedan combinarse, como en find —ax pairdn Aqui esta el programa: seccION S10 ARGEMESTOS EN LA CINEA DECOMANDOS 129 #inclnde include ‘#detine MAXLINE 1000 {nt getline(char line, int max}: (> ind: imprime Vneas que coinciden con el patrén del ler. argumenta +/ ‘satn(int argo, char sargvt 1) { cchar line[MAXLINE]; eng lineno = 0; int ¢; except = 0, number = 0, found = 0; hile (—-arge > 0 86 (++ +argyi[0] == 9 while (¢ = ++ +argvid)) switch (c) ( case's: excopt = 1; break; umber = 1; break: default: printi“find opeisn ilegal Yeo\n", ©); arge = 0; found = —1) break;130 APUNTADURES ¥ ARREGLOS sin procesar ¥ argv apunta al primera de tstos. AS, axge debe ser 1 y *argy det + tangy es un apuniador a un argumento tx mer carter. (Una formaalvernativa vil ne mids prioridad que * y que + +, k resiGn seria tomada como * + + (axgul émpleamos en el ciclo mas interno, donde la tarea tas; en tal caso, serd mis intuitivo separarlas en dos 0 tres pasos. ome 234 4 + se evallia.como 2 G44). 0 |. Modifique el programa entab y detab (escrites como ejerci ara que acepten una lista de puntos de tabulacién como arg los tabuladores habituales sino hay argumentos, 0 Ejercicio 5-12. Extienda entab y detab de modo que acepten la abreviatura, entab—m +n que indica puntos de tabulacion cada # columns, iniciando en la columma m. leccione ef comportamiento por omision mas conveniente (para el usuario). imprime las Gltimas 7 lineas. El progeama debe comportarse en forma 1 sin importar cua poco razonable sea la entrada o el valor de mt. Escriba él mma de manera qué haga el mejor uso de a memoria disponible; las Incas almacenarse como en el programa de ordenamiento de la seccién 5.6, 00 arreglo de dos dimensiones de tamaio fijo. © 5.11, Apuntadores a funciones En C, una funcién por si sola no es una variable, pero es ‘adores a funciones, que pueden asignarse, sor coloendos en si SeCCION St APUNTADORES A FUNCIDNES 131 ones, represados por funciones y otras cosas més, Ilustraremos esto modifican- sdinmiento de ordenami it que determina el orden de cualquier par de 1 ¥ unt algoritmo de ordenamiento que realiza comparaciones ented I a es de comparaci renies criterion, Estas la matodo. La comparacién lexicogréfica de dos lineas es realizada por stremp, como an- ‘cs; también requeriremos de una rutina numemp que compare el valor numérico dz dos lincas y regrese a misma clase de indicacin que hace stremp. Estas fun- ciones se declaran antes de main, y a qsort se le pasa un apuntador @ la funcién a. Se ha hecho un procesamienio deficiente de los errores en los atx con el fin de concentramnos en los elementos prin #inclde inchude ‘#doline MAXLINES 5000 ‘char *linoptr(MAXLINES}, 1+ mdi # de lineas @ ordenar */ apustadoree a lineae de taxto +/ dinex(char +lineptel telinoa(char “linen ‘oid geontvoid “lineptr (> orden linens de ent main(int argo, char +arg 4 int alinee ‘nt cumaric = 0) J» mimoro de lineae de entra Js 1 si oe ordenamisnte oumés if (arge > 1 8 stremp{argy{l), "-n") = = ;, MAXLINES)) >= 0) { ? aumomp : strome)};182 ARUNTADORES ¥ ARREGLOS canmens ceCc1ON 52 APUNTADORES \ FUNCIONES 1383 printf (enicada demasiado grande para ser ordenada\n") ‘esconsistemie con la declaracin; comp es un apuntador a una funcién, “comp es mend jg fancion, y ’ (oomp) (vil, lett) En la llamada a qsort, stromp y numemp son direeciones de funciones. Ci gsla llamada a 0s paréntesis son neeesarios para que los componentes sean correctamente asociados; sin ellos, int tcomp(void +, void *) [+ INCORRECTO «/ ‘que comp es una funcién que regresa un apuntador a is se sabe que son funciones, el operador & no es necesario, en la misma forma mo es necesario antes del nombre de un arreglo. Hemos eserito qsort de modo que pueda procesar cualquier tipo de dato, sélo cadenas de caracterés, Como se indica por la funcién prototipo, qsort tun arreglo de apuntadores, dos enteros y una funcién con dos argumentos de apuntador. Para los argumentos apuntadores se emplea @] tipo de apuntador ngrico void *, Cualquicr apuntader puede ser forzada a ser void * y res ‘sin pérdid de in ntos a veid*, El elaborada cast del argumento de la funci Ta funcion de lo cual es muy cadens mumeéric #aclade ‘pumcmp: compare sl y 32 numéricamente ¥/ int aumemp(char *s1, char "s2) { double vl, v2 I+ geoxt: clasitica v{let]...vjright] en orden axcendente +/ void qsor( vid tn int (rcomp) (void +, void +)) { inti, last; return — 2; void swap(void *4{ J, amt, it); ase df (vl > eZ) return 1; if (elt >= right) /*no hace nada si el arreglo contiene */ ‘abe return: f+ mence de dos aletnentos */ retuen 0 + right)2); b La funcién swap, que intercambia dos apuntadores, es idéntica a la que pre Seatamas anteriormente en este capitulo, excepto en que las deelaraciones se han cambiado a void +. void sirap(void of) , int georty, Inst +1, right, come); } {Las declaraciones dchen esiudiarye con euidado. El cuarto para comp) (veld, void + vg plea 3) Puede agregarse una ‘os algunas se convierten Rjerciclo $-14. Modifique el programa de ordenamicnto de modo que maneje lia bandera —r, que indica ordenar en orden inverso (descendente). Asegirese de que “x, trabaja con —n, 0 ue indiea que comp es un apuntador s una funcidn qué tiene dos argu void * y regresa un int EL uso de comp en la linea <0 ((reomp)134 APUNTADORES ¥ ARREGLOS caprrut jereicio 5-15. Agregue la opcién ~f para igualar las letras maydseulas y mings nodo que no se haga distincién entre ellas durante el ordenamientos comparat, ay A son iguales. 5 5-16, Agregue la opci6a ~d (“orden de directorio’ independiente de opciones. “df para las entradas y —u para los nilmeros de pagina. 5.12 Declaraciones complicadas fencién que regresa un apuntador a int +/ (PC): (* pf: apuntador a une funcida que regresa un int +f ihustra el problema: + cs un operador prefijo y'ticne menor precedencia que (}, ‘modo que Jos paréntesis son necesarios para obligar a una asociacin apropi jon es extrafo que aparezcan declaraciones verdade ‘iGn verbal y viceversa. La deseripeién verbal se lee de izai La primera, del, es la més compleja, Convierte una dey deseripcién hecha con palabras, camo en estos ejemplos: aa tag. argv: apuniador a un apuntador a char int (edayr Gaylab: apuntador aun acroglo[13] de int int *daytabl23) daytab: arreglo[l3] do apuntadores 2 int ‘woid seompt ) comp: fuacion que regresa apuntador a void iCC10N 5.2 DECLARACIONSS COMPLICADAS 138 oie ¢comp) () char (6 4X: funeion que regress un apuntador @.un arreglal | de ‘ana fanesoa que ragress char apuntsdor a una juncion que regress void de apuniadores's una funcién que reareta tan apuniador 2 un arreqlo[8] de char dol esta basada en la gramatica que’ especifica un deckaraclor, que s¢ define en forma precisa en cl apéndice A, seccién 8.8; ésta es una forma simplificada: jiado como como éste (en donde dchdirecta se ha aby ( . pla ul ) 0136 APUNTADORES v ARREGLOS El corazsn del programa del es un par de funciones, del y dirdel, que a declaracin; el programa se conoce streatfout, “apnmtador a"); ) I+ ditdel: reconoce an declarador ditecto +/ vold dirdl(void) { int type; ‘U Gokentppe == ({ aol; 5 Cokentspe 1= 9) printf oer: fats )\n") } ele if (tokentype. = = NAME) /+ norihre de variable +/ stropy(name, token); se prinii('error: nombre 0 (de!) esperade\"), ‘hile (ype = geiidken( )) = = PARENS | type “= BRACKETS) Js (del) o/ cupera mucho ante los ervores, lo confunden. Fsas mejoras se dejan como ejereicios. carn funciones se Maman recursivamente una a siCc1ON 12 BECLARACIONES COMPLICADAS 137 “Aqui estiin las variables globales y Ia cutina prineipal: sinclade include #inclnde ‘#deline MAXTOREN 100 enum { NAME, PARENS, BRACKETS }; > tipo del iin token «/ int ‘okentype; ‘char ‘oken{MAXTOKEN]: ‘cher name[MAXTOKEN]; Mess awhile (e = steht 3) = =138 APUYTADOKES v aRREGLOS caprreto. totum tokentype = PARENS; Fase { ungetch(<); le del se recupere de errores en la entrada, © jue undel de modo que no agregue paréatesis redundantes 5-20, Extiende del para que maneje declaraciones con tipos de argu- 19s de funciones, calificadores como const, eioétera. relum tokentype = ¢; } Setch y ungeich se discutieron en el capitulo 4, Es mas facil ir en Ia cireccién inversa, especialmente si no nos preocup: or la generaci Paréntesis redundantes. El programa undel convierie descripcién verbal como "x ¢s una funcidn que regresa un apuntador a un de apuntadores a funciones que regeesan char”, que se expresard como C11) Tuncién undel también emplea las mismas variables externas que del. i {+ undel: convierte una descripelén verbal a declaracién */ main( ) 4 ‘at type; ‘char temp|MAXTOKEN),capuoe: Estructuras ‘Una estructura es una coleccién de una o mas variables, de tipos posiblemente diferentes, agrupadas bajo un solo nombre para manejo conveniente. (Las ex- inieturas se eonocen como “records” en algunos otros lenguajes, principalmente Pascal.) Las estructuras ayudan a organizar datos complicados, en pai dentro de programas grandes, debido a que permiten quea un grupo de variables relacionadas se les trate como una unidacl en lugar de como entidades separadas. ‘Un ejemplo tradicional de estructura es un ernplea- do esta descrito pot un conjunto de atriby mamero del seguro social, salario, ete. Algunos de estos atributos pued vez, Ser = eomponentes, como los tiene un domicilio y ‘alo un salario. Ciro ejemplo, mas tipico para C, procede de las gréficas: um pun- to es un par de coordenadas, un recidngulo es un par de puntos, y otros casos El principal cambio realizado por el esténdar ANSI es la defincién de la asig- acon de estructuras —las estructuras se pueden copier y asigiiar, pasar a funcio- nosy Ser regresadas por Funciones. Esto ha sido manejado por muchos compiladores durante Varios alos, pero las propiedades estan ahora definidas en forma precisa, Las estructuras y los arreglos automaticos ahora también se pueden inicializar. 8.1 Conceptos basicos sobre estructuras Definamos algunas estructuras propias para graficacién. EI objeto biisico es ‘wn punto, del cual supondremos que tiene una coordenada x y una coordenada ¥, ambas enteras.142 Esrmucruxas carrito s seccion 62 [ESTRUCTURAS V FUNCIONES 143 Los des camponentes pueden ser colocados en una estructura declarada asi or pgniectn al nombre URSIN Gon Jas coordenadas del pun- Fl opecador miembro de estructura el nombre del miembro. Por ejemplo, to ph printi'bd, 4d", plix, ply); pata ealcular Ja distancia del origen (0,0) a pt, double dist, sqr(double) struc ity La palabra reservada struct presenta la declaracion de una estructura, que es una lista de declaraciones entre llaves, Un nombre optativo, llamado rétuto de. estructura, puede seguir a la palabra struct (como aqui lo hase point). El rd da nombre a esta clase de estructura, yen adelante puede ser utilizado como abrevintura para la parte de decta as variables nombradas dentro de la estructura se aman siembros. miembro de estructura o rétulo, y une variable ordinaria (esto es, no. miembs x pueden tener el mismo nombre sin conflicto, puesto que siempre se pueden dis i pie ‘mos nombres de miembros, aunque por cuestiones de estilo se deberian de usar [| uit por el contexto, Ademas, en diferentes: pil dist = sari((double)pt.c* px + (double)pty + pty); Las estruet jeden anidarse. Una representacion de un rec tun par de puntos que denoran las esquinas diagonalmente Una declaracién struct define un tipo. La llave derecha que termina la e de miembros puede ser Seguida por uns lista de variables, como se hace para cua quier tipo basico, Esto es, struct rect { struct { 2.) 8 struct pein s sintécticamente andlogo a y SES ‘La estructura reot contiene dos estructuras point. Si declaramos screen como jo de que cada proposicién declara a x, y y # como variables del tipe nombrado y causa que se les reserve espacio voutiguo. Una declaracién de estructura que no esta seguida por una lista de variabl no reserva espacio de almacenamiento sino que simplemente describe una plan ola forma de una ia declaracion esta rotulada, ¢ snes de instancias dela esirue de point, struct rect screen; cntonices screen. pil se refiere a la coordenada x del miembro pil de screen, define una variable pt que es una estructura de tipo struct point. Una estruct se puede inicializar al senuir su definiciém con uma lista de inicializadores, cada uno una expresidn constante, para los miembros: struct point maxpt ~ { $20, 200); ‘Una estructura automuitica también se puede inicializar por asignacién o la o a una funcion que regresa una estructura del tipo adecuado. Se hace referencia. a un miembro de una estructura en particular en una eX resin con una construccién de la forma nombre estructure.mlombro 6.2. Estructuras y funciones cas operaciones legales sobre una estructura son eopiarla 0 asignarla ambos, La copia ¥’la asignacién incluyen pasarlas como argumentos a funciones y también regre- Sar valores de funciones. Las éstructuras no se pueden comparar. Una estructura Se puede iniializar con una lista de valores eanstantes de miembros; una estruc ‘ura automatiea también se puede inicializar eon una asignacion,144 esraverueas carttutog Investiguemos las estructuras eseribiendo algunas funciones para maniput puntos y retangulos. Hay por lo menos ites acercamicntos posibles: pasar radamente los componentes, pasar una estructura completa 0 pasar un apuntadk sella. Cada'uno tiene sus puntos buenos y malos. La primera funcién, makepoint, toma dos enteros y regresa ua estructy poial: 1 \Notese que no hay conflicto mismo nombre; incluso la struct rect screen; struct point middle; struct point makepoint(int, is!); sercon.ptl = makepoint(0, 0); screen pl = makepoint(XMAX, YMAX); middle = makepoint(ecreen.ptl.x + screen. pt2.x)/2, (screen ptl-y + screen.pi2.y)/2}; EL siguiente paso es un conjunio de funciones para hacer operaciones arit ‘icas sobre los puntos. Por Js addpolst: suma dos puntos +/ stroct point addpeini(struct peint pl, suet point 2) selum ph; } Aqui, tanto los argumentos como e! valor de retorna son estructuras. Incre ‘amos los componentes en pl en lugar de utilizar ex poral para hacer énfasis en que los parémetros de Valor como cualesquiera 0170s, secon 62 ESTRUCTURAS YFUNCIONES 148 Como otro ejemplo, Ja funcién ptinzect pruca si un punto esta dentro de un recténgulo, donde hemos adoprado la convencién de que un recténgulo incluye is lados izquierdo ¢ inferior pero no sus lados superior y derecho: (+ ptineoot: regrosa sip est en 1, O sino lo esta «/ {nt plinnect(vicuct point p, struct veet ¥) { golumn p.x >= 1pll.x G6 px < rpihx 8 py >> reply G8 py < Kp: b sto supone que el rectdngulo esta representado en una forma esténdar en donde rdenadas ptl son menores que las coordenadas piZ, La siguiente funcién un rectdngulo, garantizando que esté en forma candnica: (+ canonrect: pone en lorma candnics les coordenadas de wn rectanguls +! pact rect canonrect(struct rect ¥) struct rect tempi temp ptl.x = min(r.ptl.x, rpt2x); temp.ptl.y = min(r.ptl.y, r.pi2.y); temp.pt2.x = max(e pix, rpl22); tomp.pi2.y « max(rptl.y, rpt2y); return temp; ) una estructura granéle va a ser pasada a una fu pasar un apuntador que copiar fa estructa ructuras sont como los apuntadores « variables ord) struct point *Dp; dive que pp ¢s un apuntador a una estructura de tipo struct point. Si pp apunta @ una estructura point, *pp es la estructura, y (*pp).x y (*pp)-¥ son los miem- bros. Para emplear pp, S¢ podria escribir, por ciemplo, struct point origin, “pp; pp =Borigin; 1 origen es (S60, %d)\n", Cpp).x, (+ppl.y: ‘on necesarios en (*pp).x debido a que la precedencia del opera- dde estructura . es mayer que la de +, La expresion »pp.x significa “(Pp.x), to cual es ilegal debido a que x no es un apuntador.146 estaucruRas, capmtuto, cere ABREGLOS DE ESTRUCTURAS 147 Los spuntadores a estructuras se usan eon tanta frecuencia que se hap cionado una notacién alternativa como abreviacion. Si p ¢s un apuntador a ‘tructura, entonces Jos nombres, ¥ un arreulo de enteros para las cuentas. Una posibilidad es usar dios arreglos paralelos, keyword y keyconunt, char +keyword(NKEYS| int keycount{NKEYS} pero el hecho de que Los arreglos sean paralelos suaiere una organizacidn diferen- fe, un arreglo de estructuras, Cada entrada de una palabra es una pareja: pe >milembra de estructura jembro en particular, El operador -> es un signo menos seguida por >.) De esta manera podriamos haber escrite ‘origen es (%64,¢d)\n", pp->, pP->); Tanto . como — > se asocian de izquierda a derecha, de modo que si ten char *word: ‘at count; struct wet 3, 9p = y bey un arreglo de parejas, La declaracién de estructura stroct key { entonces estas cuatro expresiones son equivalentes: ‘char "word; ee iat (rp-> ptll).x a un tipo de estructura key, define un arreglo keytab de estructuras de 10, ¥ reserva espacio de almacenamiento para ellas. Cada elemento del arre- ‘Los operadores de estructuras . y «>, junto con ( ) para lamadas a funci Shop une ecirvelere, Beles innibnste podtta esebir ori ¥ [] para subindices, estén hasta arriba de la jerarquia de precedencias y se sian estrechamente, Por ejemplo, dada la dedlaracién strat key ( eee ha wo bie i : we Struct hoy keytab KEYS); entonves +4 poten ‘es andloga a otras anteriores —la defini incrementa a Jen, no a p, puesto que los paréntesis implicitos son + abirecieeule ot an ise clones sais ase Los paréntesis se pueden emplear para alterar la asociaciOn: (+ + p)-—>lon inen ies de tener acceso a len, Y len incrementa a p struct key { char *word ‘p+ +->atr incrementa a p después de hacer el acceso a lo que str apunt 6.3 Arreglos de estructuras CConsidérese eseribir un programa para contar las ocurrencias de cada reservada de C. Se requiere de un arreplo de cadenas de caracteres para mallizadores se listan en parejas correspondientes alos miembros de las . Podria ser mils preciso encerrar los inicializadores para cada“ estruetura entre Haves, como en pero las Haves internas no son necesarias cuando los inicializadores som varial simples o cadenas de caracteres, y cuando todos estan pr 1 numero de entradas ea el arreglo keytab se caleulard 8 presentes y el [] se deja vacio, progam que ches pas palabras reservadas debe estar orddenada en forma ascendente en Ia include ‘Pinchode #inchde ‘#doline MAKWORD 100 int getword(char +, int binsearch(char *, i ot key +, 1+ cuenta palabras resorvadae do C */ nain{ ) { int a; char word[MAXWORD]; while (aoiword(word, MAXWORD) |= EOF) i ‘eyiak(a|.covnl, keytablal.word); nde la funciona de busqueda binaria que se eseribié en el capitulo rae ARREGLOS DE ESTRUCTURAS 149 rotwen Q; } J binsearch: encuentra una palabra en tabfO). . .tabfn—1) «/ int binsoarch{char *word, struct key tab( | , int 2) 4 ‘nt cond; int low, high, mids a low = 0; bigh = 2-1; while (low <= bi = (low shi if ((cond = stromp(word, tab[mid.word)) < 0} igh = mid — ‘lee if (cond > 0) low = mid + 1; else roturn mid } return “1; ) Mostraremos la funcién getword en un momento; por ahora es suficiente decir que cada Hamada a getword encuentra una palabra, que se copia dentro del arve- alo referido como su primer argume! La cantidad NKEYS es ol de palabras en keytab, Aungue de keytab hasia que se encu Pero esto es mas de lo que se requiere, pu Geterminado con tamano del arregio es mirada, asi que el nt: cde entradas es size of keytab / size of struct key jona un operador 1 ir para ealvular slasof ubjero sizeo! (nombre de tipo)150° stu S£0CI0N 64 APUNTABORES OESTRUCIURAS 151 =A; ira word|0]; dan un entero igual al tamano en byt ‘mente, sizeof produce un valor entero ra, Un nombre de tipo puede ser el n basico como int 0 dou! (0 un tipo derivado como una estructura © un apuntador. En nuestro caso, el nimero de palabras es te céleuta se jeron en cel capi e getword se ha coloca x adelante. La llamada a ungetch represa el caracter a la entrada para la spacios . sy digios; todas doling NEES (slenc! keytab / sizeo(steuct key) ‘otra forma de escribir esto es dividir el tamato del arceglo entre el tamana ‘#deline NKEYS (sizeo! keytab / sizeot keytabl0}) la ventaja de que no necesita set modificado si el tipo vambia, izeof no se puede utilizar en una linea #i, debido a que el preproces de tipos. Pera la expresion del #define no es evaluada el preprocesador, y aqui el codigo os lexal. ‘Ahora la funcién getword. Hemos escrito una funcién getword ‘que se requiere para este programa, pero no es complicada. ‘palabra” de la cotrada, donde una palabra es cualquiet dena de letras y digitos que principia con una espacio en blanco, El valor de la funcién EOF para fin de archivo, o el cardcter en sf mismo cuando no €s J+ qeiword: obtiene la siguiente palabra o cardcter de la entrada +) jab getword(char “word, int lim) { 6.4 Apuntadores a estructuras ara ilustrar algunas de las consideraciones invalucradas con apuntadores y arreglos de estructuras, escribamos de nuevo el programa de conteo de palabras, reservadas, esta vez utilizando apuntadores en lugar de subindices. Ladeclaracién externa de keytab no requiere de cambios, pero main y binsearch. si necesitan modificaciones, #unclude #inclade < ctype b> #include #dsfine MAXWORD 100 int getword(ohar «, int); struct kay -binsearch(char «, struct key Fs euonta palabrae xeservadas de C; version con apuntadares «/ main) 1 cher word[MAXWORD} struct key 2; while (getword{word, MAXWORD) = EOF) i ((salpha(word|0))) Uf (p= binsearch{word, keytab, NKEYS)) != NULL) po>count+ +7 for (p = keytab; p < keylab + NKEYS; p+ +) i (p—>count > 0) printd("966a Sein", p—Seounl, p~> word) return 0; for ( ; ~-lim > 0; w+ +) = gotch( )) (ane eeaesubce sie s6CCION 65 ESTRUCTURAS AUTORREFERENCIADAS 183, imer elemento después det tin de un acreglo (esto es, =tablat] + int 2) + binsoarch: encuentra una palabra en struct key *binsearch(char *woed, struct key { int cond struct key “low = Stab) struct key *high = struct key +d; iéa con p toma en cuenta et srementa_p con la cantidad correcta feglo de estructuras, y la prueba while Clow < igh) { mid = low + (high-low) / 2; [cond = stremp{word, mid— >ward)) < 0) high = mid) ‘else if (cond > 0) low = mid + 1; else zoturn mid; 1 return NUL; comentario acerca del formato del programa: cuando una funcidn regresa un tipo complicado como un apuntador a estructura, como en scuct key sbinsearch(char *word, struct koy “tab, int) ‘el nombre de la funcién puede ser dificil fexto. Por eso, algunas veces se emplea Agui hay varias cosas que ameritan nota. Primero, la declaracién de bin debe indicar que rearesa un apuntador a struct key en lugar de un entero; eto a tanto en cl prototipo de la funcién como en binsearch. Si binsearch enc palabra, regresa un apuntador a ella; sino, regresa NULL. ‘Segundo, ahora se tiene acceso a los elementos de keytab por medio de apus tadores, Esto requiere de cambios significativos en binseazch. izadores para low y high son ahora apuntadores al inicio y just despues del final de la tabla, EL cdlculo del elemento intermedio ya no puede ser simplemente yy de encontrar con un editor de lo alternative: sieucl key + binsearch(char *word, struct key #lab, int n) Esto ¢s algo de gusto personal; seleccione la forma que prefiera y manténgala. mid = (low thigh} (2 /* INCORRECTO +/ 85 Estructuras autorreferenciadas puesto que I ma, por lo qn 4 de dos apuntadores es ilegal. Sin embargo, Ta resta es le ighdow ese! miknero de-elementos,¥-aal Supbngise que descamos mana problem mis gta de contar as ote TPencias de codas las palabras en alguna Pot anticipado, no podemos or mid = low + (high-low) / 2 hace que mid apunte al elemento que esté a la mitad entre low y high. EL cambio més importante es ajustar el algoritmo para estar Seguros de qUs ‘no genera un apuntador ilegal 0 acceso a un elemento Fuera del ar alo. ambas fuera de los limites leenl desreferenciar las Sin embargo, la definicién del lenguaje garantiza que la aritmética de apu! ide a crecer en prop lemos organizar los ins? de palabras que ya es mantener siempre ordenado el con; jocando cada wna en su posiciOn c154 eSTRUCTURAS earrrvt de cualquier manera, no se podria realizar recorriendo fas palabras en un arrey lineal —tambien tornado demasiado tiempo. En lugar de ello utilizaremos i El drbol contiene ua “nodo”” por cada palabra ‘up spuntador al texto de la palabra tuna cuenta dal numero de ocurrencias un apuntador al nodo hijo de Ia iaquiorda tun apuntador al node hija de la darecha \Ningiin nodo puede tener més de dos hijos; s6lo puede tener cero 0 uno, Los nodos se mantienen de tal manera que en cualquier nodo el subsérbol | quierdo contienc sélo palabras que son lexicograficamente menores que la ‘bra que est on e) nodo, y el subdrbol de la derecha sélo contiene palabras son mayores, Este es el arbol para la oracién “Es tiempo de que todos los ‘bres buenos vengan al auxilio de su partide”, como se construy6 al insertar palabra tal como fue encontrada. aN ae” Sane we, oh Sys ahah Nes 7 \ auzllio hombres partido Para descubrir si una nueva palabra ya esta en cl art rela con la que esta almacenada en ese noda. Si coincide, la pregunta se resp la nueva palabra es menor que la palabra del érbol, conti ra manera, en el nodo hijo: Ia palabra nueva ne .propiado para agregar la sinict tnode ( + el nodo del Arbol: +/ ‘char “word; f> apunta hacia ol texto +/ int count; f+ mimers de ocurrencias */ struct inode «leit struct inode “right; hijo a la izquierda ala derecha */ ESTRUCTURNS AUTORREFERENCIAOAS 18S sec1ON 6S za declaracion recursiva de un nodo podria parecer riesgoss, pero es correcta. fo ilegal Ue ura esiruetora contenga ina instancia de si misma, ere struct tnode left; igeclaea a Tolt como wn apuntador @ trode, no como un node en sf ‘Ocasionalmente, se requiere de una variacgn de estructuras autorreferenciadas: dos estructuvas que Hagan referencia una a la otra. La forma de manejar esto es: struct t ( suet s*p; /* p apunta a una s +/ if struct «4 sicuct ts; f+ q ayiunla a uma t+) todo el programa es sorprendentemente pequeho, dado un instala en el arbol con #inclade rnclude ‘#detine MAXWORD 100 ruct inode *addtreo(struct tnode +, char *); void treep: 1 inode *); lt gotword(cbar *, it}; 1+ conteo de irocuencia do palabras */ maint ) { struct node oot) char word/MAXWORD]; root = NULL; while (getword(word, MAXWORD) != 80F) ((salpha(wordl root = addtzse(root, word); sreeprint(rcot return O; Jin addtree es recursiva. main presenta una palabra al nivel superior ‘cl arbol (fa raiz). En cada etapa, la palabra se compara con la que ya esté alma156 ESTRUCTUEAS crea un nuevo nodo, addtree regresa un apuntador a él struct tnode “talloctvoid); char *strdup(char *); new: agvege un nods con w, ano bajo p */ struct tmode raddiroe(etruct inode »p, char w) 4 int cond) == NULL) /+ Megé una nueva palabra +/ p= tallool); (crea un auewo modo +/ po>ward = stedupl); pr>eoust = ly praleft = p—>right = NULL; ) else sf ((cond = stromp(w, p~>word)) poScountt +; + palabra ra else (cond < 0) /* menor que ol contenido del subarbol ixquiordo +f po>left = addtroe(p~>left, w); 4 else J+ mayor gue el contenido del subsrbal derecho poSright = addtrea(n> right, ve); rolurn p: y ls nueva palabra se copia a un lugar bBlaremos de esas rutinas en un momento.) La cuen sé hacen nulos. Esta parte del eddigo se ejecuta s ando esté siendo agregado tun nuevo nodo. Hemos omit impeosicn del arbol p on orcas 4/ void treeprint(atruct tode =p) = NUL) { SECCION 6S LESTRUCTURAS AUTORREFERENCIADAS 187 treeprint(p—>: printl("%4d Ye ‘treeprint(n~ > right) p> eount, p~> word); 1 , Una nota practice: si el drbol se ‘“desbalancea”’ debido a que las palabras no llegan en orden aleatoria, cl tiempo de ejecucion puede aumentar demasiado, En el peor de [os casos, si las palabras ya estin en orden, este programa real cosa simulacién de bisqueda lineal. Existen gencralizaciones del ar 10 padeven de este comportamiento del peor caso, pero no las desc iremos ces dé dejar este ejemplo, también es descable una breve exposicién sobre ‘oblema relacionado can los asignadores de memoria. Es claramente desea- ble que s6lo exista un asignador de almaccnamiento en un programa, aun cuando asigne diferentes clases de objetos. Pero si un asignador va a procesar peticiones de, digamos, apuntadores a char y apuntadores a struct tnodes, surgen des pre- sguntas, Primera, :cémo cumple los requisitos de la mayor parte de las mndquinas reales, de que los objetos de ciertos tipos deben satisfacer restricciones de alinea- cidn (por ejemplo, generalmente los enteros deben ser situados en localidades pa- a4)? Segunda, ,cusles declaraciones pueden iraiar con el hecho de que un asigna- dor de memoria necesariamente debe regresar diferentes clases de apuntadores? Los requisitos de alineacién por lo general se pueden satisfacer facilmente, al espacio desperdiciado, asegurando que el asignador siempre regre 0 de declaraci6n para una funcida c pregunta acerca del para cualquier lenguaje que tome con scriedad la metodo apropiado es declarar que malloc regres un api at explicitame . malloc y las rutinas relativas estan declaradas en cl header Satdlib.h>. Asi, talloc se puede escribir como #include Js talloc: erga un tnode +/ struct tmode “talloc(roid) 4 return (struct inode +) malloc(sizeoi(etract taode)); ) Strdup simplemente copia la eaden ©, obtenido por una llamada a mal por su argumentoa un lugar segu-158 rsTaLcraAs cart | secciOn ss DUSQUEDA EN TABLAS 159 y regresa un apuntador SHEARER A)" EAS HnlIaNdD Gere sélo cadenas de earacteres. Jookup(e) busca s al lugar ea donde fue encontrado, o NULL ae EI algori queda fash —el pequefio ent ue despues Se usa para index amaleciicands) +3} 4 FL pase NG #/ Gores. Un elemento del arreglo apui quedk gin nombre ha obtenide ese valor. = EET i wate i F [oe =—7] = sombre Seta Ejercicio 6-2, Escriba un programa que lea un programa en C e imprima en or den afabético sada grujo de nombres de variable que sean idénticas en sus pri Un bloque de fa lista es una estructura que contiene apuintadores al nombre, al texto de reemplazo y al siguiente blogue de la lista, Un siguiente apuntador ‘ulo magca el final de fa lista, Ejercicia 6-3. Escriba un programst de referencias eruzacks que imprima una struct alist { ada de la tabla: +/ de todas las palabras de un documento, ¥ para cada palabra, una lista de los struct alist next; /+ siguiente entrada ex Ia cadena */ rmeros de linea en los que aparece. Elimine palabras como * har ‘name; nombre definide *! char *doln; 1+ taxto de roomplazo +! Ejercicio 6-4, Bscriba un programa que imprima las distintas palabras de su en ‘trada, ordenadas en forma descendente de acuerdo con su frecuencia de ocus cia, Precede a cada palabra por su contco. 0 E/ arreglo de apuntadores es 3610 #deline HASHSIZE 101 6.6 Busqueda en tablas sci shitiremos os commoners de un paquets de Doe en las rtinay de manejo de tablas de simibolos de -nplo, considere la proposicion #def de hash posible, pero es pequenta y cfectiva Yash: forma un valor hach para la cadena s */ unsigned hash(char *s) { unsigned haskval; for (hasbval = 0; +8 |= "\0' hhashval = +3 + 1 + hashval; return hachval % BASHSIZE, } La aritmética sin signo asegura que el valor de hash no es negative. se debe reemplazar por 1 Enisten dos rutinas que manipulan los nombres y textos de reempl install(s,t) registra el nombre s y el texto de reemplazo t en una tabla; $ yt160 rsrRuerunas. otra manera, regresa NULL. ‘busca ¢ on hashtab +/ Aeokupchar +s) J» Teokup: struct alist «np; for (ap = hashlabfhash(s)]; np != NULL; np = np~>anext] El cielo for que esta en lockup ¢s la expresidn idiomatica esténdar para moverse sobre una lista ligada: for (ptr = head; ptr != NULL; ptr = ptr~>next) unsigned hashval; (ap = lookup{name hhoshval = hash{naz xnp->aoxt = hashlab[hashvall; Libera la anterior defn +/ NOLL) :CCI0N 67 Ejercieio 6-5, Escriba una funcién undef que cidn de la tabla mantenida por lookup ¢ install imo de int. El tipo Longitud puede emplearse .ctamente de la misma manera en que lo podria Longitud len, maslea: Longitud “lengths! |; De mode asa 1a declaracién Notese que el tipo que se declara en un typedef aparece en Ja posivién de un nombre de variable, no justo después ce la palabra typedef. Sintacticamente, typedef es como las clases de almacenamient 40 nombres con mayiscula } Teeonede;162 esreverunas exprrute SeCCION 68 UNIOWES 163 encontrado en ol mancjad te pod . El valor de una constante én pa sto crea dos nuevas palabras reservadas para tipas, lamados Treenode (una ex. oman ejemplo, que pod tructura) y Treeptr (un apuntador a la estructura). Entonces, la rutina t podria ser “Toweptr manejador de tablas si el valor: do en el mismo lugar sin importar su tipo. Este es el propdsito de uri —una sola variable que puede legitimamente guardar uno de varios tipos. La sin- on typedef no crea un nuevo tipo ef ro nombre para agin tipo ya existen- Jas varinbles declaradas de esta man las mismas propiedades que las variables cuyas declar iente En una unin; si algo se almacena como un tipo y se recu- el resultado depende de Ia implantacién. iene acceso u los miembros de una union ‘AF sttemp, mumempy dentro del breve programa del capitulo 5, apuntador-unicin—> miernbro precisamente como a las estructuras. Si la variable utype se emplea para llevar ido en u, entonces se podria ver el c6digo ras cantidades enteras, y entonces hacer un conjunto apropiade de seleeciones short, int y long para cada maquina, Tipes como size y ptrdiff_t de la bibliote ‘estindar son ejemplos, EI segundo propdsito de los typedef es proporcionar mejor docu! cién para un programa —un tipo llamado Treeptr puede ser mas facil de entendi que uno declarado s6lo como un apuntador a una estructura complicada. 6.8 Uniones Viceversa) esi de-estructuras definido por struct ‘char same; sal flags,164 esrmucturas carnuto int ulype; ‘al miembro sval se le refiere como symiabi-uival yal primer cardcter de la cadena sval por cualquiera de En efecto, una unién es una estructura en un desplazamiento de cero a pa grande para mantener al imacensmiento del capitulo € muestra cémo se puede obligar a que una variable sea alineada para una clase particul 6.9 Campos de bits ‘Cuando el espacio de almacen: Paquetar varios objetos dentro de una sola palabra de maquina; un uso co! €6 un conjunto de banderas de un bit en aplicaciones como tablas de sim! para compiladores. Los formates de dato 8 eXLermamente, como inter Faces hacia dispostivos de hardware, frecuentemente requieren la capacidad de tomar partes de una palabra. Imaginese un fragmento de un compitador que manipula una tabla de sf los, Cada identificador dentro de un programa tiene cicrta informacidn asoci ‘41, por ejemplo, si es o no una palabra reservada, si es 0 no externa y/o estat macion es co 10 de banderas de un bit deniro de un char o int, La forma usual en que esto se realiza es definiendo un conjunto de “més as" correspondientes a las posiciones relevantes de bits, como en s6CC108 69 CAMPOS DEBTS 165 ‘#deline KEYWORD O1 #doline EXTERNAL 02 #dsline STATIC 4 esum | KEYWORD = 01, EXTERNAL ~ 02, STATIC = 04 }; Ciertas expresiones aparecen frecuentemente: flags |= EXTERNAL | STATIC; enciende los bits EXTERNAL y STATIC en flags, en tanto que flogs é=~[EXTERNAL | STATIC); los apaga, y igs & (EXTERNAL | STATIC)) == 0) tin apagados. struct ( unsigned int is_static 1, ) flags; is_extorn, etc. Los campos Comportan como pequchos enteros y pueden participar en expresiones aritmé- como Jo hacen otros enteras. Asi, el ejemplo previo pudo eseribirse mis na- imente como flags.is_extorn = flags.is_static = 1;166 rsraucrunas para encender tos bits; 98.is_exlern = flags.le_static = 0; para apagarl A (flag ix_extern = = 0 68 flage.iestatic = = 0) para probarlos. ‘Casi todo acerca de los campos es denendiente de la implantacion. Elique un lapar al limite de una palabra se define por la implantacion, iecesitan tener namire; los campos sin nombre (dos puntos y su: ‘ud solamente) se emplean para llenar espacios. El ancho especial 0 puede Plearse para ob| alineacion al siguient a. j Los campos se asignan de izquierda a derecha en algunas maquinas y de cha a izquierda en otras. Esto significa que aunque los campos son titiles el mantenimiento de estructuras de datos definidas internamente, la pregunt ‘qué punta viene primero tiene que considerarse cuidadosamente cuando se cionan datos definidos externamente; los programas que dependen de tales ‘ho son transportables. Los campos silo se pueden declarar como enteros; transpei lidad, se debe especificar ex} ¢ signed 0 unsigned. } ie el operador & no puede arse a ello capruto7; Entrada y salida Sstandar, normalmente et teclado, con getchar: int getchar(eoid) wr168 ENTRADA VsALIDA eaprruLo 7 getchar regresa el siguiente cardeter de la entrada cada vez que se invoca, o EOF cuando encuentra fin de archive. La constante simbélica EOF esta defiaida en . El valor es tipicamente 1, pero las pruebas se deben eseribir en fun. s6idn de BOF, de modo que sean independientes del valor especilico. En muchos mecios ambientes, 10 puede tomar el lugar del 1eeladg -empleande la convencién < para redireccionamiento de entrada: si un programa prog usa getchar, en: a de Grdenes, prog nombrearch: si preg utiliza putchar, prog >archsal cescribird la salida estandar hacia archsal. Si st pet prog | etroproy dijo Ya saida exténdar de prog en ia entrada esténdar de otropreg. La sada procueida por pein también encuentra su camino hacis lx sida es tandar. Las llamadas a putchar y @ printf pueden estar traslapadas —la sali ‘aparece en el orden en que se hicieron las llamadas. ‘Cada archivo fuente que se refiera 2 una funcién de biblioteca de entrada/' lida debe contencr la linea| include antes dele primera referencia, Cuando un nombre se del liga una busqueda del header en algunos lugares es iemas UNIX, tipicamente en el directorio /usr/inclade). Muchos prostamas teen solo un flujo de entrada y esstiben s6lo un flujo ¢ ales programas In entrada y solida von getohar, putchar y pr adecuada y en realidad es suficente para comenzar. Bi corto si se emplea la redirecciSn para conectar Ia salida de seecion 72 SALIDA CON FORMATO PRINTE 169 programa a la entrada de otro, Por ejemplo, eonsidérese al programa lower, que convierte su entrada a mindsculas: #inclade #include sain( ) J" lower: conviecte le entrada mindseules */ int 6; Escriba un programa que convierta mayisculas a miniisculas 0 vi- sa, dependiende del nombre con que se inveque, dado en axgvi0). 7.2. Salida con formato—printt ta, véase el apéndice B. nt printi(char “format, argy, a ime sus argumientos en Ja Salida estanndar bajo rniimero de caracteres impresos. La cadena de formato contiene dos tipos de objecos: earacteres ordinarios, ue son copiados al flujo de salida, y es jiones de conversion, cada uno Se fos cuales causa la conversion e impresion de los siguientes argumentos sucesi- Ws de printf. Cada especificacion de conversisa comienza con un We y termina n un caracter de conversién. Entre el % y el caracter de conversién pueden es- 1 orden: -Priatf convierte, da formato e170 EyeRADAYY SALIDA carmnoy © Un signo menos, que especifica el ajuste a la izquierda del argumento conver ‘ndmero que expecifica el ancho minimo de campo. El argumento converti- do sera impreso dentro de un campo. de al menos este ancho. Si es mecesario ado de blancos a la izquierda (0 a la derecha, si se requiere ajuste a rda) para completar Ta amplitud del campo, que separa el ancho de campo de Ia precisi6 precision, que especifies ef mimero maximo de earacteres de una, cadena que seran impresos, 0 el nimero de dixitos después del punto decimal de digitos para un emero, a ele) si sera como Ipreso como un short, © Una hsiel ent ong. Los caracteres de conversién se muestran en la tabla 7-1. Si el cardecter después del % no es una especificaciin de conversién, el comportamiento no esta definido, ‘TAMLA 71. CONVERSIONES BASICAS DE PRINTE ‘CakacteR Tivo DF ARGEMENTO: IMPRESS COMO i; mmero cetal sin sigho (sin vero inicial). xX | int; ndmero hexadecimal sin signo (con un Ox © OX inicial, usando abed © ABCDEF para 10, » ro decimal sin signo ° areter sen s char *; imprime caractecex de una cadena hasta un \O"o ol mimero de racteres dado por la precision, 4 1 Imadldddddd, ea donde el nimero de ds esta dado por la prec sion (predeterminad a 6, ek -sauco [—Jmddtdldl = xx, en donde el nimero 6 mn (predeterminado a 6). a6 Fai el exponen es menor que —4 o mayor 0 gull jpuntador (represeniacion dependiente de la yavertido en ningum argumentot iniprime un ar por +, en cuyo caso el valor. (que debe ser int). Por ejemplo, printi("6a8", max, ¢); seceton73 LSTAS DE ARGLMENTOS DE LONGITUD VARIABLE 17H La mayoria de las conversiones de formato se han jlustrado en ca sigres. Una excepcion ¢3 la precision relacionada can las cadena. dda campo para que se pueda apreciar su e he ‘hola, mundo: 26108 ‘hola, mundo: %4.108: ‘hola, mund: 5-10: hola, mundo: 41S hola, mundo: 6-188: hola, mundo %15.10e ; ola, mund: 6-15.10: chola, mud Una advertencia: prin emplea su primer argumento pata devidir eusintos tos. También debe advertr la diferencia entre estas dos print J+ BALLA eis contione % +/ pecintf("Y9s", 5); /* SURO +/ La funcién sprint re Is salida en de una cadena: Jnl sprinliichar *eadona, char "format, ar Jas misinas conversiones que printf, pero almacena sprinifda formato a los ara format como antes, pero catoca simat de acuerdo con la eostumbre local, y separar Iineas largas de texto, 3 7.3. Listas de argumentos de longitud variable sia seevibn contiene la realizacin de und versién minima de printf, para ‘Mostrar e6mo escribir una funcidn que procese una lisa de argumentos de lon ‘Wd variable en una forma transportable. Puesto que estamos interesados pr Talniente en el procesamiento de argumentos, minprint! procesard la cadena de forexata y losargumentos, nero lamar al printf real para acer las conversiones & formato,172_ENTRADS YSALIDA La declaracidn correcta para printf es ) significa que el niimero y tipo de esos argumentos pu su SOlo puede aparecer al final de la lista de argumentoy Nuestra minprintf se declara como ‘void minprinifehar “imt, ..) RO cent 1 nemuleanimeres cere printf rico sta en cémo minprint! recorre la lista de arguimentos cuanda int printi(cher “ imo argumento nombre ¢5-empleado por vastart para iniciar. Cada lamada de yaar regresa un argumento y avanza ap al sigui ‘at val; euble dvali switch (2+ +p) conse val = va_arg(ap, iat); SECCION 3.4 ENTRADA CON FORWATO-SCANF 173, (ap, double) seval; val+ +) default potoharlen); break; ) } va_end(ap); (+ limpla cuando todo eslé hecho +/ -3. Auimiente minprintt para que mane! 7.4 Entrada con formato—scant La funcién scant es la entrada anéloga de printf, y proporciona muchas. de las mismas facilidades de conversion en la direccién opuesta, int soanf{char “format, ...) cant lee caracteres de Ia entrada estindar, los imerpreta de acuerdo con las espe- cificaciones que estén en formal, y almacena los resultados almacenarse la entrada correspondientemente convertida. Como con printf, esta seveidn es un resumen de las lidades mas ‘no una lista exhaustiva. scenf se detiene cuando termina con su cadena de formato, 0 cuando alguna catrada no coincide con la especificacién de control. Regresa como su valor el uimero de items de entrada que coinciden con éxito. Esto se puede emplear para Gecidir cuamtos jtems se encontraron. Al final del archivo, regresa BOF; né~ tose que esto es diferente de 0, q -a que el siguiente caracter de enti -oineide con la primera especificacién en Ja caciena de formato, La signi ada a seanf continia la busqueda inmediatamente después del Gltimo cardc- ler que ya fue convertido. Existe también una funcién sscanf que lee de una cadena y no de Ja entrada eséndar: {at secani(ehar ‘cadena, char format, argy, ard.)174 ENTRADA SALIDA, caritULo 2 a la cadena de acuerdo con el formato en format, ¥ almacena el valor resultante a través de arg,, arg,, etc. Estos argumentos deben ser apuntadores, La cadena de formato generalmente contiene especificaciones de conversién, las cuales son empleadas para controlar la conversion de entrada. La cadena de. Formato puede contener: vo de supresién de asigna maximo de campo, una hy yun carieter de conversién La expeciticaciom de conversion dirige la conversion det siguiente campo de en trada, Normalmeme el resultado se colocs en la variable apuntada por el argus mento correspondiente. Si se indica la supresin de asignacién con el cardctet «, sin embargo, el cimpo de entrada es ignorado y no se realiza asignacfon alguna. Un campo de entrada esta definide como una cadena de caracteres que no son espa~ cio en blanco; se extiende hasta el siguiente espacio en blanco 0 que ef ancho de campo se agor 6 siiprimido: para leer el siguiente espacio no blanco, use %ls, SECEION 7 ENTRADA CON FORMATO-SCANE 175 © cadena de earscweres (no entraeor char *, apunuaa un acreglo de ssorace jentemente grande para Ia cadena y una terminacién NO" ‘que serd agresada, nlimero de punto flotante con signo, punto decimal y exponente optativos; float « % 5 literals no se hace asignacién alguna. Los caracteres de conversion d, i, ©, u, x pueden ser precedidos por h para indicar que en la a de argumentos aparece un apuntador a short en hugar de :) para indicar que aparece un apuntador a long en la lista jane, los caracteres de conversién «, £, ¢ pueden ser precedidos por I para indicar que hay un apuntadora double en lugarde a ta de arguiientos, Como un primer ejemplo, la rudimentaria calculadora del capitulo 4 se puede eseribir com seant para hacer la conversion ee entrada: include mein() /+-ealeuladore nidimentaria «/ 1 ) Supongu que deseamos leer lineas de entrada que contienen fechas de la forma 28 Dic 1988 Ls proposicién seanf es int day, year; char rionthname!20) sconi(6d %s 96a", Sday, monthname, Byes); No se emplea & con monthname, un apuntador. Pueden aparever caracteres de scant, yde- ben caincidir con los mismos caracteres de la entrada. De modo que podemos leer fechas de la forma mm/dd/yy con esta propasicién scanf: tnt day, month, year; scani{"%4a/%ha! 4d", month, Sey, Syear);316 ENTRADA Y-SALIDA carrie! scant ignora los blancos y los tabuladores que estén en su cadena de formato, Ademés, salta sobre los espacios en blanco (blancos, tabuladores, nuevas li ete.) mientras busca los valores de entrada. Para leer de entradas cuyo fe Lo est fijo, a menudo es mejor leer una linea a la vez, y despues separarla eng, sscanf. Por ejemplo, suponga que deseamos leer lineas que pueden contener fe- cchas en cualquiera de las formas anteriores. Entonces pademos escribir while (gellinegline, sizeof{line)) > 0) { sacani(line, “Yd 0 Yad", éday, morthmame, year) = = 3) rini(*vdlido: $48\0", Lie); [> forma 28 Dio 1988 +/ rcani(line, "%ed/%d/ 4d", month, &day, &yea:) == 3) porlatl(élido; Ge\n", line); J+ forma romidadlgy +! eintl(invalido: Yie\n", line); 7+ forma iavalida +/ ur mezeladas con llamadas a otras fume Hamada a cualquier funcién de entrada iniciard lo por scant, wentos de seand y sseani deben ser ap seank{"%a", n), fen lugar de Gx); Ejercielo 7-5, Reescriba {a calculadara postfija del capitulo 4 usando scant y/ scant para hacer la entrada y la conversién, © 7.5 Acceso a archivos ‘Hasta ahora todos los ejemplos han leido de la entrada estandar y eserit la salida estindar, las cuales se definen aurométicamente para los programas ema operativo local. siguiente paso es escribir un programa que dé acceso aun archivo que et ya conectado al programa. Un programa que ilustra la necesidad de tale ‘operaciones es cat, el cual concatena en la salida estandar un conjunto de atel vyos nombrados, cat se emplea para escribi fos en la pantalla, y como uf ACCRSO A ARCHIVOS 177 -4 programas que nombre. Por ejemy id de tener acceso a los archivo: cal ne v6 jmprime el contenido de los archivos x.c y y.c (y nada mis) en la salida estandar. 19 hacer que los archivos nombrados sean leidos —esto-es, iciones que leen los datos, con los nombres externos que sreglas son simples, Antes de que pueda ser Iefdo o escrito, un archivo tient {que ser abierto por la funcidn de biblioteca fopen, Ia cual toma un nombre exter- coma x.c 0 ¥.6, hace algunos arregios y negociaciones con el sistemia operati- 1yos detalles no deben importarnos), ¥ regresa un apuntador que sera usado posteriores lectures 0 escrituras del archivo, apuntador, Hamad qpuntador de archivo, apunts una estructura que ‘ontiene informacion acerca del archivo, tal como la ubicacién de un buffer, la posicién de cardcter actual en el bi archivo est siendo Iefdo 0 escrito yy si han ocurtido errores o ‘in de archivo. Los usbarios no necesitan saber los detalles, debido a que las definiciones obtenidas de incluyen una declaraci6n de estructura llamada FILE. La dnica declarackin necesaria para un apuntador de archivo se ejemplifies por FILE ofp; FILE sfopon(char enombre, char moda); que fp es un apuntador @ un FILE, ne FILE es un nombre de “La llamada a fopen en un programa es fp = fopen(nombse, medo); ble. Abrir un atehivo existente para sean desechados, mientras que de leer un archivo que a0 e: como tratar de leer un archi et eH178 ERTRADA,Y SALIDA, earrtuco seccion 76 MAMEIO DF ERRORES-SIDERR YEXIT 179 Wlarge == 1) /* sin args; copia Ia entsada esténdar + flecepr(ctdin, stdout); else. ‘while (~—argo:> Df Lo siguiente que se requiere es una forma de leer o escribir el archivo tna que est abierio. Existen varias posibilidades, de las cuales gete y puto s simples. gete regresa el siguiente cardcter de un archivo; necesita el ap del archivo para dei sal gote(FILE ip) gate regresa el siguiente cardeter del flujo al que se refiere fp; regresa EOF si geu. re algiin error. pute es una fu int putelint ¢, FILE sip) == NULL) ( 1 a0 puede abrir e\n", vargy): pute escribe el cardcter © en el archivo fp y regresa el cardcter escrito, 0 EOF return 0; ‘ocurre un error, Tal como getchar y putchar, gete y pute pueden ser macros en ugar de funciones. ‘Cuando se arranca un programa en C, el medio ambiente del sistema ‘vo es responsable de abrir tres archives ¥ proporcionar apuntadores de arc para ellos. Estos archivos son la entrada estandar, la salida esténdar y el cstindar; los apuntadores de archivo eorrespondientes a stderr, y estin declarados en , Normalmente stdin se conect al do y sldout y skderr se conectan @ Ia pantalla, pero stdin y stdout pueden ser rigidas a arehivos 0 a interconexiones (pipe: been la sees geichar y putchar pueden estar definidos en términos de getc, pute, y stdout, como sigue: ‘Hdsline gotchart ) goto(sta ‘A#doline putchar(e) pute , Js flecopy: copia el archive ifp al archiva ofp! vyold Hlecony(FILE «ifp, FILE +afp) 4 int ©; while ((¢ = aetotifp)) != EOF) puicte, oleh: ) Los apuntadores de archivo stdin y stdout son objetos de tipo FILE +. Sin embar- 180, son constantes, no variables, por lo que no es posible asignarles algo. ‘La funcion loae(FILE +fp) fue establecida por fopen en- indo al apuntador de archi- temas operativos tienen al- que un programa puede tener idea liberar los apuntadores de archive rumpe la conexién qi inverso de tops: jvo que especifica cl archivo que ser ahinuntadnrden segundo. argumento, argumento es un apuniador de a © escrito; la cadena de formato es argumentos, se procesa la entrada estandar. ‘include (+ cal: concalens archivos, versiéa 1 «/ maintint arge, char “argvt 1) { FILE “ips vyoid fiecopy(FILE +, FILE -); El manejo de los errores en cat no ¢8 el ideal. El problema es que si no se pule- de tener acceso a uno de los archivos por alguna raz6n, el diagnéstico se imprime180 wvreADay SALIDA carrrutog| al final de la salida concacenada. Bso podria ser aceptable sila salida va.a la pane ero no si ya hacia un archivo o hacia otro programa medisnte una inter. ida, Hae La sal segundo flujo de stderr rormalmente aparece enla pantalla, mensajes de error en el arc! cestiindar, Finclude while (——arae > 0) UU (Up = fopen(s + +axgv, “x)) == NULL) { nose puede abrir Sa\n", fprinifetdere, " El programa seftala errores en dos ial producida por fprinté va hacia stderr, de mot EXTAADA'Y SALIDA DELINEAS 181 secc10N 77 ida desde otras funciones, y rama de busqueda de patrones como el del sell {La funcidn feof(FILE «) ¢s analoga a ferror; regresa un valor diferente de cero si hs ocurrido un fin de archivo en el archivo especificado. 0 ode error, regresa NULL. (Nuestra geiline regresa la longiiud de la nea, que es un valor mas iil; cero significa fin de archivo. Fara slid, funn fos eeibe una cadena (que no neces content una nueva linea) @ sntfputa(char slinea, FILE +fp) Esta funci6n regresa EOF si ocurre un error ¥ cero si no acurre. Las funciones de biblioteca gets y puts son semejantes a fgets y fpuis) pero eran sobre stdin y stdout, De modo desconcertante, gets elimina et {nl termi- 2al y puts lo aarega. Para mostrar que no hay nada espe copiadas de ka biblioteca es 1 sobre funciones como fgets y fputs, i de nuestro si ay gels: cbliene hasta n earacieres de iop +/ cchar sfgots(char +s, int 2, FILE viop)192 evraapa v sation cAPHTULO rovister ite: register har *es; ‘op)) != EOF) rotum (© = = EOF 86 cs == 5) ? NULL: 6; J J+ puts: coloca Ta cadena s «8 ‘int fputs(char +s, FILE «iop) ¢ ichivo lop +/ int while (o = +344) Por razones que no son obvias, el estanclar especifica valores de retorno dif tes pare fgets y fputs. Fs facil realizar nuestro gelline @ partir de fete: resa su longitud */ Ejercicio 7-6. Escriba un programa para comparar dos archivos, imprimiendd primera linea en donde difieran, 0 Ejercicio 7-7. Modifique el programa de busqueda de un patrén del capitul Para que tome sw entrada de un conjunio de 2b brados 0, si mo archivos nombrados como argumentos, de la entrada estandar. {Dede oscrl el nombre del archivo cuando se encuentra una linea que coincide? C Ejereicio 7-8. Escriba un programa para imprimir un conjunto de archivos, clando cada nuevo archivo en unis pagina nueva, con un titulo y un contador pagina por eada archivo. © en OTRAS FLINCIONES 183 7.8 Otras funciones variedad de Tuneiones, Esta 7.8.1 Operaciones sobre cadenas Ya hemos mencionado las funciones sobre cadenas strlen, strepy, strcat, y siremp, que se encuentean en . En adelante, « y t son de tipo char, ¥ ey n son ints, concatena ta final dee concatenit n caracieres cea regres negatino, eto, 0 yeqeeetie rot invsl que stomp pero solo en los prmeras n caacieres copia ten s copia a lo mas n caracteres de 4 a's stelen(s) regresa fa longitu de atechr(s,e) fegresa un apuntadar al primer-e que eaté-en a, 0 NULL sino estd presente strxehr(s,¢) regresa un apuni limo © que esié en s, ¢ NULL sino esta presente 7.8.2 Prueba y conversién de clases de caracteres Varias funciones de realizan pruchas y conversiones de carac tes, En [o que se muestra a corttinuaciOn, © es un int que se puede represemtar como un unsigned char o FOF. Las funciones regres diferent dlferea regresa ¢ comvertida & mi mn mas restringida de la funcion lama ungete, ieca estindar propor Sngatch que eseribimos en el catnt ungete(int ©, FILE fp) coloca el cardcter ¢ de nuevo en el archivo fp y regresa fe garaniien poner un cay con cualquicra de junciones como scan{, getc © gotchar 7.8.4 Ejecucién de ordenes tema operative local. Como un ejemph roposiciéa system("date"); ‘a queseejecutee! programa date, el cual imprinne lt fecha y hora del ; aqui algunas de las empleadas con mas frecuencia, Cada una toma uno 0 dos argumentos double y regresa un double. seno de, xen radians soseno de x, «en radianes co tangente de x, en radianes cin exponencial e* logaritme ustural (base) de x (x= logaritmo comiin (base 10) dex (x rair cuadrada de x (x2 valor abjoluto de x 7.8.7 Generacion de nuimeros aleatorios La funcin rand( ) calcula una ia de emteros pseudoaleatorios en ef rango de cero a RAND MAX, que n . Una forms de produeir niimeros aleatorios de punto flotante mayores 0 iguales a cero pero me- noves que uno es RAND. _MAK+1)) (Si su biblioteca ya proporciona una funcion para nuimeras aleatorios de punto flotante, ¢s probable que tenga mejores propiedades estadisticas que ésta.) La funcién srand(unsigned) fije la semilla para rand. La implantacién porté- ‘il de xand y de srand sugerida por el estandar aparece en la seecidn 2.7, 10 igupper (lala allorrar espacio empo, Explore ambas poscaprtutos: La interfaz con el sistema UNIX lo esta dividido en tres partes furidamental de archivos y asignacion de alimacenamiento. Las primeras dos partes suponen una dad. com fas caracteristicas externas de los sistemas UNIX.188 LA eerueaz DFL SISTEMA UNIX carrie puede ser necesarig. 1a los derechos de hacer re que se van a eleciar a descriptor de ari salida sin preocuparse de abrir uretivos. El usuario de un programa puede redirgi la B/S hacia y desde archivos cg =¥o? prog archsal En este caso, [Shel] cambia las asignaciones predefinidas para los deseri Oy | alos archivos nombrados. Normalmente cl descriptor de archivo 2 per ce asignade ara que los mensaes de ervor puedan ir hacia Gbservac se apican para la entrada y slide sociada con una saakenaitn deartivstavanbia Sieh 19 programa. El programa no sabe de dénde proviene su entrada ni hacia donde da, miniras seal archivo 0 para entrada y 1'y2 para sida. ; 8.2. E/S de bajo nivel—read y write La entrada y salida usa las lamadas al sistema xead y writ acceso desde programas escritos en C a través de dos funcions write, Para ambas, el primer argumento es un descriptor de archivo. argumento es un arreglo de earacreresperteneciente al programa hacia o de do fos datos van a ir o venit. Bl tercer argumento es el ulmero de bytes que $2 transferidos. Cada llamada regresa una cuenta del niimero de byt cl miimero de bytes rearesados puede ser menor que el lor de regreso de cero bytes implica fin de archivo y —I indica un error de: SECCION 82 PSDP RAIONIEL—eeAD Y wRITE 189 tipo, Para escritura, el valor de retorno es el mimero de bytes escritos: si éste no 6s gual al nero toledo scar ut ro lamada pueden leerse cualquier numero de bytes. Los valores mis co- mane son Ir que sein tn caret ala ver (n 1024.0 4098, que corresponde al tamafio de un blogue fi siferico. Los valores mayores serdn mas eficientes debido a que serdn re ‘menos Hamadas al sistema, Para juntar estos temas, podemos escribir un sencillo programa que copie su entrada a su salida, el equivalente del programa copislor de archivas escrito para ei capitulo 1, Este programa copiard cualquier cosa a cualquier cosa, ya que la entrada y la salida pueden ser redirigidas hacia cualquier archiva 0 dispositive, #includs "sysealis.h” main() { (+ copia Ia entrada a la salida +) char bu(BUFSIZ); 1 chive llamado sysealls.h, de modo que podamos incluirlo en los programas de este capitulo. Sin embargo, este nombre no ¢s estandar. El parmetro BUFSIZ tambien estd definido dentro de syscalls.b; su valor ¢s lin timano adeeuado para el sistema local. mafo del archivo no es un ri de BUFSIZ, algun read regresara un niimero menor de bytes a ser escritos la a read despues de eso regresart cero, se pueden usar read y write para consteuir sutinas de ako nivel como getchar, putchar, ete. Por ejemplo, aqui esta una versién de get- char que realiza entrada sin b yendo de la entrada estdndar un eardeter ala vez, #include “syscall.” getchar: Int getchar(void) t de un carécter simple sin butler «/ char ¢; return (read(0, &e, 1) = = 1) ? (unsigned char) © = EOF; }190. vrenraz net sisTeNwA UNI carmmut9y © debe ser un char, a que read nevesita un apa ¢ Scr unsigned char en In proposicion de regreso el de extensién de signo. “Lasepuda ves de gocher act in entrada rand rgmentosy acy los caracteres uno a Ia vez. include “eyscalle.h” fe getchar: version con bufler simple «/ int gotchar(void) { r static char buf[BUFSIZ); ststic char vbufp = bul; static int n = 0; (a == 0){ Je ol Buller ead vecio +! a = r0ad{0, buf, sioo! bul) Iufp = bot; } return (—-a >= 0)? (unsigned cher) sbutp+ + + BOF; } Si esta version de getohar fuese a ser compilada con incluida, jinar la definicidn del nombre getchar con #undef en caso de q 8.3 Open, creat, close, unlink Ademés de la entrada, la salida y e1 error estindar, se pueden abrir explic mente archivos para leerlos © sen dos Namadas al sistema para to, open y creat.§ ‘open es como el fopen expuesto en el capttulo 7, excepto que en lugar de. seresar un apuntador de archivo, reucesa un descriptor de archive, que es tan so ln nt. open regresa —1 si ocurre algiin error. Facade it fd; int open(char «nombre, int flags, int perms); 4d = open(aombre, flags, perms); Como con fopen, el argumento nombre es una cadena de caracteres que contien€ €] nombre del archivo. El segundo argumento, flags, es un int que especifi dino send abierto el archivo; los principales valores son 4 poser de geen ig a palabra correcta es “ent, cl nombre de a farm 5 40 stone (Node) SECCION 63 OPEN, CHEAT, CLOSE, UNLINK 191. O_ADONLY abrir slo para lecture O_WRONLY abrir slo para eseritura O_RDWR abrir para leetura y eseritira Estas constantes esti definidas en en sistemas UNIX System V, y Pata abrir un archivo ya existente para lecture, fd = open{nombre, O_RDONLY, 0); El argumento perms es siempre cero para los usos de open que discutiremos, Es un error tratar de abrir un archivo que no existe. Para crear nuevos archi- ema creat. vos © reeseribir anteriores, se proporciona la llamada al int creat(char «nombre, int perms); fd = cresi(nombre, perms); segresa un descriptor de archivo. ‘archivo, que controlan cl aces a la lectura 1a para el propietatio del archivo, para el grupo del propietario y para todos los demés. Asi, un miimero octal de tres digitos es convenience para ‘especificar los permisos. Par ejemplo, 0755 especifica permisos para leer, escribir ppara cl propietario, y leer y para el grupo y para cualquier otro rarlo, aqui esté una versin simplificada del programa cp de UNIX, que copia un archivo 8 otro, Nuestra version copia slo un archivo, na permite segundo argumento sea un directorio ¢ inventa los permisos en lugar de include include include “syscalls bi" ‘Adeline PERMS 0846 /-lecturs y escriture para propisierio, grupo y otros! void error(cher +, .): fe op: copia fla int arge, char “argv 1) (arge |= error (Use: op de hacia’)192 La nvreRPa@ EL sistEMA UNI carreg) (iL = epenargv{l], ORDONLY, 0}) = = —) erot(‘ep: no ce puede absir 36s", argvitD) (12 = erecifergr[2, PERMS)) = = —1) I able de argumentos es reemplazada por ¥ mando a la macro vastart. En soinciden con {printf y sprintf ma semejante, viprinll y vs #include #aclude J+ error: smprime ua mensaje de erzor y musre +/ void erzor(char fmt, ..) wiprintl(siderr, mt, args {printiistderr, “\n"); va_end(args); cexi(a}; un programa que: archivos debe ser preparado para ceutilizar descriptores n close(int fd) suspende la conexi6n entre un descriptor de chivo y un archivo abierto,y libera al descriptor de archivo para ser utlizado' algin otro archivo; correspond a felose de la biblioieea estandar excepto: ‘que no existe un buffer que vaciar. La terminacién de un programa via exit 0 turn desde el programa principal eierra todos los archivos abiertos. seCCION 84 ACCESG ALEATORIO—ISEEK 193 La funci6n unlink(char *nombre) remueve ¢| archivo nombre del sistema de archivos, Corresponde 4 1a funcign de ta biblioteca estindar remove, Ejercido #1. Reescribael programa vat del capitulo 7 usando read, write, open yyolose, en lugar de-sus equivalentes de la biblioteca esténdar. Haga experimentos para determinar la velocidad relativa de las dos versiones. 0 8.4 Acceso aleatorio—iseek La entrada y Ie salida son normalmente secuenciales: cada read o write ‘hiv justo después de la anterior. Sin embargo, odesde e! fin det archivo, respectivamente, Por ejemplo, para agreuar a un ar >> enel [shell] de UNIX, o “@” de fopen), hay queir Iseok(fd, OL, 2); Para regresat al principio (“'rebobinar"*), lecek(ld, OL, 595, al precio de uit acceso mas nimero de bytes en cual include “syacali h get: lee n bytes de la posicida pos +/ int get(int id, long pos, char “buf, snt 2) { if (acef(fd, poe, 0) > return read(ld, ‘on pos */194 LA INTURFAZ DEL SISTEMA UNIX eAPHTULO sF0C108 45 [IEMPLO-UNA IMPLEMENTACION DE.FOPEN Y.GETE 195 lee ‘Adeline stdin (obl0) return -1) Hachne.stdout (0b) } Adaline stderr (@cb{2)) El valor de regreso de Iseek: es un long que da la nueva posieién en el archivo, ea gs ( © —1 si ocurre un error. 8.5 Ejemplo—una realizacion de fopen y gete funci6n de bibliote seek, excepto en que el primer argumento es un FILE + y €l valor de resreso 65 diferente de cero si ocurrié un error. estindar iseek es semejante a “READ = 01, _/+ archivo ablerlo para lectura «/ “WRITE = 02, /« archive abierto para caoritura +/ CUNBUF = 04, /+ archive sin bulfer «/ TEOF = 010, _/+ ceurrié fim de archivo (HOF) on cate archive: +) ERR = 020 /+ oourtid un eor en este archivo «/ ® ‘nt fillbul(FILE int ushbul ILE +); archivos en la biblioteca estandar son desctitos por apum ‘#ietise lool) (((p}-> flag & FOF) = 0) lel archive: un ap en grandes fragmentos; ‘#detine NULL #doline EOF +#define BUFSIZ ‘define OPEN_MAX typed struct iobuf { ) FILE; extern FILE _iob|OPEN_MAX]; en vez de con des ‘#deline ferror(e) (p)—> flag & ERR) |= 0) wdstine Wene(e) (@->1) #éstine getolp) (——(p)—>omt >= 0 2 (unsigned char) +(p)—>ptr+ + + illbul(e)) ‘#dsfine pute(x,p) (——(p)—>emt >= 0 2 (p)—>phr+ + = (x) flushbuf((),0)) #define getchar( ) +#define putchar(*) Aunque no discutiremos ningin de para mostrar que opera en forma cy 1004 20 /+ maximo nimoro de archivos abiertos a la ver «/ i -aracteres que quedan «/ + posicién del siguiente cazdcter */ + lecalizacion del buffer +/ Js moda de accato al azchive «/ /+ descriptor de archivo */ Waclude H#iaclude "syscalls.b” ‘#deline PERMS 0666 [+ loctura’y escsitura para propielario, grupo, otros96 La ITERFAZ DEL SISTEMA UNIX ‘+ fopen: abro wn archivo, ro¥rosa un apuatador de archive +/ FILF , lopen(char wname, char smode) { int fd; FILE ofp; it (smode I= "Y' @& emode |= 'w' && smede I= ‘2 (p—>flag & (READ j WHITH break: (ae encentr6 un: Wp >= toh + OPENMAZ) J+ nh zoturn NULL: 1d = open{name, O_RDONLY, 0); ida == —) Je nig bube acceso al nombrd «/ return NULL; fp—>te = fa; } sténdar, aungue el agregarlis no se llevaria mucho e6digo. En particular, ‘tra fopen no reconoce la “(8 que indica acceso binacio, ya que es0 no ti ficado en sistemas UNIX, ni el “(3)” que permite tanto lectura como es La primera llamada 2 gete para un archivo en particular encuentra una cuet de cero, lo que obliga a una llamada a fillbaf, Si_fillbufencuentra que el a no estd abierto para leviura, regresa EOF de inmediato, De otra forma, trata asignar un buffer (Gi la lectura seré con butfer) Una vez que el buffer ha sido establecido, filloulf llama a read para lena fija la cuenta y los apuntadores, y regresa el cardcter del principio del butler. posteriores Uamadas a fillbuf encontrarén un buffer asignado. sieci0n 4s EILNDPLO-UNS IMPLESENTACION DE HOMER YGEKE—A9T ‘include “oyvcalls-h" js Silbut: asigna y llona un bulfer de entrada +/ int fllbul(FILE fp) ' int bulsice; 38 (lp—>flaga(-READ|.SOF|_naM)) 1= READ) return EOF; bulge = (fp-—Slag & UNBUF) ? 1; BUFSI2; if p—>base == NULL) /+ sin buffer san +/ 41 ((p—>base = (char +) malloc(bulsize)) = = NULL) rohim FOF; i+ no puede obtener vn buffer */ Ip—>ple = fp~>base; fp—>ent = readth (tp pent < | fpr, bolsiee); il (Seat ) fp—>flag |= _ EOF, lee ip—>flag |= ERR, fp—>ent = 0; rolumn EOF, t return (unsigned char) +fp—>pir+ +; cabo suclto es izado para stain, jo arranear todo. El arreglo Lich debe ser defini tdout y stderr: La inteializacién de la parte flag de la estructura muestra que stdin ser4 leido, Sldout sera escrito, y slderr sera es butter Disefte y eseriba _flushiba 8-4. La funcidm de bi int eak(FILE «ip, Jong ofise ish, y folose. 0 reca astindar origen)198 Ln itera DBL SISTEMA UNIX carta! SecCION 8 LIEMPLO-LISTADO OF BIRECTORIOS 199 copendiente del sistema, opendir regresa un apumiador a-una est DIR, andloga a FILE, que es empleada por readdir y closedix, La es revolectada en un archive llamado dirent.h ‘decline NAME MAX 14 /+ componente de nombre de archivo mas gran. ee; a! foeck. Asegirese de que su fseek se coordina apr de buffers realizado por las otras funciones de la bi Jn dependiento del o 8.6 Ejemplo—tistado de directorios tynedaf strict { /+ entrada de directorio lransporlabl long ino; cher name[NAME MAX+ 1]; ) Diront; tepede! struct { ) DIR; DIR sopondir(char «dirname); ymada al sistema stat toma un nombre de archivo y regresa toda la ini macion que esta en 1 nodo-i para ese archivo, 0 —1 si existe un F lena ta estructura stbuf con ta informacién det nodo-i para el nombre de archivo. [a estructura que describe el valor segresado por stat esta en , yt struct slat —_/+ informacion de node-i reqreeada porstat +/ dev inet show hora de czeacion original »/ @ el niimero de node-i y ef nombre. La longltié lel nombre de archivo ey NAME_MAX, que es un ¥La entrada st_mode La definicién de banderas es {querimos de la parte que tiene que v« ffdefine S_IFMT 0160000 define §_1FDIR 0040000 ‘define S_IFCHR 0020000 #dofine $ IFBLK 0060000 #doline | SIFREG 0100000 + mal de modo que el proceso es 7+ banderas para lectura y exer Jes.h> /+ typedef */ > /vestructura regresada por sat “ while (--arge > 9) fsize(-+ erg; retum 0; we lade = =, carry explicados por los campos de comentario. Los lefinidos en , que tambien debe ‘con los argumentos de la linea de érdenes; nasa tada nombre %9/%e demasiado largo\n”, ~Nea/%68", dir, dp—>name); ISTADO DE DIRECTORIOS 201202 La iwUEREAZ DEE SISTEMA UNI capnuto e: ion para el sixuiente , que aparece ifndef DIRSIZ ‘#doline DIRSIZ 14 endif struct direct fs entrada dal directorio’ { Inout Lino; har namo DIRS smimero de nado: «/ tos nombros largos no tienen NO! «/ h -Alguntas versiones del sistema permiten nombres mucho més largo y tienen ws estructura de directories mis eomplicada lipo ino-t ¢5 un typedel que describe al indice foma que usamos regularmente es un unsigned shezt, pero ésta no es de informacién para inciuir en un programa; puede ser Fente, de modo que typedef es mejor. Un juego completo de tipos “del sistema!’ se encuentra en . opendir abre el directorio, veilica que el archivo sea wn directorio (eta v Por medio de llamada al aun descriplor de archivo), asigna una estruct macién opendis: directorio para lamadas de readdir «/ IR vopendis{char «dienams) return NULL; elocedir cierra ol f+ clovedir: clerra un diractoris abiento por opendit «/ void elosedin(DIA sep) include /-LSTADO DE DIRECTORIOS 203 ap—>id = return do: 0 ¥ Ti o dat di spacio /s eetructura loval de disecterio «/ readdir: lee en seowoncia lag entradaa de un ditactorio «/ Duseat roaddir(DIR +p) struct direct dirbul; / octruotura local de direotosio */ static Dureut d, —/ regroso: esiructura ansperiable-+! while (read(dp—> id, (ehar *) Edizbul) = = sasol(dsrbuf) if (dirbuf.d_ino == 0) /ventyada que no esiS ex, use */ continue; dino = ditbud_ino; stracpy(d nama, dimame[DIRSIZ] return id; Ib return NULL;2041s 1ereRPAZ DEL SISTEMA ONIN EJEMPLO-ASIGNADOR DE MEMORIA 208 igar apropiado paca insertar el Bloque que esta iberado es adyacemte a un blogue libre gn él en un blogue nico mas-grande, po .e fragmenta demasiado, Determinar la adyacencia es facil puesto que bre es mantenida en orden ascendente de direcciones. Un problema, al que aludimos en el capitulo 5, es asegurar que el almacena- regresado por malloc es me para los ebjetos que macién contenide en Ia entrada del nodo-i. (1 8.7 Ejemplo—asignador de memoria No 5 presentamos ut asienador de memoria muy en otras, basta int o long. siguiente bloque de la cadena, un ; iniones y typedef a in ver de asignar un arreslo precompilado de Jogra median dor ¥ una ocu rmente hemos hecho long: lel long Align; /+ para elineamiente al limite mayor */ contiene un tamano, un apuntador al siguiente Bloque, y el epee Baw Alen; wh geet 7 ‘ques son mantenidos en orden ascendente de dircecién de almacenamiento, tihimo bloque (ireeciéa mas alta) apunta al primero. union header —_/+ encabezador del biogue +/ struct { satire union header iouiente Bloque si tid on ls lista bre «/ ne R= unsigned seg," tamafo de este blogue */ ———> a a le a Vs we vio_[uss ies ign =; (+ oblige a la alinzncign de bloques «/ libre aprpiao por ws]] 180, apropiado por malloc ‘80 apreplado por malloc aprgpindo de unidades de taimai lad mas, para el encabezador en si, apuntadar es regresado © puede desorganizar206 La INTERFAX DEL SISTEMA UNIX caput & seeclON 87 BIEMPLO-ASIGNADOR DEMEMORIA 207 iceep = prevp: abunta al siguente Blogs libre rotam (void «) (p+ 1); ' If (@ == freap) [dio Ja vusta @ la lista libre +) 8 (p = morecore(nunite)) = = NULL) return NULL; /+ neda libre +! __— cireseism rearesads al usuario Ua Bloque sezresudo pr malloe to del sistema operati- ma. Debido @ que pe- sn comparativamente costosa, no deseamos ne Pad se usa para comenzar. Si freep & NULL. como 10 een ida de malloo, ler caso, luego La bitsqueda de un blogue libre de tamaiio adecusado pri a llamada sbrk(n) al sistema UNIX regresa un apuntador jamiento. srk regresa —1 si to hubo espacio, aunque ora iniciae +! ‘inicio de wna lista bre «/ ‘general de-apu 1024/4 minimo # de unidades por requerir «/ \f (au < NALLOC) zu = NALLOG; ep = sbri(eu + szecKHesden); for (p = prevp—>apte; reve = pp = p> eit | (ep == (char «)—1) (+ no hay nada do espacio +! ii (p—Pe.size >= nunite) | (+ sufselentemente grande */ olen NULL; i (p—>sasize = = nun Js wxacto */ up = (Header +) ep: pievp—ra.pie = puoa.ste; . luo { f+ asigna Ja parte final +/ return frees; p= p—>ssize; pr>ssite = munis;208 LA INTERFAZ DEL SISTEMA UNIX carr free cs Ia ditima s doade insectar el blogue extremos de Is lista. En eu: {corre la lista libre, injelando en freep, bu re, Esto es entre dos blogucs exisientes 0 en uno de luier caso, si el blogque que esta siendo libersdo los bloques adyacentes se combinan. Los ii § apuntadores seMtalando a las eosas correetas y ra (+ fee: coloca el bleque ep on la lista vacia. +/ void free(void + ep) ( =1) (7 apunte al encaberador de un bloque « > p &G bp < p—>sptr); p = p—>s pts) (p >= p—>s.ptr 86 (bp > pj bp < p—>s.plx)) ‘break; + libera Bloque al inicio o al final «/ (op + bp—>ssize = = p—>spty) { /* ung al br superior +) bp—>eee += p—>aph—>ssice, oP PE ele = poeple apt | else J+ une al abr inferior «/ pdesue += bp Sa.size; yaa PDE = bare po>splr = bp; freep = Pi nuly pequena del programa. El uso ineasion {suponiende que sbrk proporcio jones ferzasas haven que los apuntadores apuntador a'n objetos de tamafio 19, Eseriba calloc, invocando a malloc 0 cio. Mejore esas sion de errores. © sec1ow a7 Ejercicio 8-8. Escriba de n caracteres en la lisia libre manter tun wstiario puede aureear un arregto qquier momento, CI IEMPO-ASIGNADOR OF MEMORIA 200 utina bfree(p;n) que libere un blogue arbitrariv. p la por malloc y free. Utilizando bfree, litico 0 exierno a [a Visca hbie en cual.212 MANUAL DE RESERENCIA APENDICE A, A2.2 Comentarios Los caracteres /+ inician un comentario, que termine con los caracier rentarios no se anidan y no pueden estar dentro de cadenas o curse! A2.3 Identificadores eles identificadores son palabras reservadas y no se pueden auto, éoable int struct break else long switch case enan register typedez char extern return union const = flleat_—« short ©=—unsigned continue for signed void defauit goto sizeof volatile ao if static while Aguas fplntciones nmin restau frteen ‘A28 Constantes Hay varias os tipas basico sk cCION a2 CCONVENCIONES LEXICAS 213, constarte: enstinieentert we-di-easicter consiante locante consiante-enumeracicn 42.5.1 Constantes enteras, ra que eanslate en una socuencia de dig mma como octal si igto cero), de oxra manera es decimal, Las canstantes actales no contie- 6.9, Una secuencia de digitos precedida por Ox & OX (disito cero) se yo un entero hexadecimal, Los digitos hexadecimales incluyen de la a 0 A hasta oF con valores 10 al 15. Una constante entera puede tener la letra w 0 U com unsigned. También puede tener eomo sufijo Ia ete i comstante'entera depended su fora, valor y sul dn de tipos). Us decimal sin Ui const (ease 94 parauna jo tiene el primero de estos pos, en el que su valor jaed long int. Stes cel 0 hexadacimnal sin tlie es enteras va consderablemente més ala ela primera edici, que simplemente hacia que les grates comsantes tera fuera Jong: Eos sutjas ron revo. A2.5.2 Constantes de caracter 2s siguientes soeuencias de escape, sme a algunos otros caracteres, se pueden wt muewa linea NEAL) Nn diagonal inversa , yw tab horizontal HT vc Interrozael6n 7 fab vertical = VT w 4 Me retraces Bs \e "oN regreso de carro CR Xe rnbmero octal 900 \o0o) ‘vance de forma FF \e ndimero hexadecimal Ah ehh seal audible BEL (Na214 MANUAL DE REFERENCIA APENDICE, SBOCION Ad SIGNIFICADO DE LOS moenTiFICADORES 215 9 char como signed, el val aster que siguy a \ 3. Notacién sintactica Denteo de Ta notacién sintécien que se emplea en este manual, Jas categoria sintcticas 2.5.3 Constantes tlotantes q it imaxis se resume en §A13, con dese be, Inge Una constante Motante eonsta de una parte en 82.5.4 Constantes de enumeracién Los idenificadores dectarados como enumeradores (véase §A8.4) som constantes de tipo int. AZ.6 Cadenas literales 4.1 Categorias de almacenamiento Existen dos categories de almacenamicnto: aucomatica servadas, junio con el contesto de Ia declarac de almacenamiento.. Los abjetas automeiticos son 1yendo uno gue proporcione el lox abjeton esttigos se declaran con a palabra teservadalad Los cbeton que se dele216 MANUAL be KEMERESCIA Avena PENDICE SECCION AS conveRsiones 217 Debide a que Tos objetos de estos tipos se pueden interpreter como niimeros, shard ssfereneia a ellos como tioas arimeticos. Los tipos char e tnt de wodos los tama, eada yes de enumeraciin, se Namardn conjuntamente tipos fanelones que no gencran un valor. 4.3 Tipos derivados Adem de los tipos bdsicos,exlste una categorla conceptualmente inflata de tips de- sivades, construidos a partir de los «pos fundamentales en las formas siguientes: ‘menores de cada tipo dentro de la implunacién loca), dos en el apéndice B muestran las menores magnicudes aceptables, (9s declarados como caracieres (char) son suficientemente grandes para alma: ier miembro del conjunto de caracteres en ejecucién. Siu carécter genulng ‘orregios de objctos de un tipo dado; Janciones que regresan dajelos de wn tipo dado: lepuniadores a obietos de un tipo dado; tunianes capaces de eontener un objeto eualouiera de vari En general esi08 métodos de construcein de ebjetos se pueden aplicsr en forma recursiva, ‘4.4 Calificadores de tipo A.5 Objetos y valores! Un objeto es una vegion de almacenamiento con nombre; un vafor—f es une expresion que se rflere a un objeto. Un ejemplo obvio de una expresion valor~1¢s un idemtficador po adeeuado y una categoria de almacenamie adores que prod- cen valores“: por ejemplo, si E es una expresidn de t fonces +E es una cexpresién-valor—I que se rfiereal objeto al cual apuri lor-t"" proviene ie la expresidn de asignacion E1 = 22 en la que el operador izquierdo El debe ser und capresidn valor-I. La discusiOn de cade operador especifica si espera operardas valor—l y slentrega un valor-L cn la Hissa son al meno long double es nueva, La we raha precisos como Los que los anteved fa edcion hizo s Tong Sloat equvelene A8., Conversiones Algusos operadores pueden, dependiendo de sus eperandos, provocar la conversion del lun operando de un tpa'a otro. Exta seein expel resultado que se espers de tales versiones, $A6,$ resume las conversiones demandadas por la may ‘operadores os; en donde se requir, sera somolementida con a " onstantes © una expresin de su tipo. de eat218 MARUAL DE REFERENCIA APENDICE A original, eatonces el valor es convertido & signed int, Esve prageso ve llama p 6.2. Conversiones enteras, 4 Un eateos sont aun tp sn signe dao encontande el menor valor no negaivg al truncamiento por la izquierda si el patron de bits del tipo sin signo es ms estrecho, y al Signo y extension de signo en valores con sizno 5: el tipo. siguiente mais alo mas bajo. Stel resulcado estd fuera de rango, el comportamien indefiniaa, 6.4 Tipos flotantes mds preciso se convierte a un io 6 el siguiesta mas bajo. Si el resultado 6 fuera de rango, el vompoctamiento esta indefinide. ‘A6.5 Conversiones aritméticas fando es ynsigued long int, ss convertido a unsigned loag it SeOCION a6 CONVERSIONS 219 De otra manera, sin operando es long int y¢l otro es unsigmed ini cl efecto depende de si ua long int puede representar a todos los valores de in unsigned sal; si asi, / operaado unsigned int € convertido a long int; sino lo et, ambos son convertidos unsigned long ink tun operand es long inl, el otvo #4 convertide « long iat oaljuler operando es unsigned iat, el otra es eonvectido @ unsig: .dores 2 objetos del mismo tipo, dentro del mismo erteglo, pueden. os; el resultado es convertido a un entero como se especifica em la discusion del uperador convelsion de Gpo o ast ($947.5 ABS) Un apumrador se puede convertir a un tipo entero auficientemente grande para mante- 0 roquerido depende de la mplamtaciGn. La funcion de mapeo también de- Finalmente, un apuntador a una funcién se puede convertt @ un apuntador a otto tipo 4 funcion. La llamada a la funcién especiticada por el apuntador coavertido es depen-220 MANUAL DF REFERENCIA APENDICH a. spccion a7 EXPRESIONSS 221 dients de ta tino original sin embargo, si ol apuntador convertid es reconvertide a su joes idéutico al apuncador original 46.7 Void void no se puede ui ‘© implica a ningon ar en ninguna Forma, requeride e (889.2) ol operando izquierda de un ejemplo, una conversiin de laexpresion es alterado “apuntador a 7". Est opcrando de un operader & unario, un operdor de ssignacién tse ia de for dscutida en §AB.6, gue re eto, Ws hacia y desde apuntadores Je ipo void + y pueden aa imerpretaién de apustadotes old» es nueva dores char “i A7.2 Expresiones primaries Identifleador AT. Expresiones La precedencia de los operadores en expresiones ions principales de es recede yasociatvdad de los operadores en eipecitcada tompltament, jon de las expresones st 447.1, usualmente se modifica Un gplimtadar al primer eardcter de [a cadena. La conversion tampoco ocurre en ciertos Inicializadores; véase §A8,7. Una expresién entre paréntesis es una expresign primaria cuyo tipo y valor son idéati- los de ura expresion que no Io esté, La prescngia de paremesis nu aTecta el que la ‘spresion 42 un valorAPENDICE 4 222 MANUAL DE REFERENCIA A7.3 Expresiones postijas presiones nosfijas se agrupan de ix { expreson 1 lstacdeexpresionesargumtentday) ldentficador => idenifiador + Uisia-expresiones-argumento: expresidn-de-asienacion listarexpresiones-argumento expresidn-de-asignaciin AT.3.1 Roforoncias a arreglos seaulda por unt es indexada a arcealo. Una de les la orra debe tener tipo emtero; el 1(E2 es idéntica (por definici6n) a: sion posfila (Jesmués de una a y §A7.1) debe ser del tipo "'apuntador a funcién que seuresa 7", cl valor de Ia llamada a a funcién para alga tipo de T.¥ 1 terming pardmetro se emplea ps por una definiclon de funcidn o descrito dentro de a declaracién de una funcién, Las te SECCION 47 EXPRESIONES 223 jeumento (parametto ‘misma distincion ‘mente, se usan algunas En sveparacion pa cada ‘odo el paso de argumentos es estrietamiente por valor. Una Funcidn puede cambiar Ios va. lores de sus ebjetos parametros, que son copias de las expresiones arguments, pero estos no puedea afectar los valores de los argumentos. Sin embargo, es posible pasar euida por un pus rondo de fae22 MANUAL DE REFERENCIA, SSECCION A EXPkESONES 228 [ATA.2 Operador de dleacion ido es un apuntador a un obj Asi Is expresidn E1~>MOS es lo mismo que (+E1).MOS. 1.as estructuras y uniones : Bich po de a cxprentn es un “apuntadora 7", se discuten en $8.3 AT.4.4 Operador mis nario Eloperando del opéruior unario + debe tener tipo aritmético 0 apuatador y valor del operarda. Un operat tado es el tipo del oerando promovido. + unayios es new en el entdndar ne, Se agrees por seta con = unio, AT.4,5 Operador mens unario Eloperador del ~ unaio debe tener tipo aritmética y el resultado es el negative de su re promocion entera. E negativo de una cantidad promevido del mayor valor del tipo promovido y agregdndole uno: pero el ero negative es cero. El tipo del resultados tipo del operando promovi¢o.. ins dlscuson de operadores avs @A.72) 9 ds signacin (@A.217) par ‘esiiceiones en el operando y detalles de la operacién. Fl resultado no es un valor=1. ‘AT Operadores unarios 47.4.6 Operador compemento a uno [Las expresiones con operadores uitarios se agrupan de derecha @ taquierd, fi apieando * y reefesa sltipe dd operand provovio <= expresin-unaria operador-unario expresincast 7.4.7 Operador de ngacién légica . El opera del operacor tebe tener tip! artmético 0 sec un apuntador, yel resultado .2l valor de su openndo es compara igual # 0. y U en case contcario. El tipo del A741 Operadores prefijos de increment lado es int Ln exrenin unari presedida por um operat. ++ 0 =~ sina esi uni A7.4.8 Operador sizect valor después del incremento operador sizeed profuce el mimero de bytes requerides para almacenar un objeto ‘susibm de operadores aditivos (§A7.7) y de asignacion (§A7-17) para posterfores te jo de su operando. B operando es una expresidn, que no es evaluada, o un nombre pn pss ass “out fies en el operando y deralles de Ia operaciés, El resultada no es un valor~1226 MAUAL DE REFERENCIA APENDICE de tipo entre paréntesis. Cuando sizeed se aplica a char, e] resultado es 1; cuando se ATS Cast Una expresién vnaria precedida por el nomsre entre paréntess de un tipo provoca I conversion del valor de la expresin al ipa nombrado, expresin-cast: ‘expresién-unaria ) exprestén-ces: A7.6 Operadores multiplicativos Los operadores multiplicatvos +, J, y 95 se agrupan de ixquierda a devecha. expresion-cast espresidn-muliplicative * expresidn-cast expresion-multiplieava / expresién-cast expresicn-multiplicativa % expresidr-cast Los operandos de * y / deben tener tipo aritmético; los operandos de % deben Lipo entero, Las conversiones uritméticas usuales se realizan sabre los operands, y 0 que (a/b) + b + a%éb esi los operands es negativo, emtonces el residuo es no negarivo y menor qi Jo son, se garantiza sélo que el valor absoluto del residuo es menor que #l valor a del divisor. A77 Operadores aditivos 1Los operadores aditivos + y ~se agrupan de iaquierda a derecha, Si Jos oper tienen tipo aritmética, se realizan las conversiones aritméticas usvales. Existen algunas sthilidades adcionales de tipos para cada ope SECCION A? EXPRESIONES 227 exprestén-aditiva: expresion- multiplicativa expresionaditiva + expresion-multiplicativa expresidnaditiva ~ expresion-muliplicativa spuntadar apunta. La suma es un apumtador det ta a otro abjevo dentro del mismo arreglo, desplazado apropiadamente del nos de que los 3p punta al 7.8 Operadores de corrimiento Los operadores de corrimiento << y >> se agrupan de irquierda a derecha. Para nto sel oerando dei deecha es negative, mayor o igual l numero de Wis del tipo de la expresién de (a izquierda. expresién.de-corrimionta: expresién-aditva expresién-de-corrimienta << expresién-aditive expresibn-de-corrimienta >> expresiénvaditiva El valor de E1< expresiin-de-corrimienio expresidn relacional <= expresidn-de-currimiono exprensn-relacional >= expresién-de-corrimiena > (mayor que), <= (mencr o igual a) y >= (mayor El tipo del resute uales; si los apusitadores hacen refer la comparacién es equivalente a la comparacin de los co- ‘ubindices, Si P apunta al tlkimo miembro de un arreslo, entonees P+1 somo mayor que P, ineluso sunque P+1 apunte fuera del arreglo, De otra A7.10 Operadores de igualdad expresin de iguaidad: expresténrelactonal expresidr-de-igualdad == expresin-relacional ‘expresién-de-igualdéad |= expresiéa-relacionat {0 igual a) som andlogos a los operadores de retaciéa siacb == c count «e reffere al campo count de la estructura & fa que apunta spe evtett se teflere al apuntador al subsdrbol tzquierdo de Ia extracts s.cight->twora{01 se refiere al primer caricter del miembro tword del subérbol derecho de s. KY ten uns secuencia initial com ‘permite hacer rere idas. Por ejemplo, el es legttimo: union { Gf (u.m.type == FLOAT) ‘sin(a-n€.floatnode) ‘AB.4 Enumeraciones Las enumereciones som tipos con valores que fluctlan entre un eanjunto de comstantes ombrades que se llaman enumeradores. La forma de un especificador de enumeracion se toma de Ia de las estructuras ¥ uniones. especificador-enutn: enum ideniificador, enum idemtficador isia-de-onumerador: ‘enumerador (iste-de enumerador , enumerador ‘enumerador: tyieador dentificador = exprestén-consiante listasde-enumerador |238 MANUAL DE REFERENCIA, APENDICE A, ‘Los identficadores dentro de una lista de enumerncor se declaran como constantes de tipo. 3 puoden apacever en vier ec de ext ib, pero sl parce del lengua por algunos ace, a ABS Declaradores, ‘Los declaradores tienen Ia sintaxis: declarador anuntador,., declarador-directo yo: yarreglos; el agrup 8.6 Signiticado de ‘un deciarsdor. El tipo atribuide al identficador en Ins varias formas del declarador 3¢ seseribe inductivamente empleando esta notacion, SECCION AB DECLARACIONES 239, Enwuna desloracida T Ddonde De: un ih doves T oi yolo, el tipo del En una declaracion T D donde D tiene ta forma parentess ny alera el ipa, pe ‘A8.6.1 Declaradores de apuntadores Es una declasacidn TD en donde D tiene ta forma ‘Como otros ejemplos, ls declarsciones int i, +pi, sconst epi = Bi; const int ci = 3, *peis declacan un enters i y un apumtador @ un e tao puede ser eambiado; siempre apania c Is 8.8.2 Declaradores de arregios En una declaracién 7 D donde D tiene la forma Di lexpresidn-constante,,.) Ge tipo incompleto. Esto implica que para un arzeglo multidimensional, solo se ‘primer dimensién, Eltipe de un objeto de tipo arreglo incompleto se com240 MANUAL OF REERENCIA APENDICE A spccio AB DECLARACIONES 241 peta con otra des (GA8.7). Por ejempl objeto (SA10.2), completa o por su Y un srealo de apuntadares a ndmero float. Por otto lado, 1s ridimcasional esttico de enteros, eon rango 3x § x 7. Con todo. dual, 3a es un arreplo de ts e cada una de les iltimos static int 23a(3) 10 tiene tipo iat, Mas espectfiea- mente, x: arteglo de 5 arreglos de 7 ena la de modo que E1{E2) es idéntica cadores, se discuten en SAB. En Una dcclaravion de funeién del estilo anterior T D, donde D tiene la forma bido a las reglas de conversién que'se aplican a + ya los arregl Bilder: Bondi ($46.6. A7.1, A7.7), siBL es un arregla y E2 un entero, entonces £1/E2] se refiere dos que regresa T™. Los pardimeures (si estin presentes) tienen Ta forma Iista-de-identificadores: ldentijicador Tistasde-dentificadores , identificador ‘A8.6.3 Declaraci6n de funciones En uma eciaraciin del nuevo estilo T D, donde D tiene la forme ‘on pique regresa un apuntador aun entero. En ninguna de estas secs taxis de los pardmetros es on dos argumentos,e sropy es vila Tuneidn que regresa un iat, Nista-rpos-ae-pardmera: {ista-de-pordmetros ardcter y el segundo un ne (istarde-pordmetras , son realmente comentarios. La segunda func {ista-de-pardmetros: dectaracidn-pardmetro Uisia-de-pardmetros , declaracién-pardimetro decleracién-pardmetro: especificadores-de-decleracién declarador especificadores-de-declaracicn declarador-absiractoyy,242 MANUAL DE REFERENCIA, seccroN as DECLARACIONES, 243 cjuyenda el sarfcter milo de terminacién, determina su tamano; si su tamano es fio, ef nimero de earacteres de Ia eadena, sin contar el eardcter nulo de redler al tamafo del arreglo. inteiatteador= expresidn-asignacion { lsta-e-niciaizadores } | listarde-iniializadores ,} jo no principia con una lave izquerda, entonees solo se roman de la {os suficientes para los miembros del subagsegado; cvalesquiera miembros reseantes se do- dectara¢ inicialiaa x como un arreglo de una dimension con tres miembros, pulesto que no se ha especifieedo tamato y existen tres inicializadores 1 por lo que Et inicilizador para 7 prineipia con una llave izquierda, pero el de y' i lementos de se utilizan tres elementos de la lista. De la misma forma los siguient |. También, Inieiaina ta resto ea 0, Finalmente, char magt] = "Error de sintazis'en linea s\n"; a columaa de y (considerado como un arregio bidimensional) y deja alAPENDICE 4 244 MANUAL DE REFERENCIA {os miembros son inicalizados con una cada; su tac cian 4 declarador-absiracto: spuntador Apuntador,,, declarador-abstracio-directo declarador-abstracto-dir AB.9 Typecet pl strane iy pind eer scenic eyed ode ran tor en ga de elo die encores que obra ipo Too at dores se Haman nombres typedef. eS a Sh nombre-typedep: identificadtor SECCION #9 PRoPosICIONES 14S Por ejemplo, después de ‘ypedet long Blockno, *Blockptr; typedef struct { double r, theta; } Complex; las vonstrucciones Blockno 2; ‘apuniador a long", 9 rctura, para tipos que se pedrian fe un alcance més interno, pero se ‘Los nombres typedef se pueden debe dar un conjunto 20 vacio de espe extern Blockno; no redetlara aBLockne, pero extern int Blockno; so hace, ‘48.10 Equivalencia de tipo sqiera identificadares de pardmetros ecificadores de tipo. Los tamaflos de Las propo proposicién: ‘proposieidn-eriquetade roposicién-expresién roposicién-de-salto2A MANUAL DE REFBRENCIA. APENDICE A SeCCION As pmoposicioxes 247 ‘A3.1.Proposiciones etiquetadas a Inlcallzacién de objetos automaticos se realiza cada vez que sc entra al bloque por la parte superior, ¥ procede en el orden de los decaradores. Si se cjecuta un salto dentro del Bloque, estas nicilizaciones no se alizan. Las inicialaaciones de obetos safc se real Propostclén-etiquetata: vas Solon Yer, antes de que el programa comience sw eje identificedar : propesicién caus expresién-constanie : proposictén oteult : proposicién 9.4 Proposicionos do soloccién Una etiqueta consistente en un identifiador declara al identificador. Ei Las proposiciones de seleccién eligen uno de varios fujos de control, d) 2a: by return (> 0) 2m 1 0} specificador de la devlaraciOn; max(i logue con el codigo para D, int ¢) es el declarador de oa. La correspondiente defini int max(a, >, ©) int a, bye: Mo donde ahora int max(a, b, ¢) es el declarador, @ tnt a, b, e; es para los pardmetros. ‘A10.2 Declaraciones externas282 MANUAL DE REFERENCTA APENDICE A, AML. Aleance léxico oporado para sus miemibras, de modo queen ia estuctuas pede sparecer el msm oie. Tata regle be ido na pee ‘oman por muchos anes. lance Lexico del identificador de un objeto © funeidn dentro de une deelaracién externa principia al final de su declarador y persiste hasta el final de la unidad de tradue- idm en la que aparece. El sleance del pardmetro de una definici6n de funcién principia rétulo de una estrnenura, unién 0 enumera- pia al aparcecr cn un especilicador de tipo. idueciOn (para declaraciones en el nivel externo), suyendo el m0 blogue dor se declara explfcitamente a la cabeza de un blog n, cualquier declaracion Gel identficador fuera: PREPROCESAMIENTO 253 A12. Preprocesamiento in preprovesador realiza macrosubstituclones, compilacién condicional e inclusion de ‘varias faser lgicamente succsivas que, on se pueden condensar jeas que se describen en §A12.1 son reemplazadas por separasos por earaeteres ecpac espacio. Después se obedecen ales constanes (G§A2.3.2, 42.6) « reemplazan por sus equivalents; despise concalenan as cadenas sadyacentes, 5, El resultado se traduce, después se liga junto con otros programas y bi lectando 10s programas y datos nevesarios y conesiando las funciones y objetos exter- ros can sus definciones, A121 Secuencias trigréficas res de los programas fuente de C esta contenido dentro del cbdi ‘eo.e5 un superconjunco del iso 646-1983 frvariant Code Set. Para representar a los programas en €] conjunto reducido, todas las ocurrencias de fas Pe siguientes secuersciastrgraficas se reemplazan por el cardcter sirople correspondiente. Este reemplazo ccurte antes de cualquier otto procesamiento. om a wre 7 ON 77) 1 a 8 a) re No cus izin otro reempl Ls seeuenclas Fens Son nuevas en al extindar A 12.2 Unién de thmeeraocesaminn7o 255 254 MANUAL DE REFERENCIA AAPENDICE A sCCIOW Anz 12.3 Detinicién y expansién de macros ‘Una linea de contra! de ba forma # define identificador secuencia-de-tokens have que o] preprocesador reomplace fas instancias stseo Secuencia de 1okens da # celine identifieadar ( tista-de-identifieadares ) secuencia-de tokens donde no hay espacio en blaneo entre el primer identiticador ¥ ol (, cs {:0n pardmetros dados por ia lista de identificadorcs. Tal com ios en blanco alrededor dela ecuencia de rekons se descarter ‘én en Je que el mimero y deseripeion de par lo, esta puede faefine TABSIZE int table(TAssi La definicien # undef identificador faetine ABSDIFP(a, b) ((a)>(2) 7 (a) hace que el prepracesador olvide Ia definicion del identifica esa el valor abs a icin Ue identifiador, No es ervoneo apt 4 macro que regresa el valor at sar tundel a m « iade Ia funcién que hece Ia misma macro se ha definida en la sex pueden tener cualquier tipo aritmeti iador iden lener efeeios colaterales som evaluados di of val Dada la definicion faeeine temptile(aiz) la macrollamada tempfilefust/imp) entrega *yasr/tmp" "/Xs" fais "Ae" t ‘que posteriormente se eancatenard como uns cadena sencilla, Después de faefine catix, yl x FY faduce 123, d2bido a que la &x- pansidn de xcat en si no iavolucr En la misma forma, ABSDIEF(ABSDIF? ‘completamente expandido, if rradores ##, Ad produce lo esperado, un resultado ‘una sscuensia de rokens de reemplar9,256 MANUAL DE aETEARNeIa APENDICE 4, A124 Inclusién de archivos (Una tinea de contrat de la forma # include ‘ocasiona el reemplazo de esa linea por el contenido completo d Los saractres del nombre nombredearchivo no deben i vo mombresde- > o nueva linea mibrade se busca en fase deliberadamente de entonces lo hace como ex la primera 0 /* enel nombre del archivo permanece indefinido, pero. std permitido > Finalmente, una directiva de fa forma # include see riaee-tokens Los aychivos #incde pusden estar anidados. ‘412.5 Compilacién condlelonal ‘Parte de un programa se pucden compilar condicionalmente, de acuerdo con la sigue te sintaxis esquematica, reprocesador-condicional: Nrew-if texto partes-eif parte-lse,y. dendil Jinewif: 1H if expresidn-constante 4 ifde! idemificador # ilndel identifieudor artes-lif: Unes-elif texto Partes-elife, incase # olil expresidn-constante parte-else: linea-else texto Vincalse: elee ‘Cada una de tas directivas (linea if, linea-eif nea, Las expresiones constantes que estén incaclse, y #endit) aparece sola en una’ ify posteriores lineas #elif se evalian SECCION a2 PREPROCESAMIENTO 257 ord ns que newer exten con alr fresh Gra exo que tae fa Linea con valor vero se descar ‘ormalmente. Aqui luna linea i 0-Felif con ‘onal se ignora, excepto para verficar el condieionales. La expresién constante en #if'y més, cualesquier cxpresiones de la forma dofined identificador 4 sujets a macroreemplezo ordinario, Ade- defined { identiffeador } se reemplazan, antes de bussar macros, por 1 detinido preprocesador y por OL Las lineas de control ‘ide! identificador diindet identificador son equivalentes a # defined identifieadar # if! defmed identficador seein ms “olif es nueva desde la primera edicién aunque ha estado disponible en algunos Sepecnlna opener aoe 2 penoar tab soe 412.6 Control de tinea Para benefielo de otros preprocesadores que generan programas en C, unalinea en uaa ae las formas # line constante “nombre-de-archive” # line constante ode errores, que el n= esimal, yqueel nombre recordado ne cumbia cra288 MANUAL DF RBFERENCIA APENDICE A, ‘12.7 Generacién de errores Una linea del preprocesador de Ie forma # orror svewencia essiona que el prerocesatortscrita un mensaje de dlasnbstico ue inca a seen de tokens, 12.8 Pragmas Una tinea de control de le Forma ‘12.9 Directiva nula Una linea del preprocesador de la forma expanden para producir informac seprovesador defined, pucder st de la compilacion, en la forima definido come 1 séto en imple se encuentre una recapitulacién de la gramtica expuesta lo largo de 4 este apéndice, Tiene exactamente cl mismo contenido, pere se encuen , | GRAMATICA 259 unidad.te-raduccion: declaracidn-exierna unidad-de-traduccién decloracién-exierna declaracién define -funcidn: especifcadores-de-declaraviGna, declarador lista-de-declaraviontg, propesiciSn-compuesta dectaractn: expectficadoressdesdectoracion lstatelaradoresiniy Fisterde-decloraciones: ideclracién lisia-de-dectaraciones declaraciin especificadares de-dectaracin _especyfcadar-categarialmacenamiento especificadoresde dectoracdt gy especificador-de-tipo especificudoresde-declaractétcy calificader-de-tipo especificadares-de declaraciday especificadar-categoria-almacenaméenio: uno de auto register static extern typeder especificador-de-tipo: wne de void char short long fleat double signed ticador,, { lst-declaracionessteuct } ‘estructura-o-unién identifieador declarador260 NANUAL. DD REFERENCIA expresién-constante especificador enim: enum idenifcador, {lita de-enumerador | enum identifcader stade-enumeroder: deelorador: ‘amano declared directo directo: ifcador ista-calificadores-de-tip0 iy, caifeadores-de-1ip0y spuntador eclaraei6n-parsimetro APENDICE a SECCION 413 GRAMATICA 261 ye [ exprestdn-constante se | directo, ( liste-tipos-de- aso exprestén-consant : proposicin default: proposciin roposciinexpresién: ePTee § proposcin-compesa ‘stadetaractén lista-de-proposicionesy | st de-propsiciones: ‘roposelén ‘istarde-proposiciones proposicion propasciin-de seecién Wf Cexpresidn ) proposicidn ‘i ( expresidn ) proposicidn elee propasivin switch ( espreson ) propose262 MANUAL DU KaFERENCIA APENDICE 4 SECCION A oramaricn 263 break ; expres cexpresién-de-asignacién lexpresién , expresin-de-asignacion expresidnde-asignacin: ‘expresion-condicional ‘expresiin-uaria operador-de-asignacién expresién-de-astenactin operador-unario expresion-cast sisee! expresion-unaria expresion-constante: sizeet ( nombre-de-tipo ) expresién AND expresidn- OR -exclustvo ~ expresion-AND expresin-AND: expresionde-igualdad expresin-AND 6 expresién-de igualdad president: expresidn.de-asignacion expresién relzcion oki) oe eagle omen tents, grein ualdad I= expresién-relacional © constante-entera # include secucneia de.264 # lin constanie “nombre-de archivo” # line consea reprocesafor-condicional preprocesador-condicioral: Unewif texto partes-lif parte-elte,y # endit lines if: APENDICE & apenvice 8: Biblioteca estandar cansert.h> qmathuns — Se puede ‘ener acceso a un heuder por medio de Pinclade headers eaiers se puclen fuera de cualquier cosa que declare. No es neces ‘Los identificadores externos que principian con subguidn estan reservados para uso de 1a biblioteca, como Io estén todos los otros identificadores que principian con un subguion y una letra mayiiscula w otro subguién,266 nIDLIOTECA ESTANDAR APENOICE B 181.1 Operaciones sobte archivos size_t evel ipo com operaciones sobre archives. El ! gperudor size. PILE +fopen(const char *£Llenane, const char anode) .y Tegresa un-fiujo, o NULL si fal fopen abre el archivo nombra valores legtimos de mede i ne" abre archive de texto para nu" crea archivo de texto puta ese existe ra; descarta el comtenido previo si final ‘9 escrituray ‘cualquier contenie freopen abre el archivo con el modo estipulado yy ssocia al flujo con él. Regresa seam, o NULL si ocurre un error. Freeper cormalmete se usa para cambiar los archi ‘os asociados con sidin, sideut 0 stderr. int relose(FILE +stream) {lose descarga cualquier dato no cscito de stream, descarta cualquier buffer de en- sualguier buffer asignado autométicamente, después cierta elf ‘oeurre evalquler error y cero en easy contratio EMIWADA Y SALIDA 267 419.0 NULL si no puede erear el archive, char stnpnan(char s[t_tapnam]) una cadena que no es el nombre de un archivo exstente y raresa vol setbuf (FILE +strean, char «buf) Si buf es NULL, se suspende el uso de buffer para el flujo, De otra manera, sotbul es equivalente a (void) setybut(stream, buf, IOFBF, BUFSI2), 1.2 Salida con formato {Las funciones print! proporcionan conversiones de salida con formato. int fprinte(PILE wetream, const char +Zormat toma una salida y la convierte y esc lor regresaco es el iimero de car rri6 algin error. La cadena de formato contiene dos tipos de ob} Piados al flujo de saida, y especificaciones de con la conversion ¢impre cién de conversion principia con el cardeter % y wermina eon un cardcter de convetsin, Enire el que son co. sidn, cada uno de ks cuales provoca * Banderas (on cusiquer orden), que m =, que eepeificnajuse de! argu:268 minijoteca EsrantaR AreNDie ‘qsiersolade dierent de cro scr prefijade con Ox 0 OX. Pa. 5. ¥°G, la sligasiem, pre tendra om punta decimal para @'y G, los eros acarendos no sera removides Eka un datos den puede especificar la amplitud o precisién, o ambas, convirtenda al (os) Los caracteres de conversin sus significados 8 que estpals el nimero maximo de caracterey ena cadena que sen ‘numero de diits que serinimoresosderpis del pinta decimal para conversiones acgumento corespondiente ve mento es load © utigned caso el valor so calcula uiente(s) argumento(s), que debe(a) ser int ran en la tabla Bl Sie cardeter ‘que est despues del 96 no es un caracter de conversign, el comportamieate estd indefinido, CaRACTER ‘TABLA B-L. CONVERSIONES DE PRINTF Tio De ARGUMENTO: CONVERTIDO A [-lm.ddddaderex 0 especificado por la pre= 5: una precision 0 suprime el punto (es USA Ybe 6 HE sel exponente e¢ menor que ~4 o mayor 0 ‘gual que la precisibn; de otra forma es usado %f, Los ceros y el punto de- SecoION wt ENTRADA Y SALIDA 269° int printé(const char +format, . peinte(..) eb equivalents # ¢priai verintf(const char «format, va_list arg! YEprintt (FILE setream, const char efornat, va_list arg) ysprintf (char +8, const char *format, va_list ara) Las funciones vpriat vip ones printf, excepto que la cig de en la sevcis B13 Entrada con formato Las funcionés soant tratan con la conversion de entrada con formato, int fsoant(PILE ¢stream, const char +format deargumentos subsecuent doformat se haagotad de la conversidn; de otra forma regress el niimero de a ssignados, ‘La cadena de formato gencralmente contiene especificaciones de conver utilizadas para dirgi la interpretacin de lwentrada. La cadena de fort slos de entrada convertidos ¥ sim del siguiente campo de en tuada, Normalmeat le apuntada por el argumento co- rrespondiente, Sin embar campo de entrada simplemente ve sass fo por una cadena de caracterss diferentes de espacio en blanco; s© rerpretacin del campo de entrada, argument Los varacteres de conversidn legals se mucsiran tar precedidos por ksi el argu- le)Si.clargumento ¢s un apun yg pueden estar precedios por I si es Los caraccores de conversion d, 1,0, 0,» ‘mento es un apuntador a chert en ver de tador a long. Los earacteres de conv270 siaL6TECA ESTANDAR, APENDICE B la lita dea a long double, puncador a double y no a float, y por ks bay un ap TABLA B.2. CONVERSIONS DE SANE “CaracteR | __Dat@ be ENTaADA: TIPO DE ARGUMENT i" a x ‘entero hexadecimal (con o sin Ox o OX al priscipio); int +. © ssuracieres; cher *. Los siguientes earacteres de entrada se pondran en el ado, hasta el mimero dado por el ancho el conjunto entre corchetes; char +, Se aprega un " el conjunta, no se hace tiniguna asignacion, Ant seant(const char +format, ...) ‘seang(...) ¢s idénticaa feeant(stdin,..) 81.4 Functones de entrada y salida de caracteres int fgete(PILE sstream) fgeto regresa el siguiente cardcter de siroam como unsigned char (conventido a uh EOF $i se caconicd el fin de archive o vn ereor SCION BL ENTRADA Y SALIDA cSTMOM> 271 char tfgets(char es, int n, FILE +stream) dois ete otipinas 2-1 los, deteniéndose si encuentra AUT. fgets que es Magenta & MULL sta encunta fin Ge archive 9 sure Ant fpute(int ¢, PILE +stream) pute escribe el eardcter © (couvertido @ unsigned char) en stream, Regresa el ca: raeter escrito, @ EOF en caso de error, int fputs(const char #s, FILE +strean) {pule excribe Ia cadena « (que no necesita contener ‘\n') en stream; regress wn valor 00 negativo, © HOF si hay error int gete(PILE sstrean) ‘gotc es equivalente a igete excepto que si es uns macro, pucde evaluvar @ streara mas de una ver. int getehar(voia) getchar es equivplente a gete( stain) char agets(onar «: gatsice a inea de encrady ke aa el cardeter nuewa Tinea final con \O" Regresa e, 0 NULL si ocurre fin de archivo o error, int pute(int ©, PILE wstream) ‘pute €¢ equivalente a ipate excepto ide una vez sles una macro, puede evaluar astream més int putchar(int ¢) putenar|c) es cquivalente 4 putele,etdout). int pots (const char +8) be Ia cadens s y un nueva linea @ tdout. Regresa HOF si ocurre un ervor, de forma, un valor no negativo, int ungeto(int ¢, FILE sstrean) tungete repiesa e (convertido en unsigned char) de tuevo al stream, de donde sera regresado en la prdxima lestura. Sélo se garantiza wn cardcter de regreso por fu. EOF no puede ser regresado, srgate devuelve el caracter resresada, 0 EOF en caso de error B1.8 Funciones de entrada y salida directa size, size_t nob}, FILE satveam) size_t frendivoid «ptr, size. freed lee de straam en el arregio piz hasta nobj objeios de tamafo size. fread regresa t size, size_t nobi, scribe, del arreglo ptr, aobj objecos de tamafos size en stream. Desuelve el n, que e menor que-mobj en caso de error xn deo27 MBLIOTECA RsTANDAK APENDICE'S 81.6 Funciones de colocacion en archivos ja a offset caractcres de orig SEEK CUR (posicién actual), ¢ SEEKEND cifset debe ser cero, 0 un valor regresado por ‘tell (en tl caso origin debe ser SEEK.” SET.) fseok cegresa un valor diferente de oer0 en caso de error. long ftel1 (PILE «stzean) ftell regress Ja posicign actual de stroam en el archivo , 0 ~IL. en caso de error, void revind(FILE stream) rewind(tp] es equivalente a focek(fp,Ol, SEEK,SET); claarers{f), Ant fgetpos(FILE sstrean, frost eptr) ‘getpes eraba cn *ptr la posicion actual de stream, para uso posterior de fastpos, 1 tipo fpos.t es adecuado para grabar tales valores, fgetpoe regresa un valor diferente de cero en caso de error. int Eeeipoe(#KLe etrean, const ¢pos_t sptr) ersbada en *ptr por igetpos. En caso de error, faetpos races in valor deren de cer. ¥y probar explicitamente, Ademés, la Jh> puede contener un mimero de error que feof rogresa un valor diferente de cero si std encendido el indieador de fin de archivo para {stream|. Ant ferror (FILE sstrean| ferror regresa un valor diferente de oero si esti lo ol indicador de error de seam fprinté(stderz, "Ks: Ka\n", Ver strorzor en Ie secciéa BS. B2. Pruebas de clasificacién de caracter acgumento es un int cuyo valor debe ser EOF o representable por un unsigned char, y el valor de retomno es un int, Las funciones regresan diferente de cero (verdadero) si el argumento © satisface la condicion deserta, y eta si no lo hace i FUNCIONES PARA CADENAS: 273 Swalpha(c) 0 Seaigit(c) os verdadera Ssupper(c) 0 istower(e) «9 verdadera caricier de control islower(e) isprintic) Aspunct (e) isspace(c) digit. Asapper(e) Asxdigitiel de impresion son de 0x20 0x 1F (US) y 0x72 (DEL). ; mes de tipo size; y.¢ es un int convertido a char char estropy(s,ct) copia la cadena ot a la cadena s, incluyendo “\O'; regress char retrnepy(s,ct,n! char xetreat(s,ot) char sstrneat: int stromp(cs,ot) int strnemp(cs, ct n) char ssteche(os,e) char *strrchr(ce,¢] NULL si no esta presenteOTECA ESTANDAR sizet strspntes,ct) APENDICE regresa la longitud del prefijo de es que eonsiste em foy ca size t strespn(es,ct) de esque voniste en as ca. char totrpbrk(os,ct) la primera ocurrencta en la cadena. ‘delacadena et, 6 NULL si ningu- char estrstr(es,ct) buscando jus a partir dé cnciientra rakens. La cadena et 6 y ot sou de tipe const void +; nes d io a unsigned char. yees um inteor void smemony( void ‘mernove( copia n caracteres de et a s, y regrese # lo mismo que memepy excepto que Fanciona aun si los labjetos se 1 int menenples,et.a) compara los primeros n caracteres de es com ot; regres lo mismio que stremp. regresa un apuntador ala primera ocurrencia del cardcter fc enes, o NULL si no-estd presente entre los primeros 2 void ‘menche(es,e,n| void smenset(s,c,n) een los primeros m caracteres des, 1 B4. Funclones mateméticas: El leader davlara funciones y macros matemticas, ‘Las macros EDOM y ERANGE («} _ PUNCIONES DE UnnuaaiA: om parte entera y fod \,7) 85. Funciones de utileria: ‘n> deelara funciones para conversién numérica, asignacion de me- mioria y tazeas semejantes. Gouple atof(const char +5) aiof convierte 6 ¢ double; es equivslente a strtoa + (ohare swuLE,276 laLioTECA ESTANDAR AvENDICE & int atoi(const char +8) coonvierte 8 a int; os cquivaleme a (int)etetoi(e, (ehares)MuLL, 10) Jong atelleonst char + ‘convierte 2.a long; e equ! lea stetol(s, (ohare+)NULL, double strtod(const char #8, char svendp) ‘bora, se regresa LONG_MAX 0 LONG_MIN, lo, y exrmo schacc ERANGE. unsigned long etrtoul(const char 42, char swendp, int base) stricul es lo mismo que strtel excepto que cl resultado es unsigned long y el valor de error es ULONG_MAX, int rand (void) aud deyuelve un entero pseudoaleatorio en el rango dea RAND_MAX, que es al me nos 32767 wa nueva secuencia de niimeros psevdoaleator void scaloc|size t nob} let size) acia para un arreglo de nob chjetos, cada uno de inp puede sarsfacerse, El espacio sc inicaliza a void smalloc(size t ize) ‘malloc regresa wn apuntador al espacio para un objeto de tama size, o NULL si It solicitud no se puede satisfacer. El espacio no se inicializa, SECCION Be FUNCIONES PARA UTILERIA: 277 Ji pes NULL, no hace nada, pdeve ser un ado por calloc, mallee, 9 realloc 2 STGABRT), Lowe void thscarch(const void *key, const void these, int -omp) (const void «keyval, const void +datun)) bsoaroh busca skoy. La funcion ‘omp debe regresar un valor negativa menor q Los elem ‘apuaiader al elemento coiucideate, o NULL si no existe geort el: ‘o size. La funcién de comparacién emp es como en beearch, int abs(int 2) ‘abe rearesa el valor absolute de su argumento int long labs(tong n} ;siduo de num/denom. Lo: y rem de una esiructura de quot y rom de u278 UBLIOTECA ESTANDAR APENDICE BG. Diagnésticos: La macro assert es usada para agreuar dlagndsticos a los programas: void assert (int expresién) Si expresin es cero cuando assert (expresicm) ‘macro assert imprimira én sldesr un mensaje, como, expresin, file filename, Line nnn ia abort para termina la ejecucién. El archivo fuente filename y el nimero FILE y __L:cnx__ del preprocesador. ‘cuando se incluy® «assert .h> se ignora la mucro assert, B7. Listas de argumentos variables: El Reader proporciona recursos para recorrer una lista de argumentos de funcidn de, tamano y tipo desconocido. Supéngase que lastarg ese ultimo pardmetro nomrado de una funeldn £ con nm. variable de arguments. Entonves se declara dentro de f una variable ap de tipo va List que a) va lice ap se debe inicializar una ver con la macro va_list antes de tener acceso a cualquier argu- mento mo nombracio’ La macro, void va_end(va_iist ap); jarcionan. una fora de eviter la se- ie para permitic un regres in- SECCION 8 SERALES: 279 condiciones exeepeionales que de facililades pare man srupeidn de une fuente externa aparecen durante Ia cjecucidn, tal eomo una sefal de (0 un error en Ia ejeeneidn ipo de Ia sonal SIGAERE SIGFPE sIGTL SIGINT SIGSEGY sTeneRM, int raise(int sis) ‘aise es ia a sohal aig al program: reivesa un ¥ B10. Funciones de fecha y hore APENDICE 8. no lees mepativa sde-e iniio de si pO en segUTCOS. té disponible. eleck{ } /CLK_0CK e: tine represa a jora getual del ealendiario, © 1 si ne esté disponible. Si tpne. como también es asignado a stp. double difftine(time + tine2, tine t tinet) iffume regresa time2-timel expresédo en segundos char sasctime(const struct tn +ep) fsetime convierte 1s hora de Ia estructura +p a una cadena de la Forma Sun Jan 3 15:14:72 1988\n\o e ba hoa d anctime( Localtime (tp: SCION Ht |S DEFINIDOS EN LA IMPLANTACION 281 vas de omax caracteres. strftime rearesa © cero si fueron produeidos mis de max pisdos de! entorna. Eas 0 s€ col el ndimero de earacteres, excluyendo a nombre abreviado del dia de Ia semana %A nombre completo de la semana, xx nombre abreviado del mes, ‘a nombre completo del mes. %e teprosentacién local de fecha y hora wa dia del mes (01-3), ahora (reloj de 24 horas) (00-23). 1 hora (reloj de 12 horas) (01-12). x dia xm mes ya mui Xp eat xs segundos (00-59). xv niimero de semana del aflo (lomingo es el primer dia de ta semana) (00-83) Kw ia de la semana (0-6, domingo es 0). 8A adimero de semana del ano (lunes es el primer dia de la semana) (00.53), ‘ke representaciéin local de la fecha. ‘x _representacién local de la hora. Hy aflosin els aio cou el Etheadér Toresmostrados son magni cHaR Bx CHARMAX —UCHAR_MAX or ‘SCHAR, MAX CHARMIN 0 or SCHAR_MIN INT MAK, +33767 INT_MIN -32767 LONG_max — +2147483647L. Longs = -21474836471, ‘SCHAR MAX +127 ‘SCHAR_MIN 127 minimo de signed char ‘SHRT_HAX 432767 smaximo de short SHRT_MIN 732767 iminimo de short ‘UCHAR Max 2550 valor maximo de unsigned char ‘UINT AX 655350 valor maximo de unsigned int282 mIBLIOTECA FSTANDAR APENDICE B LONG MAK 429496729507 valor mximo de unsigned Jong USHRT_MAK 655250 valor maximo de unsigned short arenoicec: Resumen de modificaciones FLT _RADIX 2 enema FUT_ROUNDS mode de redondeo de yur_ore 6 digitos decimales de precision PLE_EPSELON 78-5 menor mimero tal que PLP Mant pre itos de base ¥Lst_RADIX eh la mantisa Pur _Max, 72437 oudxime ndmero de punto flotante Foo Max_ExP maximo m tal que FET_RADTX'—} es representable FLT MEN 18-27 minimo mimero normalizado de punto Mlotante PLT_MIN EXP ‘minimo tal que 10" es un admero normalizado BL_DIS. 10 digitos decimales de preeisién DBb_EPSILON —TE-9 menor nilmero x tal que 1.0 +x 1.0 } : 8, y posteriorments se han ad DBb_MANT_DIG rnimero de digitos de base FL®_RADIX en la mantisa” do por otros proveederes de com lenguaje C. Recienteme DBG_MAX 18437 maximo nimezo double de punto Mlotante inoorporé mas de esos cambios estandarizando el lenguaie, ¥ DBL_MAK_EXP ‘maximo 7 tal que FL?_RADIX'I es representable liffcaciones significativas. Su reporte fue en parte anticlnado por algunos compladores ‘PBL _MIN 18-37 minimio mero double normalizado de punto flotante ‘DBL _MIN. EXP ainimo: tal que 10" es un mimero normalizado plictamete basscio en rakes (simbales):existen nuevos ‘operadores para la concatenacién de rokens (##) y creacion de cadenas (#); hay audvas lineas de control como #eli y #pregma; est explicitamente permitida a redeclaracién trigrificas introducidas por 2? ‘que no se encuentran en algunos conjuntos. Est ‘Véase §A12.1. Obsérvese que la de cadenas que contengun la 283284 RESUMEN DE BLODEFICACIONES APENDICE € cen los rangos de tipos aritmeticos ydeleg n>) el dar las caractersticas de cada implantacidn meraciones son algo auevo desde la primera edicién de-este libro. + Bl estindar adopta de C++ la nocién de (648.2) * Las cadenas ya no son medificables, por lo quis pueden siuarse en memoria de sélo lectura ‘+ Se cambisron tas ‘‘convenciones ar 40s, unsigned siempre gana; para 9 al tipo mas pequeto de suficiente capacidad’ * Los antigues operadores de asia bi saparecieron. Tam- asoclativos como computacionalmente asec + Se introdujo un operador unario + por simetria con el ~ unario, * Un apuntador a una funcién se puede utilizar como un designador de funetén sin un 10. Vase §A7.3.2. ras Se pueden dsignar, pasar a funciones, y regresar por funciones. + Esid permitido apliear el operador “direccién de’” a arreglos, y el resultado es un apuntador al arreglo. + El operador sizeof, en la primera edicién, dabs ef tipo sat; posteriormente, muchas uuneigned. El estandsr hace [pero requiere que el ripo size. sea defini en un header estindar ( ). Un cambio semsjante acurre en el tipo (ptrditi.t) de la. dife- ia entre apuntadores. Véase 7.4.8 y §A7.7. + El operador & (direccion de") n0 se puede aplicar a un objeco declarado register, cid decide no mantener al objeto en wn registo, RESUMIEN DE 2sIndice oper éedrecese 1M, a7EL LENGUAJE DEL PROGRAMADOR C INDICE ELLENGUAJE DEL PROGRAMADOR INDICE 289 lesa eps 25 ERANGE 71 rms 2/2, 27829D ELLENGUAJE DEL PROGRAMADOR C INDICE 2s ass fundin de onsen alle 276 funn de biases secre 2) funcon de sos Hoar EL LENGUAJE DEL RAN Fanci de bites ctv 267 Gebietes sane 273 fain de Sitolees am 25 funciona fats teINDICE 293 22_PLLENGUAIEDEL PROGRAMADORE INpIee Fropovibn de accion 48 Proponasn do 8, 209204 EL LENGUAJE DEL PROGRAMADOR C veateurient por dvs 1, 4 INDICE boLowe max, 24 ‘ned de rau 21,209, 281 tose baller vane Selb Sel ‘aloe auntie de eoresones iit 48 ‘aloe sume de wn erresin de rein 46 4 ii een 15, 685