Funciones y Procedimientos en VB.net

Fecha: 20/Feb/05 (18 de Febrero del 2005)

Autor: Jesús Enrique Gonzáles Azcarate

Email: [email protected]

 


 

La diferencia entre las dos es que las primeras (Sub) no retornan valores y las segundas (Function) si.

Ninguna de las dos puede definirse dentro de una misma  función o un procedimiento.

Se pueden definir dentro de un módulo, clase, interfaz o estructura.

Ambos métodos son por defecto públicos y los parámetros que se les pasa por defecto son por valor ByVal, que significa que lo que hace una copia de la variable al parámetro. 

ByRefl para la dirección de la variable.

 

Veamos como se define una función

 

 

Public Sub Mostrar(ByVal a As Short)

 

End Sub

 

Y un procedimiento

 

Public Function Mostrar(ByVal a As Short)  As Integer

 

Return 0

End Function

 

Ahora, de una función se puede salir de las siguiente maneras:

 

Primera forma

 

Function Muestra() as String

Muestra =”cadena a retornar”

End Function

 

Segunda forma

 

Function Muestra() as String

Return ”cadena a retornar

End Function

 

El siguiente ejemplo aclarará lo expuesto tanto para las funciones como para los procedimientos

 

Option Strict On

OPTION Explicit On

Module Module1

    Public Sub MOSTRAR(ByVal X As Integer, ByVal Y As Integer)

        Console.WriteLine("Valor de A después de asignarselo a x={0} al entrar a la función", X + 1)

        Console.WriteLine("Valor de A después de asignarselo a y={0} al entrar a la función", Y + 1)

        'Para salir de la función se puede hacer de dos maneras,

        'primera forma, se ha colocado en comentario pero se puede usar cualquiera de las

        'dos "Return"

 

        'Return

 

        'segunda forma "Exit Sub"

        Exit Sub

    End Sub

    Public Function ProdMOSTRAR(ByVal X As Integer, ByVal Y As Integer) As Integer

        Console.WriteLine("Valor de A después de asignarselo a x={0} al entrar a la función", X + 1)

        Console.WriteLine("Valor de A después de asignarselo a y={0} al entrar a la función", Y + 1)

        'Para salir de un procedimiento se puede hacer de dos maneras,

        'primera forma, se ha colocado en comentario pero se puede usar cualquiera de las

        'dos "Return valor_o_cadena_a_retornar"

 

        'Return X + Y

 

        'segunda forma "MOSTRAR = X + Y"

 

        ProdMOSTRAR = X + Y

 

    End Function

 

    Sub Main()

        Dim A As Integer = 2, B As Integer = 5, c As Integer

        Console.WriteLine("Valor inicial de A={0}", A)

        Console.WriteLine("Valor inicial de B={0}", B)

        MOSTRAR(A, B)

        c = ProdMOSTRAR(A, B)

        Console.WriteLine("Valor final de A={0}", A)

        Console.WriteLine("Valor final de B={0}", B)

        Console.WriteLine("Observe que después de salir tanto de la función MOSTRAR(A, B), como del procedimiento c=ProdMOSTRAR(A, B), las variables A y B")

        Console.WriteLine("conservan los valores iniciales.  Quiere decir que los parámetros")

        Console.WriteLine("son copias de las variables originales y las originales no sufren modificaciones")

        Console.WriteLine("La razón es por la palabra que vb.net le coloca antes de cada parámetro ByVal (por valor)")

        Console.WriteLine("Sin embargo la función no retorna valores y el procedimiento si ")

        Console.WriteLine("Este es el resultado de lo que retorna el procedimento {0}", c)

        Console.WriteLine("Después de realizar la siguiente operación ProdMOSTRAR = X + Y")

        Console.Read()

    End Sub

 

End Module

 

** Ahora veremos un ejemplo cuando los parámetros son por referencia.

Option Strict On

OPTION Explicit On

