Introducción a la programación

Vamos a ver un poco de teoría primero, porque si no, no sé dónde meterla ni cómo contarla sin que parezca un insulto. Perdonadme que esto sea un pelín rollero las primeras 40 líneas (o así), y ya el resto lo explico con ejemplos. No la contaría si no fuera necesaria O:)

. Estructuras repetitivas

Este tipo de estructuras marcan como orden de ejecución la reiteración de una serie de acciones basándose en un bucle.

Un BUCLE (loop, en inglés) es un trozo de algoritmo cuyas instrucciones son repetidas un cierto número de veces, mientras se cumple una cierta condición que ha de ser claramente especificada. La condición podrá ser verdadera o falsa, y se comprobará en cada paso o iteración del bucle.

Básicamente, existen tres tipos de estructuras repetitivas; los bucles "mientras..." (o "while"), los bucles "repetir... mientras que" (o "do... while") y los bucles "desde" (o "bucles for"). Vamos a verlas todas dentro de un ejemplo para clarificar los dos párrafos iniciales, que quedan tan bonitos como oscuros para quien nunca ha visto un bucle (ni es verde ni tiene antenas, lo siento %-D ).

Sólo un poco de teoría más antes de pasar a los ejemplos para cada una de las estructuras repetitivas; hay que hacer notar que todo bucle consta de tres partes básicas, a saber:

  • Decisión: donde se evalúa la condición y, en caso de ser cierta, se ejecuta el...
  • Cuerpo del bucle: son las instrucciones que queremos ejecutar repetidamente un cierto número de veces.
  • Salida del bucle: es la condición que dice cuándo saldremos de hacer repeticiones ("mientras protestes, seguirás fregando platos", en cuanto dejas de protestar, se acabó fregar más platos).

Una forma de controlar un bucle es mediante una variable llamada CONTADOR, cuyo valor se incrementa o decrementa en una cantidad constante en cada repetición que se produzca.

También, en los bucles suele haber otro tipo de variables llamadas ACUMULADOR, cuya misión es almacenar una cantidad variable resultante de operaciones sucesivas y repetidas. Es como un contador, con la diferencia que el incremento/decremento es variable.

Sí, sí, sí... ya sé que no me habeis entendido ni jota... ya vamos a por ejemplos, y ahí vereis a qué me refiero.

. Una situación real como aplicación

Vamos a suponer que estamos pensando en un programa que deba REPETIR algunas veces una acción. Por ejemplo, el ordenador se ha portado mal (el güindoze se ha vuelto a colgar, no sé, por decir algo };-D ), y, como castigo, le vamos a hacer imprimir por pantalla 300 MILLONES de veces la frase "Prometo ser bueno O:-)"

¿Cómo lo hacemos? ¿Escribimos 300.000.000 de veces la instrucción pertinente? ¡Vaya martirio! ¡Ni con "Copy'n'Paste"! ¡Se supone que el castigo es para la máquina, no para uno mismo!

Pues bien, las ESTRUCTURAS REPETITIVAS vienen a rescatarnos de la tediosa tarea de repetir cientos de líneas que en unas pocas quedan apañadas.

. Estructura MIENTRAS(condición)

En este tipo de estructura, el cuerpo del bucle (ya sabeis, las acciones que deben ejecutarse repetidas veces) se repite MIENTRAS se cumple una determinada condición, que especificamos entre paréntesis.

Su estructura, genéricamente, es esta:

 mientras(condición) hacer
         acción 1
         ........
         acción N
 fin mientras 

Aplicado a nuestra situación real, sería:

 Declaración de variables
   ENTEROS: Contador
 fin Declaración variables

 inicio
 
 Contador <- 1
 mientras(Contador<=300.000.000) hacer
     mostrar por pantalla 'Prometo ser bueno O:-)'
     Contador <- Contador+1
 fin mientras
 
 fin 

Con toda la idea, a la variable que "lleva" (por decirlo de alguna manera) la cuenta de las veces que el bucle se ha ejecutado, la he llamado contador.

