CICLOS (while y for)

    Escribe un programa que lea dos números enteros y escriba todos los números mayores que el primero y menores que el segundo

    Ingresa el primer número: 38

    Ingresa el segundo: 45

    Los números son: 39 40 41 42 43 44

    Muchas gracias por usar este programa

    Un intento (incorrecto) de solución es:

  1. int a,b;

  2. printf ("Ingresa el primer número :");

  3. scanf (“%d”,&a);

  4. printf ("Ingresa el segundo:");

  5. scanf (“%d”,&b);

  6. print ("Los numeros son");

  7. if (a+1<b) printf (“%d\n”,a+1);

  8. if (a+2<b) printf (“%d\n”,a+2);

  9. if (a+3<b) printf (“%d\n”,a+3);

  10. if (a+4<b) printf (“%d\n”,a+4);

  11. if (a+5<b) printf (“%d\n”,a+5);

  12. if (a+6<b) printf (“%d\n”,a+6);

  13. if (a+7<b) printf (“%d\n”,a+5);

  14. if (a+8<b) printf (“%d\n”,a+6);

  15. ... etcétera

    Flujo de un programa

    Hasta ahora todos los programas que hemos visto se caracterizan por el hecho de que las instrucciones se van ejecutando en orden y una sola vez. Esto impide realizar un programa como el queremos hacer.

    Sin embargo, C, al igual que muchos otros lenguajes, permite repetir una cierta cantidad de instrucciones mientras una condición se cumpla.

    Esta instrucción de control de flujo se llama while, se esquematiza en la figura 1 y su sintaxis es:

    while (condicion) {

    instrucciones;

    }

    while evalúa la condición entre paréntesis y si esta es verdadera, ejecuta todas las instrucciones entre los paréntesis { }. Cuando ha ejecutado la última instrucción, vuelve a evaluar la condición. El proceso se repite hasta que al terminar de ejecutar las instrucciones se evalúa la condición y esta es falsa.

    Figura 1

    En caso que sólo se repita una sola instrucción, se pueden eliminar los paréntesis

    while (condicion)

    instrucción;

    Un ejemplo

    Un primer ejemplo de while se ve en el siguiente programa:

  16. int a,b,i;

  17. printf ("Ingresa el primer número: ");

  18. scanf(“%d”,&a);

  19. printf ("Ingresa el segundo:");

  20. scanf(“%d”,&b);

  21. printf ("Los numeros son");

  22. i=a+1;

  23. while (i<b) {

  24. printf (“%d ",i);

  25. i=i+1;

  26. }

  27. printf ("\nMuchas gracias por usar este programa\n");

    Línea(s)

    Ejecución

    16-20

    Se escriben los mensajes en la pantalla y se leen las respuestas del usuario desde el teclado

          Ingresa el primer número: 38

          Ingresa el segundo: 45

          Los números son :

    21

    La variable auxiliar i se va a usar para escribir los valores a<i<b. Se inicializa con a+1, en este caso, 39.

    22


    Si i es menor que b, entonces las instrucciones en las líneas 24 a 25 se ejecutan una vez. Si no es así se sigue la ejecución con la línea 27

    24


    Se escribe el valor de i

          Ingresa el primer número: 38

          Ingresa el segundo: 45

          Los números son : 39

    25


    El valor de i se incrementa en 1

        i __40__

    22


    Cuando se llega al final de las instrucciones, el programa se devuelve a la instrucción while y la condición se reevalúa. En este caso se compara i (40) con b (45). Como i es menor que b la condición es verdadera y nuevamente se ejecutan las líneas 22 a 23

    24-25


    Se escribe el valor de i y luego se incrementa

          Ingresa el primer número: 38

          Ingresa el segundo: 45

          Los números son : 39 40

        i __41__

    22


    Como nuevamente se llego al final de las instrucciones dentro del while, se reevalua la condición del while, que es verdadera y se vuelve a iterar.

    ...

    ...

    24-25

    El programa ha seguido iterando, y se ha entrado a las instrucciones con un valor de i de 44. Se escribe el valor de i y se incrementa

          Ingresa el primer número: 38

          Ingresa el segundo: 45

          Los números son : 39 40 41 42 43 44

        i __45__

    22


    Se vuelve a evaluar la condición del while, en este caso es falsa. C salta inmediatamente a la línea que sigue a las instrucciones del while, es decir, la línea 26

    26


    Se escribe el mensaje de agradecimiento y finaliza el programa

          Ingresa el primer número: 38

          Ingresa el segundo: 45

          Los números son : 39 40 41 42 43 44

          Muchas gracias por usar estre programa

    A veces existen muchas formas de llevar a cabo una tarea. En el caso del programa que acabamos de analizar se puede usar un contador en el ciclo while.

    Un contador es una variable auxiliar que se usa junto a un while para repetir un trozo de código una cierta cantidad de veces. En nuestro ejemplo, sabemos que la cantidad de números entre a y b son b-a-1. Por ejemplo, si a vale 5 y b 8, hay que escribir 8-5-1=2 números, que son 6 y 7.

    Una nueva versión del programa es:

  28. printf ("Ingresa el primer número: ");

  29. ...

  30. printf ("Los numeros son");

  31. i=b-a-1;

  32. while (i>0) {

  33. print (“%d ”,b-i);

  34. i=i-1;

  35. }

    Otra versión, igualmente correcta es:

  36. printf ("Ingresa el primer número: ");

  37. ...

  38. printf ("Los numeros son");

  39. i=b-a-1;

  40. while (i>0) {

  41. i=i-1;

  42. printf (“%d”,b-(i+1));

  43. }

  • Una ejecución del grupo de instrucciones se denomina iteración. Si se ejecuta 10 veces el grupo de instrucciones, se dice que el ciclo tuvo 10 iteraciones.

  • No existe un límite al número de iteraciones que se pueden llevar a cabo en un ciclo.



Ámbito de una variable

El ámbito de una variable es la parte del programa donde la variable es conocida y puede ser usada. Como ya vimos, una variable puede ser usada sólo después que se ha definido. En C, el ámbito de la variable termina cuando se encuentra el paréntesis } que cierra al paréntesis { que precedía la declaración de la variable.

Cualquier referencia a una variable tiene que ser hecha dentro del ámbito de la variable, si no, C no compila el programa.

La siguiente tabla muestra el ámbito de las variables del código de ejemplo:

a

b

c

Código

     

int a;

     

scanf(“%d”,&a);

     

while (a<5) {

     

int b=a*2,c;

     

Printf (“%d”,b);

     

c=a-b-2;

     

Printf (“%d”,c);

     

}



Por ejemplo, sería erróneo usar la variable b ó c fuera del while, ya que al ser declaradas dentro de él, su ámbito termina al cerrarse el bloque de instrucciones.

Las variables que son declaradas dentro de un while pierden su valor al fin de cada iteración, y se declaran nuevamente en la siguiente iteración (como si fueran "variables nuevas").



Indentación del while

Indentar es ordenar un programa agregando espacios al lado izquierdo de las instrucciones. Dos formas de indentar un while son las siguientes:

Parentesis de comienzo de bloque en la misma línea de la cláusula while

while (condición) {

instrucción;

instrucción;

instrucción;

}

Paréntesis de comienzo de bloque en una nueva línea

while (condición)

{

instrucción;

instrucción;

instrucción;

}

En ambos casos se deja un espacio antes del comienzo de cada instrucción dentro del bloque para clarificar el programa. Nunca olvides indentar. Si bien no es obligación hacerlo te puede simplificar bastante entender lo que hace el programa.

Whiles anidados

Es perfectamente posible colocar un while dentro de otro while (while anidado). Como ejemplo, considera el siguiente programa, que escribe la tabla de multiplicar del 1 al 10:



  1. int i=0;

  2. while (i<10) {

  3. int j=0;

  4. while (j<10) {

  5. printf ("%d x %d es %d ",i,j,(i*j));

  6. j++;

  7. }

  8. i++;

  9. }

Break

Errores (demasiado) comunes

Un error muy común es creer que un while puede terminar (salir de) en la mitad del bloque de instrucciones, bastando que una instrucción haga que la condición del while sea falsa, olvidando que lo que realmente ocurre es que C evalúa la condición del while antes de entrar por primera vez al bloque y antes de reentrar en cada iteración.

  1. int i=3;

  2. while (i>1) {

  3. i=i-1;

  4. printf (“%d”,i);

  5. }

  6. printf ("fin");

(1)® (2) ® (3) ® (4) ® (2) ® (3) ® (4) ® (2) ® (6)

y no

(1) ® (2) ® (3) ® (4) ® (2) ® (3) ® (6)

  1. int i,n;

  2. printf ("ingresa n:");

  3. scanf(“%d”,&n);

  4. i=1;

  5. while (i<=n) {

  6. int factorial=factorial*i;

  7. i=i+1;

  8. }

  9. printf ("Factorial %d\n",factorial);

La solución correcta, que solo modifica ligeramente el programa, es:

  1. int i,n,factorial=1;

  2. printf ("ingresa n:");

  3. scanf(“%d”,&n);

  4. i=1;

  5. while (i<=n) {

  6. factorial=factorial*i;

  7. i=i+1;

  8. }

  9. printf ("Factorial %d\n",factorial);

    Problemas resueltos

        Problema 1: Factores de un número

    Escribe un programa que pida ingresar un número mayor que 1 y entregue todos los factores de ese número. Si el número ingresado no es mayor que 1, el programa debe terminar. Recuerda que cualquier número tiene al menos como factor al 1.

    Solución:

  10. int n, factor;

  11. /* Preguntamos por el numero */

  12. printf("CALCULO DE FACTORES");

  13. printf("Ingrese un numero mayor que 1 ? ");

  14. scanf(“%d”,&n);

  15. /* Verificamos que este en el rango */

  16. if(n>1)

  17. {

  18. printf ("Los factores son: ");

  19. factor=1;

  20. /* Hacemos un ciclo probando todos los posibles factores */

  21. while(factor<=n){

  22. if (n%factor==0)

  23. printf(“%d ",factor);

  24. factor++;

  25. }

  26. /* Indicamos que termina la lista */

  27. printf(".\n");

  28. }

  29. else

  30. printf("El numero debe ser mayor que 1\n");

Problema 2: Digito verificador del carné de identidad

El sistema de identificación que se usa en Chile sa basa en un código (llamado numero del carné de identidad) que corresponde a un número entero (que se le asigna a cada habitante) y un dígito verificador (que se calcula usando el numero anterior) para saber si algunos de los dígitos del carnet han sido modificados. Así, para saber si la cédula 12.575.538-1 está correcta, debemos calcular el dígito verificador para 12575538 y compararlo con 1. Si son iguales, el número está bien, si no, fue adulterado.

Para calcular el dígito verificador se utiliza el siguiente algoritmo:

Solución

  1. int carnet,resultado;

  2. /* Preguntamos por el numero */

  3. printf("Ingrese un numero de carnet (mayor que 1) ? ");

  4. scanf(“%d”,&carnet);

  5. /* Verificamos que este en el rango */

  6. if(carnet>1)

  7. {

  8. int factor=2,suma=0,digito=0;

  9. /* Hacemos un ciclo que termina cuando carnet sea 0

  10. Para rescatar los digitos rescatamos el ultimo y

  11. lue go lo quitamos. */

  12. while (carnet>0)

  13. {

  14. /* Rescatamos es ultimo digito */

  15. digito=carnet%10;

  16. /* Quitamos el ultimo digito del numero */

  17. carnet=carnet/10;

  18. suma=suma + digito*factor;

  19. factor++;

  20. if(factor>=8)

  21. factor=2;

  22. }

  23. resultado=11-(suma%11);

  24. if(resultado==11)

  25. resultado=0;

  26. /* Mostramos el resultado */

  27. if (resultado==10)

  28. printf("El digito verificador es: K");

  29. else

  30. printf("El digito verificador es: %d", resultado);

  31. }

  32. else

  33. printf("El numero debe ser mayor que 1");



Problema 3: Sapo de Micro

Un sapo de micro calcula cuánto tiempo ha transcurrido entre el paso de dos micros del mismo recorrido. Un Sapo posmoderno usará un Notebook para ayudarse en el cálculo.

  1. Escribe un programa en C que sostenga el siguiente diálogo :

Es decir, que pregunte la hora en minutos. Supón que el programa se usa en un mismo día siempre.

b) Escribe el mismo programa, pero la hora se ingresa ahora de la siguiente forma:

Es decir, la hora se muestra en horas y minutos

Solución a)

  1. int antes,actual,i;

  2. printf ("A qué hora pasó la primera micro (minutos)?");

  3. scanf(“%d”,&antes);

  4. i=2;

  5. while (antes!=-1) {

  6. printf ("A que hora paso la micro %d?",i);

  7. scanf(“%d”,&actual);

  8. if (actual!=-1) {

  9. printf ("La diferencia entre la %d y la %d",i-1,i);

  10. printf (" es de %d minutos \n",actual-antes);

  11. }

  12. antes=actual;

  13. i=i+1;

  14. }

  15. printf ("Muchas gracias por usar este programa\n");

    Solución b)

  16. int hora,minutos,antes,actual,i,difh,difm;

  17. printf ("A qué hora pasó la primera micro (minutos)?");

  18. scanf(“%d %d”,&hora,&minutos);

  19. hora*60+minutos;

  20. i=2;

  21. while (antes!=-1) {

  22. int hora;

  23. printf ("A que hora paso la micro %d?",i);

  24. scanf(“%d %d”,&hora,&minutos);

  25. actual=hora*60+minutos;

  26. if (actual!=-1){

  27. difh=(actual-antes)/60;

  28. difm=(actual-antes)%60;

  29. printf ("La diferencia entre la %d y la %d es de ",i-1,i);

  30. if (difh>0)

  31. printf (“%d horas y ",difh);

  32. printf ("%d minutos",difm);

  33. antes=actual;

  34. i=i+1;

  35. }

  36. }

  37. printf ("Muchas gracias por usar este programa\n");

Pon tus conocimientos a prueba

Escribe un programa que lea las notas de un alumno del teclado y escriba su promedio en la pantalla. Escribe dos versiones; la primera versión pregunta al usuario la cantidad de notas, la segunda versión pregunta notas hasta que se ingresa un 0 para indicar el fin.

Versión 1

Versión 2

Diagramas de flujo

Un diagrama de flujo es una representación gráfica del orden en que se van ejecutando las instrucciones de un programa, cómo ya hemos visto de forma superficial en este capítulo y el anterior. Hasta ahora hemos visto tres tipos de ejecución: secuencial, cíclica y condicional, cada uno de los cuales tiene un diagrama asociado:

Secuencial

Condicional

Cíclica

inst1;

inst2;

inst3;

if (cond)

inst1;

else

inst2;

while (cond)

inst;



Para programas más complejos, basta con combinar los distintos diagramas.

Ejemplo de un diagrama de flujo

El siguiente código escribe si un número guardado en la variable x es positivo, negativo o igual a cero. A su derecha se ve su diagrama de flujo, que es una composición de dos diagramas de secuencias condicionales.

if (x>0)

    printf("positivo”);

    else {

    if (x<0)

    printf("negativo");

    else

    printf("cero");

    }



Los diagramas pueden ayudar a descubrir por qué un código no funciona. Por ejemplo, en el siguiente programa, que intenta hacer lo mismo que el anterior, el diagrama pone de manifiesto cual es el error cometido:



    if (x>0)

    printf("positivo);

    if (x<0)

    printf("negativo");

    else

    printf("cero");

Ejecución paso a paso

La ejecución paso a paso consiste en escribir el orden en que las instrucciones se van ejecutando al correr el programa. Para ello se le asigna un número a cada línea del programa. Al lado de cada línea se escribe:

Si la instrucción es ...

Se debe escribir

asignación

el nuevo valor de la variable

while o if

el valor de verdad de la condición

print

qué se escribe en la pantalla



El siguiente programa lee números enteros desde el teclado y escribe cuánto vale su suma acumulada. El programa itera hasta que se ingresa un cero.

  1. int suma= 0, num;

  2. printf("? ");

  3. scanf(“%d”,&num);

  4. while (num!=0) {

  5. suma= suma+num;

  6. printf("Total= %d\n",suma);

  7. printf("? ");

  8. scanf(“%d”,&num);

  9. }

  10. printf("Fin!\n");

    La siguiente pantalla muestra un ejemplo:

    ? 3

    Total= 3

    ? 4

    Total= 7

    ? 1

    Total= 8

    ? 0

    ¿Cómo es su ejecución paso a paso?

    (1) suma=0

    (2) escribe "?"

    (3) num=3

    (4) Verdadero

    (5) suma=3

    (6) escribe "Total="

    (6) escribe "3"

    (7) escribe "?"

    (8) num=4

    (4) Verdadero

    (5) suma=7

    (6) escribe "Total="

    (6) escribe "7"

    (7) escribe "?"

    (8) num=1

    (4) Verdadero

    (5) suma=8

    (6) escribe "Total="

    (6) escribe "8"

    (7) escribe "?"

    (8) num=0

    (4) Falso

    (10) escribe "Fin"

    Pon tus conocimientos a prueba

    El siguiente programa calcula el máximo comun divisor entre los números 15 y 24 (Propuesto: demuéstralo). Dibuja su diagrama de flujo y escribe su ejecución paso a paso.

  1. int x= 15;

  2. int y= 24;

  3. while (x!=y) {

  4. if (x>y)

  5. x= x-y;

  6. else

  7. y= y-x;

  8. }

  9. printf(“%d”,x);

Solución:

(1) x=15

(2) y=24

(3) Verdadero

(4) Falso

(7) y=9

(3) Verdadero

(4) Verdadero

(5) x=6

(3) Verdadero

(4) Falso

(7) y=3

(3) Verdadero

(4) Verdadero

(5) x=3

(3) Falso

(9) Escribe 3



For

En C existe una forma abreviada de escribir un ciclo while: la instrucción for. No sólo abrevia, sino que ademas aporta claridad en ciertos casos. Su forma es

for (instrucción1; condición; instrucción2) {

instrucciones;

}

equivale a

instrucción 1;

while (condición) {

instrucciones;

instrucción2;

}

Los siguientes programas muestran ejemplos de la equivalencia entre while y for:

Con for... Con while...

Int i;

for (i=0; i< 100; i++)

printf ("El número es %d",i);

int i=0;

while (i<100) {

printf ("El número es "+i);

i++;

}

Float tiempo;

for (tiempo=0.0;tiempo<10.0;tiempo+=0.1)

{

printf ("Tiempo = %f,posicion= %f",tiempo,pos);

pos=0.1*velocidad;

velocidad=velocidad+0.3;

}

float tiempo=0.0;

while (tiempo<10.0) {

printf ("Tiempo = %f,posicion= %f",tiempo,pos);

pos=0.1*velocidad;

velocidad=velocidad+0.3;

}