Este sitio web usa cookies de terceros para analizar el tráfico y personalizar los anuncios. Si no está de acuerdo, abandone el sitio y no siga navegando por él. ×


3.3. for

Ésta es la orden que usaremos habitualmente para crear partes del programa que se repitan un cierto número de veces. El formato de "for" es

for (valorInicial; CondiciónRepetición; Incremento)
    Sentencia;

Así, para contar del 1 al 10, tendríamos "contador=1" como valor inicial, "contador<=10" como condición de repetición, y el incremento sería de 1 en 1, con "contador=contador+1". Por tanto, el programa quedaría:

/*  ej030301.c                 */
/*  Contar con "for" (1)       */
/*  Ejemplo del apartado 3.3   */
/*  Curso de C, Nacho Cabanes  */

#include 

int main()
{
    int contador;

    for (contador=1; contador<=10; contador=contador+1)
        printf("%d ", contador);

    return 0;
}

Esta misma operación se podría haber realizado con "while", y el programa sería muy similar:

/*  ej030302.c                     */
/*  "while" alternativo a un "for" */
/*  Ejemplo del apartado 3.3       */
/*  Curso de C, Nacho Cabanes      */

#include 

int main()
{
    int contador;

    contador=1;
    while ( contador <= 10 )
    {
        printf("%d ", contador);
        contador=contador+1;
    }

    return 0;
}

Aun así, a pesar de que no haya una gran diferencia con la orden "while", se suele usar la orden "for" para crear contadores por analogía con lo que existe en otros lenguajes de programación (más legibles), como BASIC (FOR contador = 1 TO 10) y Pascal (for contador := 1 to 10 do...)

Como vimos en el apartado 1.7.4, "contador++" es una forma abreviada de escribir "contador=contador+1", de modo que se puede usar la notación compacta para aumentar la variable de uno en uno:

/*  ej030303.c                 */
/*  Contar con "for", abreviado */
/*  Ejemplo del apartado 3.3   */
/*  Curso de C, Nacho Cabanes  */

#include 

int main()
{
    int contador;

    for (contador=1; contador<=10; contador++)
        printf("%d ", contador);

    return 0;
}

(Ésta será la forma que usaremos más habitualmente).

Ejercicio propuesto 3.3.1: Crea un programa que muestre los números del 15 al 5, descendiendo (pista: en cada pasada habrá que descontar 1, por ejemplo haciendo i=i-1, que se puede abreviar i--).
Ejercicio propuesto 3.3.2: Crea un programa que muestre los primeros ocho números pares: 2 4 6 8 10 12 14 16 (primera forma: muestra el doble del valor que hace de contador).
Ejercicio propuesto 3.3.3: Crea un programa que muestre los primeros ocho números pares: 2 4 6 8 10 12 14 16 (segunda forma: aumentar de 2 en 2 en cada pasada).

En un "for", realmente, la parte que hemos llamado "Incremento" no tiene por qué incrementar la variable, aunque ése es su uso más habitual. Es simplemente una orden que se ejecuta cuando se termine la "Sentencia" y antes de volver a comprobar si todavía se cumple la condición de repetición. Puede incluso ser una "orden vacía".

Por eso, si escribimos la siguiente línea:

for (contador=1; contador<=10; )

la variable "contador" no se incrementa nunca, por lo que nunca se cumplirá la condición de salida: nos quedamos encerrados dando vueltas dentro de la orden que siga al "for".

Un caso todavía más exagerado de algo a lo que se entra y de lo que no se sale (un "bucle sin fin") sería la siguiente orden (que no incluye valor inicial, ni condición de repetición, ni incremento... y aun así es una orden válida):

for ( ; ; )

Los bucles "for" se pueden anidar (incluir uno dentro de otro), de modo que podríamos escribir las tablas de multiplicar del 1 al 5 con:

/*  ej030304.c                         */
/*  "for" anidados (tabla de multipl.) */
/*  Ejemplo del apartado 3.3           */
/*  Curso de C, Nacho Cabanes          */