Si os fijais, ANTES de entrar en el bucle le asigno el valor 1. Recordad que no es recomendable usar variables no inicializadas, no sabemos qué tienen dentro. En cuanto vemos la palabra "mientras", ya sabemos que hemos entrado en el bucle. Estamos en la decisión. ¿Es Contador<=300.000.000? Yo creo que sí, al menos si es cierto que 1<=300.000.000

Vale, es cierto, así que deben ejecutarse todas las instrucciones del cuerpo del bucle. En nuestro caso, se mostrará por pantalla la frase 'Prometo ser bueno O:-)', y, ATENCION, sumo 1 a la variable Contador. Como Contador valía 1, si ahora le sumo 1, creo que todos estamos de acuerdo en que ahora Contador vale 2. Llegamos al fin del mientras. Eso significa que se han terminado las instrucciones del cuerpo del bucle: debemos volver a evaluar la condición que tenía el "mientras" entre paréntesis para ver qué hacemos ahora.

Tenemos que ver si Contador<=300.000.000. Ahora, Contador valía 2, y se cumple que 2<=300.000.000, con lo que vuelve a mostrarse por pantalla la expresión 'Prometo ser bueno O:-)' y de nuevo se suma 1 a Contador, con lo que ahora, Contador pasa a valer 3. De nuevo llegamos al fin del mientras.

[... un buen rato después...]

Ahora Contador vale 300.000.000. Tenemos que ver si Contador<=300.000.000. Como es cierto que 300.000.000<=300.000.000, se muestra por pantalla el mensaje 'Prometo ser bueno O:-)', y sumamos 1 a Contador. Ahora, Contador vale 300.000.001. Llegamos (una vez más) al fin del mientras, por lo que tenemos que volver a evaluar la condición entre paréntesis que acompaña al "mientras".

Hay que ver si Contador<=300.000.000. Pero no es cierto que 300.000.001<=300.000.000, es más bien al revés, o sea, la condición entre paréntesis ES FALSA, ES UNA MENTIRA. ¿Eso qué quiere decir? Pues quiere decir que se acabó, que ya no se ejecuta el cuerpo del bucle, sino que hemos llegado al final, a la salida del bucle, con lo cual, el bucle ha terminado.

¿Me podría decir alguien qué hubiera pasado si no incluimos la línea "Contador <- Contador+1" dentro del cuerpo del bucle?

Sólo adelanto que se llegaría a una situación que debe evitarse por completo; si tenemos suerte, habrá un error de desbordamiento, en el peor de los casos, el bucle... completad la frase ;)

Una nota importante:

Fijaos en una cosa, si, por ejemplo, al empezar nuestro algoritmo, en vez de hacer

Contador <- 1

hubiéramos hecho

Contador <- 1.000.000.000.000.000.000

aparte de que tenemos posibilidades de salirnos de rango (vamos a suponer que no fuera así), al entrar en el mientras, la condición es "Contador<=300.000.000", y Contador es, claramente, mayor estrictamente que 300.000.000

¿Qué pasaría aquí? Pues es sencillo: la condición es falsa, luego el cuerpo del bucle se ejecuta CERO veces. ¿Y qué utilidad tiene poner un bucle para que luego no se ejecute? En este caso concreto, ninguna, pero puede haber situaciones en las que sí nos sea útil. De hecho, sucede a menudo :)

. Estructura REPETIR... MIENTRAS QUE(condición)

Aquí, lo que se desea es que un bucle se ejecute AL MENOS UNA VEZ antes de comprobar la condición de repetición.

La estructura del REPETIR ... MIENTRAS, genéricamente, es esta:

 repetir
         acción 1
         ........
         acción N
 mientras que(condición) 

Notar que no hace falta poner "fin del repetir", puesto que está claro que se acaba donde pone "mientras que(condición)".

