Ahhhh recuerdo muy bien estas pruebas de escritorio en mis clases de la universidad a principios...je era bastante molesto todo eso.
Hoy en día es mi pan de cada día como dicen por ahí.
Voy a intentar dejar el esquema claro:
#include <stdio.h>
void main() {
int i, a[10];
for (i = 0; i < 10; i++)
{
a[i] = 9 - i;
}
for (i = 0; i < 10; i++)
{
}
for (i = 2; i < 7; i++)
{
a[i] = a[a[i]]+2;
}
for (i = 0; i < 10; i++)
{
}
}
/*
Salida primer for (i = 0; i < 10; i++)
9 8 7 6 5 4 3 2 1 0
Salida segundo for (i = 2; i < 7; i++)
9 8 4 5 6 8 7 2 1 0
*/
Ahora examinemos el paso a paso:
Salida primer for (i = 0; i < 10; i++)
Tenemos lo siguiente:
a[0] = 9 - 0 = 9
a[1] = 9 - 1 = 8
a[2] = 9 - 2 = 7
a[3] = 9 - 3 = 6
a[4] = 9 - 4 = 5
a[5] = 9 - 5 = 4
a[6] = 9 - 6 = 3
a[7] = 9 - 7 = 2
a[8] = 9 - 8 = 1
a[9] = 9 - 9 = 0
Creo que ahi va todo en orden, facil de entender.
Ahora sigue lo interesante, el segundo for
Salida primer for (i = 2; i < 7; i++)
Tenemos lo siguiente:
a[0] = 9 //No cambia
a[1] = 8 //No cambia
a[2] = ? //cambia
a[3] = ? //cambia
a[4] = ? //cambia
a[5] = ? //cambia
a[6] = ? //cambia
a[7] = 2 //No cambia
a[8] = 1 //No cambia
a[9] = 0 //No cambia
Para entender el ciclo, es necesario puntualizar que se toma las posiciones del arreglo, que tiene un valor, que a su misma vez, es otra posición de ese mismo arreglo, y que una vez se realiza el cambio, actualiza la posición del arreglo, que luego se utilizara en ese mismo ciclo para los pasos siguientes
Por ejemplo:
a[2] = a[ a[2] ] + 2 // a[2] = 7
a[2] = a[ 7 ] + 2 // a[7] = 2
a[2] = 2 + 2
a[2] = 4
a[0] = 9 //No cambia
a[1] = 8 //No cambia
a[2] = 4 //cambia
a[3] = ? //cambia
a[4] = ? //cambia
a[5] = ? //cambia
a[6] = ? //cambia
a[7] = 2 //No cambia
a[8] = 1 //No cambia
a[9] = 0 //No cambia
Y ahora seguimos con los otros, hasta que i se menor que 7 (i<7) y así se rompe el ciclo:
a[3] = a[ a[3] ] + 2 // a[3] = 6 | a[4] = a[ a[4] ] + 2 // a[4] = 5
a[3] = a[ 6 ] + 2 // a[6] = 3 | a[4] = a[ 5 ] + 2 // a[5] = 4
a[3] = 3 + 2 | a[4] = 4 + 2
a[3] = 5 | a[4] = 6
a[0] = 9 //No cambia | a[0] = 9 //No cambia
a[1] = 8 //No cambia | a[1] = 8 //No cambia
a[2] = 4 //cambia | a[2] = 4 //cambia
a[3] = 5 //cambia | a[3] = 5 //cambia
a[4] = ? //cambia | a[4] = 6 //cambia
a[5] = ? //cambia | a[5] = ? //cambia
a[6] = ? //cambia | a[6] = ? //cambia
a[7] = 2 //No cambia | a[7] = 2 //No cambia
a[8] = 1 //No cambia | a[8] = 1 //No cambia
a[9] = 0 //No cambia | a[9] = 0 //No cambia
Ahora ves que los elementos de los arreglos van cambiando de valor nuevamente?? hay que usar esos nuevos valores para las nuevas sumatorias:
a[5] = a[ a[5] ] + 2 // a[5] = 4 | a[6] = a[ a[6] ] + 2 // a[6] = 3
a[5] = a[ 4 ] + 2 // a[4] = 6 | a[6] = a[ 3 ] + 2 // a[3] = 5
a[5] = 6 + 2 | a[6] = 5 + 2
a[5] = 8 | a[6] = 7
a[0] = 9 //No cambia | a[0] = 9 //No cambia
a[1] = 8 //No cambia | a[1] = 8 //No cambia
a[2] = 4 //cambia | a[2] = 4 //cambia
a[3] = 5 //cambia | a[3] = 5 //cambia
a[4] = 6 //cambia | a[4] = 6 //cambia
a[5] = 8 //cambia | a[5] = 8 //cambia
a[6] = ? //cambia | a[6] = 7 //cambia
a[7] = 2 //No cambia | a[7] = 2 //No cambia
a[8] = 1 //No cambia | a[8] = 1 //No cambia
a[9] = 0 //No cambia | a[9] = 0 //No cambia
finalmente tenemos el arreglo:
a[0] = 9
a[1] = 8
a[2] = 4
a[3] = 5
a[4] = 6
a[5] = 8
a[6] = 7
a[7] = 2
a[8] = 1
a[9] = 0
Puede que parezca algo largo, extenso y complicado, pero en realidad es facil de entender si se usa un debug apropiado, yo use para este caso el de codeblocks
http://wiki.codeblocks.org/index.php/Debugging_with_Code::BlocksEspero que sea de ayuda.