Curso Básico de Programación
en Visual Basic
Sexta
Entrega: 11/Ago/97.
por Guillermo "guille" Som
Si quieres linkar con las otras entregas, desde el índice lo puedes hacer
![]()
Solución
de los ejercicios de la Quinta Entrega
Pulsa este link para ver la
solución de los ejercicios de la quinta entrega (aunque el nombre la
página sea: basico06_sol)
Como hemos
visto en el apéndice de la entrega anterior, la instrucción
IF... THEN... nos permite tomar decisiones según el valor de una
variable o el resultado de una expresión. En esta entrega
veremos como sacarle rendimiento a esta instrucción.
Pero antes de entrar en detalles, veamos cómo podemos decirle al
Basic que haga las cosas. En realidad vamos a ver la forma en que
se le puede decir que las haga...
Forma de
especificar las instrucciones en Visual Basic
Las instrucciones en Basic no tienen porqué estar cada una en
una línea. Se pueden escribir varias instrucciones en la misma
línea, pero separándo cada una de ellas con el signo : (dos puntos).
Cuando VB encuentra los dos puntos, deja de 'interpretar' la
instrucción y pasa a la acción, una vez traducido a su lenguaje
interno, toma lo que hay después del signo : y sigue su camino en busca de
más instrucciones o el final de la línea.
Veamoslo de forma práctica:
Nombre =
"Pepe" : Print Nombre
Esta línea tiene dos instrucciones: una asignación y una
instrucción Print.
Podemos poner cuantas instrucciones queramos, separadas con los
dos puntos.
Pero, (siempre hay un pero), si una de las instrucciones es el
IF/THEN la cosa puede cambiar...
Ya vimos que IF comprueba la expresión que viene a continuación, si es cierta, ENTONCES procesa lo que haya después de THEN. En caso de ser en la misma línea, interpretará todas las instrucciones que estén a continuación; en caso de ser un bloque IF... THEN... END IF, ejecutará todo lo que esté dentro de ese bloque. Ahora bien, si la expresión es falsa pasa a la siguiente línea, tanto si es o no un bloque. En el caso del bloque la siguiente línea a interpretar será la que esté después de END IF.
En los tiempos del BASIC interpretado de MS-DOS, era habitual encontrar las líneas con varias instrucciones separadas por dos puntos. En mi caso, cuando empecé a usar el QuickBasic 2.0 y al poder usar bloques IF... THEN... END IF, fui dejando a un lado el "mogollón" de instrucciones en la misma línea... Ahora prácticamente y salvo contadas excepaciones, escribo cada instrucción en una línea.
Después de
este pequeño respiro, veamos cómo estaría formada una línea
de VB para usar con un IF... THEN...
[instrucciones:] IF
<expresión> THEN <instrucciones si es cierto [:más
instrucciones...]>
A continuación de THEN podemos incluir cuantas instrucciones
queramos, separadas por dos puntos.
Estas sólo se ejecutarán cuando la expresión sea cierta. Si el
resultado de la expresión es falso, se obvia 'todo' lo que hay
después de THEN y se pasa a la siguiente línea.
Espero que lo hayas asimilado y que no te indigestes con lo
siguiente...
Pero, (...),
existe otra instrucción que PUEDE acompañar al IF... THEN... y
es para los casos en los cuales el resultado de la expresión sea
FALSO.
Si, ya sé que dije que cuando es falso se pasa a la siguiente
línea, pero eso es cuando no se usa la cláusula ELSE.
Con ésta, la definición de la instrucción "tomadora de
decisiones" quedaría así:
IF <expresión>
THEN <si se cumple> ELSE <si no se cumple>
Tanto en <si se
cumple>
como en <si no se
cumple>
pondremos tantas instrucciones como queramos, (separadas por dos
puntos).
Pero no te recomiendo que lo hagas, es preferible, al menos para darle "claridad" a nuestro código, usar el bloque:
IF <expresión> THEN
<si se cumple>
ELSE
<si no se cumple>
END IF
Sé que esto puede ocupar más líneas de código, pero nuestro "coco" lo agradecerá, ya que es más fácil de comprender, sino veamos un ejemplo:
IF numero > limite THEN
Print "tu número es grande"
ELSE
Print "OK, McKey!"
END IF
Ahora veamoslo
en una sóla línea:
IF numero > limite
THEN Print "tu número es grande" ELSE Print "OK,
McKey!"
En este ejemplo, aún queda claro, pero lo podríamos complicar con más instrucciones para ambos casos, es decir, para cuando la expresión es cierta y también cuando es falsa.
En los tiempos
del BASIC que venían incorporados con los ordenadores, cada
línea del programa había que numerarla, ya que todo lo que se
escribía sin número de línea, se ejecutaba inmediatamente; al
igual que ocurre con lo que se escribe en la ventana Inmediate
del Visual Basic.
Los números de líneas se usaban, además de porque era
obligatorio, para cambiar el orden de ejecución, sobre todo
después de una comparación. De esta forma, aún sin tener
bloques IF/THEN/ELSE/END IF, se podían simular.
¿Cómo se lograba?
Usando una instrucción que muchos creen que es "indecente,
antisocial, etc"
La
estrella del Basic: (redoble de tambores) "GOTO"
A partir de hoy, más de un purista de la programación no me
dirigirá la palabra... pero no me importa...
Se ha
"denostado" (injuriado) con exageración el uso de esta
instrucción. Realmente es una instrucción de
"bifurcación", es decir, sirve para "IR A"
otro sitio de nuestro programa.
Su uso ha sido el más criticado de los NO PARTIDARIOS del Basic
y siempre han basado sus críticas en el exagerado uso del GOTO
en todos los programas Basic. Pero aclaremos que C también tiene
esta instrucción y que cualquier programa en código máquina
(ensamblador) está "plagado" de JMP que para el caso
es lo mismo que el sufrido GOTO, realmente una instrucción GOTO
número_linea se convierte en JMP número_linea.
No voy a
recomendar el uso del GOTO, para nada, ya que hoy día es
innecesario su uso. Antes no teníamos más remedio, porque el
BASIC no disponía de instrucciones para poder estructurar el
código. Pero sería una tontería querer hacer creer que no
existe esta instrucción. Sabiendo que está y cómo podemos
evitarla, es preferible a decir que no existe y si por casualidad
la descubres... a que la uses.
Por tanto, insisto en mi recomendación, (de esta forma los
PURISTAS volverán a dirigirme la palabra), NO USES EL GOTO, ni
aún cuando creas que no tienes más remedio... aunque, aquí
entre nosotros, algunas veces es más cómodo usarlo... pero que
no se entere nadie...
Este es un programa de los de antes, sirve para mostrar en pantalla los números del 1 al 10 y sin usar el FOR/NEXT
10 A = 1 20 Print A 30 A = A + 1 40 IF A <= 10 THEN GOTO 20 'Con el Commodore este programa se solía escribir así: 10 A=1 20 PRINTA:A=A+1:IFA<=10GOTO20 'Sin ESPACIOS NI NADA... TODO APELMAZADO... ¿que más daba usar el GOTO?
Imagine there's no heaven... (es que está sonando J.Lennon... un momento...)
En este ejemplo, es obvio que podríamos sustituirlo con:
10 For A = 1 To 10 20 Print A 30 Next
El NEXT hace
lo mismo que la asignación y la comparación.
Pero hay otras maneras, para ello existe una serie de
instrucciones que funcionan de manera similar, veamos otros
ejemplos con más instrucciones para hacer bucles, seguiré
usando los números de línea por aquello de la
"nostalgia", pero salvo en el primer ejemplo, en los
demás no es necesario.
10 A = 1 20 While A <= 10 30 Print A 40 A = A + 1 50 Wend
El WHILE/WEND
ya casi ni se usa, porque tienen un sustituto más versátil,
ahora lo veremos, pero el uso sería:
WHILE <expresión>
<instrucciones si se cumple>
WEND
Es decir, MIENTRAS la expresión sea cierta, repite todo lo que
haya hasta el WEND.
Por supuesto podemos ponerlo todo en una sóla línea:
10 A = 1 : While A <=
10 : Print A : A = A + 1 : Wend
Pero esto
tampoco es recomendable, queda algo "difuso"...
El WEND funciona como IF A <=10 THEN GOTO xxx, con la ventaja
que evitamos el GOTO y lo que hace es comprobar si la expresión
que hay tras el WHILE es cierta o no, en caso de que sea
verdadero el resultado, (ya sabes, distinto de CERO), se
ejecutará todo lo que hay entre WHILE y WEND. Estas
instrucciones ya existían en el GWBASIC (el basic de los PCs)
Hay que tener cuidado con esto de que la expresiones evaluan el cero como FALSO y cualquier otro valor como VERDADERO, por ejemplo:
A = 1 o
While A While 1
Print A Print A
A = A + 1 A = A + 1
Wend Wend
En ambos casos el bucle sería "infinito", realmente se detendría en un momento dado, ya que llegaría a "desbordarse" el valor máximo y en ese momento el programa acabaría por producirse un error... pero prueba esto y verás:
While 1
Print "Hola Mundo"
Wend
Esto nunca finalizará, salvo que pulses CRTL+BEAK (o INTERrumpir), para detener el programa.
Más
instrucciones para hacer bucles
Con el QuickBasic 3.0, (yo no llegué a tenerlo, pero creo que
fue ahí dónde se introdujo), entró en funcionamiento una nueva
forma de hacer bucles:
DO... LOOP
El último ejemplo podríamos escribirlo así:
Do
Print "Hola Mundo"
Loop
Pero la
"gracia" de este tipo de bucle es que podemos usar dos
nuevas cláusulas para evaluar cuanto durará el bucle.
La primera es WHILE y funciona igual que en WHILE/WEND
A = 1 Do While A <= 10 Print A A = A + 1 Loop
La ventaja es
que WHILE se puede poner tanto después de DO como a
continuación de LOOP.
Si lo usamos como DO WHILE <expresión>... la forma de
actuar es igual que WHILE/WEND, es decir, se evalua la expresión
y sólo en caso de que sea cierta, se ejecta lo que está dentro
del bucle, es decir entre DO y LOOP.
Pero si evaluamos la expresión en LOOP, se ejecutará todo lo
que hay tras el DO, como mínimo una vez y se seguirá repitiendo
si se cumple la condición. De esta forma, como he dicho, se
ejecutará el contenido del bucle, como mínimo una vez.
Veamos un ejemplo:
A = 1 Do Print A A = A + 1 Loop While A <= 10
El problema es
que si A, en lugar de valer 1, tiene un valor superior a 10,
también se ejecutará, al menos, una vez.
A = 11 : Do : Print A: A
= A + 1: Loop While A <= 10
Que mal queda en una sóla línea, ¿verdad?
Pero con DO/LOOP también puede usarse UNTIL, en este caso, el bucle se repetirá HASTA que se cumpla la expresión
A = 1 Do Until A > 10 Print A A = A + 1 Loop
Fijate que la
expresión ha cambiado de <= (menor o igual) a > (mayor),
ya que ahora se evalúa de esta forma:
Hasta que A sea mayor que diez, REPITE todo hasta LOOP.
Por suepuesto también podemos usarlo después del LOOP:
A = 1 Do Print A A = A + 1 Loop Until A > 10
Aquí hago la
misma aclaración que antes, si el valor incial de A es más de
10 se ejecutará como mínimo una vez.
Realmente para contar de forma secuencial y prácticamente para
casi todo tipo de bucle, no es necesario hacer los bucles con
DO/LOOP, ya que FOR/MEXT lo hace bastante bien.
Sigamos con estos bucles, pero en lugar de contar de menor a mayor, vamos a contar "pa trás", es decir de mayor a menor... quién sabe, lo mísmo necesitas hacer un programa que cuente al revés...
A = 10 Do While A >= 1 Print A A = A - 1 Loop
Cuando se muestre el 1, A=A-1 se convertirá en A = 0 y la comparación A >= 1 no se cumplirá, por tanto dejará de repetirse el bucle, pero esto también se puede hacer con FOR/NEXT:
For A = 10 To 1
Print A
Next
El único
inconveniente es que NO SE REPITE NI UNA VEZ... ¿Por qué?
Porque si no se le indica lo contrario, FOR/NEXT siempre cuenta
de forma ascendente y cuando ve que A debe ir de 10 hasta 1 y que
eso no es ascendente... pasa de ejecutar el bucle. Esto es una
cosa a tener en cuenta, FOR siempre evalúa los valores del bucle
que tiene que hacer y si no está entre los valores que debe, no
se ejecuta ni una sola vez. En este caso debe empezar por DIEZ y
llegar hasta UNO, así que se da cuenta de que ya ha terminado...
incluso sin haber empezado... ¡que listo es el FOR!
Para que el
FOR cuente hacia atrás, necesitamos un nuevo peldaño (esto en
inglés quedaría "clavado"), en la escala evolutiva
del FOR/NEXT (ahí queda eso!!!)
Ya sin coñas, se necesita la palabra STEP para indicarle que no
queremos ir de uno en uno de forma ascendente, en nuestro ejemplo
lo usariamos así:
For A = 10 To 1 Step -1
Print A
Next
De esta forma
contará desde 10 hasta 1, restando uno en cada repetición.
Pero, ¿que hacer si queremos usar otros valores?
Simplemente ponerlo después de STEP, por ejemplo:
For A = 10 To 1 Step -1
For A = 1 To 10 Step 3,
etc, etc.
Insisto, todo
esto está muy bien, pero en la práctica usaremos otras cosas
además de contar de forma lineal, con incrementos o sin ellos...
habrá veces que queramos salir de un bucle.
Ya lo hemos visto, por ejemplo Exit Sub salía del procedimiento,
¿recuerdas el Exit For?
Para salir de los bucles podremos Exit y a continuación For, Do,
etc. Pero NO podremos salir de un bucle WHILE/WEND.
Ya veremos ejemplos para estos casos y otros que surgirán más
adelante.
Bien, creo que ya hemos dado demasiadas vueltas con tanto bucle, para terminar: los ejercicios esos que tanto os gustan.
1.) Haz un programa que al pulsar en un botón (CommandButton) haga un bucle entre dos valores que habrás introducido por medio de dos cajas de textos (una para el inicio y otra para el final)
2.) Otro que tenga una tercera caja de textos y que el valor introducido en ella sea el incremento.
3.) Como
tercer ejercicio, una vez terminado el bucle, que muestre en un
Label las veces que se ha repetido.
Por ejemplo, si hacemos un bucle del uno al diez de uno en uno,
se repetirá diez veces; pero si lo hacemos de dos en dos, se
repetirá cinco veces...
Como pista, decirte que no tendrás que hacer ninguna
comparación para obtener el resultado, la solución es tan
SIMPLE que seguramente la descartarás "porque no puede ser
tan fácil"
Por supuesto, me gustaría que los bucles los hicieras tanto con FOR/NEXT y DO/LOOP. Ya puestos, podrías hacerlo con el WHILE/WEND e incluso con el GOTO...
¡Feliz programación!
Y seguimos con
la costumbre esta de pedirte tus comentarios sobre el curso.
Sobre todo necesito saber si realmente está claro y
entendible... ya que si no no valdrá para mucho el montón de
horas que le dedico a cada una de las entregas... si, aunque no
te lo creas, le dedico más de 5 horas a cada entrega...
Si no pasa
nada raro, seguramente en este mismo mes habrá una nueva
entrega.
Nos vemos.
Guillermo
![]()