Vamos a ver cómo resolver nuestra situación REAL con este tipo de estructura:

 Declaración de variables
   ENTEROS: Contador
 fin Declaración variables

 inicio
 
 Contador <- 1
 Repetir
     mostrar por pantalla 'Prometo ser bueno O:-)'
     Contador <- Contador+1
 mientras que(Contador<=300.000.000)
 
 fin 

Le seguimos la pista igual que se la hemos seguido al anterior caso: empezamos con la asignación del valor 1 a la variable Contador. Llegamos a repetir, quien NO NOS EXIGE, para su entrada, verificar condición alguna. Mostramos por pantalla la frase 'Prometo ser bueno O:-)', y sumamos 1 a la variable Contador, con lo que ahora pasa a valer 2. Y AHORA es cuando llegamos a la condición: ¿es Contador<=300.000.000? Yo diría que sí, así que ale, de vuelta a repetir: mostramos por pantalla nuestra frase, sumamos 1 a contador...

[... varios minutos después...]

Y ya, por fin, Contador alcanza el valor 300.000.001, con lo que la comparación dice "¡MENTIRA!", y se acabó repetir esa tarea.

Nuevamente, os invito a que me digais qué hubiera pasado si no hiciéramos Contador <- Contador+1 ...

Otra nota importante:

Vamos a remarcar una diferencia IMPORTANTE entre esta estructura y la anterior "mientras". Si al empezar nuestro algoritmo, en vez de hacer

Contador <- 1

hubiésemos hecho

Contador <- 1.000.000.000.000.000.000

de nuevo tenemos posibilidades de salirnos de rango, pero va, vamos a poner que esto que no fuera así; la palabra REPETIR no nos está pidiendo nada, así que ejecutamos una vez el cuerpo del bucle. Se nos muestra la frase, se incrementa el contador, y llegamos al mientras. Como la condición es falsa, no volvemos a ejecutar el bucle.

¿Cuál es la diferencia?

Pues que con la estructura "mientras", el bucle se ejecutaba CERO veces, sin embargo, con la estructura "repetir...mientras que" el bucle se ejecuta UNA vez. Esta sutil diferencia es la que hace que unas veces se elija al primero y otras al segundo.

. Estructura DESDE

Esta estructura hubiera sido la más adecuada para resolver nuestra situación real, como veremos a continuación.

La estructura "desde", tiene una pequeña peculiaridad, y es que ella solita incrementa (o decrementa) DE UNO EN UNO a la variable que utilicemos como contador.

Su estructura es:

 desde Contador<-Inicio hasta Contador=Fin [, decrementar,] hacer
       accion 1
       ........
       accion N
 fin desde 

La palabra "decrementar" entre corchetes significa que es opcional, es decir, que se puede poner o no. Si NO se pone, por defecto se asume que al terminar las acciones del bucle, se hará Contador <- Contador+1

Si ponemos "decrementar", al terminar las acciones del bucle se hará Contador <- Contador-1. Cuidado con esto, pues si no especificamos "decrementar", es ILEGAL escribir

desde Contador<-500 hasta Contador=200 hacer

así como, si escribimos "decrementar", es igualmente ILEGAL poner

desde Contador<-1 hasta Contador=1257 , decrementar, hacer

No se admite otro tipo de incrementos/decrementos (de 2 en 2, de 0.5 en 0.5 o de -10 en -10), para ello ya tenemos las estructuras "mientras" y "repetir...mientras", en las que nosotros elegíamos el incremento/decremento.

En el lenguaje de programación Pascal esto también sucede así en los bucles FOR. En otros lenguajes, como FORTRAN, BASIC o C, el FOR es mucho más potente, siendo el caso del lenguaje C el que riza el rizo, pudiendo llegar a hacer verdaderas obras de arte con un "simple" bucle FOR.

Bueno, al grano O:)