Module Module1

    Public Sub MOSTRAR(ByRef X As Integer, ByVal Y As Integer)

        X += 1 'Incrementa en 1 el valor de la variable x y X=A

        Console.WriteLine("Valor de A después de asignarselo a x={0} al entrar a la función", X)

        Console.WriteLine("Valor de B después de asignarselo a y={0} al entrar a la función", Y)

        'Para salir de la función se ´puede hacer de dos maneras,

        'primera forma, se ha colocado en comentario pero se puede usar cualquiera de las

        'dos "Return"

 

        Return

 

        'segunda forma "Exit Sub"

        'Exit Sub

    End Sub

    Public Function ProdMOSTRAR(ByVal X As Integer, ByRef Y As Integer) As Integer

        'Para salir de un procedimiento se puede hacer de dos maneras,

        'primera forma, se ha colocado en comentario pero se puede usar cualquiera de las

        'dos "Return valor_o_cadena_a_retornar"

        Y *= 2

        Return X + Y

 

        'segunda forma "MOSTRAR = X + Y"

 

        'ProdMOSTRAR = X + Y

 

    End Function

 

    Sub Main()

        Dim A As Integer = 2, B As Integer = 5, c As Integer

        Console.WriteLine("Valor inicial de A={0}", A)

        Console.WriteLine("Valor inicial de B={0}", B)

        MOSTRAR(A, B)

        Console.WriteLine("Valor final de A después de salir de la función={0}", A)

        Console.WriteLine("Valor final de B después de salir de la función={0}", B)

        c = ProdMOSTRAR(A, B)

        Console.WriteLine("Valor final de A después de salir del procedimiento={0}", A)

        Console.WriteLine("Valor final de B después de salir del procedimiento={0}", B)

        Console.WriteLine("Observe que después de salir de la función MOSTRAR(A, B) A cambió de valor")

        Console.WriteLine(" y después de salir del procedimiento B también cacmbió de valor")

        Console.WriteLine("realmente lo que se pasa al parámetro es la dirección de memoria")

        Console.WriteLine("quiere decir que la varible X en la función apunta a A y cualquier modificación que")

        Console.WriteLine("se haga sobre la varible X en la funcion también se realizará en la variable A")

        Console.WriteLine("Sucede lo mismo en el caso del procedimiento. Este es el resultado de lo que retorna el procedimento {0}", c)

        Console.WriteLine("Después de realizar la siguiente operación  Y *= 2 y ProdMOSTRAR = X + Y")

        Console.Read()

    End Sub

 

End Module

 

Cuyo resultado debe ser como el siguiente:

 

 

Si no han entendido, el siguiente ejemplo terminará por aclarar (creo).

 

Option Strict On

OPTION Explicit On

Module Module1

   

    Public Function ProdMOSTRAR(ByRef X As Integer) As Integer

        X -= 1

        Console.WriteLine("X={0}", X)

        Return X

    End Function

 

    Sub Main()

        Dim A As Integer = 10

        Console.WriteLine("Valor inicial de A={0}", A)

        Do While A > 0

            ProdMOSTRAR(A)

        Loop

        Console.WriteLine("Valor final de A después de salir del procedimiento={0}", A)

        Console.Read()

    End Sub

 

End Module

 

Cuyo resultado debe ser como el siguiente:

 

 

O este otro ejemplo

 

 

Option Strict On

OPTION Explicit On

Module Module1

   

    Public Function ProdMOSTRAR(ByVal X As Integer) As Integer

        X -= 1

        Console.WriteLine("X={0}", X)

        Return X

    End Function

 

    Sub Main()

        Dim A As Integer = 10, b As Integer = 1

        Console.WriteLine("Valor inicial de A={0}", A)

        Do While A > 0

            ProdMOSTRAR(A)

            'Observe se ha hecho uso de una variable auxiliar para detener el ciclo

            'porque de lo contrario llegará hasta que alcance el máximo

            'de la variable integer y ocurrirá un error

            b += 1

            If b = 10 Then

                Exit Do

            End If

        Loop

        Console.WriteLine("Valor final de A después de salir del procedimiento={0}", A)

        Console.Read()

    End Sub

 

End Module

 

 

Cuyo resultado debe ser como el siguiente:

 

 

Matrices de parámetros

 

La palabra clave ParamArray permite a una función aceptar un número variable de argumentos.

 

Un argumento ParamArray debe declararse como un tipo de matriz unidimensional. La declaración no incluye parámetros después del nombre de argumento

 

Utilice la palabra clave ParamArray para denotar una matriz de parámetros. Se aplican las siguientes reglas:

Un procedimiento sólo puede tener una matriz de parámetros, que debe ser el último argumento de la definición del procedimiento.

La matriz de parámetros debe pasarse por valor. Es un hábito de programación recomendado incluir de manera explícita la palabra clave ByVal en la definición del procedimiento.

El código del procedimiento debe considerar a la matriz de parámetros una matriz unidimensional; el tipo de datos de los elementos de la matriz ha de ser el mismo que el tipo de datos de ParamArray.

La matriz de parámetros es opcional de forma automática. Su valor predeterminado es una matriz unidimensional vacía del tipo de elemento de la matriz de parámetros.

Todos los argumentos que preceden a la matriz de parámetros deben ser obligatorios. La matriz de parámetros debe ser el único argumento opcional.

Cuando uno de los argumentos del procedimiento al que se llame sea una matriz de parámetros, ésta podrá tomar cualquiera de estos valores:

Ninguno, es decir, puede omitirse el argumento ParamArray. En este caso, se pasará una matriz vacía al procedimiento. También puede pasarse la palabra clave Nothing, obteniéndose el mismo efecto.

Una lista con un número de argumentos indeterminado, separados por comas. El tipo de los datos de cada argumento debe poder convertirse implícitamente al tipo de elemento ParamArray.

