Estructuras de control: bucles for anidados

Bucles anidados

Un bucle anidado es un bucle que se encuentra incluido en el bloque de sentencias de otro bloque. Los bucles pueden tener cualquier nivel de anidamiento (un bucle dentro de otro bucle dentro de un tercero, etc.).

Al bucle que se encuentra dentro del otro se le puede denominar bucle interior o bucle interno. El otro bucle sería el bucle exterior o bucle externo.

En los bucles anidados es importante utilizar variables de control distintas, para no obtener resultados inesperados.

Bucles anidados con variables independientes

Los bucles anidados con variables independientes son los bucles en los que ninguna de las variables de uno de los bucles interviene ni en la condición de continuación ni en la expresión de paso de los otros bucles.

Un ejemplo de bucles anidados con variables independientes sería el siguiente:

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {               // Bucle exterior

    for ($j = 10; $j < 12; $j++) {         // Bucle interior
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>

Su ejecución daría el siguiente resultado:

Ejemplo de bucle anidado con variables independientes

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
      print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>
<p>i: 2 -- j: 10</p>
<p>i: 2 -- j: 11</p>
<p>Final</p>

Puede ver la ejecución paso a paso de este programa utilizando los iconos de avance y retroceso situados abajo a la derecha.

Siguiente

Paso 1

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>

Se ejecuta la primera instrucción del programa.

En este caso, imprime el párrafo de comienzo.

Anterior Siguiente

Paso 2

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>

A continuación se ejecuta el primer bucle (bucle exterior). El primer paso es dar el valor inicial a la variable de control.

En este caso, la variable de control es $i y toma el valor 1.

Anterior Siguiente

Paso 3

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>

A continuación se comprueba que la condición de continuación del bucle exterior se cumple.

En este caso, $i es inferior a 3 (vale 0), así que se pasa a ejecutar las instrucciones del bloque de sentencias del bucle exterior.

Anterior Siguiente

Paso 4

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>

En el bloque de sentencias se encuentra el segundo bucle (o bucle interior). El primer paso es dar el valor inicial a la variable de control. del bucle interior

En este caso, la variable de control es $j y toma el valor 10.

Anterior Siguiente

Paso 5

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>

A continuación se comprueba que la condición de continuación del bucle interior se cumple.

En este caso, $j es inferior a 12 (vale 10), así que se pasa a ejecutar las instrucciones del bloque de sentencias.

Anterior Siguiente

Paso 6

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>

A continuación se ejecutan las instrucciones del bloque interior.

En este caso, se imprime el texto <p>i: 1 -- j: 10</p> ya que $i tiene el valor 1 y $j el valor 10.

Anterior Siguiente

Paso 7

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>

A continuación se ejecuta la instrucción de paso del bucle interior.

En este caso, la variable $j aumenta una unidad, por lo que ahora vale 11.

Anterior Siguiente

Paso 8

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>

A continuación se comprueba que la condición de continuación del bucle interior se cumple.

En este caso, $j es inferior a 12 (vale 11), así que se pasa a ejecutar las instrucciones del bloque de sentencias del bloque interior.

Anterior Siguiente

Paso 9

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>

A continuación se ejecutan las instrucciones del bloque interior.

En este caso, se imprime el texto <p>i: 1 -- j: 11</p> ya que $i tiene el valor 1 y $j el valor 11.

Anterior Siguiente

Paso 10

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>

A continuación se ejecuta la instrucción de paso del bucle interior.

En este caso, la variable $j aumenta una unidad, por lo que ahora vale 12.

Anterior Siguiente

Paso 11

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>

A continuación se comprueba que la condición de continuación del bucle interior se cumple.

En este caso, $j ya no es inferior a 12 (vale 12), así que no se ejecutan las instrucciones del bloque de sentencias y el bucle interior se termina.

Anterior Siguiente

Paso 12

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>

A continuación se ejecuta la instrucción de paso del bucle exterior.

En este caso, la variable $i aumenta una unidad, por lo que ahora vale 2.

Anterior Siguiente

Paso 13

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>

A continuación se comprueba de nuevo que la condición de continuación del bucle exterior se cumple.

En este caso, $i es inferior a 3 (vale 2), así que se pasa a ejecutar las instrucciones del bloque de sentencias del bucle exterior.

Anterior Siguiente

Paso 14

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>

En el bloque de sentencias se encuentra el segundo bucle (o bucle interior). El primer paso es dar el valor inicial a la variable de control. del bucle interior

En este caso, la variable de control es $j y toma el valor 10.

Anterior Siguiente

Paso 15

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>

A continuación se comprueba que la condición de continuación del bucle interior se cumple.

En este caso, $j es inferior a 12 (vale 10), así que se pasa a ejecutar las instrucciones del bloque de sentencias.

Anterior Siguiente

Paso 16

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>
<p>i: 2 -- j: 10</p>

A continuación se ejecutan las instrucciones del bloque interior.

En este caso, se imprime el texto <p>i: 2 -- j: 10</p> ya que $i tiene el valor 2 y $j el valor 10.

Anterior Siguiente

Paso 17

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>
<p>i: 2 -- j: 10</p>

A continuación se ejecuta la instrucción de paso del bucle interior.

En este caso, la variable $j aumenta una unidad, por lo que ahora vale 11.

Anterior Siguiente

Paso 18

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>
<p>i: 2 -- j: 10</p>

A continuación se comprueba que la condición de continuación del bucle interior se cumple.

En este caso, $j es inferior a 12 (vale 11), así que se pasa a ejecutar las instrucciones del bloque de sentencias del bloque interior.

Anterior Siguiente

Paso 19

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>
<p>i: 2 -- j: 10</p>
<p>i: 2 -- j: 11</p> 

A continuación se ejecutan las instrucciones del bloque interior.

En este caso, se imprime el texto <p>i: 2 -- j: 11</p> ya que $i tiene el valor 2 y $j el valor 11.

Anterior Siguiente

Paso 20

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>
<p>i: 2 -- j: 10</p>
<p>i: 2 -- j: 11</p>

A continuación se ejecuta la instrucción de paso del bucle interior.

En este caso, la variable $j aumenta una unidad, por lo que ahora vale 12.

Anterior Siguiente

Paso 21

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>
<p>i: 2 -- j: 10</p>
<p>i: 2 -- j: 11</p>

A continuación se comprueba que la condición de continuación del bucle interior se cumple.

En este caso, $j ya no es inferior a 12 (vale 12), así que no se ejecutan las instrucciones del bloque de sentencias y el bucle interior se termina.

Anterior Siguiente

Paso 22

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>
<p>i: 2 -- j: 10</p>
<p>i: 2 -- j: 11</p>

A continuación se ejecuta la instrucción de paso del bucle exterior.

En este caso, la variable $ aumenta una unidad, por lo que ahora vale 3.

Anterior Siguiente

Paso 23

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>
<p>i: 2 -- j: 10</p>
<p>i: 2 -- j: 11</p>

A continuación se comprueba de nuevo que la condición de continuación del bucle exterior se cumple.

En este caso, $i ya no es inferior a 3 (vale 3), así que no se ejecutan las instrucciones del bloque de sentencias y el bucle se termina.

Anterior Siguiente

Paso 24

<?phpprint "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 10; $j < 12; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 10</p>
<p>i: 1 -- j: 11</p>
<p>i: 2 -- j: 10</p>
<p>i: 2 -- j: 11</p>
<p>Final</p>

Una vez terminado el bucle, se ejecuta la instrucción que sigue al bucle.

En este caso, imprime el párrafo final.

Anterior

En estos casos, si el bucle exterior se ejecuta M veces y el bucle interior se ejecuta N veces cada vez que se ejecuta el bucle exterior, en total el bloque de instrucciones se ejecutará M x N veces.

Bucles anidados con variables dependientes

Los bucles anidados con variables dependientes son los bucles en los que la variable de uno de los bucles interviene en la condición de continuación o en la expresión de paso de los otros bucles.

Un ejemplo de bucles anidados con variables independientes sería el siguiente:

<?php
print "<p>Comienzo</p>\n";

for ($i = 1; $i < 3; $i++) {               // Bucle exterior
    for ($j = 0; $j < $i; $j++) {         // Bucle interior en el que aparece $i
        print "<p>i: $i -- j: $j</p>\n";  // en la condición de continuación
    }
}
print "<p>Final</p>\n";
?>

Su ejecución daría el siguiente resultado:

Ejemplo de bucle anidado con variables dependientes

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
  <p>Comienzo</p>
  <p>i: 1 -- j: 0</p>
  <p>i: 2 -- j: 0</p>
  <p>i: 2 -- j: 1</p>
  <p>Final</p>
  

Puede ver la ejecución paso a paso de este programa utilizando los iconos de avance y retroceso situados abajo a la derecha.

Siguiente

Paso 1

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>

Se ejecuta la primera instrucción del programa.

En este caso, imprime el párrafo de comienzo.

Anterior Siguiente

Paso 2

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>

A continuación se ejecuta el primer bucle (bucle exterior). El primer paso es dar el valor inicial a la variable de control.

En este caso, la variable de control es $i y toma el valor 1.

Anterior Siguiente

Paso 3

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>

A continuación se comprueba que la condición de continuación del bucle exterior se cumple.

En este caso, $i es inferior a 3 (vale 0), así que se pasa a ejecutar las instrucciones del bloque de sentencias del bucle exterior.

Anterior Siguiente

Paso 4

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>

En el bloque de sentencias se encuentra el segundo bucle (o bucle interior). El primer paso es dar el valor inicial a la variable de control. del bucle interior

En este caso, la variable de control es $j y toma el valor 0.

Anterior Siguiente

Paso 5

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>

A continuación se comprueba que la condición de continuación del bucle interior se cumple.

En este caso, $j (que vale 0) es inferior a $i (que vale 1), así que se pasa a ejecutar las instrucciones del bloque de sentencias.

Anterior Siguiente

Paso 6

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>

A continuación se ejecutan las instrucciones del bloque interior.

En este caso, se imprime el texto <p>i: 1 -- j: 0</p> ya que $i tiene el valor 1 y $j el valor 0.

Anterior Siguiente

Paso 7

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>

A continuación se ejecuta la instrucción de paso del bucle interior.

En este caso, la variable $j aumenta una unidad, por lo que ahora vale 1.

Anterior Siguiente

Paso 8

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>

A continuación se comprueba que la condición de continuación del bucle interior se cumple.

En este caso, $j (que vale 1) ya no es inferior a $i (que vale 1), así que no se ejecutan las instrucciones del bloque de sentencias y el bucle interior se termina.

Anterior Siguiente

Paso 9

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>

A continuación se ejecuta la instrucción de paso del bucle exterior.

En este caso, la variable $i aumenta una unidad, por lo que ahora vale 2.

Anterior Siguiente

Paso 10

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>

A continuación se comprueba de nuevo que la condición de continuación del bucle exterior se cumple.

En este caso, $i es inferior a 3 (vale 2), así que se pasa a ejecutar las instrucciones del bloque de sentencias del bucle exterior.

Anterior Siguiente

Paso 11

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>

En el bloque de sentencias se encuentra el segundo bucle (o bucle interior). El primer paso es dar el valor inicial a la variable de control. del bucle interior

En este caso, la variable de control es $j y toma el valor 0.

Anterior Siguiente

Paso 12

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>

A continuación se comprueba que la condición de continuación del bucle interior se cumple.

En este caso, $j (que vale 0) es inferior a $i (que vale 2), así que se pasa a ejecutar las instrucciones del bloque de sentencias.

Anterior Siguiente

Paso 13

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>
<p>i: 2 -- j: 0</p>

A continuación se ejecutan las instrucciones del bloque interior.

En este caso, se imprime el texto <p>i: 2 -- j: 0</p> ya que $i tiene el valor 2 y $j el valor 0.

Anterior Siguiente

Paso 14

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>
<p>i: 2 -- j: 0</p>

A continuación se ejecuta la instrucción de paso del bucle interior.

En este caso, la variable $j aumenta una unidad, por lo que ahora vale 1.

Anterior Siguiente

Paso 15

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>
<p>i: 2 -- j: 0</p>

A continuación se comprueba que la condición de continuación del bucle interior se cumple.

En este caso, $j (que vale 1) es inferior a $i (que vale 2), así que se pasa a ejecutar las instrucciones del bloque de sentencias del bloque interior.

Anterior Siguiente

Paso 16

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>
<p>i: 2 -- j: 0</p>
<p>i: 2 -- j: 1</p> 

A continuación se ejecutan las instrucciones del bloque interior.

En este caso, se imprime el texto <p>i: 2 -- j: 1</p> ya que $i tiene el valor 2 y $j el valor 1.

Anterior Siguiente

Paso 17

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>
<p>i: 2 -- j: 0</p>
<p>i: 2 -- j: 1</p>

A continuación se ejecuta la instrucción de paso del bucle interior.

En este caso, la variable $j aumenta una unidad, por lo que ahora vale 2.

Anterior Siguiente

Paso 18

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>
<p>i: 2 -- j: 0</p>
<p>i: 2 -- j: 1</p>

A continuación se comprueba que la condición de continuación del bucle interior se cumple.

En este caso, $j (que vale 2) ya no es inferior a $i (que vale 2), así que no se ejecutan las instrucciones del bloque de sentencias y el bucle interior se termina.

Anterior Siguiente

Paso 19

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>
<p>i: 2 -- j: 0</p>
<p>i: 2 -- j: 1</p>

A continuación se ejecuta la instrucción de paso del bucle exterior.

En este caso, la variable $ aumenta una unidad, por lo que ahora vale 3.

Anterior Siguiente

Paso 20

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>
<p>i: 2 -- j: 0</p>
<p>i: 2 -- j: 1</p>

A continuación se comprueba de nuevo que la condición de continuación del bucle exterior se cumple.

En este caso, $i ya no es inferior a 3 (vale 3), así que no se ejecutan las instrucciones del bloque de sentencias y el bucle se termina.

Anterior Siguiente

Paso 21

<?php
print "<p>Comienzo</p>\n";
for ($i = 1; $i < 3; $i++) {
    for ($j = 0; $j < $i; $j++) {
        print "<p>i: $i -- j: $j</p>\n";
    }
}
print "<p>Final</p>\n";
?>
<p>Comienzo</p>
<p>i: 1 -- j: 0</p>
<p>i: 2 -- j: 0</p>
<p>i: 2 -- j: 1</p>
<p>Final</p>

Una vez terminado el bucle, se ejecuta la instrucción que sigue al bucle.

En este caso, imprime el párrafo final.

Anterior

En estos casos, es difícil decir a priori cuántas veces se ejecutará el bloque de instrucciones.

Ejemplo: generación de una tabla

Para generar una tabla de varias filas se pueden utilizar bucles for anidados.

Supongamos que queremos generar la siguiente tabla:

<table border="1">
  <caption>Tabla</caption>
  <tbody>
    <tr>
      <th></th>
      <th>1</th>
      <th>2</th>
      <th>3</th>
      <th>4</th>
    </tr>
    <tr>
      <th>1</th>
      <td>1-1</td>
      <td>1-2</td>
      <td>1-3</td>
      <td>1-4</td>
    </tr>
    <tr>
      <th>2</th>
      <td>2-1</td>
      <td>2-2</td>
      <td>2-3</td>
      <td>2-4</td>
    </tr>
    <tr>
      <th>3</th>
      <td>3-1</td>
      <td>3-2</td>
      <td>3-3</td>
      <td>3-4</td>
    </tr>
  </tbody>
</table>
Tabla
1 2 3 4
1 1-1 1-2 1-3 1-4
2 2-1 2-2 2-3 2-4
3 3-1 3-2 3-3 3-4

Para identificar las partes que son susceptibles de ser generadas por bucles, buscamos las repeticiones en el código html. El resto del contenido (que en este caso son los números) debe también seguir algún patrón, para poderlo generar aprovechando las variables que controlan los bucles.

Así, se pueden identificar tres bloques:

El resto del código se generaría fuera de los bucles. En el cuadro siguiente se han marcado los bloques que generaría cada bucle.

<table border="1">
  <caption>Tabla</caption>
  <tbody>
    <tr>
      <th></th>
      <th>1</th>    ⌉
      <th>2</th>    † Bucle 1
      <th>3</th>    †
      <th>4</th>    ⌋
    </tr>
    <tr>                          ⌉
      <th>1</th>                  |
      <td>1-1</td>   ⌉            |
      <td>1-2</td>   † Bucle 3    |
      <td>1-3</td>   †            |
      <td>1-4</td>   ⌋            |
    </tr>                         †
    <tr>                          |
      <th>2</th>                  |
      <td>2-1</td>   ⌉            |
      <td>2-2</td>   † Bucle 3    | Bucle 2
      <td>2-3</td>   †            |
      <td>2-4</td>   ⌋            |
    </tr>                         †
    <tr>                          |
      <th>3</th>                  |
      <td>3-1</td>   ⌉            |
      <td>3-2</td>   † Bucle 3    |
      <td>3-3</td>   †            |
      <td>3-4</td>   ⌋            |
    </tr>                         ⌋
  </tbody>
</table>

El bucle 1 es un bucle simple. Los bucles 2 y 3 son bucles anidados que necesitan dos variables independientes para controlar cada uno de ellos. Los números contenidos en cada celda se pueden generar fácilmente a partir de las variables que controlan los bucles.

Un esbozo del código podría ser el siguiente:

"<table>"
"<caption>"
"<tbody>"
"<tr>"
"<th></th>"
for (columnas)
    "<th>columna</th>"
"</tr>"
for (filas)
    "<tr> "
    "<th>fila</th>"
    for (columnas)
        "<td>fila-columna</td>"
    "</tr>"
"</tbody>"
"</table>"

El código PHP podría ser el siguiente:

<?php
$columnas = 4;
$filas    = 3;

print "<table border=\"1\">\n";            // Abre la tabla
print "  <caption>Tabla</caption>\n";      // Crea la leyenda <caption>
print "  <tbody>\n";                       // Abre el cuerpo de tabla <tbody>

print "    <tr>\n";                        // Abre la primera fila
print "      <th></th>\n";                 // Crea la primera celda <th> de la primera fila (sin número)
for ($j = 1; $j <= $columnas; $j++) {      // Bucle 1 se ejecuta tantas veces como columnas tenga la tabla
    print "      <th>$j</th>\n";           // Crea las celdas <th> de la primera fila (con número)
}
print "    </tr>\n";                       // Cierra la primera fila

for ($i = 1; $i <= $filas; $i++) {         // Bucle 2 (genera el resto de filas de la tabla)
    print "    <tr>\n";                    // Abre la fila
    print "      <th>$i</th>\n";           // Crea la primera celda <th> de cada fila (con número)
    for ($j = 1; $j <= $columnas; $j++) {  // Bucle 3 se ejecuta tantas veces como columnas tenga la tabla
        print "      <td>$i-$j</td>\n";     // Crea el resto de celdas <td> de cada fila (con números)
    }
    print "    </tr>\n";                   // Cierra la fila
}

print "  </tbody>\n";                      // Cierra el cuerpo de tabla <tbody>
print "</table>\n";                        // Cierra la tabla
?>

En el bucle 1, la variable que controla el bucle se ha llamado $j, aunque se podría haber llamado $i. Pero como en los bucles anidados 2 y 3 la variable que crea las celdas de cada fila se ha llamado $j, en el bucle 1 se le ha llamado también $j ya que juega el mismo papel (generar las celdas de la fila).