Supongo que la estructura está suficientemente clara, sin embargo, para terminar de clarificarla, vamos a aplicarla a nuestra BIEN conocida situación REAL:

 Declaración de variables
   ENTEROS: Contador
 fin Declaración variables

 inicio
 
 desde Contador<-1 hasta Contador=300.000.000 hacer
     mostrar por pantalla 'Prometo ser bueno O:-)'
 fin desde
 
 fin 

Umm... lo primero que se observa es que no hace falta asignar el valor 1 a Contador fuera del bucle, puesto que en la parte Contador<-Inicio (Contador<-1, en este caso) ya se asigna automáticamente ese valor.

Lo siguiente es, como ya he mencionado, que no hace falta que incrementemos el valor de Contador, puesto que es una acción que se realiza sola en un bucle de este tipo.

Por último, como no hemos usado la palabra decremento, se asume entonces que incrementamos de 1 en 1 el valor de la variable Contador.

¿Y cómo se hubiera hecho esto usando decrementos? Pues, por ejemplo, así:

 Declaración de variables
   ENTEROS: Contador
 fin Declaración variables

 inicio
 
 desde Contador<-300.000.000 hasta Contador=1 , decrementar, hacer
     mostrar por pantalla 'Prometo ser bueno O:-)'
 fin desde
 
 fin 

Aunque yo lo he hecho aquí por estar manejando variables de tipo entero, debo decir que es PELIGROSO usar una comparación de IGUALDAD entre dos números cualesquiera, y que, para evitar que por truncamientos, redondeos o algún otro motivo que lleve a pérdidas de decimales en los números, en vez de poner = es mejor poner <= o >=. Así, en nuestros dos ejemplos de bucle mientras, la línea "decisoria" en el bucle (por llamarla de alguna manera) es más recomendable escribirla así:

desde Contador<-1 mientras Contador<=300.000.000 hacer

o así, en el caso del decremento:

desde Contador<-300.000.000 mientras Contador>=1 , decrementar, hacer

Y con esto queda terminado el capítulo de las estructuras básicas para escribir nuestros algoritmos.

Notar que aquí he cambiado la palabra hasta por la palabra mientras. Lo que quiere decir es que, mientras que Contador sea menor o igual que 300.000.000, seguiremos dentro del bucle.

"Ah, no, con la paliza que nos has dado, ahora la que no se escapa eres tú. A ver, ¿y qué hay de esas variables llamadas 'acumuladores' que has mencionado antes y que no has usado para nada?"

Bueno, este... ¡me alegro de que me haga esa pregunta! :-D

Voy a poner un ejemplo de un acumulador para que se vea claro para qué sirven. Suponed, por ejemplo, que quiero sumar los primeros 10 números naturales. Una posible solución sería esta:

 Declaración de variables
   ENTEROS: i,acum
 fin declaración variables

 inicio
 
 acum<-0
 desde i<-1 hasta i<=10 hacer
       acum<-acum+i
 fin desde
 
 mostrar por pantalla acum
 fin 

Probad a seguirle la pista al bucle, y decidme qué sale. ¿Lo sabríais escribir usando las otras dos estructuras repetitivas vistas hoy? Si es así, hacedlo }:-)

En el primer paso del bucle, acum vale 0, y le sumamos lo que vale i, que es 1. Vale, ahora acum vale 1. Se incrementa i y volvemos al cuerpo del bucle. Sumamos a acum lo que vale i. Ahora acum vale 1, e i vale 2; tras la suma, acum vale 3.

A eso es a lo que me refería antes, unas cuantas (pero cuántas) líneas atrás, cuando decía eso de "ACUMULADOR, cuya misión es almacenar una cantidad variable resultante de operaciones sucesivas y repetidas. Es como un contador, con la diferencia que el incremento/decremento es variable".

A diferencia de nuestro ejemplo REAL, en el que el incremento era siempre 1, aquí el incremento primero es 1, luego 2, luego 3... espero que con este ejemplo quede más claro, y si no, me pedís que ponga otro, y otro... hasta que lo entendais.