Una matriz con el mismo tipo de elemento que la matriz de parámetros.

En el siguiente ejemplo se muestra cómo se puede definir un procedimiento con una matriz de parámetros:

 

Option Strict On

OPTION Explicit On

Module Module1

    Public Function Sumatoria(ByVal var As String, ByVal ParamArray Cadena() As Integer) As Integer

        Dim i As Integer

        Dim j As Integer

        For i = 0 To UBound(Cadena)

            Console.WriteLine(var & " " & i & ": " & Cadena(i))

            j = j + Cadena(i)

        Next i

        Sumatoria = j

    End Function

    Sub Main()

        Dim a, b, c, d As Integer

        a = 4

        b = 3

        c = 5

        d = 9

        Console.WriteLine("Resultado: {0}", Sumatoria("Parámetro", a, b, c))

        Console.WriteLine("---------------------------------------")

        Console.WriteLine("Resultado: {0}", Sumatoria("Nuevo Parámetro", a, b, d))

        Console.Read()

    End Sub

 

End Module

 

 

Parámetros opcionales

 

Un argumento de un procedimiento puede ser opcional si así se especifica, es decir, que no es necesario suministrarlo al llamar al procedimiento. Los argumentos opcionales se indican mediante la palabra clave Optional en la definición del procedimiento. Se aplican las siguientes reglas:

Todos los argumentos opcionales de la definición del procedimiento deben especificar un valor predeterminado.

El valor predeterminado de un argumento opcional debe ser una expresión constante.

Todos los argumentos que vayan a continuación de un argumento opcional en la definición del procedimiento también deben ser opcionales.

 

 

Un ejemplo un poco sencillo pero aclarara lo anterior:

 

Module Module1

    Public Sub FuncionaGeneral(ByVal x As Integer, Optional ByVal var As String = "Prueba", Optional ByVal p As Integer = 0, Optional ByVal y As Integer = 0)

       

        If var = "Prueba" Then

            Console.WriteLine("No se cambio el parámetro var")

        Else

            Console.WriteLine("Cambió el parámetro var")

        End If

        If p = 0 And y = 0 Then

            Console.WriteLine("No se asignó ningún parámetro para (p) y (y)")

        ElseIf p <> 0 Then

            Console.WriteLine("P ha sido cambiado (p)")

        ElseIf y <> 0 Then

            Console.WriteLine("Y ha sido cambiado (y)")

        End If

 

    End Sub

    Sub Main()

        Dim a, b, c, d As Integer

        a = 4

        b = 3

        c = 5

        d = 9

        FuncionaGeneral(a, , b, c)

        Console.WriteLine("---------------------------------------")

        FuncionaGeneral(a, "hola a cambiado", b)

        Console.Read()

    End Sub

 

End Module

 

Por último funciones recursivas

 

Un procedimiento recursivo es aquél que se llama a sí mismo. Por ejemplo, el siguiente procedimiento utiliza la recursividad para calcular el factorial de su argumento original:

 

Un ejemplo clásico

 

Function Factorial(ByVal N As Integer) As Integer

   If N <= 1 Then     

      Return 1        

   Else               

      Return Factorial(N - 1) * N

   End If

End Function

Nota :  Si un procedimiento Function se llama a sí mismo de manera recursiva, su nombre debe ir seguido de un paréntesis, aunque no exista una lista de argumentos. De lo contrario, se considerará que el nombre de la función representa al valor devuelto por ésta.

Los programas tienen una cantidad de espacio limitado para las variables. Cada vez que un procedimiento se llama a sí mismo, se utiliza más espacio. Si este proceso continúa indefinidamente, se acaba produciendo un error de espacio de la pila. La causa puede ser menos evidente si dos procedimientos se llaman entre sí indefinidamente, o si nunca se cumple una condición que limita la recursividad.

Debe asegurarse de que los procedimientos recursivos no se llamen a sí mismos indefinidamente, o tantas veces que puedan agotar la memoria. La recursividad normalmente puede sustituirse por bucles.

Pasar vectores con longitud fija  a funciones

Un ejemplo aclarara lo anterior

Module Module1

 

    Public Function sumar(ByVal x() As Integer) As Integer

        Dim i, j As Integer

        For Each i In x

            Console.WriteLine("{0}", i)

            j += i

        Next

        sumar = j

    End Function

    Sub Main()

        Dim valor() As Integer = {1, 2, 3, 4, 5}

        Console.WriteLine("Resultado:{0} ", sumar(valor))

        Console.Read()

    End Sub

 

End Module

 

 

Deben disculparme si he cometido errores tanto en la redacción o en el código, sin embargo he tratado de correr todos los ejemplos.  También si se han dado cuenta algunos apartes han se han tomado de la ayuda del SDK, porque están mejor explicados que lo que yo podría hacer.

 


ir al índice