TEMA 7.
- ESTRUCTURAS DE CONTROL, FUNCIONES Y PROCEDIMIENTOS
7.1. Introducción
Las estructuras de control te van a permitir manejar el flujo de ejecución de un
programa, posibilitándote repetir cierta sección de código un determinado
numero de veces, o hasta que se cumpla alguna condición.
Si recuerdas el teorema de la estructura, cualquier programa puede ser
modelado mediante la secuencia, selección o iteración de instrucciones, y
precisamente empezaremos por ver cual es la sintaxis de Visual Basic adecuada
para este propósito.
Por otro lado las funciones y procedimientos son porciones de código que
realizan tareas muy concretas y que pueden ayudarte a optimizar la producción
y mantenimiento de tus programas.
En el momento que termines este tema ya estarás en disposición de realizar
tus primeros programas sencillos y modelar algoritmos de baja complejidad con
código en Visual Basic .NET.
Programación .NET I . Estructuras de control y procedimientos 7.1
7.2. Estructuras de control
Selección
Mediante estas estructuras es posible fijar bifurcaciones en la ejecución del
código, permitiendo que se ejecuten o no un determinado bloque de sentencias
dependiendo del resultado de evaluar una cierta expresión.
Puedes ver estas sentencias de selección como un mecanismo de toma de
decisión sobre lo que hará tu programa en función de que se cumplan o no
algunas condiciones.
Dentro de las sentencias de selección se puede diferenciar entre las estructuras
de selección simple y las estructuras de selección múltiple es decir:
Estructura If / Then / Else
Estructura Select / Case
If ... Then ... Else
La estructura If / Then / Else la consideramos simple no por su
mayor o menor grado de complejidad si no por que la selección del
flujo de ejecución se basa en una única expresión booleana.
Si la expresión boolena devuelve un valor verdadero (True)
entonces se ejecutan las sentencias del bloque 1, de no cumplirse
se ejecutaran las sentencias del bloque 2, las que van detrás de la
palabra reservada Else
La sintaxis es la siguiente
If (Expresión booleana) Then
Bloque Sentencias 1
Else
Bloque Sentencias 2
End If
Ejemplo:
If x > 10 Then
WriteLine("Mayor que 10!")
Else
WriteLine("Menor que 10!")
End If
7.2 Programación .NET I . Estructuras de control y procedimientos
Select ... Case
La estructura Select / Case la consideramos compleja por que la
selección del flujo de ejecución se basa en la evaluación de una
expresión con múltiples valores.
La sintaxis es la siguiente
Select Case Expresión Evaluación
Case Expresión 1
Bloque Sentencias 1
Case Expresión 2
Bloque Sentencias 2
. . .
Case Else
Bloque Sentencias Else
End Select
El funcionamiento es sencillo, se evalúa la expresión de evaluación
con la Expresión 1, si coincide entonces se ejecuta el primer bloque
de sentencias, de no ser así se evalúa la expresión de evaluación
con la Expresión 2, si coincide entonces se ejecuta el bloque de
sentencias asociado, si no se evalúa la siguiente expresión… así
hasta que se encuentra alguna expresión de evaluación que coincida
o si no se ejecutará el bloque de sentencias Case Else
Ejemplo:
Select Case x
Case Is > 10
WriteLine("Case Mayor que 10!")
Case Else
WriteLine("Case Menor que 10!")
End Select
Programación .NET I . Estructuras de control y procedimientos 7.3
Ejemplo de sentencias de selección
Imports [Link]
Module Module1
Sub Main()
Dim x As Integer
Write("Introduzca un valor numérico: ")
x = ReadLine()
'Para saber si un numero es par basta con mirar el resto
'de su división entera entre 2, si el resto es 0 entonces
'el numero es par
If x Mod 2 = 0 Then
WriteLine("Es un numero par!")
Else
WriteLine("Es un numero impar!")
End If
ReadLine()
'Unas comprobaciones simples para saber en que rango
'está el número
Select Case x
Case Is > 100
WriteLine(x & " es mayor que 100!")
Case Is > 50
WriteLine(x & " es mayor que 50 y menor que 100!")
Case Is > 10
WriteLine(x & " es mayor que 10 y menor que 50!")
Case Else
WriteLine(x & " es Menor que 10!")
End Select
ReadLine()
End Sub
End Module
7.4 Programación .NET I . Estructuras de control y procedimientos
Iteración
bloque de sentencias, lo que también se denomina bucle. Cuando decimos que
la repetición es finita es que el número de veces que se repetirá el bucle debe
llegar a cero en algún momento.
Es este numero de iteraciones lo que nos ofrece una aproximación a la
clasificación de las distintas sentencias de iteración: las estructuras de iteración
con un numero conocido de repeticiones y las estructuras de iteración basadas
en una condición:
Estructura For / Next
Estructura Do (While | Until)/ Loop
Es muy importante tener en cuenta que tanto si usamos la estructura For / Next
o los bucles Do / Loop siempre hay que proveer un mecanismo para que el
bucle termine en algún momento y no se quede dando vueltas indefinidamente.
For ... Next
Es la mas sencilla de emplear cuando se conoce el numero de
iteraciones del bucle a priori. Estos bucles se basan en un contador,
que indicara cuantas pasadas (iteraciones) se llevarán a cabo.
Su uso es bien sencillo: al contador se le asigna un valor inicial y un
valor final (y opcionalmente un valor de incremento/decremento
para cada pasada) , el bloque de sentencias se irá repitiendo,
contando las veces que se repite desde el valor inicial hasta alcanzar
el valor final... o si lo prefieres ver de esta manera, el numero de
iteraciones es igual a la diferencia entre el valor final y el valor inicial.
La sintaxis es la siguiente
For x = valor_inicio To valor_fin (paso)
sentencias()
Next
Ejemplo:
For x = 1 To 10
WriteLine("Iteracion: " & x)
Next
Programación .NET I . Estructuras de control y procedimientos 7.5
Do ... Loop
Este tipo de bucles se basan en una condición, es decir que a priori
no vamos a conocer el número de iteraciones y por lo tanto las
sentencias se repetirán mientras (o hasta) que se cumpla
determinada condición booleana
Estos bucles se pueden presentar de cuatro formas distintas,
dependiendo de si se evalúa la condición antes de entrar en la
repetición del bloque de sentencias o si bien la condición se evalúa
a la salida. Por otro lado hay que considerar si el bucle se repite
mientras se cumpla la condición (While) o hasta que se cumpla la
condición (Until)
Do While condition_booleana
1
sentencias
Loop
Do Until condition_booleana
2
sentencias
Loop
Loop
3 sentencias
Do Until condition_booleana
Loop
4 sentencias
Do While condition_booleana
Por norma general para expresar una estructura Do While / Loop se
emplea otra sintaxis, mucho más extendida pero que ofrece la
misma funcionalidad, esta sintaxis es:
While condition_booleana
sentencias
End While
7.6 Programación .NET I . Estructuras de control y procedimientos
Ejemplo de bucles
Imports [Link]
Module Module1
Sub Main()
Dim i, x As Integer
Dim password As String = ""
For i = 1 To 10 Step 2
WriteLine("Iteracion adelante de dos en dos: " & i)
Next
ReadLine()
For i = 10 To 1 Step -1
WriteLine("Iteracion hacia atras: " & i)
Next
ReadLine()
Do Until password = "sesamo"
Write("Introduce una contraseña: ")
password = ReadLine()
If password <> "sesamo" Then
WriteLine("Contraseña incorrecta, velve a
intentarlo")
Else
WriteLine("Contraseña correcta !!")
End If
Loop
x = 1
Do While x < 10
‘ [Link] determina el color de fondo
[Link] = x
WriteLine("Valor: " & [Link])
x += 1
Loop
ReadLine()
End Sub
End Module
Programación .NET I . Estructuras de control y procedimientos 7.7
Anidando estructuras de control
Puedes colocar instrucciones de control dentro de otras instrucciones de control,
por ejemplo un bloque If...Then...Else dentro de un bucle For...Next. Cuando
una instrucción de control se coloca dentro de otra, se dice que está anidada.
Sin embargo debes tener cuidado de no cruzar las estructuras, es decir, no
puedes solapar el final de una de ellas con el principio de otra, cualquier
estructura anidada debe estar completamente incluida dentro de la siguiente
estructura más profunda.
Si por alguna razón no anidas las estructuras correctamente tu código no
compilará.
Ejemplo de bucles mal anidados
Sub Main()
Dim i, x As Integer
i = 20
If i > 10 Then
For x = 1 To i
WriteLine("valor de la iteración: " & i + x)
End If
Next
End Sub
7.8 Programación .NET I . Estructuras de control y procedimientos
7.3. Funciones y Procedimientos
Qué son y por qué usarlos
Es muy posible que ya sepas algo sobre las funciones y los procedimientos,
sobre todo si has programado con anterioridad o si has prestado atención a los
primeros temas del curso, pero podemos repasar la definición como “segmentos
de código que realizan unas tareas muy concretas, que pueden aceptar valores
de entrada (denominados parámetros) y que pueden devolver (o no) valores
de salida”.
Aunque es una definición muy genérica, más adelante entraremos en el detalle,
lo que es interesante saber es por qué usar las funciones y procedimientos.
Aquí tienes cuatro razones:
Calidad del código, rapidez de desarrollo
Divide y vencerás
Cambiar y actualizar
Reutilizar (cajas negras)
Calidad del código, rapidez de desarrollo
Cuando estas llevando a cabo un desarrollo pequeño es bastante
sencillo programar y probar el código, sin embargo en desarrollos
más grandes esta labor puede ser complicada.
Al separar la funcionalidad en procedimientos y funciones es más
sencillo limitarse a una sección de código concreta que puede ser
depurada y probada exhaustivamente hasta asegurarnos de que
hace lo que realmente queremos sin tener que preocuparnos por el
resto del código de la aplicación
Otra ventaja de separar código por procedimientos y funciones es
que se puede involucrar a más de una persona de manera
simultánea en el proceso de desarrollo, asignando a cada una de
ellas la programación de funciones y procedimientos concretos sin
que esto suponga interferencias entre el trabajo de unos y otros
Programación .NET I . Estructuras de control y procedimientos 7.9
Divide y vencerás
Ante la resolución de un problema de complejidad considerable
puede ser muy recomendable abordarlo utilizando la metodología
de “divide y vencerás” que no es mas que intentar fraccionar el
problema a resolver en varios problemas más pequeños o de menor
complejidad.
En estas situaciones es cuando el uso de funciones y procedimientos
es muy útil, en lugar de pensar en una aplicación como un todo de
gran complejidad puedes pensar en un conjunto de funciones o
procedimientos cada uno de los cuales resuelve una cuestión más
específica.
Por ejemplo, puedes pensar en una compleja operación en un
quirófano, seguramente será llevada a cabo por varios cirujanos,
anestesistas y auxiliares, cada uno de los cuales es un especialista
en su campo, sería impensable que una única persona llevará a cabo
todo el trabajo.
Por lo tanto cuando hagas tus programas puedes pensar en las
funciones y procedimientos como en los especialistas que van a
llevar a cabo cada una de las tareas que comprenden todo el
proceso.
7.10 Programación .NET I . Estructuras de control y procedimientos
Cambiar y actualizar
Otra gran ventaja del uso de funciones y procedimientos es que se
implementan una sola vez pero se pueden usar todas las veces que
queramos en nuestro código.
Al estar implementada la funcionalidad en una única parte del
programa (y no repetida en varios sitios), en caso de que necesites
llevar a cabo algún cambio o actualización solo tendrás que hacerlo
en un único lugar, sin tener que preocuparte de revisar el resto del
código fuente.
Reutilización del códigor
Una vez que tengas un conjunto de procedimientos y funciones bien
probados es una buena idea hacer una recopilación de los mismos
en librerías, de esta manera no solo podrás usarlo en el proyecto
donde fueron desarrolladas sino que te resultarán útiles para usarlas
más adelante en otros proyectos.
Es lo que se denomina “caja negra”, de hecho solo tendrás que
acordarte del nombre y parámetros de la función o procedimiento,
y obviar como esta implementado.
No necesitas conocer como esta hecho un microondas, para saber
que introduciendo los alimentos y definiendo el tiempo obtendrás
comida caliente.
Programación .NET I . Estructuras de control y procedimientos 7.11
Funciones
Las funciones son subprogramas que aceptan uno o varios parámetros de
entrada y devuelven un único valor de salida.
La sintaxis en visual Basic .Net es la siguiente:
Function miFuncion(ByVal var As Tipo, ..) As TipoRetorno
miFuncion = valor_de_retorno
End Function
Como se aprecia para que la función devuelva un valor se asigna al nombre de
la función dicho valor, aunque otra forma de hacerlo sería mediante la clausula
Return
Function miFuncion(ByVal var As Tipo, ..) As TipoRetorno
Return valor_de_retorno
End Function
Para hacer uso, de una función, lo que se denomina comúnmente como llamar
a la función o invocar a la función, lo único que hay que hacer es escribir el
nombre de la función con los parámetros de entrada que pudiera tener.
Dado que las funciones devuelven un valor de retorno es importante tener en
cuenta que dicho valor debe recogerse en alguna variable o formar parte de
alguna expresión
7.12 Programación .NET I . Estructuras de control y procedimientos
Ejemplo de función
Imports [Link]
Module Module1
Function es_mayor(ByVal a As Integer, ByVal b As Integer) As Boolean
If a > b Then
es_mayor = True
Else
es_mayor = False
End If
End Function
Sub Main()
Dim uno, dos As Integer
Write("introduce el primer numero: ")
uno = ReadLine()
Write("introduce el segundo: ")
dos = ReadLine()
If es_mayor(uno, dos) Then
WriteLine("El primer numero introducido es mayor")
Else
WriteLine("El segundo numero introducido es mayor")
End If
ReadLine()
End Sub
End Module
Programación .NET I . Estructuras de control y procedimientos 7.13
Procedimientos
Un procedimiento es un subprograma que agrupa una sentencia o grupo de
sentencias que realizan una acción, y permiten darles un nombre por el que se
puedan identificar posteriormente
Los procedimientos aceptan cero, uno o varios parámetros de entrada pero a
diferencia de las funciones no se declara el tipo de valor del resultado, dado
que los procedimientos no están pensados para retornar ningún valor calculado.
Sin embargo más adelante verás que se pueden utilizar los procedimientos para
devolver valores, incluso más de uno, algo que no se puede hacer con una
función.
La sintaxis de un procedimiento es la siguiente:
Sub miProcedimiento(ByVal var As Tipo, ..)
sentencias
End Sub
Para usar un procedimiento, basta con llamarlo por su nombre entregándole
además sus posibles parámetros de entrada en caso de que los tenga.
7.14 Programación .NET I . Estructuras de control y procedimientos
Ejemplo de procedimiento
Imports [Link]
Module Module1
Sub mostrar_mayor(ByVal arr As Integer())
' en la variable cuantos guardamos la posición del último elemento
' del array, en la variable mayor guardamos el mayor numero
' encontrado hasta el momento, en la variable posición, almacenamos
' la posición del elemento mayor
Dim cuantos, mayor, posicion, i As Integer
' en la variable cuantos guardamos la longitud del array
cuantos = [Link] - 1
' ejecutamos un bucle con un total de pasadas igual al numero
' de elementos el obejtivo es ir almacenando el mayor numero
' que vayamos encontrando
For i = 0 To cuantos
' en la primera pasada suponemos que el mayor es el primer elemento
' del array
If i = 0 Then
mayor = arr(0)
posicion = 0
Else
' en pasadas posteriores comprobamos si el elemento del array
' de la pasada actual es mayor que el encontrado hasta el
' momento, de ser así nos quedamos con el como numero mayor y
' apuntamos en que posición lo hemos encontrado
If arr(i) > mayor Then
mayor = arr(i)
posicion = i
End If
End If
Next
Programación .NET I . Estructuras de control y procedimientos 7.15
' mostramos el resultado por pantalla
WriteLine("El numero mayor es :" & [Link] &
" y se encuentra en la posición " & [Link])
ReadLine()
End Sub
Sub Main()
'Inicializamos un array con varios números
Dim array_nums() As Integer = New Integer(4) {57, 18, 112, 500, 4}
' llamamos a la función que muestra el mayor
mostrar_mayor(array_nums)
Dim array_nums2() As Integer = New Integer(6) {57, 18, 112, 500, 4,
8000, 20}
mostrar_mayor(array_nums2)
End Sub
End Module
7.16 Programación .NET I . Estructuras de control y procedimientos
Parámetros por referencia y valor
Hasta el momento en la definición de la sintaxis tanto de funciones como de
procedimientos los parámetros de entrada venían precedidos de la palabra
reservada ByVal, esto quiere decir que lo que se le pasa a la subrutina es una
copia del valor de la variable y cualquier cambio que se realice de dicho valor
dentro de la subrutina no va a afectar al valor de dicha variable fuera de la
subrutina.
Sin embargo en ocasiones necesitamos que los valores de los argumentos
retornen alterados desde las subrutinas en las que son utilizados. En este caso
se debe utilizar en la definición de la subrutina la palabra reservada ByRef, es
lo que se conoce como pasar el parámetro por referencia. De esta manera no
se pasa una copia del valor de la variable, sino la dirección en memoria de la
variable misma, de tal forma que cualquier cambio se verá reflejado en la
variable después de abandonar la subrutina.
En el siguiente ejemplo puedes observar el distinto comportamiento de dos
procedimientos de lógica idéntica pero con distinto paso de parámetros
Programación .NET I . Estructuras de control y procedimientos 7.17
Ejemplo de parámetros por valor y por referencia
Imports [Link]
Module Module1
Sub dobla_por_valor(ByVal var As Integer)
var = var * 2
WriteLine("Valor de X dentro del procedimiento por
valor: " & var)
End Sub
Sub dobla_por_referencia(ByRef var As Integer)
var = var * 2
WriteLine("Valor de X dentro del procedimiento por
referencia: " & var)
End Sub
Sub Main()
Dim x As Integer
x = 2
WriteLine("Contenido de X antes de pasar por el
procedimiento: " & x)
dobla_por_valor(x)
WriteLine("Contenido de X despues de pasar por
el procedimiento por valor: " & x)
dobla_por_referencia(x)
WriteLine("Contenido de X despues de pasar por
el procedimiento por referencia: " & x)
End Sub
End Module
7.18 Programación .NET I . Estructuras de control y procedimientos