#include 

int main()
{
    int tabla, numero;

    for (tabla=1; tabla<=5; tabla++)
        for (numero=0; numero<=10; numero++)
            printf("%d por %d es %d\n", tabla, numero, tabla*numero);

    return 0;
}

(Nota: este fuente usa \n, como vimos en el apartado 1.11, para que los textos aparezcan en líneas separadas y el resultado sea más legible; es algo que usaremos cada vez con más frecuencia a partir de ahora).

En estos primeros ejemplos, después de "for" había una única sentencia. Como puedes imaginar, si se desea que se hagan varias cosas, basta definirlas como un bloque (una sentencia compuesta) encerrándolas entre llaves. Por ejemplo, si queremos mejorar el ejemplo anterior haciendo que deje una línea en blanco entre tabla y tabla, sería:

/*  ej030305.c                */
/*  "for" anidados (2)        */
/*  Ejemplo del apartado 3.3  */
/*  Curso de C, Nacho Cabanes */

#include 

int main()
{
    int tabla, numero;

    for (tabla=1; tabla<=5; tabla++)
    {
        for (numero=0; numero<=10; numero++)
            printf("%d por %d es %d\n", tabla, numero, tabla*numero);
        printf("\n");
    }

    return 0;
}

Al igual que ocurría con "if" y con "while", suele ser buena costumbre incluir siempre las llaves, aunque haya una única orden que se repita en el "for", para evitar funcionamientos incorrectos si después hay que añadir más sentencias que deban repetirse y se olvida incluir las llaves en ese momento.

Ejercicio propuesto 3.3.4: Crea un programa que muestre la tabla de multiplicar del 6.
Ejercicio propuesto 3.3.5: Crea un programa que escriba en pantalla los números del 1 al 50 que sean múltiplos de 3 (pista: habrá que recorrer todos esos números y ver si el resto de la división entre 3 resulta 0).

Los "bucles anidados" y el carácter especial de avance de línea "\n" permiten hacer muchos ejercicios de dibujo de figuras geométricas sencillas (bastantes de las cuales quedan propuestas para que tú las intentes). Por ejemplo, se puede dibujar un rectángulo con:

/*  ej030306.c                */
/*  Rectángulo de asteriscos  */
/*  Ejemplo del apartado 3.3  */
/*  Curso de C, Nacho Cabanes */

#include 

int main()
{
    int fila, columna;
    int alto = 5;
    int ancho = 10;

    for (fila=1; fila <= alto; fila++)
    {
        for (columna=1; columna <= ancho; columna++)
            printf("*");
        printf("\n");
    }

    return 0;
}

La salida de este programa será:

**********
**********
**********
**********
**********

(Nota: si analizas fuentes ajenos, verás que es habitual usar el nombre "i" como abreviatura de "índice", para nombrar los contadores de la orden "for". Es un arcaismo, heredado de los tiempos en los que los ordenadores tenían 16 KB de memoria o menos, y era vital ahorrar cada byte. Hoy en día es preferible usar nombres más significativos, que expresen mejor qué es lo que se está contando. Esa es la política que emplearemos en este texto: fuente legibles antes que compactos.)

Ejercicio propuesto 3.3.6: Mejora el ejemplo 030306 (rectángulo de asteriscos) para que sea el usuario quien introduzca el ancho y el alto.
Ejercicio propuesto 3.3.7: Haz un programa que dibuje un cuadrado de asteriscos, cuyo ancho (y alto) será introducido por el usuario.
Ejercicio propuesto 3.3.8: Crea un triángulo de asteriscos, que mostrará uno en la primera fila, dos en la segunda, tres en la tercera y así sucesivamente, hasta llegar al tamaño indicado por el usuario.
Ejercicio propuesto 3.3.9: Dibuja un triángulo de asteriscos descendente. Por ejemplo, si el usuario escoge "4" como tamaño, la primera fila tendrá 4 asteriscos, la segunda tendrá 3, la siguiente tendrá 2 y la última tendrá 1.