Otra nota (no sé cuántas llevo): podemos anidar los bucles. Esto es: dentro de un bucle, podemos ejecutar otro bucle, con la condición de que ese otro bucle esté COMPLETAMENTE CONTENIDO dentro del primero, si no, el algoritmo no es válido.

Por ejemplo: El caso más típico de bucle anidado es querer asignar valores a una matriz. Quien no sepa qué es una matriz, que espere al capítulo 7 del curso. Supongamos que nuestra matriz tiene por dimensiones 10 y 12, y queremos asignar valores a cada una de sus componentes. Esto lo haremos así:

 Declaración de variables
   A: Matriz(1..10,1..12) de ENTEROS
   ENTEROS: i,j {variables para recorrer la matriz}
 Fin declaración de variables

 Inicio
 
 desde i<-1 hasta i<=10 hacer
       desde j<-1 hasta j<=12 hacer
             A(i,j)<-i+j
       fin desde {j}
 fin desde {i}
 
 Fin 

Como veis, el bucle que gobierna la variable j está totalmente contenido dentro del bucle gobernado por la variable i, y, por cada iteración del bucle que dirige i, se ejecutan las 12 repeticiones del bucle dirigido por j. ¿Quién me dice cómo quedará nuestra matriz tras la asignación de valores que hemos hecho? Para no marearos, tomar las filas con la i, y las columnas con la j, como es usual en la notación de matrices.

Vamos ahora a por lo que a mí me gusta... los ejercicios };-D

  1. Suponed que teneis un vector de 20 componentes (ver el capítulo 7 del curso). Escribid un algoritmo que lo invierta, es decir, la componente 1 pasa a ser la 20, la 2 pasa a ser la 19, la 3 será la 18... y así con todas.
  2. Escribid un algoritmo que muestre por pantalla las tablas de multiplicar del 1 al 10. PISTA: Usad bucles anidados.
  3. Escribid un algoritmo que muestre por pantalla la suma de los cuadrados de los N primeros números.
  4. Escribid un algoritmo que calcule la media aritmética de una serie de N números.

Eso es todo (ahora sí), nos vemos en la próxima entrega, en la que hablaremos de... FUNCIONES Y PROCEDIMIENTOS.

COMPARTE ESTE ARTÍCULO

ENVIAR A UN AMIGO
COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN GOOGLE +
SIGUIENTE ARTÍCULO

HAY 2 COMENTARIOS
  • Anónimo dijo:

    Muy pero Muy interesante el articulo, solo que tengo una critica. Explican todo muy bien, pero donde se supone que tenemos que hacer los ejercisios, en que programa!!! en un notepad?? en un Word¡?¡ en un Exel?? en Dreamweaver?, en una hoja?? Aguardo su respuesta!! Gracias.

  • [email protected] dijo:

    En fortran !Ordenacionde vectores por el metodo de la Burbuja Program Ordena_burbuja integer,dimension(100)::x integer::i,j,k,n integer::temp print*,"Ingrese la cantidad de datos al vector" read*,n print*,"Ingrese datos al vector" read*,(x(i),i=1,n) print* !usando el algoritmo de ordenacion por la burbuja Do i=1,n-1 Do j=1,n-1 if (x(j)>x(j+1)) then temp=x(j) x(j)=x(j+1) x(j+1)=temp end if end do end do Print*,"Vector ordenado" Print*,(x(k),k=1,n) end program ordena_burbuja !Ordenacionde vectores por el metodo de seleccion Program Ordena integer,dimension(100)::x integer::i,j,min,n integer::temp print*,"Ingrese la cantidad de datos al vector" read*,n print*,"Ingrese datos al vector" read*,(x(i),i=1,n) print* !usando el algoritmo de ordenacion por seleccion Do i=1,n-1 min=i Do j=i+1,n if (x(j)<x(min)) then min=j end if temp=x(i) x(i)=x(min) x(min)=temp end do end do Print*,"Vector ordenado" Print*,(x(i),i=1,n) end program ordena atte William

Conéctate o Regístrate para dejar tu comentario.