Está en la página 1de 114
| ! CAPITULO 4 ‘unciones 4.1. Introduccién F Para resolver problemas complejos y/o de gran tamaiio es conveniente | utilizar el concepto de reduceién de problemas. De esta forma, el | problema se descompone en subproblemas, los cuales a su vez pueden descomponerse en subsubproblemas, y asi continuar hasta que el pro- i blema original queda reducido a un conjunto de actividades bésicas, | que no se pueden 0 no conviene volver a descomponer, La solucién | de cada una de estas actividades basicas permite, luego, aplicando i razonamiento hacia atrés, la solucién del problema final. i { En el lenguaje de programacién C la solucién de un problema se ex- presa por medio de un programa; la solucién de un subproblema, por medio de una funci6n. El uso de funciones tiene miiltiples ventajas: facilitan la lectura y escritura de los programas, permiten el trabajo 138 Capitulo 4. Funciones en paralelo —diferentes programadores se pueden encargar de diferentes funcio- nes—, facilitan la asignacién de responsabilidades, permiten que el cédigo de la funcion se eseriba solamente una vez y se uilce tantas veces como sea necesario, facilitan el mantenimiento de jos programas, etc. De esta manera, un programa en € esté constituido por un programa principal y un conjunto de funciones. El programa principal consta generalmente de pocas Ineas, las cuales pueden ser llamadas a funciones. La llamada a una funcién in- dica al procesador que debe continuar con el procesamiento de la funcién. Una vez que ésta concluye, el contro} regresa al punto de partida en el programa prin- cipal. Por otra parte, la funcién se escribe de forma similar al programa princi- Pal. pero con diferencias principalmente en el encabezado de la misma. Una funcién resuelve un subproblema de forma independiente y se ejecuta solo cuan- do recibe una Hamada desde e] programa principal o desde otras funciones. El Tenguaje de programacién C permite que una funcién pueda incorporar llamadas a otras funciones, Ta comunicaci6n entre las funciones y el programa principal, al gual que entre las mismas funciones, se Teva a cabo par medio de pardmetros por valor, paréme- {ros por referencia y variables globales. Estas tltimas son menos utilizadas por Tazones de eficiencia y seguridad en Ja escritura de programas. En los dos tiltimos capftulos utilizamos funciones que pertenecen a bibliotecas del lenguaje C. Por ejemplo, la funcién pow que se encuentra en la biblioteca math.n se ha utilizado én numerosas Ocasiones. Pero cabe aclarar que las funciones que utilizaremos en este capitulo son diferentes, porque tienen la particularidad de que nosotros mis- mos las desarrollaremos. Es decir, no se encuentran en ninguna biblioteca del lenguaje C. 4.2. Variables locales, globales y estaticas Las variables son objetos que pueden cambiar su valor durante la ejecucién de un programa. En el lenguaje de programacién C podemos distinguir entre tres ti- Pos de variables: locales, globales y estaticas. Las variables locales son objetos definidos tanto en el programa principal como en las funciones y su alcance est limitado’solamente al programa principal o a Ja funci6n en la cual estén defini- das. Por ejemplo, cada variable local definida en una funcin comienza a existir S6lo cuando se ama a esa funcign, y desaparece cuando el control regresa al 4.2 Variables locales, globales y estaticas 139 programa principal. Puesto que no retienen su valor, deben ser ini vez que se ejecuta la funcién, de otra forma contendrin basura. C permite ademas definir variables locales a un bloque —conjunto de instruccio- nes—, las cuales desaparecen luego de ejecutar el bloque. Cabe destacar que las variables locales tienen prioridad sobre las variables globales. Es decir, si tene- mos una variable global entera 1 y una variable local entera también denomina- da Ten una funcién, cada vez que utilicemos la variable en la funcién estaremos haciendo referencia a la variable local. Incluso una variable local definida en un bloque tiene prioridad sobre una variable local definida obviamente con el mis- mo nombre en la misma funcién. Por otra parte, las variables globales son objetos definidos antes del inicio del programa principal y su aleance es muy amplio, ya que tiene influencia tanto en el programa principal como en todas las funciones. Finalmente, las variables estaticas son similares a las locales, pero conservan su valor durante la ejecucién del programa. Es decir, comienzan a existir cuando se lama a la funcién y conservan su valor aun cuando el control regresa al progra- ma principal, En el Ienguaje C una funcién se escribe de Ja siguiente forma: {* El conjunto de instrucciones muestra la sintaxis de una s*funcién en el lenguaje C. */ | tipo-de-resultado Nombre-de-funcién (Parametros) 7 instrucciones; I* cuerpo de 1a funcién. */ } Donde: tipo-de-resultado representa el tipo de resultado que devuelve la funcién (entero, real, caracter, cadena de caracteres, etc.); si no regresa ningéin resultado, entonces se escribe la palabra reservada void. Nombre -de-funcién representa el nombre de la funcién. Es conveniente utilizar un nombre representativo de lo que realiza la funcién. Pardmetros se utiliza para indicar la lista de parametros que recibe la funcién (los analizaremos en la seccién 4.3). instrucciones representa, como su nombre lo indica, al conjunto de instrucciones que pertenecen a la funcién 140 Capitulo 4. Funciones A continuacién presentamos diferentes ejemplos para clarificar los conceptos anteriores. Cabe destacar que a partir de este capitulo, por cuestiones basica- mente didécticas y dando por sentado que ya conoces y puedes desarrollar dia, gramas de flujo, omitiremos el uso de éstos en la solucién grifica de los diferentes problemas. Evyempto 4.1 Escribe un programa que calcule, utilizando una funcién, el cubo de los 10 pri- meros némeros naturale: 7 Programa 4.1 #include /* cubo-1 El programa calcula el cubo de los 10 primeros numeros naturales con la | ayuda de una funcién. En la solucién del problema se utilize una variable | global, aunque esto, como verenos mas adelante, no es muy recomendable. */ Ant cubo(void) ; I* Prototipo de funcion. */ | ant 1; /* Variable global. */ void main(void) { int CUB; for (I mH) { | CUB = cubo(); /* Llamada a la funcidn cubo. */ I | printf (*\n€l cubo de %d es: %d", I, CUB); | fea | | } int cubo(void) /* Declaracién de la funcién. */ /* La funeién calcula el cubo de 1a variable global I. */ { return (I*I*I); + Observa que la segunda instruccién del programa: int cubo(void 4.2 Vaflables locales, globales y estaticas 14 | es un prototipo de la funci6n. Puesto que esta funci6n se declara posteriormente, pero se utiliza en el programa principal, el compilador del lenguaje C requiere + estar enterado de Ja existencia de la misma. Toma nota de que el tipo de Ia fun- } _cidmes entero (int) y no tiene pardmetros. Las funciones pueden regresar resulta- E dos de diferentes tipos de datos o bien no regresar ninguno, en cuyo caso al F inicio se debe incluir Ia palabra reservada vot. i i i La linea int 15 indica que 1 es una variable global de tipo entero. Observa que la variable global se defini6 antes del programa principal La instrucci6n cuB = cubo(); cus. expresa que el resultado de la funcién cubo() se asigna a la variable loc: 5 Observa la forma de invocar o Hamar a la funcién, Cabe destacar que es posible evitar el uso de la variable local cus escribiendo el resultado del lamado a la funcin cubo como se muestra a continuacién: printf(*\nE1 cubo de %d es: %d", cubo()); Finalmente, ya en la funci6n cubo, la instruccién: return (I*I*I); regresa el resultado obtenido al programa principal. Siempre que la funci6n es de un tipo de datos determinado es necesario utilizar un return para regresar tanto el resultado como el control al programa principal. Itado que arroja el programa: A continuacién se muestra el res -pereeremrmepecentrenssscwementpec tener mere Bo [eve unig da tee" “Os at El cubo de 2es: 8 i El cubo de 3es: 27 : El cubo de 4es: 64 it El cubo de Ses: 125 f El cubo de 6 es: 216 a El cubo de 7 es: 343 t El cubo de 8 es: 512 t El cubo de 9 es: 729 i El cubo de 10 es: 1000 [142 Capitulo 4. Funciones \ Esempto 4.2 Observa lo que sucede en la solucién del problema anterior al declarar una varia. ble local en la funcién cubo. Programa 4.2 Hinclude 1* Gubo-2 £1 programa calcula el cubo de los 10 primeros numeros naturales con la ayuda de una funcién. */ int cubo(void); {* Prototipo de funcidn. */ int 1 /* Variable global. */ void main(void) | | | | { { int cuB; for (I = 1; I <= 103 ++) cuB = cubo(); {* Llamada a la funcién cuko. */ printf("\nE1 cubo de %d es: %d", I, CUB); } } int cubo(void) /* Declaracién de la funcién. */ J* La funeién calcula el cubo de 1a variable local I. */ { int I = 2; /* Variable local entera I con el mismo nombr: | | “que la variable global. */ | return (I*1*1); | | } El cubo de £1 cubo ce El cubo de El cubo de El cubo de El cubo de £1 cubo de amen me ma 4.2 Variables locales, globates y estaticas “743 | El cubo de 8 es: 8 | £1 cubo de 9 es: 8 | El cubo de 10 es: 8 La variable local 1 tiene prioridad sobre la variable global que tiene el mismo nombre y por esta raz6n siempre calcula el cubo del niimero entero 2. 4.2.1. Conflicto entre los nombres de las variables Las variables locales, tal y como lo analizamos anteriormente, tienen prioridad sobre las globales que cuentan con el mismo nombre. Es decir, si existe una va- riable global entera I y una variable local entera con el mismo nombre, cada vez. que utilicemos la variable en Ia funcién estaremos haciendo referencia a la variable local, Sin embargo, puede ocurrir que en algunos casos necesitemos hacer referencia a la variable global. En esos casos debemos incorporarle pre- viamente a la variable global el simbolo ::, de tal forma que si queremos hacer referencia a la variable global 1, debemos escribir: t Evsempto 4.3 Observemos a continuaci6n el siguiente programa, el cual utiliza en una misma i funcién dos variables con el mismo nombre, una local y otra global. Programa 4.3 /* Conflicto de variables con el mismo nombre. */ void ft (void) ; 1* Prototipo de funcién. */ int K = 5; * Variable global. */ } void main (void) 4 i int 1; ' for (I = 1; I <= 3; I++) i} AQ: | Fe | | void f1(void) [144 Capitulo 4. Funciones | Ee /* La funcién utiliza tanto 1a variable local I cono 1a variable | wolobal I. */ | { int K (* Variable local. */ | Ka | printf(*\n\nEl valor de 1a variable local es: %d", K); K+ K; J* Uso de ambas variables. */ printf(*\nE1 valor de la variable global es: %d", ::K); El valor de la variable local es: 4 El valor de la variable global es: 9 El valor de la variable local es: 4 El valor de la variable global es: 13 El valor de la variable local es: 4 A continuacién se presenta un ejemplo en el cual se utilizan variables locales, globales y estaticas. Exsempto 4.4 En el siguiente programa podemos observar el uso de variables locales, globales y estaticas. Incluso en la funcién #4 se hace referencia tanto a la variable local como a la variable global que tienen el mismo nombre. Programa 4.4 ] Hinclude | J* Prueba de variables globales, locales y estaticas. | 1 programa utiliza funciones en las que Se usan diferentes tipos de ‘variables. */ int t1(void); int f2(void); = - EAS ant £3(void); int *4(void); int K = 3; /* Variable global. */ void main(void) { int Ij en 42 Variables locales, globales y estaticas I* Prototipos de funciones. */ Iss) for (= 1; 7 printf (*\nEl resultado de 1a funcién ft es: printf(*\nEl resultado de 1a funcion f2 es printf(*\n€l resultado de 1a funcién 3 es printf("\nE1 resultado de la funcién f4 es int f1 (void) /* La funcién f1 utiliza la variable global. * K 42 Ky return (K); int f2(void) /* La funcién #2 utiliza la variable local. */ | [et int K = 1; Ke; | return (kK); nt *3(void) * La funcién f3 utiliza la variable estatica. * 10); £2()); 3())5 140); | static int K = 8; kw 2s return (K); } int f4(void) /* La funcién f4 utiliza dos variables con el mismo nonbre: local “y global. */ ha | int K = 5; R= K + tks /* Uso de 1a variable local (K) y global (::k) */ return (K); be [146 Capitulo 4. Funciones Los resultados que arroja el programa son los siguientes: El resultado de la funcién ft El resultado de 1a funcién f2 es: 2 El resultado de la funcién f3 es: 10 El resultado de la funcién f4 es: 11 El resultado de 1a funcion ft 12 El resultado de 1a funcién f2 2 El resultado de 1a funcion 13 12 El resultado de la funcién f4 7 El resultado de la funcién fi es: 24 El resultado de la funcién 2 es: 2 | E1 resultado de la funcién #3 es: 14 El resultado de la funcién f4 es: 29 4.3. Parametros por valor y por referencia La comunicacién entre las funciones y el programa principal, o bien entre las mismas funciones, se Heva a cabo mediante variables globales y pardmetros por valor y por referencia. El uso de variables se estudié ampliamente en la seccién anterior, y en ésta nos concentraremos en los parmetros por valor y p referencia. Los pardmetros por valor permiten pasar datos entre el programa principal y funciones, e incluso entre las mismas funciones. En el parémetro se escribe u copia de la variable original. Si el parémetro sufre una alteraci6n en la funcién que lo recibe, la variable original no se ve afectada. 4 Los pardmetros por referencia también permiten la comunicacién entre el p' grama principal y las funciones, o entre las mismas funciones. Sin embargo, en este caso, en lugar de escribir una copia de Ia variable en el pardmetro se escril la direccién de la misma. Si el pardmetro sufre una alteracién en la funcién que lo recibe, la variable original también se ve afectada. En C, las llamadas por refe rencia se realizan mediante apuntadores. Un apuntador es una variable que co! tiene la direccién de otra variable y se representa por medio de operadores de direccién (a) e indireccién (+). Observemos a continuacién diferentes ejgypplos para clarificar estos conceptos. en ramen agence 4,3 Parametros por valor y por referencia 147; Esempto 4.5 Escribe un programa que calcule el cubo de los 10 primeros ntimeros naturales, utilizando una funcién y realizando la comunicacién mediante parémetros por valor. | programa 4.5 Hinclude /* Cubo-3. El programa calcula el cubo de los 10 primeros numeros naturales con la “ ayuda de una funcién y utilizando pardémetros por valor int cubo(int); J* Prototipo de funcién. El pardmetro es de \ tipo entero. */ void main(void) { int I; for (I = 1; I <= 10; 144) printf (*\nEl cubo de T es:%d", cubo(I)); J* Ulanada a la funcién cubo. E1 paso del parametro es por valor. */ } int cubo(int K) /* Kes un pardmetro por valor de tipo entero. /* La funcién calcula el cubo del pardénetro K. */ { return (K*K*K); } Observa que la instru int cubo(int); es un prototipo de funcién que informa al compilador que el parémetro que se utilizard es por valor y de tipo entero. La siguiente instruccién permite escribir el resultado de la funcién, Observa que el pardmetro que se utiliza es una copia de la variable 1 printf("\nE1 cubo de %d es: %d", cubo(I)); [148 Capitulo 4. Funciones Finalmente, ya en la funci6n cubo, la instrucci6n: return (K*K*K) 5 regresa el resultado obtenido al programa principal. Esempto 4.6 Observemos a continuacién el siguiente programa, el cual utiliza ahora pardme- tros por referencia, Programa 4.6 #include /* Prueba de parémetros por referencia. * void f1(int *); /* Prototipo de funcién. £1 pardmetro es de tipo entero y por referencia | —observa el uso del operador de indireccién. */ void main(void) { int 1, K = 4) for (I= 1; I <= 3; I++) { printf("\n\nValor de K antes de llamar a la funcién: 4d", +k); printf(*\nValor de K después de llamar a la funcién: %d", £1(8K)); /* Llamada a la funcién f1. Se pasa la direccion de 1a variable K, | = por medio del operador de direccién: & */ } 3 void fi(int *f) /* La funcién f1 recibe un parametro por referencia. Cada vez que el \ parametro se utiliza en la funcién debe ir precedido por el operador de | ™ indireccién. * \o4 La instruccién: void f1(int *); _ ame eit nen ——— o 4.3 Parémetros por valor y por-referengia 149) es un prototipo de funcién que informa al compilador que el pardmetro que se va a utilizar es por referencia y de tipo entero. Se utiliza el operador de indi- reccién: *, La siguiente instruccién permite escribir el resultado de la funci6n. Observa que en la Hamada a Ja funcién se utiliza un pardmetro por referencia. La direccin de Ja variable se pasa mediante el operador de direccién: a. printf(*\nValor de K después de llamar a la funcion: %d", f1(&K)); Finalmente, ya en la funcién #1, cada vez que se utiliza el pardmetro por referen- cia, se debe anteponer al mismo el operador de indireccién, Bl resultado que arroja el programa es el siguiente: Valor de K antes de llamar a la funcién: Valor de K después de llamar a 1a funcién: (perenne mre } Valor de K antes de llamar a la funcién: 1 valor de K después de llamar a la funcién: 22 valor de K antes de llamar a la funcién: 23 Valor de K después de llamar a la funcion: 46 ExempLo 4.7 Analicemos a continuacién el mismo programa del ejemplo anterior, pero utili- zando ahora pardmetros por valor en lugar de pardmetros por referencia. Programa 4.7 “include rueba de parémetros por valor. nt ft (int); /* Prototipo de funcién. E1 parémetro es por valor “ y de tipo entero. */ oid main(void) [150 Capitulo 4. Funciones n\nValor de K antes de llamar a la funcién: %d*, +#K); print? ( printf("\nValor de K después de llamar a la funcion: %d", f1(K)); /* Llamada a la funcién f1. Se pasa una copia de la variable K. */ } } int f1(int R) { B+ Ry return (R); } El resultado que arroja el programa es el siguiente: [Walor Ge «antes de Hanar'a la funcions 5 | Valor do K después de Ilona a te funoson: 18 | Valor de K antes de llamar a la funcién: 6 Valor de K después de llamar a la fun 12 Valor de K antes de llamar a la funcién: 7 Valor de K después de llamar a la funcion: 14 A continuaci6n presentamos un programa en el que se combinan variables ‘eolggy y globales, y parémetros tanto por valor como por referencia. Esempto 4.8 Analiza cuidadosamente el siguiente programa e indica qué imprime. Programa 4.8 #include /* Combinacién de variables globales y locales, y pardmetros por valor | y por referencia. */ | ant a, b,c, dj * variables globales. */ void funciont(int *, int *); /* Prototipo de funcién. observa que los dos parémetros son por — | referencia. * 4,3 Parémetros por valor y por referencia 151) int funcion2(int, int *); {| J en este prototipo el primer parémetro es por valor y el segundo por | | 2 reterencsa. #7 jf | yotd main(void) jo § | int a: [+ Nota que @ es una variable local. */ ant; /* Se asigna un valor a la variable local a. */ b= 2) /* Se asignan valores a las variables globales b, ¢ y d. c= 3} a= 43 printf(*\ntd Sd %d &d", a, b,c, d); funcion’ (&b, & printf("\nkd Sd Sd 80", a, b a= funcion2(c, &d); printf("\nid Sd Sd 8d", a, b,c, d)5 } void funciont(int *b, int *c) { int 5 a= 55 J* Observa que se hace referencia a la variable global a. d= 33 Nota que se hace referencia ala variable locel d. * (byt | Ge) + | printt( ) c,d); 25 nd Sd Ad Sd", a, 10, di int funcion2(int c, int *d) { int b; a ba 7; ct 3 (1d) + 25 printf("\nad Sd Sd Bd", a, b, c, *d); return (c); } */ Compara tu resultado con el que presentamos a continuacién. J [152 Capitulo 4. Funciones 4.4, Paso de funciones como parametros En la practica encontramos problemas cuyas soluciones se podrian formular A cilmente si pudiéramos pasar funciones como pardmetros. Por fortuna, en el Ien- guaje de programacién C es posible realizar esta actividad, es decir, pasar una funcién a otra funci6n como parémetro por referencia ~en el pardmetro se es- cribe la direccién de la funci6n—. Debemos recordar que en C las llamadas por referencia se llevan a cabo por medio de apuntadores, y un apuntador no es mas que una variable que contiene la direccién de otra variable o de una funcién y se representa por medio de los operadores de direccién (&) e indireccién (+). Este paso de una funcién como pardmetro permite que una funcién se transfiera a otra como si fuera simplemente una variable. Esempto 4.9 En el siguiente programa pasaremos una funci6n a otra funcién como parémett por referencia, Nota que la funci6n contro} recibe como pardmetro una funcién. Dependiendo de cual sea ésta, realiza la Hamada a la funcién correspon Suna 0 Resta. Programa 4.9 Hinclude /* Paso de una funcién como parametro por referencia. */ int Suma(int x, int Y) J* La funcién Suna regresa 1a sua de los parémetros de tipo entero wexKyY { return (X+Y); } int Resta(int xX, int_y) J* Esta funciGh"Fegresa 1a resta de los parémetros de tipo entero / ey et | return (x-Y); } i om | } | ane? fa", RIN; Problemas resueltos 153) int Control(int (*apf) (int, int), int x, int y) 7* Esta funcién recibe como parametra otra funcién —1a direccién— y dependiendo de cual sea ésta, Llama a la funcign’ Suma o Resta. */ { int AES; RES = (*apt) (X,Y); J* Se llama a la funcién Suma o Resta. */ return (RES); | , i void main(void) { int RI, R2; Ri = Control(Suma, 15, 5); /* Se pasa cono pardmetro la funcion Suma. */ R2 = Control(Resta, 10, 4); /* Se pasa como pardmetro la funcién Resta.*/ printf("\nResultado 2: ed", R2); Problemas resueltos Problema PR4.1 Escribe un programa en C que, al recibir como datos dos ntimeros enteros, deter mine si el segundo ntimero es miiltiplo del primero. Datos: NU1, Nu2 (variables de tipo entero que representan los niimeros que se : ingresan). rograma 4.10 # include (* Moltiplo £1 programa, al recibir cono datos dos nimeros enteros, determina si ‘el segundo es miltiplo del primero. */ int miltiplo(int, int); J* Prototipo de funcion. */ void main(void) { int NUT, NU2, RES; printf ("\nIngresa los dos numeros: Scanf ("ed Sd*, BNUY, 8NU2); RES = multiplo(NUt, NU2); _ ‘ [154 Capitulo 4. Funciones if (RES) printf("\nE1 segundo numero es miltiplo del primero"); else printf(*\nE1 segundo nimero no es miltiplo del primero“); } int multiplo(int Ni, int N2) (* Esta funcién determina si N2 es miltiplo de NI. */ | Jet | int RES; | if ((N2 % Nt) == @) RES = 1; else RES = 0; return (RES); } Problema PR4.2 Escribe un programa en C que, al recibir como dato un mimero entero positivo, determine el mayor divisor de dicho néimero. Dato: NuM (variable de tipo entero que representa el nimero que se ingresa). Programa 4.11 # include /* Mayor divisor. El programa, al recibir como dato un nimero entero positivo, calcula su mayor divisor. */ int mad(int) ; J* Prototipo de funcion. */ void main(void) { int NUM, RES; printf (*\nIngresa el numero: scanf("Sd", NUM) ; RES = mad(NUM); printf("\nEl mayor divisor de %d es: %d", NUM, RES); } int mad(int N1) J* Esta funcién calcula el mayor divisor del numero Nt. */ { am — y ~ ee Problemas resueltos 155) int I= (Nt / 2)3 | /* I se inicializa con el maximo valor posible que puede ser divisor | wede Me */ while (Nt % I) | jt El ciclo se mantiene activo mientras (N1 % I) sea distinto de cero. ‘> Cuando el resultado sea 0, se detiene, ya que se habré encontrado = el mayor divisor de NI. */ Problema PR4.3 Escribe un programa en C que, al recibir como datos dos ntimeros enteros, deter- mine el m4ximo comin divisor de dichos ntimeros. Datos: Nui, nv2 (variables de tipo entero que representan los mimeros que se ingresan). Programa 4.12 # include téximo comin divisor. EL programa, al recibir como datos dos némeros enteros, calcula el méximo | comin divisor de dichos némeros. */ | ant mea(int, int); void main(void) { int NU1, NU2, RES; printf(‘\nIngresa los dos numeros enteros: scant ("%d %d", &NU1, &NU2); RES = med (NU1, NU2); printf("\nE1 maximo comin divisor de %d y %d es: %d", NUT, NU2, RES); } | int mod(int N1, int N2) {* Esta funcion calcula el mxino comin divisor de los nimeros Ni [oy Na. 47 4 int 1; if (Ni < N2) | 1° | \ —_iggagigmmaacamacamaniaaaas “ [56 Capitulo 4, Funciones Programa 4.13 else T= N2/ 25 /* I se inicializa con el m4ximo valor posible que puede ser divisor de NT y N2. */ while (Nt % I) J} (N2 % 1)) J* El ciclo se mantiene activo mientras (NI % I) 0 (N2% I) sean \ distintos de cero. Cuando el resultado de la evaluacién sea 0, el \ ciclo se detiene ya que se habra encontrado el méximo comin divisor Teej return T; + Problema PR4.4 Escribe un programa en C que, al recibir como datos W néimeros enteros, deter mine cudntos de estos niimeros son pares y cudntos impares. Datos: N, NUM, Nyy NUM, Donde: nes una variable de tipo entero que representa el nfimero de datos que ingresan. Nuy, es una variable de tipo entero que representa al némero i (1 < i= #include #include /* Pares e inpares. E1 programa, al recibir como datos N nimeros enteros, calcula cudntos “> de ellos son pares y cudntos impares, con la ayuda de una funcion. */ void parimp(int, int *, int *); /* Prototipo de funcién. */ void main(void) { int 1, N, NUM, PAR = 0, IMP = 0; printf(*Ingresa el ndmero de. datos: soanf("%d", &N) 5 for (I { IH) printf("Ingresa el numero %d soanf("%d", &NUM) ; Parimp(NUM, &PAR, &IMP); Di — Problemas resueltos 157) /* Llamada a la funcién. Paso de parémetros por valor y por Preferencia. */ 1 | | | | | printf("\nNimero de pares: %d", PAR); printf(*\nNimero de inpares: %d°, INP); void parimp(int NUM, int *P, int *1) /* La funcién increnenta el paranetro *P 0 *I, segin sea e1 nimero par se 0 impar. */ { int RES; RES = pow(-1, NUM); if (RES > 0) sR 15 wise if (RES < 0) Problema PR4.5 calificaciones de un grupo de alum- Escribe un programa en C que, al recibir I nos que presentaron su examen de admisién para ingresar a una universidad pri- vada en la Ciudad de México, calcule y escriba el niimero de calificaciones que hay en cada uno de los siguientes rangos: a... 3.99 4... 6.99 6. 7.99 8... 8.99 oe... 10 Datos: CAL,, CAL,, .... -1 (CAL, es una variable de tipo real que representa la califi- caci6n del alumno i). Programa 4.14 | Hinclude /* Rango de calificaciones iii 158 Capitulo 4. Funciones SR ETT aS Na ne eMmEEARE rE El programa, al recibir como dato una serie de calificaciones, obtiene = el rango en el que se encuentran. */ void Rango(int) ; /* Prototipo de funcién. */ int PAI int AR2 int RAS /* Variables globales de tipo entero. */ int RAS int RAS = 0; /* El uso de variables globales no es muy reconendable. En estos “+ problenas se utilizan dnicamente con el objetivo de que el lector “> pueda observar 1a forma en que se aplican. */ void nain(void) { float CAL; printf(*Ingresa la primera calificacién del alumno: *); scanf("Sf", &CAL); while (CAL I= -1) { Rango(CAL); /* Llamada a 1a funcién Rango. Se pasa un parémetro por valor. */ printf("Ingresa la siguiente calificacién del alumno: scant (*%f*, &CAL); > printf ("\n0. RAI); printf (*\ng RA2) 3 printt("\n6. RAS); print#(*\n8. RAG); printf("\n9.. RAS); } void Rango(int VAL) J* La funcién incrementa una variable dependiendo del valor del % parénetro VAL. */ 4 if (VAL < 4) RAt++; else if (VAL < 6) RADt+; else if (VAL < 8) fis RASS; else if (VAL < 9) RAa++; else RASt+; } Problemas resueltos 159) Problema PR4.6 Escribe un programa en C que calcule e imprima la productoria de los w prime- ros nimeros naturales. Dato: NUM (variable de tipo entero que representa el niimero de naturales que se ingresan, 1 < NUM < 100) ograma 4.15 /* Productoria EL programa calcula 1a productoria de los N primeros numeros naturales. */ int Productoria( int); J* Prototipo de funcién. */ void main(void) fe nt J* Se escribe un do-while para verificar que el nimero del cual se \ quiere calcular 1a productoria sea correcto. */ do { { | a f i printf(“Ingresa el nimero del cual quieres calcular 1a } productoria: "); scanf("8d", &NUM) ; ) while (NUM >100 | NUM < 1); printf("\nLa productoria de %d es: %d", NUM, Productoria(NUM) ); } J* La funcién calcula la productoria de N. */ | int Productoria(int N) { int I, PRO = 1; for (I TN; I) | PRO *= "I; + | return (PRO); Problema PR4.7 cribe un programa que, al recibir como datos 24 mimeros reales que represen- tan las temperaturas registradas en el exterior en un periodo de 24 horas, encuentre, i160 Capitulo 4. Funciones con la ayuda de funciones, la temperatura promedio del dia, asf como la tempe- ratura méxima y la minima con el horario en el cual se registraron. Datos: TeM,, TEM,,..., TEM,, (Variables de tipo real que representan las tempe- raturas). Programa 4.16 #include #include /* Temperaturas, E1 programa recibe como datos 24 nimeros reales que representan las \ temperaturas en el exterior en un periodo de 24 horas. Calcula el \ promedio del dia y las temperaturas maxima y minima con la hora en 1 | = que se registraron. */ | void Acutem(float); void Waxima(float, int); /* Prototipos de funciones Void Minina(float, int); float ACT = 0.0; float MAX = -50.0; /* Variables globales. */ float MIN = 60.0; int HMAX; int HMIN; /* Variables globales. ACT se utiliza para acumular las temperaturas, por esa razén se inicializa en cero. MAX se utiliza para calcular 1a maxima; se inicializa en -8@ para que el primer valor que se ingrese modifique su contenido. MIN se usa para calcular la minima; se inicializa con un valor muy alto para que el primer valor ingresado modifique su contenido. HMAX y HMIN se_utilizan para almacenar el horario en que se produjeron las temperaturas méxima y minima, respectivamente. */ reerces void main(void) 4 float TEN; int 1; } for (f= 1; 1 <= 24; 144) ett | printf (*Ingresa 1a temperatura de 1a hora ‘%d: | scant (*sf", TEM); Acutem (TEM); Maxima(TEM, 1); /* Llanada a las funciones. Paso de parénetros por valor. */ Di Minima (TEM, I); Problemas resueltos 161) printf("\nPromedio del dia: %8.2f", (ACT / 24)); printf (*\nMléxima del dia: 45.2 \tHora: Sd", MAX, HMAX); printf("Initinima del dia: %5.2f \tHora:~ 8d"; MIN, HNIN); | y* Esta funcién acumula las temperaturas en la variable global ACT we para posteriormente calcular el promedio. */ { ‘ACT | I void Acutem(float T) nue void Maxima(float T, int 4) J* Esta funcién almacena 1a temperatura maxima y 1a hora en que se w produjo en 1as variables globales WAX y HWAX, respectivamente. */ { if (MAX < T) } [> void Minima(float T, int H) i | /* Esta funcién almacena la temperatura minima y la hora en que se Eb = produjo en las variables globales MIN y HMIN. */ ied Lode (aN > 1) PRE, Man = 7 i HIN = A fie k i Problema PR4.8 i £ Enel centro meteorolégico ubicado en Baja California Sur, en México, se regi {> tran los promedios mensuales pluviales de las principales regiones del pafs. Exis- £ ten seis regiones denominadas NORTE, CENTRO, SUR, GOLFO, PACIFICO y CARIBE. | Eseribe un programa en C que obtenga lo siguiente, slo para las regiones GOLFO, PACIFICO y CARIBE: i a) El promedio anual de las tres regiones. b) La regién con mayor promedio de Huvia anual (considera que los promedios de Iluvias son diferentes) (162 Capitulo 4. Funciones Datos: GOL,, PAC,» CAR,, GOL, PAC, GARjy.+y GOLyy PAC, CAR, Donde: 60t,, PAC, y CAR, son variables reales que representan las lluvias mensua- les de las diferentes regiones (1 < 4 < 12) Programa 4.17 #inolude * Lluvias E1 programa permite calcular el promedio mensual de las lluvias caidas en \ tres regiones importantes del pais. Determina también cual es la regién “con mayor promedio de lluvia anual. */ void Nayor(float, float, float); /* Prototipo de funcion. void main (void) { int 15 float GOL, PAC, CAR, AGOL = 0, APAC = 0, ACAR = 0; for (I =1; I <= 12; I++) { printf(*\n\nIngresa las lluvias del mes %d", 1); printf("\nRegiones Golfo, Pacifico y Caribe: °); scant("f Sf Sf", &GOL, BPAC, &CAR); AGOL #= GOL; APAG += PAG} | AGAR += CAR: > printf ("\n\nPromedio de Lluvias Regién Golfo: %6.2f*, (AGOL / 12)); printf("\nPromedio de Lluvias Regién Pacifico: %6.2f *, (APAC / 12); printf(*\nPromedio de lluvias Regién Caribe: %6.2f \n", (ACAR / 12); Mayor(AGOL, APAC, ACAR); /* Se llana a 1a funcién Mayor. Paso de parémetros por valor. */ jeu void Mayor(float R1, float R2, float A3) J* Esta funcién obtiene 1a regién con mayor promedio de lluvia anual. to 4 if (Rt > AQ) if (RT > RS) printf (*\nRegién con mayor promedio: Regién Golfo. Promedio: iti > 36.2F", Ri / 12); else ~wome-printf("\nRegién con mayor promedio: Reg#n Caribe. Promedio = 36.2F", Raj 12); else ee —— ee Problemas resueltos 163) { if (R2 > Ri | printf("\nRegién con mayor promedio: Regién Pacifico. Promedio: | = 66.2f", | R2 / 12); else print#(*\nRegién con mayor promedio: Regién Caribe. Promedio: = 36.2F", RB / 12); . | Problema PR4.9 Escribe un programa en C que imprima todos los valores de 1, P y @ que satisfa- gan la siguiente expresién: 15°T! + 124P> + gta < 5500 Nota: Observa que las tres variables s6lo pueden tomar valores enteros positiv gf Programa 4.18 #include /* Expresion. El programa escribe los valores de T, P y @ que satisfacen una determinada Ser pe eee j int Expresion(int, int, int) /* Prototipo de funcién. */ void main(void) { int EXP, T= 0, P= 0,aQ=0 EXP = Expresion(T, P, 0) while (EXP < 5500) { ‘NR ASRS mR while (EXP < 5500) { while (EXP < 5500) i { printf("\nT: %d, P: &d, Q: %d, Resultado: %d", T, P, Q, EXP); art; EXP = Expresion(T, P, Q); I i E 5 Capitulo 4. Funciones Expresion(T, P, int Expresion(int T, int P, int a) /* Esta funcién obtiene el resultado de la expresién para los valores oe T, Py Q. */ { int RES; RES = 15 * pow(T,4) + 12 * pow(P,5) + 9 * pow(,6); return (RES); } Problema PR4.10 | | } | { | Sigue y analiza cuidadosamente el siguiente programa e indica qué imprime. tus resultados coinciden con los presentados, felicitaciones. Si son diferentes, re- visa principalmente la aplicacién de los pardmetros por referencia, porque tal ve? hay algiin concepto que atin no domina Programa 4.19 #include {* Funciones y parénetros. * int a, b, ¢, dj * variables globales. */ void funciont(int, int *, int *); /* Prototipos de funciones. * int funciona(int *, int); void main(void) { int a; =4j a= 4 printf ("\nid %d %d 80", a, b, ¢, d); a = funcion2 (8a, 0); Pere ee ee Problemas resueltos 165) bry | void funciont(int r, int *b, int *c) Phe int d; a= *c; d= ats tb; | bf atin { tb = tb + 25 bas a2 tat get } { printt(“\nid Ad Sd Ad", a, *d, te, ds | ; : int funcion2(int *d, int c) { int asty b= 7; funciont(-1, d, 8b); J* Observa que el pardmetro d que enviamos a funciont es por referencia ‘Es equivalente escribir &d a escribir solamente d. */ printf (*\ntd %d Sd Rd", a, b, cy *d)5 | | c+ 3; | j (rd) += 25 printf ("\nkd Ad Ad Sd", a, by c, *d)s return (c); ) [166 Capitulo 4. Funciones Problema PR4.11 Analiza cuidadosamente el siguiente programa e indica qué imprime. Si tus re- sultados coinciden con los presentados, felicitaciones. Si son diferentes, revisa principalmente la aplicacién de los pardmetros por referencia, porque tal vez hay algtin concepto que atin no dominas. Programa 4.20 i # include J* Funciones y parémetros. */ int Fi(int , int *); J* Prototipo de funcion. */ int A int 8 int 6 /* Variables globales. */ | void main(void) { A= Ft (C, 8D); printf("\nid id sd 8a C= 3; C= Fi (A, aC); printf("\nid ad &d Ad", A, B,C, D); } { int A; A=; cH; By; printf ("\ntd Sd Sd %d", A, B, C, D); nye return (0); | int Fi(int X, int *Y) 15 8 9 5 2 5 9 5 2 15 13 4 2 5 13 4 2 Re ——_—_ —— Problemas resueltos 167) | Problema PR4.12 ' i Sigue y analiza cuidadosamente el siguiente programa e indica qué imprime. Si tus resultados coinciden con los presentados, felicitaciones. Si son diferentes, re~ visa principalmente la aplicacién de los par4metros por referencia, porque segu- ramente hay algtin concepto que atin no dominas. Programa 4.21 eS Za # include /* Funciones y parametros. */ int 2, y /* Variables globales. */ z | int F1(float); void F2(float, int *); {* Prototipos de funciones. */ a void main(void) { int w; | float x; y=7} | w= 2} x= (floaty / 23 printf ("\nPrograma Principal: Ad %d %.2f 8d*, Zz, YX, W); F2 (x, aw); printf("\nPrograma Principal: Sd %d %.2f %d", Zz, y, Xx, W); } a int Fi(float x) \nFI: Ad Sd %.2F Ad, 2) ys Hy KD: | return(k) 5 ey I void F2(float t, int *r) ‘ Funciones y pardmetros. */ int a, b, ©, dj Sint pal(int, int); J* Prototipo de funcion. */ joid main(void) as 2; c= 3} d= 5; a = pal(c, 9); printf("\nad Sd Sd Ad", a, b, c, 4); b= 4; b= pal(b, a); printf (*\ntd &d %d %d", a, bd, ©, a); > int pal(int x, int y) 4 int ¢; bext yy bry yr yt th printf(*\ned %d Sd 8d”, b,c, x, y)i return (x); ) _| [172 Capitulo 4. Funciones q Problema PS4.11 Examina cuidadosamente el siguiente segmento de programa: Programa 4.23 include void trueque(int *x, int *y) { int tea tem = *x; ei | ty = tem; } int suma(int x) { return (x + x); } y determina cudles de las siguientes Ilamadas a las funciones son correctas si x, y ¥ z son variables de tipo entero. trueque(suma (Xx), 8X); trueque(3, 4)5 suma( 10); y = suma(1@); z= trueque(&x, &y); trueque(ax, &y); Ee Problema PS4.12 Escribe los resultados que se obtienen al ejecutar el siguiente programa: Programa 4.24 Hinclude | /* Paranetros y funciones. */ Ant f1(void); Ant f2ivoia) ; P —— ~ Problemas suplementarios 173 int £3(void) 5 int 14(void) j ant K = 8} void nain(void) { int 1; for (I= 1; I <= 4; I++) { 7 printf ("\n\nEl resultado de la funcién f1 es: 8d", £1()); printf("\nEl resultado de la funcin f2 es: 8d", £2()); printf("\nEl resultado de la funcién £3 es: %d", 13()); printf(*\nEl resultado de la funcién f4 es: %d", £4()); + int f1(void) ¢ Ke K return (Kk); } int 2(void) { int K al return (K); } int f3(void) { static int K = 6; kK += 3; return (kK); ) int f4(void) per aemee ges enn CAPITULO Arreglos unidimensionales 5.1. Introduccion En la prictica es frecuente que enfrentemos problemas cuya solucién serfa muy dificil de hallar si utilizéramos tipos simples de datos para resolverlos. Es decir, datos que ocupan una sola casilla de memoria. Sin embargo, muchos de estos problemas se podrian resolver ficil- mente si aplicdramos en cambio tipos estructurados de datos, los cuales ocupan un grupo de casillas de memoria y se identifican con un nombre. Los arreglos que estudiaremos en este capitulo constitu- yen un tipo estructurado de datos. Los datos estructurados tienen varios componentes, cada uno de los cuales puede ser un tipo simple de dato o bien un tipo estructurado de dato, pero es importante recordar que los componentes del nivel mas bajo de un tipo estructurado siempre serdn tipos simples de datos. [76 Capitulo 5. Arreglos unidimensionales Formalmente definimos un arreglo de la siguiente manera: = en ey re | “Un arreglo es una coleccién finita, homogénea y ordenada de elementos. Finita, porque todo arreglo tiene un limite, es decir, se debe determinar cual es el ntimero maximo de elementos del arreglo, Homogénea, porque todos los ele- mentos del arreglo deben ser del mismo tipo. Ordenada, porque se puede deter- minar cual es el primer elemento, cual el segundo, y asf sucesivamente. 5.2. Arreglos unidimensionales Formalmente definimos un arreglo unidimensional de la siguiente manera: “Un arreglo unidimensional es una colecci6n finita, homogénea y ordenada de datos, en la que se hace referencia a cada elemento del arreglo por medio de un indice. Este ultimo indica la casilla en la que se encuentra et elemento.” Un arreglo unidimensional permite almacenar N elementos del mismo tipo (enteros, reales, caracteres, cadenas de caracteres, etc.) y acceder a ellos por medio de un fndice. En los arreglos unidimensionales se distinguen dos pat- tes fundamentales: los componentes y el indice. Los componentes hacen referencia a los elementos que se almacenan en cada una de las celdas 0 casillas. El indice, por su parte, especifica la forma de acceder a cada uno de estos elementos. Para hacer referencia a un componente de un arreglo de- bemos utilizar tanto el nombre del arreglo como el indice del elemento. En Ja figura 5.1 se puede observar la representacién grifica.de un arreglo unidi- mensional. 5.3 Declaracién de arreglos Unrdimenstonales 177) 1 — Segundo elemento N-ésimo elemento Primer elemento Ficura 5.1 Representacién gréfica de un arreglo unidimensional En la figura 5.2 se muestra el arreglo unidimensional A que contiene 10 elemen- tos de tipo entero. El primer indice del arreglo es el 0, el segundo, el 1, y ast sucesivamente. Si queremos acceder al primer elemento del arreglo debemos escribir {0}, pero si requerimos acceder al quinto elemento debemos escribir [4]. Por otra parte, se puede observar que el valor de a{7} es 4, el de ai3+5) es 5, el resultado de Af2} + (5) es 2, y el resultado de a(7) * a(g} es 32. a4 [+5 |e ff tf f f ft f T Ff ft Alo) Alt] Al2] ALS] AL4]. ALS]. AIG] AL71. ATS] ALS Figura 5.2 indices y componentes de un arreglo unidimensional 5.3. Declaracion de arreglos unidimensionales Los arreglos ocupan espacio en memoria, que se reserva en el momento de reali- zar la declaracién del arreglo. A continuacién presentamos diferentes formas de declarar arreglos, con la explicacién correspondiente. [178 Capitulo 5. Arreglos unidimensionales void main(void) { int A[1@]; I Definicién de un arreglo de tipo entero de 10 elementos. */ float B[5]; /* Definicin de un arreglo de tipo real de 5 elementos. */ } Una vez. que se definen los arreglos, sus elementos pueden recibir los valores a través de multiples asignaciones, o bien, como ocurre frecuentemente en la préc- tica, a través de un ciclo. Observemos a continuacién el siguiente ejemplo. Esempto 5.1 Construye un programa que, al recibir como datos un arreglo unidimensional de 100 elementos de tipo entero y un néimero entero, determine cudntas veces se en- cuentra este ntimero dentro del arreglo. Datos: ARRE{100}, Nut (donde ARRE es un arreglo unidimensional de tipo entero con capacidad para almacenar 100 valores enteros y nul es una variable de tipo entero que representa el mimero que se buscard en el arreglo). Programa 5.1 | #include | 1 cuenta-nimeros. | e1 programa, al recibir como datos un arreglo unidimensional de tipo | Sentero y un numero entero, determina cuantas veces se encuentra el | “snimero en el arreglo. */ j void main(void) 4 int I, NUM, CUE = int ARRE[ 100]; J* Declaracién del arreglo */ for (I=0; I<100; I++) { printf ("Ingrese el elemento %d del arreglo: ", I+1); scant ("%d", ARRE[I]) ; 7* Lectura -asignacién— del arreglo */ } Printf("\n\nIngrese e1 numero que se va a buscar en el arreglo: "); | seanf(*ed", aNUM) ; for (1=0; 1<100; I++) 4f (ARRE[T] == NUM) /* Conparacién del numero con los elementos del | warreglo */ curt printf (*\n\nel %d se encuentra %d veces en el arreglo", NUM, CUE); | Lokes sauce ts 5.3 Declaraci6n de arreglos unidimensionales ~ 179 Otra forma de asignar valores a los componentes de un arreglo es al realizar la declaraci6n del mismo. A continuacién presentamos diferentes casos con la ex- plicacién correspondiente, junto con figuras en las que se muestran los valores que toman los diferentes componentes del arreglo. int A[10] = {0}; /* Todos los componentes del arreglo se inicializan en 0. */ T T T A fe OMe Atl AL1] AL21 AIS]. AA] ALS]. ALS] AI7]. ALB] ALS] Ficura 5.3 Declaracién del arreglo unidimensional A int 8(5) = {5}; /* El primer componente del arreglo se inicializa con el nimero 5 y el resto con 0. 7 a(e) Bit] 812] B13] Bla) BR Ficura 5.4 f Peclaracidn det arrego unidimensional 8 b int C[5] = {6, 23, 8, 4, 11}3 /* Cada componente del arreglo recibe un valor. La asignacién se realiza en forma consecutive. */ c 6 23 8 4 " t i r tf tf Tt fT i cio} city cz) C3) cra] Ficura 5.5 Declaracién del arreglo unidimensional ¢ | 180 Capitulo 5. Arreglos unidimensionales int DI5) = {6, 23, 8, 4, 11, 35}; /* Esta asignacién genera un error de Wesintaxis que se detecta en la compilacién. €1 error ocurre porque el arreglo ‘tiene capacidad solanente para § componentes y hay 6 elementos que se quiere wasignar. */ int E[] = (83, 21, 48, 5, 11}; /* En este caso, como se omite el tanafio del wearreglo en 1a definicién, se considera que el nimero de elementos del arreglo ‘ses igual al numero de elementos que existen en la lista por asignar. */ E 33 at 48 5 oe t t tel t E10) E11] E[2) E13] Eta] Figura 5.6 Declaracién del arreglo unidimensional € Esewpto 5.2 Los organizadores de un acto electoral de un pais sudamericano solicitaron un programa de cémputo para manejar en forma electrénica el conteo de los votos. En la eleccién hay cinco candidatos, los cuales se representan con Jos valores del 1 al 5. Construye un programa en C que permita obtener el mimero de votos de cada candidato. El usuario ingresa los votos de manera desorganizada, tal y como se obtienen en una eleccién; el final de datos se representa con un cero, Observa la siguiente lista de ejemplo: 25543445124312450 Donde: 2 representa un yoto para el candidato 2, 5 un voto para el candidato 5, ¥ asf sucesivamente, Datos: Vor}, VOT2,..... @ (variable de tipo entero que representa el voto a un can- didato). Programa 5.2 #include I* Eleccién | EL programa almacena los votos enitidos en una eleccién en 1a que hubo cinco. | ‘reandidatos © inprine el total de votes que obtuvo cada une de ellos. */ | é 5.4 Apuntadores y arreglos ina a 181) ‘ ' | void main(void) | ppt } | int ELE(5] = {0}; | /* Declaracién del arreglo entero ELE de cinco {| ant 1, vor; } [printf ("Ingresa el primer voto (@ - Para terminar): | |. seanf ("%d", VOT); ) | while (vor) | 4f ((VOT > 0) && (VOT < 6)) /* Se verifica que el voto sea i | wcorrecto. */ | ELE[VOT-1]++; /* Los votos se almacenan en el arreglo. wRecuerda que la primera posicién del arreglo es 0, por esa razén a la | variable VOT se le descuenta 1. Los votos del primer candidato se wealmacenan en la posicién 0. */ else printf("\nEl voto ingresado es incorrecto.\n"); printf("Ingresa el siguiente voto (0 - Para terminar): "); scanf("%d", &VOT); } « |. printf("\n\nResultados de 1a Eleccién\n"); for (I = 0; I <= 4; I++) printf(*\nCandidato %d: %d", I+1, ELE(TI); } i 5.4. Apuntadores y arreglos e Un apuntador es una variable que contiene la direccién de otra variable y se re- & presenta por medio de los operadores de direccién (&) e indireccién (*). El pri- Fiero proporciona la direccién de un objeto y el segundo permite el acceso all # objeto del cual se tiene la direccién. Los apuntadores se utilizan mucho en el lenguaje de programacién C, debido principalmente a que en muchos casos representan la tinica forma de expresar una operacién determinada. Existe una relacién muy estrecha entre apuntadores y arreglos. Un arreglo se pasa a una funcién indicando tnicamente el nombre det arreglo, que representa el apuntador al mismo. Para comprender mejor el concepto de apuntadores, observemos a continuacién diferentes instrucciones con su explicacién correspondiente. Luego de cada gru- po de instrucciones se presenta una tabla en la que puedes observar los valores que van tomando las variables. int X= 3, Y= 7, 218) = (2, 4, 6, 8, 10); [182 Capitulo 5. Arreglos unidimensionales J* 1X representa un apuntador a un entero. */ * IX apunta a X. IX tiene la direccién de X. */ /* ¥ tona el valor de X. Y recibe el contenido de la “edireccién almacenada en IX, es decir, el valor de X. Anora ¥ es 9. */ "IK = 1 J* X se modifica. Ahora X vale 1. */ Tasia 5.2. Apuntadores, variables y valores Valor x 1 Y 3 z10) 2 ZU] 4 z(2] 6 23] 8 214] 10 /* IX apunta al tercer elemento del arreglo Z. */ J* ¥ toma el valor de Z[2}, ahora vale 6. */ I* Z{2] se modifica, ahora vale 18. */ Tasta 5.3. Apuntadores, variables y valores Variable Valor 5.4 Apuntadores y arreglos Tz 183) X= #IK + 6; /* X se modifica, ahora vale Z[2] + § = 20. Recuerde que *IX wecontiene el valor de Z[2]. */ "IX = *IX- 5; /* 2[2] se modifica, ahora vale 10. */ quia 5.4. Apuntadores, variables y valores Variable Valor x 20 Y 6 Z(0) 2 zi] 4 zi2] 10 213) 8 z14] 10 J* Z[2] se modifica, se incrementa en 1. Z[2] ahora vale 11. */ /* Z[2] se vuelve a modificar, ahora vale 12. Observa que Y 6 z[0) 2 ZU] 4 zl2) 12 213] 8 z14) 10 X= (DK 4 1); f —/* X se modifica. £1 apuntador IX se desplaza una posicién y accede temporalmente wea Z[3], por 1o tanto X toma este valor (8). Observa que IX no se reasigna. */ Y= "Ds J* ¥ se modifica, toma el valor de Z[2] (12). */ [184 Capitulo 5. Arreglos unidimensionales Tasta 5.6. Apuntadores, variables y valores Variable Valor x 8 y 12 2[0) 2 ZU) 4 2(2) 12 213) 8 Z[4) 10 K+; J* Observa otra forma de mover el apuntador. En este caso IX se desplaza una ‘eposicién, pero a diferencia del caso anterior, ahora se reasigna. IX apunta ahora al ‘cuarto elenento de Z (Z{3]). */ Y= ATK 7* ¥ se noditica, toma ahora el valor de Z[3) (8). */ Tasia 5.7. Apuntadores, variables y valores Variable Valor 8 Y 12 210] 2 Zz] 4 22] 12 23) 8 z14) 10 k= 1K +45 J* 1X se modifica. Observa que el apuntador se desplaza cuatro posiciones y ca? ‘sen una direccién que se encuentra afuera del arreglo. Esto ocasiona un error ‘que no sefiala el conpilador de C. */ Y = 81K; /* Y se modifica, toma el valor (basura) de una celda ‘sincorrecta. Este es un error que no sefiala el compilador del lenguaje C. 5.4 Apuntadores y arreglos 185}- 8 y 9203 212) 2 zit] 4 212] 2 2131 8 214) 10 IX = BX /* IX apunta a 1a variable entera X. */ k= 44 /* TX se mueve una posicién y cae ahora en una celda eincorrecta. */ X= "1K; /* X tona el valor (basura) de 1a celda a 1a que apunta IX. */ Tasta 5.9. Apuntadores, variables y valores Variable Valor wma 20079 Y 9203 210) 2 ZU 4 212) 12 2131 8 214) En el siguiente programa se presentan todos los casos que se analizaron en la seccién anterior. Programa 5.3 #include J* Apuntadores, variables y valores. */ void main(void) 4 rriiaanniaheecinisiete [186 Capitulo 5. Arreglos unidimensionales int X= 3, Y= 7, Z{5] = {2, 4, 6, 8, 10}; printf(*\nX = sd lt Y= 9d \t Z[0} = 0 \t Z[1] = %d \t 2[3] = Sd \t 214) we td, XY, Z(01, ZU4], 221, 2131, Z041); int *1xX; 1 IX representa un apuntador a un entero. */ 1X = aX} [* IX apunta a X. IX tiene la direccién de X. */ Y= "IK; /* ¥ toma el valor de X, ahora vale 3. */ "1x = 1; 1* X se modifica, ahora vale 1. */ prante("\nx = Ad \t Y= 8d \t 2[@] = Ad \t Z[1] = Ad \t Z[2] = Ad \t 213] = 38 wit 214) = wa", X,Y, 200), 211], 212), 213), 214)); | IK = 8212}; /* IX apunta al tercer elemento del arreglo Z. */ yeeng J* Y toma el valor de 2[2], ahora vale 6. */ "IX = 185 /* Z[2] se modifica, ahora vale 15. */ printf (*\nk = Ad \t Y= Md \t Z[0] = Rd \t Z{t] = ed \t Zi2] = Ad \t 219] = ed s\t 2141 = X,Y, Z(0}, 201], 212), 213), 2141)5 X= IK + 5; J* X se modifica, ahora vale Z[2] + § = 20. Recuerda que *1X “contiene el valor de Z[2]. */ *IX = IX - 55 i* 2{2] se modifica, ahora vale 10. */ { printf (*\nX = \t Y= Sd \t ZO) = Ad \t ZI1) = Ad \t 212) = 0 \t zI3) = 4d | weit 24] = Sd", X,Y, 200), 2111, 2121, 231, 2141); HAIK; /* Z[2] se modifica, se increnenta en 1. 2[2] ahora vale 11. */| MIX 4545 J* 2[2] se vuelve a modificar, ahora vale 12. */ prant#("\nx = Sd \t Y= kd \t Z[0] = Md \t Z[1] = ad \t 212) = Md \t 218) = 80 seit 2141 fd", X,Y, 20), 2U11, 22], 203), 2041); X= "(IX +1); /* X se modifica. £1 apuntador IX accede tenporalnente a “Z{3], por lo tanto X toma este valor (8). Observa que IX no se reasigna */ Y= “IX; /* ¥ se modifica, toma el valor de Z[2] (12). */ printf(*\nx = ed \t Y= 8d \t Z[0] = 0 \t Z[1] = 8d \t Z[2] = Sd \t Z[3] = 3d wit Zi4) = fd", Xs Ys 200), ZE11, 212), 203), 214s IX= 1K #45 * IK se modifica, Observa 12 forma de mover el apuntador Ahora IX apunta al cuarto elenento de Z (Z[3]). */ Y= *1K; /*Y se modifica, ahora vale 2[3} (8). */ print#(*\nx = Sd \t Y= Ad \t Z[O]= Ad \t Z[t] = Ad \t Z[2] = 8d \t ZI9] = Ad wit 214) = X,Y, 210), 211), 2(2), 219), 21415 a - "5.5 Arreglos y funciones X= Ik #4) J* IX se modifica. Observa que el apuntador se aueve ‘4 posiciones y cae en una direccién afuera del arreglo. Esto ocasionard un werror. */ Y = *IX;” /* Y se modifica, toma el valor (basura) de una celda \eincorrecta. Es un error que no sefala el compilador del lenguaje C. */ printf("\nxX = ad \t Y= 8d \t Z[@}= 8d \t Z[1] = Sd \t Z[2} = Sd \t 723) = 8d welt 214) nd", X,Y, 201, ZU41, 22], 203], 2041); IX = 8X; /* IX apunta a la variable entera X. */ KS 415 J+ IX se mueve una posicién y cae en una celda incorrecta. */ x= IK /* X toma el valor (basura) de la celda a 1a que apunta IX.*/ printf(*\nx = Sd \t ¥ = Sd \t 2[0}= 9d \t Z[1] = Sd \t Z[2] = Ad it 213] = 80 wit Zia) fd", X,Y, 210), 201], 2121, 2131, 2141) } 5.5. Arreglos y funciones El lenguaje de programacién C utiliza pardmetros por referencia para pasar los arreglos a las funciones. Cualquier modificacién que se realice a los arreglos en las funciones afecta su valor original, En la llamada a la funcién s6lo se debe incluir el nombre del arreglo, que es un apuntador. No se deben incluir los cor- chetes porque ocasionan un error de sintaxis Esempto 5.4 Escribe un programa en C que calcule el producto de dos arreglos unidimensio- nales de tipo entero y almacene el resultado en otro arreglo unidimensional Datos: VEi{10}, VE2{10}, VE3{10} (arreglos unidimensionales de tipo entero con capacidad para 10 elementos, En ve3 se almacena el resultado del produc- to de los vectores vet y ve2). Programa 5.4 include | J* Producto de vectores: El programa calcula el producto de dos vectores y almacena el resultado | “sen otro arreglo unidimensional. */ | const int WAX “arreglos. */ 0; /* Se define una constante para el tamaho de los | [188 | be Capitulo 5. Arreglos unidimensionales Symmes void Lectura(int VEGI], int 1); void Inprime(int VEC{], int T); * Prototipos de funciones. */ Void Producto(int *X, int *Y, int *Z, int T); /* Observa que en los ‘eparénetros, para indicar que lo que se recibe es un arreglo, se puede escribir SVECI] 0 “VEC. */ void nain(void) { dnt VE1{WAX], VE2(WAX}, VES(MAXI; /* Se declaran tres arreglos de tipo entero de 10 elenentos. */ Lectura(VE1, MAX) /* Se lana'a la funcién Lectura. observa que el paso del arregio a 1a funcién es por referencia, Sélo se debe incluir el nombre del arreglo. */ Lectura(Ve2, MAX) ; Producto(VE1, VE2, VES, MAX); * Se lana a 1a funcién Producto. Se pasan los nombres de los tres arreglos. */ printf ("\nProducto de los Vectores*); Inprine(VES, MAX); ) void Lectura(int VEC), int 7) J* La funcién Lectura se utiliza para leer un arreglo unidimensional de T “elementos de tipo entero. */ { int I; printf ("\n") 5 for (1-0; I (* Frecuencia de calificaciones El prograna, al recibir como datos las calificaciones de un grupo de 60 wealumnos, obtiene 1a frecuencia de cada una de las calificaciones y ademas weescribe cual es 1a frecuencia més alta. */ const int TAM = 50; void Lectura(int *, int); void Frecuencia(int , int, int , int); J* Prototipos de funciones. * void Inpresion(int *, int); void Nayor(int *, int); void main(void) . { Aint CAL[TAM], FRE[6] = {0}; J* Declaracién de los arreglos. */ Lectura(CAL, TAM); /* Se Llama a la funcion Lectura. */ Frecuencia(CAL, TAM, FRE, 6); J* Se llama a la funcién Frecuencia, se pasan anbos arreglos. */ printf ("\nFrecuencia de Calificaciones\n"); Inpresion(FRE, 6); Mayor (FRE, 6); } void Lectura(int VECI], int T) | J* La funcién Lectura se utiliza para leer el arregio de calificactones. */ | { int 1; for (1-0; I= 0) && (A[T] <6)} __/* Se valida que la calificacién sea ‘correcta. */ BIA[I]]++; _/* Observa la forma de almacenar e incrementar las wefrecuencias. */ 4 void Mayor(int *X, int T) /* Esta funcién obtiene la primera ocurrencia de la frecuencia mas alta { int 1, MERE = 0, MVAL = x{0]; | } for (I=1; IT; I++) if (MVAL < X[1]) { eT AWAL = X[1]; } printf("\n\nllayor frecuencia de calificaciones: %d \tValor: 80", MFRE, MVAL); | | FRE , Problemas resueltos Problema PR5.1 Escribe un programa que, al recibir como dato un arreglo unidimensional de nt- meros reales, obtenga como resultado la suma del cuadrado de los némeros. Dato: vec{ 100} (arreglo unidimensional de tipo real de 100 elementos). iia —— -~ — ProbleniaSresueltos iene Programa 5.6 #include #include /* Suma-cuadrados. El programa calcula 1a suna del cuadrado de los elenentos de un arreglo ‘unidimensional de 100 elenentos de tipo real. */ const int MAX = 100; /* WAX se utiliza para reservar el espacio maximo que podra ocupar el arreglo. */ void Lectura(float *, int); /* Prototipos de funciones. */ | double Suna(float *, int); void main(void) { float VEC[MAXI; double RES; Lectura(VEC, MAX); RES = Suma(VEC, MAX); /* Se Llama a la funcién Suma y se almacena el resultado en la variable RES. */ “eprintf("\n\nSuma del arreglo: %.21f", RES); } void Lectura(float A[], int T) /* La funeién Lectura se utiliza para leer un arreglo unidimensional de T welementos de tipo real. */ { int 1 for (I-05 Tet; 1+) { print#(*Ingrese el elemento %d: *, 141); | scant (*f", 8A(I]}; } double Suna(float A[], int T) /* La funcién Suna se utiliza para calcular 1a suma del cuadrado de los ‘scomponentes de un arreglo unidimensional de T elementos de tipo real. */ { int 1; double AUX = 0.0; for (1-0; I {* Arreglo sin elenentos repetidos EL programa, al recibir como dato un arreglo unidimensional desordenado de Nv ‘elementos, obtiene como salida ese mismo arreglo pero sin los elementos wrepetidos. */ void Lectura(int *, int); /* Prototipos de funciones. */ void Inprime(int *, int); Void Elimina(int *, int *); /* Observa que en el prototipo de Elimina, el segundo parémetro es por ‘referencia. Esto, porque el tamafo del arreglo puede disminuir, void main(void) | { int TAM, ARRE[100]; J* Se escribe un do-while para verificar que el tamafo del arreglo que se “ingresa sea correcto. */ do q printf ("Ingrese el tamafio del arreglo: *); | scanf(“ed", &TAM); + while (TAM > 100 || TAM <1); Lectura(ARRE, TAM) ELimina(ARRE, &TAW); j* Observa gue el tanafio del arreglo se pasa por referencia.*/ Imprime(ARRE, TAM); , void Lectura(int A[], int T) /* La funcién Lectura se uti ‘elementos de tipo entero. */ ‘ printf (*\n"); int 1; for (1=0; I /* Primos, El programa almacena en un arreglo unidimensional los primeros 100 nimeros “primo. */ const int TAM = 100; void Inprine(int, int); J* Prototipos de funciones. */ | void Primo(int, int *); | void main(void) { | ant Prramy = (1,2); int FLA, J = 2, PRI = 3; while (J <= TAI) | FLA = 1) | Primo(PRL, FLA); /* Se llama a 1a funcién que determina si PRI es ‘primo. */ if (FLA) /* Si FLA es 1, entonces PAI es primo, */ { Pld] = PRI; wy | | } PRI += 2; fut Imprime(P, TAM); } Void Primo(int A, int *8) /* Esta funcién determina si A es primo, en cuyo caso el valor de *B no se wealtera. */ { int OI = 3; | white (*8 88 (or < (A / 2))) peer if ((A% DI "B= 05 °) void Inprime(int Primos[}, int T) J* Esta funcién inprime el arreglo unidimensional de numeros prinos { int 1; for (1-0; I J* Bisqueda secuencial en arreglos desordenados. */ const int MAX=100; void Lectura(int, int); /* Prototipos de funciones. */ int Busca(int *, int, int); | void main(void) fn nes, ete, vaN, vEO(MAH; do { printf : scant ( "Ingrese el tamafio del arreglo: *); sd", TAM); | 3; while (TAM>MAX | TAM<1); /* Se verifica que el tamafo del arreglo sea | scorrecto. */ Lectura(VEC, TAM); print#(*\nIngrese el elemento @ buscar: scanf("sd", 8ELE); | RES = Busca(VEC, TAM, ELE); /* Se llana a la funcién que busca en el wearreglo. */ if (RES) /* Si RES tiene un valor verdadero —diferente de @~, se escribe 1a posicién teen 1a que se encontré el elemento. */ printf (*\nEl elemento se encuentra en 1a posicién 4d", RES); else printf(*\nEl elenento no se encuentra en el arreglo + Capitulo 5. Arreglos unidimensionales void Lectura(int af], int T) /* La funeién Lectura se utiliza para leer un arreglo unidimensional de T | | \eelementos de tipo entero. */ { int 1; for (1-0; I J* Bésqueda secuencial en arreglos ordenados en forma creciente const int MAX=100; | void Lectura(int, int); I* Prototipos de funciones. */ int Busca(int *, int, int); void main(void) { | int RES, ELE, TAM, VEC(MAX]; do q printf("Ingrese el tamaio del arreglo: "); soanf(*%d", &TAM); } while (TAM > MAX | TAM < 1); J* Se verifica que el tamafo del arreglo sea correcto. */ Lectura(VEC, TAM); printf("\nIngrese el elemento a buscar:"); scanf("Sd", BELE); RES = Busca(VEC, TAM, ELE); /* Se llama a la funcién que busca en el searreglo. */ if (RES) J* Si RES tiene un valor verdadero —diferente de “eposicién en la que se encontré al elemento. */ | printf(*\nél elemento se encuentra en la posicidn: %d", RES); else —, se escribe la | printf("\nEl elemento no se encuentra en el arreglo"); } void Lectura(int Af], int T) /* La funcién Lectura se utiliza para leer un arreglo unidimensional de T “elementos de tipo entero. */ { Ant 1; for (1 { I= A[1}) 8& IRAN) | J* observa que se incorpora una nueva condicién. */ if (A[T] == €) BANS; else 1H; af (BAN) RES = I+ 4; J* Se asigna I+t dado que las posiciones en el erregio comienzan des de cero. */ | eise RES = BAN; return (RES); } i a } oy pésqueda binaria. const int MAX=100; “Void Lectura(int, int); /* Prototipos de funciones. */ int Binaria(int *, int, int); void nain(void) { int RES, ELE, TAM, VECINAX]; * do { "Ingrese el tamafo del arreglo: aTAM) ; printf scant ( Unie (TAWUAX | TAllc1); /* Se verifica que el tanafo del arregio sea secorrecto. */ | Lectura(VEC, TAM); printf(*\nIngrese el elemento a buscar: *); scant ("sd", &ELE) 5 RES = Binaria(VEC, TAM, ELE); /* Se llama a la funci6n que busca en el sarreglo. */ if (RES) /* Si RES tiene un valor verdadero —diferente de 0—, se esc! wposicién en la que se encontré el elemento. */ printf (*\nEl elemento se encuentra en 1a posicién: %d*, RES); be la else printf(*\nEl elemento no se encuentra en el arreglo"); } void Lectura(int Af], int T) /* La funcién Lectura se utiliza para leer un arreglo unidimensional de T ‘elementos de tipo entero. */ { | int 15 | for (I-05 1 AICEN}) 120 = GEN + 1; else DER = CEN - 1; } return (BAN); > Problema PR5.7 Ordenacién por insercién directa (forma creciente). Este es el método que utilizan generalmente los jugadores de cartas cuando las ordenan, de ahi que también se le conozca con el nombre de método de la baraja, La idea central del método consiste en insertar un elemento del arreglo en la parte izquierda del mismo que ya se encuentra ordenada. El proceso se repite desde el segundo hasta el enésimo elemento Observemos a continuacién un ejemplo en la tabla 5.10 para ilustrar el método Consideremos un arreglo unidimensional A de tipo entero de ocho elementos. Pasadas AO] Ali] Al2]_Al3)_ Al] lS] Al6) AI) Ia, ae 27) rt S406 19 a 2a. 2 34 22 u 5436. 19 7 3a. 2 22 34 ir 5436. 19 7 4a. 11 m2 2 34 S54 36 19 7 Sa, ate 12) 2 34 54 36 19 7 6a. Me 17 22 3436 1s 19 7 Ta. nu DR 19 22 34 (36 7 8a. 7 ou 2 19 224 —— Problemas resueltos. . —~ 201) Dato: vec{N) (arreglo unidimensional de tipo entero de w elementos, 1 < N < 100). Programa 5.12 #include J* Ordenacién por insercién directa. */ const int MAX = 100; void Lectura(int *, int); void Ordena(int *, int); void Inprine(int *, int); [* Prototipos de funciones. */ void main(void) { int TAM, VECINAX]; do 1 printf("Ingrese el tamaho del arreglo: *); scanf("%d", &TAM); | nile (TADUAX | Tai); /* Se verifica que el tanafo del arregio sea wcorrecto. */ Lectura(VEC, TAM); Ordena(VEC, TAM) ; Imprime(VEC, TAM); } void Lectura(int Al], int T) /* La funcién Lectura se utiliza para leer un arreglo unidimensional de T ‘elementos de tipo entero. */ { int 1; for (1-0; I } Void Inprime(int A[}, int T) /* Esta funcién se utiliza para escribir un arreglo unidimensional. “ordenado de T elementos de tipo entero. */ { int 1; for (1=0; I= 0) && (AUX < A[L})) { AULA] = AULT; Ley | - ATL#1] = AUX; Problema PR5.8 Ordenacién por seleccién directa (forma creciente). Es el mejor de los méto- dos simples de ordenacién (intercambio —burbuja— e inserci6n). La idea basica de] método consiste en buscar el elemento mas pequefio del arreglo y colocarlo en la primera posicién. Luego se busca el segundo elemento mas pequefio y se coloca en la segunda posicidn; y asf sucesivamente hasta que todos los elementos del arreglo queden ordenados. En Ja tabla 5.11 se presenta un ejemplo para ilustrar al método. Consideremos un arreglo unidimensional A de tipo entero de ocho elementos. Tasia 5.11. Ordenacion por seleccién directa Pasadas A[0] Alt] Al2] _A[3]__Al4]__Al5]__Alé]__Al7] la. 12 34 22 i 5436 19 1 2a. 7 34 22 uw oageee 36 19 12 3a. 7 i 22 ood 36 19 2 4a, 7 ul 12 345436 19 Sa. 7 u 12 9 54-36 34 6a. 7 u 12 19 =22—— 36 34 Ta, 7 rt 2 9 2 M 36 54 8a, 7 u 12 19 Cy eS 54 =n “—Problemas resueltos programa 5.13 winclude * Ordenacién por seleccién directa, */ | const int MAX = 100; void Lectura(int *, int); void Ordena(int *, int); /* Prototipos de funciones. */ void Imprime(int *, int); | void main(void) fine TAH, VEo{WAXI; do { printf("Ingrese el tamafo del arreglo: scanf("%d", &TAM); B while (TADMAX || Talict); /* Se verifica que el tanafo del arreglo sea “correcto. */ Lectura(VEC, TAM); Ordena(VEC, TAM); | Imprine(vEc, TAM); } void Lectura(int Al], int T) /* La funcién Lectura se utiliza para leer un arreglo unidimensional de T “elementos de tipo entero. */ ¢ int I; for (I=0; [ AIL] = ALL ALI] = MEN; | > i Problema PR5.9 Construye un programa que, al recibir un arreglo unidimensional de tipo entero que contiene calificaciones de examenes de alumnos, calcule lo siguiente: a) ‘La media aritmética. Esta se calcula como la suma de los elementos entre el ntimero de elementos. b) La varianza. Esta se calcula como la suma de los cuadrados de las desvia- ciones de la media, entre el ntimero de elementos. ) La desviaci6n esténdar. Se calcula como la raiz cuadrada de la varianza. d) La moda. Se calcula obteniendo el nimero con mayor frecuencia. Dato: ALu(N} (arreglo unidimensional de tipo entero de N elementos, 1 < Ns 100). Programa 5.14 #include #include I* Estadistico El programa, al recibir como dato un arreglo unidimensional de enteros | ——|."que contiene calificaciones, calcula la media, la varianza, la ‘desviacion estandar y la moda. */ F _—— ~ re — = f ~ Problemas resueltos 205 | eo =a = = f const int MAX = 100; void Lectura(int *, int); float Media(int *, int); float Varianza(int *, int, float); 1* Prototipos de funciones. */ float Desviacion(float) ; void Frecuencia(int *, int, int *); int Moda(int *, int); void main(void) { int TAM, MOD, ALU[MAX], FRE[11] = {0}; float MED, VAR, DES; do { printf (*Ingrese el tamafo del arreglo: scant (*%d", &TAM) ; a | while (TAM > MAX || TAM < 1); | [* Se verifica que el tamafio del arreglo sea correcto. */ Lectura(ALU, TAM); | MED = Media(ALU, TAM); VAR = Varianza(ALU, TAM, MED); DES = Desviacion(VAR); Frecuencia(ALU, Tall, FRE); Mop = Moda(FRE, 11); printf ("\nlledia: %.2f", MED); printf (*\nVarianza: %.2f", VAR) printf (*\nDesviacion: %.2f", OES); | print (\nlioda: a" , WOD) ; , | void Lectura(int A[], int T) J* La funcién Lectura se utiliza para leer un arreglo unidimensional de T “elementos de tipo entero. */ { int I; for (1=0; I {* Apuntadores y arreglos */ void main(void) { int X= 5, Y= 8, V5] = (1, 3, 5, 7, 9}; int “AY, *AX; AY = 8Y; X= tAY; vay = VIB] + VI21; printf ("\nx="d Yekd — V[O]=8d VI1]=8d Vi2|=%d VI3]=%0 Vial=%d", x Y, Viol, It], Vi2I, VI31, veal); AX = BVIVEO}*VI1]]; X = FAX; Y= *AX* VENI; *aX = AY - 33 printf ("\nx=xd Youd VEO]=8d Vt ]=80 v(2i=ad vis VEa}=ad", x, Y, VQ], VEtl, V2}, VISI, EAI): } Compara los resultados que hayas obtenido con los que se presentan a conti- nuacién: XB Y=12 V(QJ=1V[1]=3 V[2I=5 VI3]=7—VI4]=9 Xe7Ye21Vf@}=1 Vit Vi2i=5 Vi3]=18 vi4i-9 r l Problema PR5.11 Analiza cuidadosamente el siguiente programa y obtén los resultados que se ge- neran al ejecutarlo. Programa 5.16 #include J* Apuntadores y arreglos */ } 208 Capitulo 5. Arreglos unidimensionales { int Vi[4}= (2, 3, 4, 7h, V2{4]= (6}5 int *Ax, *A) AX = 8V1[3]5 AY = aV2[2]; Vitveto}-Vi[2}]= AY; *AY= TAX - VI[015 Printf("\nVi[0]=%d V1[1]=%d VI[2]=%d VI[3]=%d \tV2[0]=8d V2 1]=%d V212]=8d va[s]=d", VI{0),Vif1],V1{2) ,V1[3] ,V2{0},V2i1] ,Vel2] ,v203]); vat] = ++#Ax; va{si = (*AY) ++ YAK 45 25 printf("\nVi[O]=%d VI[1]=%d V1[2]=%d VI[3]=%d \tVv2[@]=Rd V2[1]=%d V2[2]=%0 va[a]=%d", V1[0],VAl1),V1[2],V1(3] ,V2[O] ,V2t1] ,V2(2] ,V2t3]); ‘Compara los resultados que hayas obtenido con los que se presentan a conti- nuacién: haces Vitt]=3° Vi[2]=0 V1[3]=7 Vifo1=2_VIL11=3_Vil2|=0_v1ia}=10 Problema PR5.12 Analiza cuidadosamente el neran al ejecutarlo. Programa 5.17 = i | #include /* Apuntadores y arreglos */ void main(void) { Ant Vi[4] = (1, 3, 5, 7H, V2l4l= {2,4}5 int AX, *AY; AX = aV1[2]; AY = av2(2]; ve(2} = *(AX+1); v2[3} = *AX; AX = AK + 45 Vito] = *axs” printf ("\nvi[O]=%4 Vi[1]=%d VU[2}=ad Vt v2[o}=6 v2i1]=0 ve(2j=5 v2{3}=0 vaiol=6 V2tt}=8 vat2i=6 vatsi=8 iguiente programa y obtén los resultados que se ge~ [S]}-hd \tv2[o]=8d v2[1]=80 _ Problemas resueltos—— — 209) i [vapor virsy,vecar,vatat, vores, vert1,v2re vara; P| vila) = ta | Vi[1] = --AY3 | AX = AK +43 VII3] = *AX; printf ("\nVi[O]=8d Vi[1]=%d Vi[2]=ad Vi[a]=%d \tv2[0]=kd V2[1]=%d val2j=sd Ve[s]=Sd", Vi{O],V1(1] ,VI[2},V1 {3} ,V2C0] ,V2t1],V2c2) 2031); Compara los resultados que hayas obtenido con los que se presentan a conti- nuacién: 7 vatay=2 vatt val2i=7 v2[a}=5 VifO]=7 Vi[1]=3. VIE2]=5 vats: | Vtlo]=7, Vi(1]=6 vi[2]=7 v1[a}=basura v2[ol=2 v2r1}=4 Vo[2I=6 vel3]=5 Problemas suplementarios Nota: Todos los problemas deben ser resueltos con la ayuda de funciones. Problema PS5.1 Escribe un programa que, al dar como dato un arreglo unidimensional de nimeros enteros, determine cudntos de ellos son positivos, cudntos negativos y cudntos nulos. Dato: vec{N} (arreglo unidimensional de tipo entero de N elementos, 1 < N < 100) Problema PS5.2 Escribe un programa que reciba como entrada un arreglo unidimensional ordena- do de N enteros y obtenga como salida ese mismo arreglo pero sin los elementos repetidos. Dato: véC(N} (arreglo unidimensional de tipo entero de N elementos, 1 < N < 100). {210 Capitulo 5. Arreglos unidimensionales Problema PS5.3 Escribe un programa que almacene en un arteglo unidimensional los primeros 100 néimeros de Fibonacci e imprima el arreglo correspondiente. Problema PS5.4 Escribe un programa que inserte y elimine elementos en un arreglo unidimensio- nal de tipo entero que se encuentre desordenado. Considera que no se pueden in- sertar elementos repetidos. Datos: VEC(N}, ELE Donde: vec es un arreglo unidimensional de tipo entero den elementos, 1 < N < 100, y ELE una variable de tipo entero que expresa el ntimero que se va a insertar o eliminar. Problema PS5.5 Escribe un programa que inserte y elimine elementos en un arreglo unidimensio- nal de tipo entero que se encuentre ordenado en forma creciente. Toma en cuenta que no se pueden insertar elementos repetidos. Datos: VEC(N], ELE Donde: vec es un arreglo unidimensional de tipo entero de N elementos, 1 < N < 100, y ELE una variable de tipo entero que representa el ntimero que se va a insertar o eliminar, Problema PS5.6 En un arreglo unidimensional de tipo real se almacenan las calificaciones de un grupo de w alumnos que presentaron un examen de admisién a una universidad. Escribe un programa que calcule e imprima lo siguiente: a) El promedio general del grupo. b) El porcentaje de alumnos aprobados (todos aquellos alumnos cuyo puntaje su- pere los 1300 puntos). c) El néimero de alumnos cuya calificacién sea mayor o igual a 1500. a Dato: ALU{N] (arreglo unidimensional de tipo real de N elementos, 1 < N < 100). Problemas resueltos 211 Problema PS5.7 En un arreglo unidimensional de tipo real se tienen almacenadas las toneladas mensuales de cereales cosechadas durante el afio anterior en una estancia de la pampa Argentina. Escribe un programa que calcule e imprima lo siguiente: a) El promedio anual de toneladas cosechadas. b) {Cudntos meses tuvieron una cosecha superior al promedio anual? c) {En qué mes se produjo el mayor mimero de toneladas? {Cusntas fueron? Dato: cos(12] (arreglo unidimensional de tipo real de 12 elementos). Problema PS5.8 Construye un programa en C que, al recibir como datos dos arreglos unidimen- sionales de tipo entero, desordenados, de n y w elementos respectivamente, genere un nuevo arreglo unidimensional ordenado en forma descendente de N+ elementos de tipo entero, mezclando los dos primeros arreglos. Datos: VEC1[N}, VEC2[M] Donde: vect y vec son dos arreglos unidimensionales de tipo entero de Ny # elementos, respectivamente, 1 < N < 100, 1 t primera columna segunda columna enésima columna Ficura 6.1 Representacién gréfica de un arreglo bidimensional. i 6.3 Declaracién de arreglos bidimensionales 215) En la figura 6.2 se muestra el arreglo bidimensional A que contiene 18 elementos de tipo entero. Observa que el arreglo tiene tres filas y seis columnas. A cada ele- mento del arreglo se accede por medio de dos {ndices. El primero se utiliza para las filas y el segundo para las columnas. Si queremos acceder al elemento de la primera fila y la primera columna, debemos escribir A(0) {0); si en cambio queremos acceder al quinto elemento de la primera fila, debemos escribir A{0}{4]. El valor de A[1){5] es 4, el valor de A[21{1 + 2] es 0, el resultado de A(2][21 + A(1]{5] es 9, y el resultado de AlO}[4] * AL2}[1] es -6. A[O}O} AfOJ[1] AfO}[2] A[O}[3} AlO}{4] ALO]ES] a 4 oboo4 8 6 4 1 2 or 3 0 4 2 4 A 2 3 5) 0 2 1 —! t ft tf ie ol AIO] AZI0] ARIZ) AIG) ARI4] Al2I(5) Undices y componentes de un arreglo bidimensional, 6.3. Declaracion de arreglos bidimensionales El espacio que los arreglos ocupan en memoria se reserva en el momento de realizar la declaracién de los mismos. A continuacién presentamos diferentes formas de declarar arreglos, con su explicacién correspondiente. void main(void) { Ant A(5]{10]; /* Declaracién de un arreglo bidimensional de tipo entero de § filas y 10 colunnas. */ float 8{5][5]; /* Oeclaracién de un arreglo bidimensional de tipo real de § filas y 5 colunnas, */ [216 Capitulo 6. Arreglos multidimensionales Una vez que se definen los arreglos, sus elementos pueden recibir los valores a través de miiltiples asignaciones, o bien, como ocurre frecuentemente en la précti- ca, por medio de un ciclo y la lectura correspondiente de los valores. Analicemos el siguiente ejemplo. Evempto 6.1 Escribe un programa en C que, al recibir como dato un arreglo bidimensional cuadrado de tipo entero de dimensién 10, imprima la diagonal de dicha matriz, Dato: waT{10} {10} (arreglo bidimensional de tipo entero que almacena 100 elementos). Programa 6.1 #include J* Diagonal principal. El programa, al recibir como dato una matriz de tipo entero, escribe 1a diagonal principal. */ const int TAM = 10; void Lectura(int []| TAM], int); /* Prototipo de funciones. */ void Inprime(int [] [TAM], int); J* Observa que siempre es necesario declarar el nimero de columnas. Si no lo “haces, el compilador marcara un error de sintaxis. */ void main(void) { int MATL TAM) [TAM] ; Lectura(MAT, TAM) | Inprime(NAT, TAM) ; void Lectura(int A[]{TAM], int F) * La funcién Lectura se utiliza para leer un arreglo bidimensional. observa seque sélo se debe pasar como parénetro el numero de filas ya que 1a matriz wees cuadrada. */ { int T, Js for (1-0; 1 J* Suna matrices. El programa, al recibir cono datos dos arreglos bidimensionales del mismo ‘etamafio, calcula 1a suma de ambos y la almacena en un tercer arreglo ‘ebidimensional. */ const int MAX = 50; I* Prototipo de funciones. */ void Lectura(int [](MAX], int, int); void Suma(int {)(MAX}, imt [][MAX], int [][MAX], int, int); void Inprime(int [](MAX], int, int); void main(void) int MA[MAX] [MAX], MB[MAX] [MAX] , NCI MAX] [MAXI ; /* Declaracion de los tres arreglos * int FIL, COL} do { printf(*Ingrese ¢1 niimero de filas de los arreglos: "}; scanf(*%d", &FIL); while (FIL> MAX || FIL< 1); /* Se verifica que el numero de filas sea correcto. */ do { printf ("Ingrese el numero de colunnas de los arreglos: ") scanf("%d", &COL); } while (COL > MAX || COL < 1); J* Se verifica que el nimero de colunnas sea correcto printf("\nLectura del Arreglo MA\n"); Lectura(WA, FIL, COL); | Nh iene enema {220 Capitulo 6. Arreglos multidimensionales | printf ("\nLectura del Arreglo MB‘ Lectura(WB, FIL, COL); | Suma (MA, MB, MC, FIL, COL); printf("\ntmpresién del Arreglo MC\n"); Imprime (MC, FIL, COL); Void Lectura(int A[)[MAX], int F, int ¢) | J* La funcion Lectura se utiliza para leer un arreglo bidimensional entero de F wfilas y ¢ colunnas. */ { int 1, J; for (1-0; I A[IJ(I0} + APIO} A[2}(0110) LIL 3 A Ficura 6.6 t Indices y componentes de un arreglo tridimensional. 16.5. Declaracién de arreglos tridimensionales i i La declaracién de los arreglos tridimensionales, y en general de aquellos de mas de dos dimensiones, es similar a la de los arreglos bidimensionales. El espacio que los arreglos ocupan en memoria se reserva en el momento de realizar la declaracién | de los mismos. Observemos a continuacién las siguientes declaraciones. void main(void) { int A[5](10][3]; J* Declaracién de un arreglo tridimensional de tipo ‘entero de 5 filas, 10 columnas y 3 planos de profundidad. */ float 8(5)(5]{6]; /* Oeclaracién de un arreglo tridimensional de tipo wereal de 5 filas, 5 columnas y 6 planos de profundidad. */

También podría gustarte