Fundamentos de Informática ETSID Tema 4: Estructuras de Repetición (Bucles). Departamento de Sistemas Informáticos y Computación Universidad Politécnica de Valencia Índice 1. 2. 3. 4. 5. 6. 7. 8. Introducción Bucle for Bucle while Bucle do-while Bucle infinito Utilización de cada tipo de bucle Ficheros y bucles Bucles anidados 1 Objetivos z z z z Entender los conceptos de la repetición de instrucciones Conocer funcionamiento y utilización de sentencias while, do...while y for Combinar estructuras de repetición Reforzar conocimientos adquiridos en temas anteriores 1. Introducción Bucle: instrucción que permite repetir otra instrucción o un conjunto de instrucciones (bloque) un número de veces. Instrucción 1 Instrucción 2 Instrucción 3 2 Finalización de un bucle El bucle puede repetirse: z Un número fijo de veces. Repetir 100 veces Leer un número Sumarlo a la variable total z Otras veces finalizará cuando se cumpla una condición. Repetir hasta que la variable total llegue a 10.000 Leer un numero Sumarlo a la variable total Partes de un bucle Repetir 100 veces Cabecera del bucle Leer dos números enteros Sumarlos Cuerpo del bucle Restarlos A cada ejecución del bloque de instrucciones del cuerpo del bucle se le llama iteración. 3 Tipos de bucles for while do-while La diferencia entre ellos depende de: z z La forma de gestionar el número de veces que se repite el bucle. El número mínimo de repeticiones del bucle. Bucle for 4 2. Bucle for for (inicialización; condición; incremento) instrucciones; z z z z z Ejecuta el cuerpo del bucle un número determinado de veces. Necesita una variable de control. Puede ser de cualquier tipo, incluso real. Inicialización: sentencia de asignación que establece el valor inicial de la variable de control del bucle. Condición: expresión relacional que determina cuando finalizará el bucle. Incremento: define cómo cambiará la variable de control del bucle en cada pasada del bucle. Inicialización: le da a la variable i el valor 1. Ejemplo: Condición: debe cumplirse mientras se ejecuta el bucle. for (i=1; i<10; i++) printf(“%d\n”, i); La variable de control del bucle es i Incremento: en cada iteración del bucle la variable i se incrementa en 1. 5 for (inicialización; condición; incremento) instrucciones; z z z Se ejecuta mientras la condición sea cierta. Cuando la condición sea falsa la ejecución del bucle terminará y se reanudará en la instrucción siguiente al bucle. El bucle no se ejecuta si la condición es falsa al entrar en el bucle. Ejemplo ¿Cuál es la salida por pantalla? i=1 i<=5 Falso for (i=1; i<=5; i++) printf(“%d\n”,i); Cierto printf(“%d\n”,i); 1 2 i++ 3 4 5 Resto de Instrucciones 6 Cuerpo del bucle Si el cuerpo del bucle contiene más de una instrucción hay que poner llaves. Muy importante: identación for (i=1; i<=5; i++) { printf(“El valor del contador es: ”); printf(“%d\n”,i); } for (i=1; i<=5; i++) printf(“El valor del contador es: %d\n”,i); Ejemplo ¿Cuál es la salida por pantalla del siguiente bucle for? 1 for (i=1; i<=5; i++) printf(“%d\n”,i); printf(“Fuera: %d\n”,i); 2 3 4 5 Fuera: 6 7 1 Ejemplo for (i=1; i<=10; i++) printf(“i=%d\n”, i); 2 3 4 5 6 1 7 2 8 3 9 4 10 5 for (i=0; i<10; i++) printf(“i=%d\n”, i+1); 6 7 8 9 10 25 Ejemplo for (i=25; i!=200; i=i+25) printf(“%d\n”, i); 50 75 100 125 150 175 a b c d e for (i=’a’; i<=’z’; i++) printf(“%c\n”, i); f g … z 8 Ejemplo for (i=10; i>0; i--) printf(“%d\n”,i); printf(“Valor final: %d\n”,i); 23 21 19 17 15 13 11 Valor final: 9 10 9 8 7 6 5 4 3 2 1 Valor final: 0 for (i=23; i>10; i-2) printf(“%d\n”,i); printf(“Valor final: %d\n”,i); Cuando usar el bucle for z z Se utiliza siempre que se conoce el número exacto de iteraciones antes de ejecutar el bucle Si no se conoce previamente el número de iteraciones, no usar for: z z z Si al menos se debe ejecutar una vez: do..while Si puede no ejecutarse nunca: while Se puede alterar el contenido de variables de control del bucle desde dentro del cuerpo del bucle NO HACERLO: nunca hay que modificar la variable del bucle dentro de éste. 9 Ejemplo: NO SE DEBE HACER ¿Cuál es la salida por pantalla del siguiente bucle for? for (i=1; i<=5; i++) { i++; printf(“%d\n”,i); } printf(“Fuera: %d\n”,i); 2 4 6 Fuera: 7 Ejemplo: NO SE DEBE HACER ¿Cuál es la salida por pantalla del siguiente bucle for? 0 for (i=1; i<=5; i++) { i--; printf(“%d\n”,i); } printf(“Fuera: %d\n”,i); 0 0 0 0 … Bucle infinito 10 Ejemplo: NO SE DEBE HACER ¿Qué hace el siguiente bucle for? for (i=1; i<=10; i++) { scanf(“%d”,&n); if (n>0) printf(“%d\n”,i); else i=11; } printf(“Fuera: %d\n”,i); Lee 10 valores enteros (como máximo). Si alguno de ellos es negativo, finaliza el bucle sin completar la lectura. Los valores positivos los muestra por pantalla. Ejercicio Escribir un programa que solicite al usuario 100 números enteros y muestre la media de los valores introducidos. 11 #include <stdio.h> #define N 100 void main() { int i, num, suma=0; Usar una constante para controlar el número de repeticiones del bucle for (i=0; i<N; i++) { Acordarse del printf(“Dame un número: ”); casting scanf("%d", &num); suma = suma + num; } printf("La media es %f\n", suma/(float)N); } Ejercicio #include <stdio.h> ¿Cuál es la salida por pantalla? void main() 0 2 4 6 8 { 0 1 2 3 4 5 6 7 8 9 3 4 5 6 7 8 9 10 int i; for (i=0; i<10; i++) if (i%2==0) printf ("%d\t", i); printf("\n"); for (i=0; i<10; i++) printf ("%d\t", i); printf("\n"); for (i=3; i<=10; i++) printf ("%d\t", i); } 12 Múltiples variables de control Se pueden utilizar múltiples variables de bucle, condiciones e incrementos, separadas por comas. Ejemplo: for (i=1, j=10; i!=j; i++, j--) printf(“i=%d j=%d\n”, i-1, j+1); Ejercicio Leer 10 números. Si el número leído es el 0, terminar de leer. void main() { int i, valor, es_cero=0; for (i=0; i<10 && es_cero==0; i++) { scanf(“%d”,&valor); if (valor==0) es_cero=1; } } 13 Ejercicio ¿Cuál es la salida de este programa?. j=0; for (i=0; i<=5; i++) j++; printf(“i=%d j=%d\n”, i, j); i=6 j=5 Ejercicio ¿Cuál es la salida de este programa?. for (i=0; i<=5; i++); printf(“i=%d\n”, i); i=6 14 Eliminar partes del bucle Las variables de control, condiciones e incrementos son opcionales. La parte correspondiente se queda en blanco, pero no desaparece el “;”. for (i=1; i!=100; ) scanf(“%d”,&i); x = 0; for (; x<10;) { printf(“%d”, x); x++; } Ejemplo i = 10; for (; i>10; i--) printf(“i=%d\n”, i+1); for (;;) { scanf(“%c”,&x); if (x==’A’) break; } 15 Otros usos Se pueden utilizar partes del bucle for para ejecutar otro tipo de instrucciones. Ejemplo: for (printf(“Empiece a introducir números”); n==6; ) scanf(“%d”, &n); Ejercicio Escribir un programa que solicite al usuario el número de valores a leer. Posteriormente los leerá y mostrará la suma de los números pares por pantalla. 16 #include <stdio.h> void main() { int i, n, suma, numero; printf(“Cantidad de números a leer: ”); scanf(“%d”,&n); suma=0; for (i=0; i<n; i++) { printf(“Dame un número: “); scanf(“%d”,&numero); if (numero%2==0) suma=suma+numero; } printf(“El valor de la suma es: %d\n”, suma); } Ejercicio Modificar el programa anterior para que lea los valores de un fichero “datos.txt”. En la primera línea se encuentra el número de valores. En líneas sucesivas se encuentran los valores. 17 void main() { int i, n, suma, numero; FILE *f; if ((f=fopen(“datos.txt”, “r”))==NULL) printf(“No se puede abrir el fichero.\n”); else { fscanf(f, “%d”,&n); /* Número de valores */ suma=0; for (i=0; i<n; i++) { fscanf(f, “%d”, &numero); /* Siguiente número a sumar */ if (numero%2==0) suma=suma+numero; } printf(“El valor de la suma es: %d\n”, suma); fclose(f); } } Ejercicio Escribir un programa en C que muestre por pantalla la tabla de multiplicar de un numero introducido por teclado. Algoritmo: z z z Pedir el número. Se necesita un valor que cuente de 0 a 10. Poner el contador a cero. Mientras que el contador sea menor o igual a 10: z Mostrar por pantalla el resultado del número multiplicado por el contador. z Incrementar el contador. 18 #include <stdio.h> void main() { int num, contador; prinft(“Déme el número: ”); scanf(“%d”,&num); /* Obtener el número */ for (contador=0; contador<=10; contador++) printf(“%d × %d = %d\n”, num, contador, num*contador); } Bucle while 19 3. Bucle while z Ejecuta el cuerpo del bucle mientras se cumple la condición (condición cierta). while (condición) instrucción; z z Instrucción: simple o bloque de instrucciones. Condición: expresión, siendo cierto cualquier valor <> 0. while (condición) instrucción; Condición Falso z z z El bucle se ejecuta mientras la condición es cierta. Cuando la condición sea falsa el control en el programa pasa a la línea siguiente después del código del bucle. El bucle puede no ejecutarse si la condición resulta ser falsa al inicio del bucle. Cierto Instrucción Resto de Instrucciones 20 Ejercicio Leer números hasta que la suma de estos sea mayor o igual a 1000. total=0; while (total<1000) { printf(“Dame un número: “); scanf(“%d”,&n); total = total + n; } Ejercicio i = 1; while (i <= 5) { printf(“%d\n”,i); i++; } ¿Qué hace este bucle? 1 2 3 4 5 for (i=1; i<=5; i++) printf(“%d\n”, i); 21 Ejercicio Calcular la suma de los números introducidos desde teclado. El programa se detendrá cuando se introduzca un cero. No se conoce cuantas veces se debe ejecutar el bloque de instrucciones del while. La expresión del while se convierte normalmente en una comprobación del valor del contador. En este caso no hay contador y es el valor del número introducido el que determina el final del bucle. Algoritmo: z z z Inicializar la variable de acumulación. Pedir el número. Mientras que el número sea distinto de cero: z z z Acumular el valor del número. Leer nuevo número. Imprimir el resultado. 22 #include <stdio.h> Versión 1: se inicializa la variable void main() número fuera del bucle para que entre { la 1ª vez. Ese valor nunca se usa. int n, suma, numero; suma=0; /* Inicializar variable acumulador */ numero = 1; /* Se inicializa a cualquier valor distinto de 0 */ while (numero!=0) { printf(“Déme un número: “) scanf(“%d”, &numero); suma=suma+numero; /*Acumular número*/ } printf(“La suma total es: %d\n”, suma); } #include <stdio.h> void main() { int n, suma, numero; Versión 2: se solicita el primer valor fuera del bucle. Dentro del bucle primero hay que sumar el valor, para que el valor de fuera no se pierda. suma=0; /* Inicializar variable acumulador */ printf(“Déme un número: “); /* Lee un número fuera del bucle */ scanf(“%d”, &numero); while (numero!=0) { suma=suma+numero; /*Acumular número*/ printf(“Déme un número: “) scanf(“%d”, &numero); } printf(“La suma total es: %d\n”, suma); } 23 Ejercicio Escribir un programa que lea números de teclado hasta que el número introducido sea negativo. El programa debe obtener la suma de todos los valores. Los valores negativos no se suman. Versión 1: se inicializa la variable #include <stdio.h> número fuera del bucle para que entre void main() la 1ª vez. Ese valor nunca se usa. { int n, suma=0, numero; /* Inicializa el número para que entre la primera vez en el bucle */ numero =0; while (numero >=0) { printf(“Déme un número: “); scanf(“%d”,&numero); /* Lee el siguiente número a sumar */ /*Sólo se suma si el valor es correcto */ if (numero>=0) suma=suma+numero; } printf(“El valor de la suma es: %d\n”,suma); } 24 #include <stdio.h> void main() { int n, suma=0, numero; printf(“Déme un número: “); scanf(“%d”,&numero); Versión 2: se solicita el primer valor fuera del bucle. Dentro del bucle primero hay que sumar el valor, para que el valor de fuera no se pierda. No hace falta el if, porque ya se comprueba en la condición del bucle. while (numero >=0) { suma=suma+numero; printf(“Déme un número: “); scanf(“%d”,&numero); } printf(“El valor de la suma es: %d\n”,suma); } Bucle do-while 25 4. Bucle do-while z Ejecuta el cuerpo del bucle mientras se cumple la condición (condición cierta). do { instrucción; } while (condición); z z z Instrucción: sentencia simple o bloque de sentencias. Siempre lleva llaves, aunque haya una única instrucción. Condición: expresión, siendo cierto cualquier valor <> 0. Termina siempre en ; (a diferencia del bucle while). do { instrucción; } while (condición); Instrucción Cierto Condición z z z Comprueba su condición al final del bucle (condición de salida). El bucle siempre se ejecuta al menos una vez. Se ejecuta mientras se cumpla la condición (sea cierta). Falso Resto de Instrucciones 26 Ejemplo Leer números hasta que el valor introducido sea un 0. do { printf(“Dame un valor: “); scanf(“%d”,&valor); } while (valor!=0); z z z Se ejecuta el bloque de instrucciones al menos una vez. Aunque es parecido al while no siempre existe una correspondencia entre ellos. Especialmente indicado para validar datos de entrada (se le solicita un dato al usuario), sobre todo para menús. 27 Ejercicio Solicitar al usuario un número entre el 10 y el 20 (ambos inclusive). • Solicita un valor. do • Si el valor es correcto (está { entre 10 y 20): printf(“Dame un valor: “); • El bucle termina. scanf(“%d”,&valor); if (valor<10 || valor>20) • Si es incorrecto: printf(“Valor incorrecto\n”); • Solicita de nuevo el } valor. while (valor<10 || valor>20); • Da un mensaje de error. Ejercicio Escribir un programa que muestre la tabla de multiplicar de un valor solicitado al usuario. El valor pedido al usuario comprendido entre 1 y 9. debe estar Debe comprobarse antes de mostrar la tabla que el valor introducido es correcto. 28 #include <stdio.h> void main() { int num, contador; /* Solicita el valor. El bucle termina cuando el usuario escribe un valor entre 1 y 9. */ do { prinft(“Dame un número entre 1 y 9: ”); scanf(“%d”, &num); } while ((num<1) || (num>9)); /* Escribe la tabla de multiplicar. */ for (contador=0; contador<=10; contador++) printf(“%4d × %4d = %4d\n“, num, contador, num*contador); } Ejercicio Escribir un programa que muestre el menú de un cajero automático y lea la opción elegida. Si la opción elegida por el usuario es incorrecta se debe repetir el menú hasta que teclee una opción correcta. Las opciones posibles son: 1. 2. 3. 4. Extraer dinero Ingresar dinero Últimos movimientos Salir 29 #include <stdio.h> void main() { int opcion; Repite el bucle hasta que selecciona una do opción correcta: { valida la lectura printf(“1.- Extraer dinero\n”); printf(“2.- Ingresar dinero\n); printf(“3.- Últimos movimientos\n); printf(“4.- Salir del menú\n" ); scanf( "%d", &opcion ); } while (opcion<1 || opción>4); } Ejercicio Escribir un programa que muestre el menú de una máquina de café. Las opciones posibles son: A. B. C. D. E. F. Café sólo Café cortado Café con leche Capuchino Té Apagar máquina 30 #include <stdio.h> void main() { char opcion; do { prinft(“Indique opción deseada:\n”); prinft(“A. Café sólo\nB.- Café cortado\nC.- Café con leche\n D.- Capuchino\nE.- Té\nF.- Apagar máquina\n”); scanf(“%c”,&opcion); switch (toupper(opcion)) { case ‘A’: printf(“Café sólo”); break; case ‘B’: printf(“Café cortado”); break; case ‘C’: printf(“Café con leche”); break; case ‘D’: printf(“Capuchino”); break; case ‘E’: printf(“Té”); break; case ‘F’: printf(“Salir”); break; default rintf (“Opción no valida”); } } while (opcion!=‘F’); } Repite el bucle hasta que selecciona la opción de salida 5. Bucle infinito z z z Bucle que se repite eternamente. Esto ocurre porque nunca deja de cumplirse la condición del bucle Ejemplos: for ( ; ; ) printf(“Hola\n”); n=0; do { printf(“Hola\n”); } while (n==0); n=0; while (n==0) { printf(“Hola\n”); } 31 Ejemplo Leer 10 números y sumarlos. ¿Hace lo que se pide? void main() { int n, suma, numero; prinft(“Cantidad de números a leer: ”); El valor de n nunca scanf(“%d”,&n); cambia Ö BUCLE suma=0; INFINITO while (n!=0) { printf(“Valor del número: “); scanf(“%d”,&numero); ¿Cómo suma+=numero;n--; solucionarlo? } printf(“El valor de la suma es: %d\n”, suma); } 6. Utilización de cada tipo de bucle Depende de: z z Número de iteraciones Bucles con condición de entrada o de salida 32 Número de iteraciones Nº mínimo de iteraciones Nº máximo de iteraciones while 0 Variable do ... while 1 Variable for 0 Fijo Condición de entrada o salida z Bucles con condición de entrada: evalúan la condición antes de entrar al bucle (for y while). z z z Necesarios cuando el bucle puede no ejecutarse dependiendo de cierta condición. Ante la duda, son más legibles con condición de entrada. Bucles con condición de salida: evalúan la condición después de ejecutar el cuerpo del bucle, por lo que siempre ejecutan al menos una vez el cuerpo (do-while). 33 Bucles con condición de entrada: for y while z z Funcionalmente son idénticos. Se usa for cuando: z z z Se inicializa y actualiza una variable (contador). Se conoce de antemano el número de iteraciones. Se usa while cuando: z La condición del bucle depende de condiciones que no sea el incremento de variables. Ejemplo /* Suma los 100 primeros números enteros positivos */ suma=0; for (cont = 1; cont <= 100; cont++) suma += cont; /* Suma números hasta que el total sea >= 1000 */ suma=0; while (suma<1000) { printf(“Dime un número:”); scanf(“%d”,&n); suma += n; } 34 Conversión de bucles while ⇒ for while (condición) cuerpo; for ( ; condición; ) cuerpo; for ⇒ while for (inicializar; condición; actualizar) cuerpo; inicializar; while (condición) { cuerpo; actualizar; } do instrucción; while (condición) { instrucciones; } do-while ⇒ while { instrucciones; } while (condición) ; Ejercicio Escribir un programa que lea un número entre 1 y 100 (el programa debe asegurarse que el número es correcto). Después, debe calcular el factorial del número. Decidir cual es el tipo de bucle más apropiado. 35 #include <stdio.h> void main() { char N, i; double Factorial; #include <stdio.h> void main() { char N, i; double Factorial; /*Bucle de validación del número leído */ printf (“Número (0 –100): ”); scanf(“%d”, &N); while ((N<0) || (N>100)) { printf (“Número (0 –100): ”); scanf(“%d”, &N); } /*Bucle de validación del número leído */ do { printf (“Número (0 –100): ”); scanf(“%d”, &N); } while ((N<0) || (N>100)); /*Bucle de cálculo de factorial*/ i = 1; Factorial = 1; while (i<=N) { Factorial *= i; i++; } printf (“El factorial de %d es %g \n”, N, Factorial); } /*Bucle de cálculo de factorial */ Factorial = 1; for(i=1;i<=N; i++) Factorial *= i; printf (“El factorial de %d es %g \n”, N, Factorial); } Mejor opción Ejercicio Leer un número entero (long int) y decir si es capicúa. Ejemplo: 12321 es capicúa 4567 no es capicúa 3 es capicúa 36 Algoritmo: z z Pedir un número. Mientras queden cifras. z z z Quitar la última cifra. Poner la última cifra como primera de un nuevo número. Si el nuevo número y el antiguo son iguales: capicúa. #include <stdio.h> void main() { long int valor, nuevo=0, aux_valor; int resto; printf("Introduce un valor: "); scanf("%ld", &valor); aux_valor = valor; while (aux_valor>0) { /* Toma la última cifra */ resto = aux_valor % 10; aux_valor = aux_valor / 10; /* La pone como primera de un nuevo número */ nuevo = (nuevo * 10) + resto; } if (valor == nuevo) printf("Capicúa\n"); else printf("No es capicúa\n"); } 37 while (aux_valor>0) { resto = aux_valor % 10; aux_valor = aux_valor / 10; nuevo = (nuevo * 10) + resto;} valor resto aux_valor nuevo 12321 - - 0 12321 - 12321 0 12321 1 1232 0 x 10 + 1 = 1 12321 2 123 1 x 10 + 2 = 12 12321 3 12 12 x 10 + 3 = 123 12321 2 1 123 x 10 + 2 = 1232 12321 1 0 1232 x 10 + 1 = 12321 12321 1 0 12321 7. Ficheros y bucles z z z Los ficheros finalizan siempre con el carácter EOF. La función fscanf retorna EOF cuando, realizando la lectura, uno de los datos que ha leído es EOF. Para leer el contenido de un fichero se puede leer hasta que se encuentre EOF. while (fscanf(f, “%d%f”, &a, &b)!=EOF) printf(“%d %f\n”, a, b); 38 Ejercicio Leer caracteres del fichero “a.txt”. Escribir sólo uno de cada 3 caracteres, en el fichero “b.txt”. abcdefg adg EOF a.txt EOF b.txt void main () { int i=0; char c; FILE *e, *s; if ((e=fopen(“a.txt”, “r”))==NULL) printf(“No se puede abrir el fichero a.txt\n”); else { /* 1 */ if ((s=fopen(“b.txt”, “w”))==NULL) printf(“No se puede abrir el fichero b.txt\n”); else { /* 2 */ 39 while (fscanf(e, “%c”, &c)!=EOF) { if (i%3==0) fprintf(s, “%c”, c); i++; } fclose (s); } /* 2 */ fclose (e); } /* 1 */ } while (fscanf(e, “%c”, &c)!=EOF) { if (i==0) fprintf(s, “%c”, c); i++; if (i==3) i=0; } Otra versión 40 8. Bucles anidados z z z Anidar: incluir un bucle dentro de otro bucle. Cada vez que ejecuta el bucle externo una iteración, se ejecutan todas las iteraciones del bucle externo. Puede anidarse cualquier tipo de bucle, no es necesario que sean del mismo tipo. Ejemplo: for (i=0; i<10; i++) for (j=0; j<30; j++) .... Anidación Correcta Incorrecta El bucle más interno debe estar incluido completamente dentro del externo (no deben existir solapamientos). 41 Ejercicio for (i=0; i<3; i++) { for (j=0; j<5; j++) printf(“%d ”, j+1); printf(“\n”); } ¿Salida por pantalla? 12345 12345 12345 Ejercicio for (i=0; i<5; i++) { for (j=0; j<=i; j++) printf(“%d ”, j+1); printf(“\n”); } ¿Salida por pantalla? 1 12 123 1234 12345 42 Ejercicio for (i=0; i<5; i++) { for (j=1; j<=5-i; j++) printf(“%d ”, j); printf(“\n”); } ¿Salida por pantalla? 12345 1234 123 12 1 Ejercicio Se dispone de los datos sobre las edades y coeficientes de inteligencia (CI) de los hijos de varias familias. Escribir un programa en C que lea el número de familias y para cada familia lea el número de hijos así como la edad y el CI de cada hijo, y calcule: z z z z El número máximo, mínimo y promedio de hijos por familia. El CI máximo, mínimo y promedio de todos los hijos. El CI promedio de los hijos menores de 6 años. El CI promedio de los hijos mayores de 6 años. 43 Algoritmo: z z Pedir el número de familias Para cada familia: z z z Pedir el número de hijos Cálculos de máximo y mínimo de nº de hijos Para cada hijo: Pedir el CI y edad del hijo Cálculos de valores solicitados Nota: z INT_MAX: Constante incluida en limits.h que da el mayor valor entero representable. z INT_MIN: menor representable. valor entero 44 #include <stdio.h> #include <limits.h> void main() { int i, j, total_hijos=0, max_hijos=0, min_hijos=INT_MAX, max_ci=0, min_ci=INT_MAX, menores6=0, mayores6=0, ci_menores6=0, ci_mayores6=0, familias, hijos, edad, ci, total_ci=0; printf("Número de familias: "); scanf("%d",&familias); for (i=1; i<=familias; i++) { printf("Número de hijos de la familia %d: ",i); scanf("%d",&hijos); /* Máximo y mínimo de hijos por familia */ if (hijos>max_hijos) max_hijos = hijos; if (hijos<min_hijos) min_hijos = hijos; /* Total de hijos para calcular la media de hijos por familia */ total_hijos += hijos; 45 for (j=1; j<=hijos; j++) { printf("Edad del hijo %d: ", j); scanf("%d",&edad); printf("CI del hijo %d: ", j); scanf("%d",&ci); /* CI máximo y mínimo */ if (ci>max_ci) max_ci = ci; if (ci<min_ci) min_ci = ci; /* CI total de los hijos para la media */ total_ci += ci; /* CI de menores y mayores de 6 años */ if (edad<6) { ci_menores6 += ci; menores6++; } else { ci_mayores6 += ci; mayores6++; } } /* For de hijos por familia */ } /* For de familias */ 46 if (familias>0) printf("Hijos por familia, máximo: %d, mínimo: %d, promedio: %f\n", max_hijos, min_hijos, total_hijos/(float)familias); if (total_hijos>0) printf("CI, máximo: %d, mínimo: %d, promedio: %f\n", max_ci, min_ci, total_ci/(float)total_hijos); if (menores6>0) printf("Promedio, menores 6: %f”, ci_menores6/(float)menores6); if (mayores6>0) printf("Promedio, mayores 6: %f\n", ci_mayores6/(float)mayores6); } Ejercicio Calcular y para una n y x dadas por el usuario: 1 ⎛ x − 1⎞ y=∑ ⎜ ⎟ i =1 i ⎝ x ⎠ n i 47 #include <stdio.h> Versión 1: con bucles anidados. void main () { int n, i, j; float x, y=0, aux_valor, termino, valor; printf("Dame el número de términos: "); scanf("%d", &n); printf("Dame el valor x: "); scanf("%f", &x); /* Cálculo de la parte constante del sumatorio */ valor = (x-1)/x; for (i=1; i<=n; i++) { /* Cálculo de ((x-1)/x)i */ aux_valor=1; for (j=1; j<=i; j++) aux_valor = aux_valor * valor; /* Cálculo del término */ termino = aux_valor / (float)i; /* Sumar el término a y */ y = y + termino; } printf("y=%f\n",y); } 48 #include <stdio.h> Versión 2: sin void main () bucles anidados. { int n, i; float x, y=0, aux_valor=1, termino, valor; printf("Dame el número de términos: "); scanf("%d", &n); printf("Dame el valor x: "); scanf("%f", &x); valor = (x-1)/x; /* Cálculo de la parte constante del sumatorio */ for (i=1; i<=n; i++) { aux_valor = aux_valor * valor; termino = aux_valor / (float)i; y = y + termino; } printf("y=%f\n",y); } #include <stdio.h> #include <math.h> void main () { int n, i; float x, y=0, termino, valor; Versión 3: sin bucles anidados y con pow printf("Dame el número de términos: "); scanf("%d", &n); printf("Dame el valor x: "); scanf("%f", &x); valor = (x-1)/x; /* Cálculo de la parte constante del sumatorio */ for (i=1; i<=n; i++) { termino = pow(valor,i) / (float)i; y = y + termino; } printf("y=%f\n",y); } 49