Está en la página 1de 38
Arreglos en C Objetivos + Introducir la estructura de datos tipo arrego. + Comprender el uso de arreglos para almacenar, ordenar y buscar lista y tablas de valores. + Aprender c6mo declarare inicializar un arreglo, y cémo hacer referencia a elementos individuales de un arreglo, + Entender como pasar arreglos a funciones. + Comprender las técnicas basicas de ordenamiento + Declarar y manipular arreglos con miltiples subindices. Entre sollozos y ligrimas descubrio A aquellos de mayor tamatio, Lewis Carroll Intenta hasta el final, y no te detengas ante la duda; Nada es tan dificil, la buisqueda Io demostrara. Robert Herrick Ahora ve, escribelo antes que nadie en una tabla, {y andtalo en un libro. Tsaias 30:8 Esté guardado en mi memoria, ¥ ti deberds guardar la Mave. William Shakespeare 178 Arregios en ¢ Capitulo 6 Plan general 61 Introduccién 6.2 Arreglos 63 Declaracién de arregios 64 Ejemplos de arreglos 65 Cémo pasar arreglos a funciones 66 Ordenamiento de arreglos 67 Ejemplo prictico: Célculo de la media, la mediana y la moda a través de arreglos 68 Busqueda en arregios 69 Arreglos con milltiples subindices ‘Resumen + Terminologia + Ervores comunes de programacisn + Tips para prevenir errores + Buenas prdcticas de rogramacin Tips de rendimiento + Observaciones de ingenieria de software + Ejercicis de autoevaluacién Respuestas alos ejercicios de autoevaluacin + Kjecicias « jerccias de recursividad 6.1 Introducci6n Este capitulo sirve como una introduccién al importante tema de las estructuras de datos. Los arreglos son es- tructuras de datos que consisten en elementos de datos relacionados del mismo tipo. En el capitulo 10, expli- caremos la nocién de C de struct (estructura), una estructura de datos que consiste en elementos de datos relacionados que posiblemente sean de diferentes tipas. Los arregls y la estructuras son entidades "estaticas {que mantienen el mismo tamaiio durante la ejecucidn del programa (por supuesto, podrfan pertenecer a la clase de almacenamiento automatic y, por lo tanto, crearse y destruirse cada vez que se entra y se sale de los blo- ques en los que se definen). Enel capitulo 12, presentaremas estructuras de datos dinamicas coma lista, cols, pilas y arboles que pueden crecer y disminuir durante la ejecucién de los programas. 6.2 Arreglos Un arreglo es un grupo consecutivo de localidades de memoria relacionadas por el hecho de que tienen el mis- ‘mo nombre y el mismo tipo, Para hacer referencia a una localidad o a un elemento del arreglo en particular, es- pecificamos el nombre del atreglo y la posicin numérica del elemento en particular dentro del artegto La figura 6.1 muestra un arreglo de enteros llamado . Este arreglo contiene 12 elementas. Es posible hacer referencia a cualquiera de estos elementos al dar el nombre del arreglo seguido por la posicién numérica del clemento en particular dentro de corchetes ([1). Bl primer elemento de cada arreglo es l elemento cero. Enton- es, la referencia al primer elemento del arreglo c es e[ 0 ]. la referencia al segundo elemento del arreglo es €[ 1], lareferencia al séptimo elemento del arreglo es ¢ [6 ], y en general, la referencia al iésimo elemento del arreglo c es ef 4 ~ 1 J. Los nombres de arreglo, como los demés nombres de variables, pueden contener sélo letras, digitos y guiones bajos. Los nombres de arreglos no pueden comenzar con un digito, La posicion numérica que se encuentra entre corchetes se denomina, de manera formal, subindice. Un subindice debe ser un entero o una expresién entera. Si un programa utiliza una expresién como subindice, centonces la expresién es evaluada para determinar el subindice. Por ejemplo, si a= 5 y b= 6, entonces la instruceidn cla tb] 42 stma 2 al elemento e[ 11]. Observe que el subsndice del nombre del arreglo es un Ivalue: éste solo puede uilizarse del lado izquierdo de la asignacién Examinemos con mas detalle el arreglo © de la figura 6.1. El nombre de todo el arreglo es e. Asus 12 ele- ‘mentos se hace referencia como ¢[ 0], ef 1], ¢[ 2 ]..... ¢[ 11 J. Bl valor almacenado en ef 0 ] es ~45, el valor de e[ 1] €s 6, el valor de ef 2 ] es 0. el valor de ef 7 ] es 62 y el valor de e[ 11 ] es 78. Para desplegar la suma de los valores que se encuentran en las primeras ites posiciones del arreglo e, escribiriamos. printe( “4d”, cf 0] +ef 2] tel 2) ); Capitulo 6 ArregiosenC 179 Nombre celanegl (observe que todot los elementos de este regio tlenen el amo nombre. ©) | e601 =45 ett) 6 er2i ° eral 72 et41 [1543 ers a9 ereél ° emi 62 ere = e193 2 er101 | 6453 eri) 78 Posielén numérica Figura 6.1 Avaglo de 12 elementos Para dividir entre 2 el valor del séptimo elemento del arreglo e, y asignar el resultado a la variable x, escribi- eee 61/2; Error comiin de programacién 6.1 [Es importantenotar la diferencia entre el “séptimo elemento del arreglo™y el “elemento sete del arreglo™. Debido ‘que los subindices de los arreglas comienzan en 0, el “séptimo elemento del arregio” tiene un subindice de 6 Ientras que “el elemento set el arregio" tiene un subindice de 7 yen realidad, es el octavo elemento del arre- slo. Estes una fuente de “errores de desplazamiento en uno Los corchetes que se utilizan para encerrar el subindice de un arreglo, en realidad se consideran como un operador de C. Los corchetes tienen el mismo nivel de precedencia que el operador de lamadas a funcién (es decir, el par de paréntesis que se colocan después del nombre de una funcién para lamar a esa funcién). La figura 6.2 muestra la precedencia y asociatividad de los operadores que hemos presentado hasta este punto del texto, Estos aparecen de arriba hacia abajo en orden decreciente de precedencia, 6.3 Declaracién de arreglos Los arreglos ocupan espacio en memoria. El programador especifica el tipo de cada arreglo y el miimero de ele- ‘mentos que necesita el arreglo, de manera que la computadora pueda reservar la cantidad adécuada de memoria. Para indicarle a la computadora que reserve 12 elementos para el arreglo entero e, se utiliza la declaracién int ef 12.1; La siguiente declaracién int bl 100 J, x{ 27 1; reserva 100 elementos para el arreglo entero b, y 27 elementos para el arreglo entero x. 180 Arregios en ¢ Capitulo 6 Operadores Asociatividad Tipe 1 oO laquicrda aderecha ms alto + - ot (po) dderecha a igquierda ——unario . yo4 inquierda a derecha —— mulplicactn + - zqulerda a derecha ——adicion < > os fnquierda a derecha de relaciin zqulerda a derecha de igualdad inguierda a derecha AND légico " aqulerda a derecha OR Ligico 2 dderecha a tgquierda —_conticional = $= derechaaiguierda de asignacién : izqulerda a derecha coma Figura 62 Precedencia y asociatividad de operadores. Es posible declarar arreglos para que contengan otros tipos de datos. Por ejemplo, un arteglo de tipo chaz puede utilizarse para almacenar una cadena de caracteres. En el capitulo 8 explicaremos las cadenas de carac- teres y sus similitudes con los arreglos. En el capitulo 7 explicaremos la relacién que existe entre los apunta- dores y los arreglos. 6.4 Ejemplos de arreglos Esta seccién presenta diversos ejemplos que demuestran cémo declarar arreglos, cémo inicializarlos y cémo realizar muchas manipulaciones comunes a ellos Cémo declarar un arreglo y cémo utilizar un ciclo para inicializar sus elementos La figura 6.3 uiliza instrucciones fox para inicializar en ceros los elementos de tun arreglo entero n de 10 ele- ‘mentos, y para imprimir dicho arreglo en formato tabular, La primera instruccién print (linea 16) despliega Ja columna de encabezados para las dos columnas impresas en la instruccién for subsiguiente /* Figura 6,3: fi 40608. c nicializar un arreglo */ include int min@ ‘ 1 2 3 4 8 /+ La funcion min conienza la ejecucién del program */ 6 7 8 int al 10]; /* nes un arreglo de 10 enteros */ 9 nt ii /* contador =/ 10 Nf inicializa los elementos del arregio n a O del arreglo «/ 2 for (i < 10: itt) € 13 nl i 1 = 0; /* establece el clemmnto i a 0 +/ 14+) fe fin de for #/ 18 16 printf ( “gs913s¥A", “Elemento”, “Valor” ) 7 18 f* muestra el contenido del arreglo n en form tabular +/ Figura 6.3 Iniclalzacién en cero: de los elementos de un arreglo. Parte 1 de 2) Capitulo 6 ArregiosenC 181 9 for Ci i < 10; i) { 20 printf( “avas3awa", i, nf i 1): 21 } fs fin de for */ 22 23 return 0} /* indica terninacion exitosa */ 24 25» /* fin de min */ Blenento Val or 9 0 1 0 2 0 3 0 4 0 5 0 6 ° 7 0 8 ° 9 ° Figura 6.3. Inicialzaci6n en ceros de los elementos de un arreglo. Parte 2 de 2) (Cémo inicializar un arreglo en una declaracién con una lista de inicializacién Los elementos de un arteglo también pueden inicilizarse cuando se declara el arreglo, colocando un signo ‘gual seguido de un par de Haves, {}, que contenga una lista de inicializadores separados por comas. La figu- ra 6.4 inicializa un arreglo entero de 10 valores (linea $) y Io imprime en un formato tabular. Si existen mnenos inicializadores que elementos en ei arreglo, el resto de los elementos del arreglo se ini- cializa en cero. Por ejemplo, Ios elementos del arreglo n de la figura 6.3 se podrian haber inicializado en cero de la siguiente forma int nf 10} = (0); /* Figura 6.4: (120604. ¢ Inicializa un arreglo con una lista de inicializacion +/ Hinclude nt mein { 1 2 3 4 § /* 1a funcién main conienza 1a ejecucién del programa */ 6 7 8 /* utiliza la lista de inicializacién para inicializar el arreglo n */ 9 int nf 10] = { 32, 27, 64, 18, 95, 14, 90, 70, 60, 37 }: 10 int i: /+ contador */ u 12 printi( “asa; Elemento”, “Valor” ) 13 14 /* muestra el contenido del arreglo en form tabular +/ 1% for Ci i < 10; v4 16 printé( “aamasaWa", i, al i |): 17} f# fin de for +f 18 19 return O; /+ indica Lerminacién exitosa / 20 21) /* fin de min «/ Figura 6.4 Inicialzacién de los elementos de un areglo con una lista de niclalzacién. Parte 1 de 2) 182 Arregios en ¢ Capitulo 6 Elenent o Val or 32 27 64 18 95 4 90 70 60 37 Figura 6.4. Iniclalzacién de los elementos de un arreglo con una Ista de iniclalzacién. Parte 2 de 2) Fst incialza en cero de manera explicit al primer elemento, y de manera implicita alos nueve elementos restantes, debido a que en el arreglo existen menos inicializadores que elementos. Es importante que recuerde Que log aregls nts inca aufeasticamente en cero, El programadar debe iniclalizar al menos ol prez elemento en ceo, para que los elementos retantes se inicalicenautomiticamenteen cero. Pst metodo de in- cializacién de elementos a cero se lleva a cabo en tiempo de compilacién para los arreglos estaticos (static) Yen Gempo de gjecucidn para los areglos automstics, __. Etter comin de programacién 6.2 (a ‘Dividar inicalizar Ios elementos de un arreglo, cayos elementos debleran llcializarse. La declaracién del arreglo int al 5] = ( 32, 27, 64, 18, 95, 14); cocasiona un error de sintaxs, debido a que hay ses inicial _.. Error comin de programacién 6.3 (GB) Peper asta na sa aac Tas ae am or esa izadores y sélo cinco elementos en el arreglo. Si se omite el tamafto de un arreglo que se declaré con una lista de inictalizacién, el mimero de elementos cen el arreglo serd el mimero de elementos de la lista de inicializacién. Por ejemplo, ant af] = (1, 2, 3, 4, 505 crearia un arreglo de cinco elementos. Cémo especificar el tamaiio de un arreglo mediante una constante simbélica y cémo inicializar Jos elementos de un arreglo mediante calculos La figura 6.5 inicializa los elementos del arreglo de 10 elementos llamado s con los valores 2, 4, 6, ... 20, ¥ se imprime el arreglo en forma tabular. Los valores se generan multiplicando por 2 al contador de ciclo y su méndole 2. f+ Figura 6.5: fi g06_05.c Inicializa los elementos del arreglo s a los enteros pares de 2 a 20 +/ include define TAMINO 10 /* La funcién min conienza la ejecuci én del prograrn +/ int min) c Figura 65 Generacién de valorer a colocarse en los elementos de un angle. (Parte 1 de 2) Capitulo 6 ArregiosenC 183 9 J+ se puede utilizar la constante simbélica TAMANO para especificar el tamio del arreglo */ 10 int s[ TAMWNO J; /* el arreglo s contiene 10 elementos */ u int ji /* conntador */ 12 13 for (i = OF j < TARNG, j++) { /= establece Los valores #/ 4 sLj ]=2+24i: 18} f/# fin de for */ 16 17 printf( “9s9@3s¥A", “Elemento”, “Valor” J: 18 19 /* muestra el contenido del arreglo s en form tabular «/ 2 for (j= Oj < TAMING: j +t) 21 printé( “avamasawa", j, st j 1) 2 ©) Js fin de for +/ 23 24 return 0: /+ indica Lerminacién exitosa +/ 25 26) f+ fin de min ¥/ Blenento Val or 0 2 1 4 2 6 3 8 4 10 5 2 6 u 7 16 8 18 9 20 Figura 6.5 Generacién de valores a colocarse en las elementos de un ameglo. Parte 2 de 2.) 1a directiva de preprocesador #define se introduce en este programa, La linea 4 define TAMANIO 10 define una constante simbdlica TAMANTO, cuyo valor es 10. Una constante simbélica es un identificador que es reemplazado por el preprocesador de C con texto de reemplazo, antes de que se compile el programa. Cuan- do se ptepracesa el programa, todas las ocurrencias de la constante simbélica TAMANTO se reemplazan con el texto de reemplazo 10. Utilizar constantes simbélicas para especificar el tamafio de un arreglo hace que los programas sean mas escalables. En la figura 6.5, el primer ciclo for (linea 13) podria lenar un arreglo de 1000 elementos, si tan solo se modificara el valor de TAMANTO en la directiva #define de 10 a 1000. Sino hu- biéramos utilizado la constante simbélica TAMANTO, hubiéramos tenido que cambiar el programa en tres luge res diferentes para escalarlo y que pudiera manejar un arreglo de 1000 elementos. Esta técnica se vuelve mi Util para escribir programas mas claros, conforme éstos se vuelven més grandes Error comiin de programacién 6.4 Finalizar una directiva de preprocesador #e. tuvas de preprocesador no Son instrucciones de C. “Jucle con un punto y coma. Recuerde que las direc Si la directiva de preprocesador #de#ine de la linea 4 termina con un punto y coma, el preprocesador reemplaza todas las ocurrencias de la constante simbdlica TAMANTO con el texto 10. Esto puede ocasionar ertores de sintaxis en tiempo de compilacisn, o errores de logica en tiempo de ejecucién. Recuerde que el pre- procesador no es C; sélo es un manipulador de texto 184 x [sy Arregios en C Capitulo 6 Error comin de programacién 6.5 ‘signar un valor @ una constante simbdlica en wha lnsirucclGn gjecutable, es un error de sintaxis, Una constant simbélica no es una variable, El compilador no reserva espacio alguno para ella, como To hace con las vartables ‘que contienen valores en tiempo de ejecucisn. Observacién de ingenieria de software 6.1 DDefinir el tamaiio de un arreglo como una constante simbdlica hace qué las programas sean mas escalables Buena préctica de programacién 6.1 Uiilice sélo letras mayisculas para los nombres de constantes simballcas, Esto hace quo estas constantes resalen fen un programa y recuerda al programador que las constantes simbdlicas no som variables Buena practica de pregramacién 6.2 En nombres de constantes imbélicas que conlengan varias palabras, ulilice guiones bajas para separarlas y, asi @ Cémo smgjorar su legibilided. sumar los elementos de un arreglo La figura 6,6 suma los valores contenidos en el arreglo a tipo entero de 12 elementos, a. El cuerpo de la ins- truceién for (linea 16) calcula el total (Cémo utilizar arreglos para resumir los resultados de una encuesta [Nuestro siguiente ejemplo utiliza arreglos para resumir la informacién recolectada en una encuesta. Considere 1 enunciado del problema A cuarenta estudiantes se les pregunté respecto ala calidad de la comida dela cafeteria escolar, en una scala de 1a 10 (1 significa muy mala y 10 significa excelente). Coloque las 40 respuestas en un arreglo entero que resuma los resultados de Ia encuesta 1 f+ Figura 6.6 fi c 2 Caleula Ta sum de los elementos del arreglo */ 3 Hinclude 4 déefine TAMANO 5 6 /+ 1a funcién min conienza la ejecucién del prograrm */ 7 int min() ak 9 f+ utiliza una lista ée 10 int al TAMNO J = { u int ii /* contador */ 12 int total = 0; /* sum del arreglo #/ 13 14 f* sum el contenido del arreglo a +/ 1 for (i = 0; i < TANG it) { 16 total += al i i 7) f+ fin de for «/ 18 19 printf “Bl total de Los elempatos del arreglo es ¥A", total )s 20 21 return 0; /* indica terninacién exitosa #/ 2 23°} /+ fin de min *f Hl total de los elementos del arreglo es 383 Figura 6.6 Célculo de Ia suma de los elementos de un artegto, Capitulo 6 ArregiosenC 185 Esta es una aplicacién tipica de los arreglos (vea la figura 6.7). Nosotros deseamos resumir el mimero de respuestas de cada tipo (es decir, de 1a 10). Elarreglo respuestas (linea 17) contiene 40 clementos que al- rmacenan las respuestas de los estudiantes. Utilizamos un arreglo de 11 elementos llamado frecuencia (linea 14), para contar el nimero de ocurrencias de cada respuesta. Ignoramos frecuencia 0 ] porque es lgico hacer que la respuesta 1 incremente a frecuencia[ 1 ], en lugar de frecuencia [ 0 ]. Esto nos permite utilizar directamente cada respuesta como el subindice del arreglo frecuencia Buena prictica de programacién 6.3 Tip de rendimiento 6.1 Fea Fn ocaslones, las consideraclones relacionadas con el rendinleno se alejan demasiado de Tas consideracones para lograr fa claridnd 186 Arregios en ¢ Capitulo 6 Rango Frecuencia 1 2 2 2 3 2 4 2 6 uv 8 7 9 1 10 3 Figura 6.7 Programa para analizar una encuesta aplicada a estudiantes, (Parle 2.de 2.) El ciclo for (linea 24) toma las respuestas, una a la vez, del arreglo xespuestas ¢ incrementa uno de los 10contadores(frecuencia{ 1] 2 frecuencia 10 ]) de dicho amegl. La instruccién clave del c- clo es la linea 25 Hetcecoenctal respuastas[ respuesta} 1; In cual incremental contador de #xecueneia adecudo, de acuerdo con el valor de eespuestas { zes- puesta ]. Cuando la variable contador respuesta es 0, respuestas[ respuesta ] ¢s respuestas[ 0 ] ‘que es 1, por lo que la instrucci6n ++£recuencia[ respuestas|[ respuesta } ]; en realidad se inter- preta como Jo que incrementa el elemento uno del arreglo. Cuando respuesta es 1, respuestas[ respuesta ] es respuestas( 1] quees 2, porloquelainsruccin ++trecuencia[ respuestas| respuesta } ]; en realidad e interpreta. como Htrecuencia 21; Jo que icrementa el elemento dos del arreglo. Cuando respuesta cs 2, respuestas respuesta ] cs Feopuestaa[ 2 } quees 6, porlo que lainstuccién ++frecuencial reepuestas| respuesta }]; ‘en realidad se interpreta como To que increment el elemento ses el artelo, yas sucesivamente, Observe que inependientemente del ni mero de respuestas procesadas en la encuesta, s6lo se requiere un arreglo de once elementos (si omitimos el elemento cero) para resumir los resultados, Si la informacién contuviera valores no permitidos como 13, el pro- gama intenara agregar 1.2 frecuencia 13 }. Esto esaria fra de los limites del areglo. C no tene forma de verificar Ios lintes del arrego para evtar qu la computadora haga referencia a elementos inet. tents del arrepla Parl tanto, un prograraaen ceca puede slr o termina el procstrnteto de en are sin advertenca alguna. Fl programadr deber asegurrse de que oda las eferencas alos ateglos permane7. can dentro de estos limites. Error comin de programacién 6.6 (#| Hacer referencia aun elemento que se encuentra Tera de Ts Tinie dl areglo. Tip para prevenir errores 6.1 Cuando se hace un ciclo en torno a un arreglo, el subindice del arreglo nunca debe ser menor que O y siempre debe ser menor que el mimero total de elementos del arregl (lamatio -1), Asegirese que la condictén de termina cin de ciclo prevenga el acceso de elements fuera de este rango. Tip para prevenir errores 6.2 Tos programas deben validar que todos los valores de entrada sean correctos, para evitar que Informacion errOnea afecte los caleulos del programa. Capitulo 6 ArregiosenC 187 Cémo graficar Ios elementos de un arreglo mediante histogramas Nuestro siguiente ejemplo (figura 6,8) lee los miimeros de un arreglo y grafica la informacin en forma de un grafico de barras o histograma: cada mimero se imprime, seguido por una barra que consiste en muchos aste- riscos. La instruccién anidada for (linea 20) dibuja las barras. Observe el uso de print ("\n") para fina- lizar la batra del histograma (linea 24). Cémo tirar un dado 6,000 veces y resumir Ios resultados en un arreglo En el capitulo 5 dijimos que mostrarfamos un método més elegant para escribir el programa de dados de la fi gura 5.8. El problema trata sobre tirar un dado de seis lados 6,000 veces para probar si el generador de miimeros aleatorios realmente producia mimeros aleatorios. La figura 6.9 muestra una version de este programa con arteglos, Blenento Val or Histogram 0 19 seaaueseseceeeoeees 1 3 wee 2 15 seanenaeeeeeoes 4 u seeassenene 5 9 sannannee 6 13 eee 7 5 wate 8 1 + Figura 6.8 Imoresién de un histograma, 188 Arregios en ¢ Capitulo 6 1 /* Figura 6,9 fi g06_09.¢ 2 Lanza un dado Ge seis lados 6000 veces */ 3. include 4 #include S #include 6 #define TAN 7 7 8 /+ 1a funcion min conienza la ejecucién del program +/ 9 int minal) 10 < n int carai /* valor aleatorio del dado entre 1a 6 +/ 12 int tiro: /+ contador de tiros 1 a 6000 +/ 13 int frecuencial TAMMNO | = ( 0}: /+ inicializa a cero 1a cuenta +/ 4 18 srand( time( MLL) ): /* generador de la senilla de alnmeros alcatorios */ 16 17 f+ tira el dado 6000 veces +/ 8 for ( tire = 1i tiro <= 6000; Lirot#) { cara = 1 + rand() % 6 20 +frecuencial cara }: /* renplaza la instrucci én switch de la linea 26 de la figura 5.8 +/ 21 fe fin de for */ 2 23 printf * ", “Cara”, “Frecuencia” ) 24 25 /* muestra los elementos 1-8 de frecuencia en form tabular */ 26 = for ( cara = 1; cara < TAMING: carat) { 27 print{( “sédmi7d¥Ws", cara, frecuencial cara ] ) 28} /* fin de for */ 29 30 return 0; /+ indica terninacién exitosa */ 31 320} /+ fin de min */ cara Frecuencia 1 1029 2 951 3 987 4 1 5 1010 5 990 Figura 69 Programa de tre de dados mediante el uso de atteglos on lugar de Ia Instuccion switch. (Cémo utilizar arregios de caracteres para almacenar y manipular cadenas Hasta el momento, slo hemos explicado arreglos enteros. Sin embargo, los arreglos son capaces de almacenar datos de cualquier tipo. Ahora explicaremos el almacentamiento de cadenas en arreglos de caracteres. Hasta este ppunto, la tinica capacidad para el procesamiento de cadens con la que contamos es la impresién de una cadena con print. Una cadena como "hola", en realidad es un arreglo estatico (static) de caracteres individua- les de C. Los arreglos de caracteres tienen muchas caracteristicas tinicas. Un arreglo de caracteres puede iniciali- zarse mediante una literal de cadena, Por ejemplo, char cadenai(] = “primero”; Capitulo 6 ArregiosenC 189 inicializa los elementos del arreglo cadena mediante los caracteres individuales de ta literal de cadena “primero”. Fn este caso, cl compilador determina el tamafo del arteglo cadena, basindose en la longi- tud de la cadena, Es importante observar que la cadena “primero” contiene 7 caracteres, mas un cardcter es- pecial de terminacién de la cadena llamado carécter nulo.Por lo tanto, el areglo cadena en realidad contiene ‘ocho elementos, La constante que representa el carécter nulo es *\0" Todas las cadenas en C finalizan con este cardcter. Un arreglo de caracteres que representa una cadena siempre debe declararse con el tamafo sufi- ciente para almacenar los caracteres de la cadena y el caracter de terminacién mulo, Los arreglos de caracteres también pueden inicializarse mediante caracteres individuales constantes en una lista de inicializacién. La definicidn anterior es equivalente a char cadenal[] = { ‘p’, ‘x7, ‘47, ‘m’, ‘87, ‘x7, Yo", ‘\O" Debido a que una cadena en realidad es un arreglo de caracteres, podemos acceder directamente alos carac- teres individuales de la cadena, utilizando la notacién de subindices, Por ejemplo, cadenat [ 0 ] es el ca- ricter *p’, y eadenal [ 3 ] es el caricter ‘m’ ‘También podemos introducir directamente una cadena en un arreglo de caracteres desde el teclado, utili- zando scant y cl especificador de conversion %8, Por ejemplo, char cadena2{ 20 1; crea un arreglo de caracteres capaz de almacenar una cadena de 19 caracteres y el cardcter de terminacién nu- Io, La instruceién scanf( “ts”, cadenaz ); Jee una cadena introducida desde el teclado en cadena2. Observe que el nombre del arreglo pasa a scant sin el & que utilizamos para preceder a las variables que no son cadenas. El ¢ normalmente se utiliza para proporcionar a seané la ubicacién en memoria de una variable, para que ahi pueda almacenarse un valor. En Ja seccidn 6,5, cuando expliquemos el paso de arreglas a funciones, veremos que el nombre de un arreglo es la diteccién del inicio del arreglo: por lo tanto, el & no es necesario, Es responsabilidad del programador asegurarse de que el arreglo en el que se lee la cadena es capaz de almacenar cualquier cadena que el usuario escriba mediante el teclado, La funcién seané lee los caracteres introducidos a través del teclado, hasta que encuentra el primer cardcter blanco; ésta no verifica el tamafio del arreglo. Por lo tanto, sean puede escribir mas allé del final del arreglo, Error comtin de programacién 6.7 ‘No proporcionarle a scant un arreglo de caracteres lo sulicientemente grande para almacenar una cadena esc ta mediante el teclado, puede ocasionar la destruccin de los datos de un programa y otras errores en tiempo de gjecucton, Un arreglo de caracteres que representa a una cadena puede imprimirse con printé y el especificador de conversidn $8, El ameglo cadena2 se imprime con la instruccién print€( “4s\n", cadena? ); Observe que print, como seané, no verifica el tamaiio del arreglo de caracteres. Los caracteres de la cadena se imprimen hasta que aparece el carter de terminacién nulo. La figura 6.10 muestra la inicializacién de un arreglo de caracteres mediante una literal de cadena, la ee- tura de una cadena que se encuentra en un arreglo de caracteres, la impresin de un arreglo de caracteres como cadena, y el acceso a los caracteres individuales de la cadena J Figura 6.10: fig06_10.¢ Mini pul acion de arreglos de caracteres com cadenas */ incl ude funcion min conienza la ejecucion del programa */ Figura 6.10 Arregios de caracteres procesados como cadenas. Parte | de 2.) 190 Arregios en ¢ Capitulo 6 6 int min() 7 8 char cadenall 20 }i /* reserva 20 caracteres */ 9 char cadena2[] = “literal de cadena”; /* reserva 18 caracteres */ WO int i; /* contador */ u 12 /+ Lee La cadena del usuario y la introduce en el arreglo cadenal +/ 13° printf ("Introduce una cadena: *) 14 scanf( "6", cadenal ); /* entrada que finaliza con un espacio en blanco +/ 15 16 /+ muestra las cadenas +/ 17 printf ( “La cadenal es: %sWicadena2 es: %s¥' 18 “La cadenal con espacios entre caracteres es: ¥i", 9 cadenal, cadena? )i 20 21 f* muestra los caracteres hasta que encuentra el caracter alo +/ 2 = for (i = 0: cadenall i | t= ‘WO: ia) 4 23 printf( “te ", cadenall i |): 2) f+ fin de for */ 25 26 printf “¥" 27 28 return 0: /* indica terninacién exitosa */ 29 30} /* fin de min */ Introduce una cadena? Ibla ani gos Ia cadenal es: Hola cadena? es: literal de cadena La cadenal con espacios entre caracteres es Hola Figura 6.10 Arregios de caracteres procesados como cadenas, (Parte 2 de 2.) La figura 6.10 utiliza una instruccién fox (linea 22) para generar un ciclo a través del arreglo cadena « imprimir los caracteres individuales separados por espacios mediante el especificador de conversién $e. La condicién de la instruccién for, cadenal [ i] != *\0" es verdadera hasta que el ciclo encuentra el cardc- ter de terminacién nulo en la cadena, Arreglos estéticas locales y arreglos automaticos locales En el capitulo 5 se explicé el especificador de clase de almacenamiento static. Una variable local static existe a lo largo de la duracion del programa, pero séto es visible en el cuerpo de la funcién, Podemas aplicar el especificador static a la declaracién de un arreglo local, para que el arreglo no se genere y se inicialice ‘cada vez. que el programa lame a la funcién, y para que el arreglo no se destruya cada vez. que el programa salga de la funcion. Esto reduce el tiempo de ejecucidn del programa, en particular de aquellos programas que contienen lamadas frecuentes a funciones que contienen arteglos grandes, Tip de rendimiento 6.2 En fanciones que contienen arreglos aufomdticos, en donde Ia fancion entra y sale con frecuencia de alcance, haga que el arreglo sea se.av ic para que éste no se genere cada vez que se savoque ala funcié, Los arreglos static se inicializan autométicamente en tiempo de compilacién, Si el programador no ini- aliza explicitamente un arreglo static. el compilador inicializa en cero a los elementos del arreglo. Ta figura 6.11 muestra la funcin iniciaArreglokstatico (linea 24) con un areglo local static (linea 27), y a funcidn inicdaArregloAutomatico (linea 47) con un arreglo local automiético (linea 50), Capitulo 6 ArregiosenC 191 Ala funcién iniciaarregloEstatico se le llama dos veces (lineas 12 y 16). El compilador iniciatiza en cero al arreglo local static de la funcion (linea 27), La funcién imprime el arreglo, le suma $a cada elemen- toy lo imprime nuevamente. La segunda vez que se llama a lafunciGn, el arreglo stati contiene los valores almacenados durante la primera llamada a la funci6n. A la funcién iniciaArregloAutomatico también se le llama dos veces (lineas 13 y 17). Los elementos del arreglo local automatico de Ta funcién se inicializan con los valores 1, 2 y 3 (linea 50}. La funcién imprime el arregio, le summa 5 a cada elemento y lo imprime nue- ‘vamente. La segunda vez. que se llama a la funcidn, los elementos del arreglo se inicializan nuevamente en 1 2 y 3, debido a que el arreglo tiene una duracién automatica de almacenamiento, Error comtin de programacién 6.8 al Suponer que ls elementos de un aregl local soa fen la que el arreglo estédeclarado, Se lniclalizan en coro cada vez que se Hama a Ta Tuncléa 1 f+ Figura 611: figdé_ite 2 Arregios estaticos que se in zan a cero + 3 finclude 4 5 void iniciaAregl ofistatica( void): / prototipo de 1a funci én »/ 6 void iniciadrregl oAutomatico( void )i /* prototipo de 1a funcién +/ 7 8 /* 1a funcién min conienza 1a ejecucién del programa */ 9 int minQ 10 4 u print{( “Primera llammda a cada funcion:¥4" ) 12 iniciadrregl oBst ati col): 13 iniciaArregl oAut omti col) 4 18 printf( “WiWiSegunda Il amda a cada funci on: Wh" ): 16 iniciaArregl oFst ati col): 17 iniciaArregl oAut omati col): 18 19 return 0; /+ indica terninacién exitosa */ 20 21) /+ fin de min */ 2 23 /+ funcién para demstrar un arreglo estatico Local */ 24 void iniciaArregl ostati col void ) 2 4 26 —/# inicializa Los elerwntos a 0 1a primera vez que se Ilan a la funcion +/ 27 static int arreglolf 3 1 28 int i: /* contador +f 29 30 print{( “WiValores al entrar a iniciaArregloEstatico: ¥A" ) 31 32 /* meestra el contenido del arreglol */ 3300 for (i =O i GB ise) 4 34 C“arreglol{ @@] = %d “, i, arreglolf i J): 35 fs fin de for */ 36 37° printf( "WiValores al salir de iniciaArregl oEstatico: ¥i" ) 38 39 /* mpdifica y muestra el contenido de arreglol +/ Figura 6.11 Si el programador no iniciaiiza explicitamente los arregios static, éstos se iniclalzan ‘utoméiticarente en caro. Parte 1 de 2) 192 Arregios en ¢ Capitulo 6 printf( “arreglol{ %d ] vi, arreglolf i | #= 55 ) ys fin de for #/ } /* fin de ta funcion inci aArregl okstatico +/ /+ Cuncién para denwstrar un arreglo local aulonético +/ void iniciaArregl oAut omnti col void ) ‘ /* inicializa los elementos cada vez que se llama la funci én */ int arreglo2l 3} =< 1, 2, 3 i nt is /* contador +/ print{( “¥a¥AValores al entrar a iniciaArregl oAuLomatico: A" ) f* mestra contenido de arregl o2 */ for Ci bea is) 4 print{(*arreglo2l %d ] = 9d “, i, arregio2l i |): ) ps fin de for +/ printf( “¥aValores al salir de iniciadrreg! oAst omati co: Wi" ) /* mdifica y muestra el contenido de arreglo2 */ SSRLSSSSSSLSHL SSL SSESeKRERLS for Ci Pe 2 it) ¢ print{( “arreglo2{ gd ] = %4 l4=5) ) /* fin de for #/ } f+ fin de la funci én iniciadrregl oAutomatico +/ Primera llamada a cada funci on Valores al entrar a iniciaArregl oFstati co’ arregioi[ 0] = 0 arreglol{ 1 ] = 0 arregloll 2] = 0 Valores al salir de iniciaArregl oBstati co’ arregioi[ 0] = 5 arregiol{ 1] = 5 arregioll 2] = 5 Valores al entrar a iniciaArregl oAut omnti co’ arregio2/ 0] = 1 arreglo2( 1] = 2 arreglozl 2] = 3 Valores al salir de iniciaArregl oAut omatico’ arregiozl 0 ] arreglo2i 1] = 7 arreglo2{ 2 | Segunda Ilamada a cada funci on Valores al entrar a iniciaArregl olstati co! arregiol[ 0] = 5 arregloll 1 ] arregloll 2 1 Valores al salir de iniciaArregl ostati co! arregiol[ 0] = 10 arreglol{ 1] = 10 arreglol{ 2] = 10 Valores al entrar @ iniciaArregl oAat omati co: arregio2[ 0] =1 arreglo2{ 1] =2 arreglozl 2] = 3 Valores al salir de ini ci aArregl oAut omati co: arreglozl 0 ) arreglo2( 1} = 7 arreglo2{ 2] = 8 Figura 6.11 Si ol programador no iniciaza explicitamente los arreglos static, ést0s se inicialzan, ‘utométicamente en cero. Parte 2 de 2) Capitulo 6 ArregiosenC 193 6.5 Cémo pasar arreglos a funciones Para pasar un arreglo como argumento a una funcién, especifique el nombre del arreglo sin corchetes. Por ejem- plo, siel arreglo tempCadaHora se declara como int tempcadaHora{ 24 }; Ja Hamada de funcién modificaarreglo ( tempCadaHora, 24 ) pasa el areglo tempCadaHora y st tamatio a la funcidn modi fi caArreglo. A diferencia de los arreglos char que contienen cadenas, estos tipos de arreglos no tienen un terminador especial. Por esta razén, el ta- rmafio del arteglo se pasa a la funcién, para que ésta pueda procesar el mimero apropiado de elementos. C pasa automdticamente pot referencia los arreglos a funciones; las funciones llamadas pueden modificar los valores del elemento en los arreglos originales de las funciones que las laman. El nombre del arreglo es en realidad la ditecci6n del primer elemento del arreglo. Debido a que se pasa la direcién inital del atreglo, la funcién lamada conoce precisamente en dénde esté almacenado el arreglo, Por lo tanto, cuando la funcidn la- ‘mada modifica los elementos del arreglo en su cuerpo de funcién, modifica los elementos actuales del arreglo en sus posiciones originales de memoria, La figura 6.12 demuestra que el nombre de un arreglo en realidad es la direccién del primer elemento del arreglo, imprimiendo arreglo, éarreglo[ 0] y éarreglo mediante el especificador de conversion &p; tun especificador de conversién especial para la impresidn de direcciones, El especificador de conversién ‘sp normalmente despliega las direcciones como miimeros hexadecimales. Los mimeros hexadecimales (base 16) consisten en digitos del 0 al 9 y las letras A a F (estas letras son los equivalentes hexadecimales de los rnimeros 10 a 15). Con frecuencia se utilizan como notacin abreviada para valores enteros grandes. El apé dice E, Sistemas numéricos, proporciona una explicacidn profunda de las relaciones entre enteros binarios (base 2), octales (base 8), decimales (base 10; enteros estandar) y hexadecimales. La salida del programa mues- tra que tanto arreglo como éarreglo[ 0 } tienen el mismo valor, a saber, 0065FDFO. La salida de este programa depende del sistema, pero las ditecciones siempre son idénticas para una ejecucién en particular de este programa en una computadora en particular. 1 fs Figura 6.12: fi g0612.¢ 2 FL nonbre de un arregla es lo nism que Sarreglol 0] +/ 3° finclude 4 5 uncién min conienza La ejecucién del prograna */ ‘6 74 8 char arreglol 5 Ji /* define un arreglo de 5 elementos */ 9 10 printe( arreglo = %p¥Aéarregl o[0] = sp¥i" u Serreglo = %p¥! 12 arreglo, Serreglo[ 0], éarreglo )i 13 14 return 0} /= indica terninacion exitosa */ 15 16) /* fin de min ¥/ arreglo = OO65EDRO Sarregl o[0] = OO65KDF0 Serreglo = 0065FDFO Figura 6.12 Elnomire de un araglo es el mismo que la dlreccién del primer elemento del arregio. 194 Arregios en ¢ Capitulo 6 Tip de rendimiento 6.3 Legal} Pasar arreglos por referencia ene sentido por motives de rendiniento- Silos arreglos se pasaran por valor, nto ‘es una copia de cada elemento también pasaria, Esto implicaria que para pasar arreglos grandes y de manera Arecuente, se requriria demasiado tempo y demasiado espacio de almacenamiento para las copias de los arregos. Observacién de ingenieria de software 6.2 [Es posible pasar un arreglo por valor (mediante un simple truco que expliaremas en el capitulo 10) Aunque arreglos completos se pasan por referencia, los elementos individuales de un arreglo se pasan por valor, como se hace con variables sencills. tales conjuntos de datos individuales (como ints, Floats y chars individuales) se les lama escalares. Para pasar un elemento de un arreglo a una funcién,utilice el nom- bre con subindice del elemento, como un argumento en la llamada de funci6n. En el capitulo 7, explicamos ‘cémo pasar por referencia escalares (es decir, variables individuales y elementos de arreglos) a funciones. Para que una funcién reciba un arreglo a través de una llamada de funcin, la lista de parémetros de la fun- cidn debe especificar que se recibira a un arreglo. Por ejemplo, el encabezado de funcién para la funcién modi ficaArreglo (que mencionamos anteriormente en esta seccién) podria escribirse como void modificaArreglo( int b[], int tamanio ) lcual indica que modi #icaArreglo espera recibir un arreglo de enteros en el pardmetro b y el mimero de ele- ‘mentos del arreglo en el pardmetro tamanio. No es necesario encerrar entre corcetes cl tamafo del areglo. Si éte se incluye, el compilador verifica si es mayor que cero para ignorarlo. Especificar un tamafio negativo gene ra un error de compilacién. Debido a que los arreglos pasan aulomiéticamente por referencia, cuando la funcién Iamada utiliza el nombre de arreglo B, ésta hara referencia al arreglo dela funcién que lama (es decir, al arreglo tempCadaliora de la llamada anterior). En el capitulo 7, presentamos otras notaciones para indicar que un arreglo esta siendo recibido por una funcién. Como veremos, estas notaciones se basan en la estrecha relacién que existe entre los arreglos y los apuntadores en C. La figura 6.13 demuestra la diferencia entre pasar un arreglo completo y pasar un elemento del arreglo, El programa primero imprime los cinco elementos del entero arreglo a (Kineas 20 a 22). Después, a y su tamao pa- san a la funcién modi ficakrreglo (linea 27), donde cada uno de los elementos del arreglo a se multiplica por 2 (lineas 56 y 57). Posteriotmente, a se vuelve a imprimir en main (Lineas 32 a 34). Como muestra la sali- da, los elementos del arreglo a en realidad son modificados por modi#icaArreglo. Ahora el programa imprime el valor de af 3 ] (linea 38) y lo pasa a la funcién modi ficaElemento (linea 40). La funcién modificaElemento multiplica su argumento por 2 (linea 67) e imprime el nuevo valor. Observe que cuando a[ 3 ] se vuelve a imprimir en main (linea 43), no se ha modificado, ya que los elementos individua- Tes de un arreglo se pasan por valor. 196 Arregios en ¢ Capitulo 6 Efectos de pasar arreglos conpletos por referencia los valores del arreglo original son o1234 Los valores del arreglo mpdificado son 02468 Efectos de pasar un elemento del arreglo por valor Hi valor de al3] es 6 El valor en mpdificaEl erento es 12 Hi valor de al 3] es 6 Figura 6.13 Paso de attegios y de elementos inalvieluales a tunclones. Parte 3 de 3) Pueden existir situaciones en sus programas en las que no se debe permitir que una funcién modifique los elementos de un arreglo. Debido a que los arreglos siempre se pasan por referencia, la modificacién de valores de arreglos es dificil de controlar. C proporciona el calificador de tipo const para prevenir que una funcién ‘modifique los valores de un arreglo. Cuando un pardmetro de un arreglo es precedido por el calificador const, los elementos del arreglo se vuelven constantes en el cuerpo de la funcién, y cualquier intento de modificar un ‘elemento del arreglo en el cuerpo de la funcién da como resultado un error en tiempo de compilacién, Esto per- rite al programador corregir un programa para que no intente modificar los elementos de un arreglo. a figura 6,14 muestra el calificador const. [a funcidn intentaModifE1Arreglo (linea 22) se de- clara con el parametto const int bf], el cual especifica que el atreglo b es constante y no puede modifi- carse. La salida muestra el mensaje de error que produce el compilador: los errores pueden ser diferentes en stu sistema, Cada uno de los tres intentos que hace la funcién de modificar los elementos del arreglo, da como re- sultado el error del compilador “1-value specifies a const object”. En el capitulo 7 explicamos suevamente el calificador const. Observacién de ingeni ia de software 6.3 Ei calficador de tipo cons puede aplicarse a un pardmetro de arreglo en Ja declaracion de una funcln, para FY prevenir que el arreglo original sea modificado en el cuerpo de la funciéin Este s otro ejemplo del principio del ‘menor privilegio. A las funciones no se les debe dar la capacidad de modificar un arreglo, a menos que sea abso Jutamente necesario. 1 /* Figura 6.14 fi g0614.c 2 Denstracion del calificador de tipo const con arreglos */ 3° include 4 5 Void intentaNbdi fH Arreglo( const int bE] )i /+ prototipo de 1a funcién «/ 6 7 f+ La funcién sin conienza la ejecucién del programm */ 8 int mint) 9 4 10 nt al] = { 10, 20, 30} /+ inicializa a +f n 12 intentaModi fl Arreglo( a )s 3 14 printi(“9d 9d aM", al O}, al 1), al 245 15 16 return 0; /* indica terminacién exitosa +/ Figura 6.14 Calficador de tipo const. (Parte | de 2) Capitulo 6 ArregiosenC 197 18) /* fin de min */ 20 /* en La funcion intent aMidif El Arreglo, el arreglo b es const, por lo tanto no puede ser 21 utilizado para mpdificar el arreglo original a en min. */ 22° void intentaMbdifEl Arreglo( const int bl] ) 23 4 24 J+ error */ 25 (* error */ 26 f+ error +/ 27) /# fin de 1a funcién intentaNbdifElArreglo +/ ‘WADEI TELWEHDSW i g06_14. c(24) : error C2166: I-value specifies const obj ect WADE TELWEHDSWi g06_14. c(25) + error C2166: L-value specifies const obj ect WADE! TELWCHD6W i g06_14. c(26) : error C2166: 1-value specifies const obj ect Figura 6.14 Calificacr de tipo const.(Parte 2 de 2) 6.6 Ordenamiento de arreglos El ordenamiento de datos (es decir, colocar los datos en un orden particular, ya sea ascendente o descendente) es uta de las aplicaciones de cémputo ms importantes. Un banco ordena todos los cheques por mimero de cuenta de manera que puede preparar los estados individuales del banco al final de cada mes. Las empresas de tele- fonia ordenan sus istas de cuentas por apellido y, dentro de este ordenamiento, hacen otro por nombre para facilitar la bisqueda de nimeros telefnicos. Virtwalmente todas las empresas deben ordenar algin tipo de dato yy, en muchos casos, cantidades masivas de éstos. El ordenamiento de datos es un problema intrigante que ha dado pie a algunas de las acciones de investigacién mas intensas en el campo de las ciencias de la computacién. En este capitulo explicamos el método de ordenamiento més sencillo, En los ejercicios y en el capitulo 12, investigamos métodos mas complejos que logran un mejor rendimiento, Tip de rendimiento 6.4 ‘lgunas veces, Ios algoritmos mas sencillos tienen un rendimiento muy pobre. Su virtud radica en que son faciles de escribir probar y depurar Sin embargo, los algoriimes més complejos son necesarios para lograr un maximo rendimient La figura 6.15 ordena de manera ascendente los valores que corresponden a los elementos del arreglo a {linea 10). La técnica que utilizamos es conocida como ordenamiento burbuja método de hundimiento, a que los valores mnés pequetios “flotan” gracualmente hacia arriba, hacia el encabezada del arreglo, como burbujas de aire hacia la superficie del agua, mientras que los valores mas grandes se hunden en el fondo del arreglo. La técnica es para realizar varias pasadas através del ateglo. En cada pasada, se comparan pares sucesivos de ele- rmentos. Stel par esté en orden ascendente (o si los valores son identicos). dejamos los valores como estén. Si el par se encuentra en orden decreciente, sus Valores se intercambian en el arreglo f= Figura 6.15: figt 15.6 Este programa ordena Los valores incl ude faci ne TAMANO 10 e un arreglo en orden ascendente «/ Figura 6.15 Orcenamiento de un aneglo mediante el orcienamiento burbuja. Parte 1 de 2) 198 Arregios en ¢ Capitulo 6 6 /# 1a funcién min conienza la ejecucién del prograrm */ 7 int min() 8 4 9 f+ inicializa a +/ 10 nt al TAMANO J 5.4, 8 10, 12, 89, 68, a7} n nt pasadas: /* contador de pasadas */ 2 int is f+ contador de conparaci ones */ 13 nt almacena: /* ubicacién temporal utilizada para el intercanbio de elementos */ printf( “Blenentos de datos en el orden original ¥A" ) f* mestra el arregio original +/ for (i = 0: i < TANG it) ¢ primf( “sia”, ali 1) ) /* fin de for */ /* ordenaniento burbuja */ for ( pasadas = 1i pasadas < TAMING pasadas** ) { J+ ciclo para controlar el namero de conparaciones por pasada */ for (i = 0; i < TAMNO- 1 itt) { /» compara los elementos adyacentes y los intercanbia si el primer 4 15 16 7 18 1” 20 21 2 23 /* ciclo para controlar el nimero de pasos +/ 24 25 26 27 28 29 30 elemento es mayor que el segundo */ 3 if Cali] >ali +11) ¢ 32 almecena = al i J: 3 ali l=ali+1] 34 al i +1] = almcena 35 } f* fin de if */ 36 7 } /* fin del for interno +/ 38 39) /* fin del for externo +/ 40 4 printf( “WaBlementos de datos en orden ascendent eA” 42 43 /* muestra el arreglo ordenado +/ 440 for (i = 0: i < TANG itt) ¢ 45 printt( "a", al i 1) 46 J+ fin de for */ 47 48 oprimtf( Wa"): 49 50 return 0: /* indica terninacién exitosa */ 51 Hlenentos de datos en el orden ori ginal 2 6 4 8 10 12 89 68 45 37 Hlementos de datos en orden ascendente 2 4 6 8 10 12 37 45 68 89 Figura 6.18 Ordenamiento de un arreglo mediante el ordenamiento burbuja, Parte 2 de 2) Capitulo 6 ArregiosenC 199 Primero, el programa compara a{ © } con af 1 J, después a[ 1] conaf 2}. luego a{ 2] conal 3] ¥ asi sucesivamente hasta que completa la pasada, comparando a[ 8 ] con a 9 J. Observe que aunque hay 10 elementos, solamente se realizan 9 comparaciones. Debido a la manera en que se realizan las comparacto- nes sucesivas, un valor grande puede moverse muchas posiciones hacia abajo en una sola pasada, pero un va- Jor pequefio puede moverse sdlo una posicin hacia arriba, En la primera pasada, se garantiza que el valor mas grande se hunde hasta el fondo del arreglo, a{ 9 ]. Ena segunda pasada, el segundo valor més grande se hun- de hasta af 8}. En la novena pasada, el noveno valor mas grande se hunde hasta a[ 1}. Esto deja al valor ‘mas pequefio en a 0 J, por lo que sdlo se necesitan nueve pasadas para ordenar el arreglo, aunque éste tenga 10 elementos El ordenamiento se realiza por medio del ciclo anidado €or (Iineas 24 a 39). Si es necesario realizar un Intercambio, éste se lleva a cabo por medio de las tes asignaciones siguientes almacena = af 4 1; atid =alieia: af i +1] = almacena; en donde la variable adicional atmacena, guarda temporalmente uno de los dos valores a intercambiar. Fl in- tercambio no puede llevarse a cabo tinicamente con las asignaciones arid sariea alita}sati Le Le Si, por ejemplo, af 4 ] es 7y af i +1] es 5, después de la primera asignacin ambos valores serén 5, y el valor 7 se perderé. De aqui la necesicad de la variable adicional almacena La principal virtud del ordenamiento burbuja es que es facil de programa, sin embargo, es lento, Esto se hace evidente cuando se ordenan arreglos grandes. En los ejercicios desarrollaremos versiones ms eficientes del ordenamiento burbuja, e investigaremos algunos métodos mas eficientes que éste. En cursos més avanza- dos se analizan con detalle el ordenamiento y la busqueda 6.7 Ejemplo practic; Calcul de la media, la mediana y la moda a través de arreglos ‘Ahora consideraremos un ejemplo mas grande. Por lo general, las computadoras se utilizan para compilar y analizar los resultados de encuestas y estudios de opinisn, La figura 6.16 utiliza el arreglo respuesta, el cual {niciaiza con 99 respuestas de una encuesta, Cada respuesta es un mimero del 1 al 9. El programa calcula la ‘media, la mediana y la moda de los 99 valores. 204 Arregios en C Capitulo 6 Respuesta Frecuencia Histogram. 1 1 2 2 5 0 05 1 1 . 2 3 we 3 4 sass 4 5 saeee 5 8 stteeeee 6 9 seaanaeee 7 23 seeaesaaseeessssssnenes 3 a7 seeeseaeseeeestessseneeties 9 19 seenssaseeeeeesanen La mda es el valor mas frecuente, Para esta ejecucion la mda es 8 el cual ocurrio 27 veces. Figura 6.17 ejemplo de Ia ejecucién del programa para analiza los datos cle una encuesta, (Pare 2 de 2) de encontrar un elemento en particular de un areglo se le conoce como busqueda. En esta seccion, explicamos dos técnicas de biisqueda: la técnica simple de busqueda lineal, y una mas eficiente, pero més compleja, la téc- nica de busqueda binaria, Los ejercicios 6.34 y 6,385 al final de este capitulo le pediran que implemente versio nes recursivas de la bisqueda lineal y de la bisqueda binaria Buisqueda en un arreglo mediante Ia buisqueda lineal a bisque lineal (figura 6.18) compara cada elemento de un arreglo con la clave de buisqueda. Debido a que 1 arreglo no se encuentra en un orden particular, la probebilidad de que el valor se encuentre en el primer ‘mento o en el iltimo, es la misma. Por lo tanto, en promedio, el programa tendré que comparar la clave de bis- queda con la mitad de los clementas del arregl. 1 /* Figura 6,18: fi 90618. 2° Bisqueda lineal en un arreglo +/ 3° include 4 #define TAMANO 100 5 6 {+ prototipo de La funcion */ 7 int busquedalineal( const int arreglo[], int Ilave, int tamnio ): 8 9 /+ 1a funcién main conienza la ejecuci én del progranm +/ 10 int mint) n ¢ 12 nt al TAMANO 1]; /+ crea el arreglo a #/ 13 int xi /+ contador para inicializar los elementos de 0 a 99 del arreglo a +/ 4 nt IlaveBusqueda: /* valor para localizar en el arreglo a / 15 nt elemento: /* variable para al mcenar | ubi caci 6n de! aveBusqueda 0 16 17 fs crea Los datos */ Wo for (x = OF x < TAMING xtt) { W alx ]=2+ x 2} /* fin de for */ 21 22 printf ( “Introduzca 1a Ilave de busqueda enterai Wa”); Figura 6.18 8squeda Ineal en un arregio, Parte | de 2) Capitulo 6 ArregiosenC 205 23 scanf( “4d”, @laveFusqueda ); 24 25 J intenta localizar 1laveFusqueda en el arreglo a */ 26 = elemento = busquedaLineal( a, IlavePusqueda, TAMANO ); 27 28 /* despliega los resultados */ 29° if ( elemento v4 30 printf( “Eneontre el valor en el elemento 9d", elemento )i 31 ) s+ fin de if +f 32 else { 33 printf( "Valor no encontradoVa” ): 34} /* fin de else +/ 35 36 return 0: /* indica terninacién exitosa +/ 37 38} /* fin de min +f 39 40 /* compara la ave con cada elemento del arreglo hasta que localiza el el erent o 41 © hasta que alcanza el final del arregio: devuelve el subindice del el erento 42 si lo encontré 0 -1 si_no lo encontré */ 43 int busquedalineal( const int arreglol], int Ilave, int tamnio ) ran 45 int ni /* contador +/ 6 47 J» ciclo a través del arreglo +/ 48 for (n= 0; n 4 define TAINO 15 5 6 f+ prototipos de Las funciones «/ 7 int busquedaBinaria( const int bl], int claveDeBusqueda, int bajo, int alto ) & void despliegalincabezadol void )i 9 void despliegalinea( const int DI], int bajo, int medio, int alto ) 10 V1 /+ La funcién min conienza ta ejecucién del prograru */ 12 int min) 13 4 14 int af TAMNO J; /* crea el arreglo a +/ 1S int i; /* contador para inicializar los elementos de 0 a 14 del arreglo */ Figura 6.19 Bd:queda lineal en un axreglo ordenado, Parte | de 4.) Capitulo 6 ArregiosenC 207 16 int Ilavei /* valor a localizar en el arreglo a */ 17 int resultado: /* variable para almucenar la ubicacién de la Ilave 0-1 */ 18 19 /+ crea los datos */ 200 for (i = 0; i < TAMING: i++) ¢ 21 ali} =25i 2 /+ fin de for */ 23 24 —printf( “Introduzea un aumero entre 0 y 28 " 25 © scanf( "#d", Mave i 26 27 cespliegaHneabezado(): 28 29 f+ busca 1a lave en el arreglo a +/ 30 resultado = busqueda naria( a, Ilave, 0, TAMANO - 1) 31 32 /+ despliega los resultados */ 33 if ( resultado t= -1) ( 34 printf( “¥a@d se encuentra en el elemento %d del arregloWs", Ilave, resultado): 35) f+ fin de if #/ 36 else 4 7 printf( “Wa8d no se encuentra”, Have ) 38} / fin de else */ 39 40 return 0; /+ indica terninacién exitosa */ 41 42) /+ fin de min */ 43 44 /+ funcion para realizar la bisqueda binaria en un arreglo */ 45 int busquedaBinaria( const int bl], int claveDeBusqueda, int bajo, int alto) 46 4 47 int central; /* variable para mantener el elemento central del arreglo +/ 43 49 /* realiza el ciclo hasta que el subinice bajo es myor que el subi adi ce alto #/ 50 while ( bajo <= alto) ¢ 51 52 {+ determina el elemato central del subarreglo en el que se busca */ 53 central = ( bajo + alto) / 2 54 55 J+ despliega el subarreglo utilizado en este ciclo */ 56 Gespliegalinea( b, bajo, central, alto ) 87 58 /* si claveDeBusqueda coincide con el elemento central, devuel ve central */ 39 if ( claveDeBusqueda == b{ central } ) 4 60 return central 61 } f= fin de if +/ 2 633 /* si claveDeBusqueda es menor que el elemento central, establece el nuevo valor de alto +/ 64 else if ( claveDeBusqueda < bf central ] ) { 65 alto = central - 1: /* busea en 1a nitad inferior del arreglo 66 } f* fin de else if +/ Figura 6.19 Bésqueda lineal en un atragio ordenado, Parte 2 de 4) 208 Arregios enc Capitulo 6 Mm 12 3 na ns n6 n7 8 ng. /* si claveDeBusqueda es muyor que el elemento central, establece el nuevo valor para bajo +/ else ( bajo = central + 1: /* busca en la nitad superior del arreglo */ } Js fin de else #/ } f* fin de while =/ return “li /# no se encontré claveDeBusqueda */ /+ fin de la funci én busquedaBinaria +/ J+ Inprine un encabezado para la salida +/ void desplicgalncabezado( void ) { int is /* contador +/ printf ( “WiSubi ndi ces! #6" ) J* muestra el encabezado de 1a columma */ for (i = 0; i < TAMANG i++) { printf( “3d “, i) } fs fin de for +f wi”); /* conienza la nueva linea de salida */ /* mestra una [{nea de caracteres - */ for Ci 4* TANGO i+) { printf ( } /* fin de for */ printf( "Wi" Ji /* inicia una nueva I{mea de } f* fin de 1a funei én despliegaBncabezado +/ Inprime una linea de salida que muestra la parte actual del arreglo que se esta procesando. */ void despliegalinea( const int bI], int baj, int cen, int alt ) ‘ int i: f+ contador para la iteracion a través del arreglo b */ I+ ciclo a través del arregio completo +/ for (i =O) i < TAMING it) { /* despliega espacios si se encuentra fuel subarreglo */ if Ci alt) ¢ printf ( ) } fe fin de if +/ else if (i == cen) { /+ despliega el elemento central +/ printt( "de", bl i] i /# murea el valor central +/ del rango actual del } Je fin de else if 4/ else ( /+ despliega otros elementos en el subarreglo */ printf( "md *, bl i 1) } J# fin de else Figura 6.19 Bd:queda lineal en un arreglo ordenado. Parte 3 de 4.) Capitulo 6 Arregios en C 209 120 121 ) fe fin de for #/ 122 123 printf( “Wa” )i /+ inicia la nueva linea de salida */ 124} /* fin de La funcion despliegalinea */ Introduzca un numero entre 0 y 28: 25 Subi ndi ces: 18 20 22 24 26 28 16 18 20 22+ 24 26 28 24 26+ 28 24s roduzea un numero entre 0 y 28: 8 8 se encuentra en el elemento 4 del arreglo Introduzea un numero entre 0 y 28: 6 Subi ndi ces’ 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 0 2 4 6 8 ID 1 6 se encuentra en el elemento 3 del arreglo Figura 6.19. Btsqueda lineal en un arreglo ordenado. Parte 4 de 4) 6.9 Arreglos con miiltiples subindices Los arreglos en C pueden tener miliples subindices. Un uso comiin de los arreglos con miltiples subindices es larepresentacién de tablas de valores que constan de informacién organizada en filas y columnas. Para iden- tificar un elemento particular de una tabla, debemos especificar dos subindices: el primero (por convenicién) identifica la fila del elemento, y el segundo (por convencién) identifica la columna del elemento. A las tablas 6 arreglos que requieren dos subindices para identificar un elemento particular se les conoce como arreglos con dos subindices. Observe que los arreglos con miltiples subindices pueden tener més de dos subindices. 210. Arregios enc Capitulo 6 Cokenna® Cokimne | Columna2 Colunna 3 rico [ aroyroy | ator tay | ar0y 2) | ©0113) riot [ataycoy | ataatay | atic) | artes) rio2 | araycoy | ataatay | atic | ataieay Subindice de column subindice de fa Nombre det aneglo Figura 6.20 Ariaglo con dos subindices con tres fas y Cuatro columnas. La figura 6.20 presenta el arreglo con dos subindices, a. El arreglo contiene tres filas y cuatro columnas, porlo que se dice que es un arreglo de 3 por 4. En general, un arreglo con mfilas y n columnas se conoce como arreglo de m por n ‘Cada elemento del arreglo a, correspondiente a la figura 6.20, esté identificado por un elemento nombre de la forma af 4 ][ 3 ]; aes el nombre del arreglo, e 4 y 3 son los subindices que identifican de manera {inica a cada elemento de a. Observe que los nombres de los elementos de la primera fila tienen un primer su- bindice de 0: los nombres de los elementos de la cuarta columna tienen un segundo subindice de 3. Error comiin de programacién 6.9 eal Facer referencia aun elemento de un arrglo con dos sbindics de Ta Toma a7 x, 7. en Tagar de hacerlo de Un arreglo con multiples subindices puede inictalizarse en su declaracién, de manera muy similar a un amreglo con un solo subindice. Por ejemplo, un arreglo con dos subindices int BI 2 1 [ 2 ] podria dectararse ¢ inicializarse con ant bE 2121 =¢ (1,2), 63, 4995 Los valores se agrupan por fila entre aves. Los valores del primer conjunto de Ilaves inicializan la fila 0, y los valores del segundo conjunto de llaves inicializan la fila 1. Entonces, los valores 1 y 2 inicalizan los elemen- tos int b[ 0} [0] y int bl 0} [1]. respectivamente, y los valores 3 y 4 inicializan los elemento int. bE1][0]y int bE 11[ 1], respectivamente. Sino hay suficientes inictalizadores para una fila dada, el resto de los elementos de esa fila se inicializan en 0. Por lo tanto, ant br 2IL27=¢ (10, 63,4005 inicializaria BE OJ [0] end, blO][1] en0.bl1][O]}en3ybl1] [1] en4 La figuraG.2i ‘muestra la declaracién y la inicializacidn de arreglos con dos subindices. 1 /* Figura 6.21: fi g0621.¢ 2 Inicializacion de arreglos miitidimpnsionales +/ 3° include 4 5 void desplicgaArreglo ( const int al][ 3] Ji /* prototipo de la funcién +/ 6 7 f+ La funcién sin conienza la ejecucién del programm */ 8 int rial) 9 ( 10 /+ inicializa arreglol, arre n int arregioll 2 J[ 3] = 12 int arregioaf 2 1 31 Figura 6.21 inicialzacién de arregios multidimensionales. Parte 1 de 2) Capitulo 6 ArregiosenC 211 13° int arrestosh 2103 P= 00 2H Cay 4 18 printf( “Los valores en el arreglol por linea son Wi" ) 16 despliegaArreglo ( arreglol ): 7 18 printf( “Los valores en el arreglo2 por linea son: Wi"): 19 GespliegaArreglo ( arreglo2 ): 20 21 printf( “Los valores en el arreglo3 por linea son: Wi"); 22 cespliegaarreglo ( arreglo3 ) 23 24 return 0; /+ indica terninacién exitosa +/ 2 2% ) /* fin de min +/ 27 28 /* funci6n para mostrar un arreglo con dos filas y tres columas «/ 29 void despliegaArreglo ( const int alll 3 1) 3 3 imt i: /* contador de filas */ 32 int j3 /* contador de clummas */ 33 34 /* ciclo a través de Las filas */ 350 for (i =O) 1 G1: is) 4 36 7 {+ mestra los valores de las columas +/ 38 for (j = 0: j <= 2 j++) ¢ 39 printf( “ad *, al i Wi 1) 40 } f= fin del for interno =/ 41 42 printf( “Wa” )i /* conienza la nueva linea de salida =/ 43} /+ fin del for externo +/ 44 45) /+ fin de 1a funcidn inprimérreglo +/ Los valores en el arreglol por linea son’ 123 456 valores en el arreglo2 por linea son: 23 450 Los valores en el arreglo3 por linea son: 120 400 Figura 6.21 Iniciaizacion de atraglos mutidimensionales. Parte 2 de 2.) El programa declara tres atreglos de dos filas y tres columnas (cada uno con seis elementos). La declara- cin de arreglot (linea 11) proporciona seis inicializadores en dos sublistas. La primera sublista inicializa Ia primera fila del arreglo (es decir, la fila 0) con los valores 1, 2 y 3; la segunda sublista iniializa la segun- da fila del arreglo (es decir, la fila 1) com los valores 4, 5 6, Si las llaves alrededor de cada sublista son removidas de arreglo1. el compiladorinicializa los elemen- tos de la primera fila seguido por los elementos de la segunda fila. La definicién de arreglo2 (linea 12) pro- porciona cinco inicializadores. Los inicializadotes se asignan a la primera fila y Iuego a la segunda, Cualquier elemento que no tenga explicitamente un inicializador, se inicializa automaticamente en cero, por lo que arreglo2[ 1] [2] se inicializa en 0.

También podría gustarte