Apúntate...


Consultas, desarrollo de programas y petición de presupuestos:

Mostrando entradas con la etiqueta subrutinas. Mostrar todas las entradas
Mostrando entradas con la etiqueta subrutinas. Mostrar todas las entradas

miércoles, 22 de agosto de 2012

Paso de parametros por valor y por referencia: BYREF

Parametros por valor
Hasta ahora hemos visto varios ejemplos de funciones, todos ellos, los parametros han sido pasado por valor, esto significa lo siguiente:
  • Cuando un argumento es pasado por valor, se hace una copia del valor del argumento y se pasa a la función que es llamada.
  • Los cambios a la copia no afectan el valor original de la variable que aparece en la llamada.
  • Una desventaja del paso por valor es que una gran cantidad de datos es pasado y copiado, puede tomar un cantidad considerable de tiempo de ejecución y espacio de memoria.
  • A este tipo de parámetros se les conoce como parámetros de “entrada”
Ejemplo:

Tenemos esta función:
-->
Public sub calc_area(rad as float)
area=3.14*rad^2
return area
end

Y la usamos en esta subrutina principal:
-->
Public sub Mmain()
  Dim r as float
print “Dame el radio:”
input r
print “El area del circulo es: “; calc_area(r) ;“ con un radio de “;r
End

 Como ves el valor de la variable "r" no ha cambiado al usarla en la función

Otro ejemplo:
  -->
Desarrollo un programa que tenga la funcion factorial para calcular la aproximacion de e (numero de Euler). La aproximacion se vala en la siguiente formula:
e=1/1!+1/2!+1/3!.....+1/N!
 Funcion:
-->
Public Function fact(n As Integer) As Integer
Dim pot As Integer = 1
Dim i As Integer

For i = 1 To n
pot = pot * i
Next
Return pot

End
 En el programa principal:
-->
Dim euler As Integer
Dim suma As Float = 1
Dim i As Integer
Print "Dame la aproximacion que quieres:"
Input euler
For i = 1 To euler
suma = suma + 1 / fact(i)
Next
Print "El valor de la aproximacion es "; suma

-->
Notas importantes:
  • Para evitar ambigüedad, se recomienda no usar el mismo nombre en los argumentos pasados a una función y los correspondientes parámetros en la definición de la función.
  • En la llamada a una función el tipo y número de parámetros debe coincidir con los de la definición de la función. ( a menos que tenga sean parametros opcionales, en tal caso pueden no aparecer.)

   -->
Parámetros por referencia
 
  • Cuando un argumento es pasado por referencia, no se hace una copia del valor del argumento, sino que se esta pasando la referencia este a la función o subrutina.
  • Los cambios a la copia si afectan el valor original de la variable que aparece en la llamada.
  • La ventaja del paso por referencia es el menor consumo tiempo y memoria, ya que no se tiene que realizar copias de los datos.
-->
Para pasar un parametro por referencia, en la definición de la función, hay que usar: byref delante del parametro y ademas en la llamada a la funcion o subrutina hay que añadirle tambien byref
Ejemplo:
Funcion:
-->
Public Sub titulo(ByRef titulo As String)
titulo = "** " & titulo & " **"

End
Uso de la funcion en el programa principal:
-->
Dim palabra As String 'definicion de variable de cadena
Print "Ejemplo de parametro por referencia"

palabra = "hola"
titulo(ByRef palabra)
Print palabra

Fijaos que en la llamada de la función también he añadido delante del parametro "palabra" la orden ByRef. En caso de no añadirla, la subrutina trataria al parametro como si fuera pasado por valor:

Resultado de la ejecución del programa:

Ejemplo de parametro por referencia
** hola **

Para descargarte los ejemplo: enlace


NOTA IMPORTANTE:
Los arrays y objetos siempre se pasan por referencia. Osea que si pasas a una función como parámetro un array de elementos integer, al modificarlo, se verá modificado el original.



viernes, 17 de agosto de 2012

Subrutina y Funciones

-->
¿por qué se usan?
Cuando escribimos nuestro código fuente, es necesario ordenarlo de alguna manera, organizándolo de forma que no repitamos las mismas ordenes. Para ello podemos usar subrutinas y funciones.

¿que diferencia hay?
Las subrutinas, pueden recibir datos, y solo van a contener ordenes.
Las funciones, suelen recibir datos, y además de contener ordenes, también nos van a devolver un resultado (que será un tipo de dato).


Esquema de como se declara:
Subrutina 
[ FAST ] [ STATIC ] { PUBLIC | PRIVATE } { PROCEDURE | SUB }   Identifier   (     [ [ BYREF ] Parameter AS Datatype [ , ... ] ] [ , ]     [ OPTIONAL [ BYREF ] Optional Parameter AS Datatype [ , ... ] ] [ , ] [ ... ]   )  
 ...  
END

Función
[ FAST ] [ STATIC ] { PUBLIC | PRIVATE } { FUNCTION | PROCEDURE | SUB }   Identifier   (     [ [ BYREF ] Parameter AS Datatype [ , ... ] ] [ , ]     [ OPTIONAL [ BYREF ] Optional Parameter AS Datatype [ , ... ] ] [ , ] [ ... ]   )   AS Datatype 
  ...
 END
Nota:
Toda funcion debe de retornar algun tipo de dato (aunque sea NULL), usando para ello la orden Return
-->
Al llegar a la orden Return, la función se deja de ejecutar y envía el valor especificado como valor de retorno, que debe de coincidir con el tipo indicado en DataType.
Este seria el esquema de como funciona una función:

Enlace para más información:
http://gambaswiki.org/wiki/lang/methoddecl



Como veis, tiene bastantes opciones... veremos algunos ejemplos para aclararlo:
Public|Private:
Al igual que las variables, las funciones y subrutinas al definirlas le estamos diciendo desde donde se puede acceder a ellas (desde todos los formularios/modulos (Public), véase Uso del Operador Punto , o solo desde el mismo formulario o módulo donde fue declarada (Private) )

Uso de una función:
-->
Hay varias formas de llamar a una función, dependiendo de lo que se desea hacer con el resultado o resultados que regrese, pero la regla que siempre se conserva es que la lista de parámetros debe coincidir con los valores que recibe la función en su declaración en tipo y cantidad.
•Un estatuto de asignación si el valor que regresa es necesario en otra operación
a = nombre (lista de parámetros)
•Una expresión
a = cantidad * nombre (lista de parámetros)

•El orden de salida, si solo nos interesa imprimir el resultado, en caso de que no haya parámetros de referencia
print nombreFuncion (lista de parámetros)
No confundir con
print nombreFuncion
cuyo resultado no tiene nada que ver, ya que imprime “el nombre interno” de la funcion en el Ide de Gambas, sin devolvernos ningún calculo ni resultado ninguno.

-->
•Una condición
               If (nombre_funcion(lista de parámetros) > 7) then ….
•En Bucles:
                while (nombre_funcion(lista de parámetros) > 7)


Ejemplo:
-->
¿como declarariamos una función, accesible solo al módulo donde estamos, llamala “promedio” y que nos devuelva el promedio de 3 números enteros? Hay que tener en cuenta que el resultado puede contener número decimales.

-->
Private Function promedio(a as integer, b as integer, c as integer) as float
Return (a+b+c)/3
End


Private -> definimos que solo lo podremos usar en el módulo o formulario donde la hemos definico
Function  -> es una función, con lo cual nos devolverá algo.
promedio -> nombre de la función
(a as integer, b as integer, c as integer) -> son los 3 parametros de entrada, que estamos indicando que son numeros enteros.
as float -> tipo de variable que devolverá, en este caso devolvera un float.
Return (a+b+c)/3 -> retornamos el valor de la operación (a+b+c)/3
End-> fin de la definición de la función 

Nota: Sobre Return
En una función puede ver varios return, ejemplo:

Public Function ver(clave As String) As String
If clave = "OK" Then
Return "Ok, es la clave"
Endif
Return "clave no es valida"

End
  
En esta función, dependiendo del valor que se introduzca, retorna "ok,es la clave", o "clave no es valida"





¿como usariamos esta función?

--> -->
public sub main()
dim valor as float 'definimos una variable que será la que contenga lo que devuelva la función
valor= promedio(3,4,2) ' calculamos el promedio de los numeros 3,4 y 2, y se lo asignamos a la variable “valor”
print "El promedio es: ";valor ' escribimos el contenido de la variable en la consola
End

 
Al ejecutar el programa, escribiría en la consola:
El promedio es: 3,33333333333333

-->
Otro ejemplo: Usando parámetros opcionales.
Declara una función, accesible desde todos los formularios, llamandola “sumatorio” y que nos sume 2 numero decimales, siendo opcional sumar un 3º número. El módulo donde se encuentra se llama FuncionesAritmeticas:

 
-->
Public Function sumatorio(a as float, b as float, optional c as float) as float
return (a+b+c)
end

Uso: 
Como es accesible a todos los formularios y módulos, si la llamamos desde otro lugar que no sea donde este definida, le añadimos el nombre del módulo donde esté definida: "FuncionesAritmeticas"
 
-->
Public sub main()
Dim valor As Float
valor = FuncionesAritmeticas.sumatorio(2, 3)
Print "sumatorio:"; valor
End

Como vereis, el hecho de pasarle dos parametros (los números 2 y 3), no dá problemas porque el 3º lo hemos definido opcional ("optional")



FAST: 
Con esta palabra reservamos, hacemos posible que se ejecute más rápidamente la función o subrutina (disponible desde Gambas3.2)


BYREF
Paso por referencia. Lo veremos más adelante.

STATIC
El método sólo puede acceder a las variables estáticas de la clase.

Nota:
-->
  • Si una función no se manda llamar, nunca se ejecuta.

Ejemplo:
-->
Ejemplo 1: Se necesita una función que calcule la distancia entre 2 puntos con coordenadas (Xa, Ya) y (Xb, Yb) . Para calcularla se usa la fórmula:
DISTANCIA = (xa – xb)² + (ya – yb)²
Definición de Función:
-->
Public Function distancia(xx1 As Float, yy1 As Float, xx2 As Float, yy2 As Float) As Float
Dim p1, p2, result As Float
p1 = (xx2 - xx1) ^ 2
p2 = (yy2 - yy1) ^ 2
result = Sqr(p1 + p2)
Return result
End
Progrma principal:
-->
'----------------------
' Funcion: Calculo de distancia
'----------------------
Dim x1, x2, y1, y2 As Float
Print "Dame las coordenadas del 1º punto:"
Print "X:"
Input x1
Print "Y:"
Input Y1
Print "Dame las coordenadas del 2º punto:"
Print "X:"
Input x2
Print "Y:"
Input Y2


Print "Resultado: ", distancia(x1, y1, x2, y2)


-->
Ejemplo 2: 
Se desea obtener el perímetro de un triángulo dadas las coordenadas de los 3 puntos.
La definición de la función es la misma que la del ejercicio anterior..(estamos aprovechando el código de un programa en otro distinto).

Programa Principal:
  -->
'----------------------
' Funcion: Calculo de perimetro de un triangulo dado por coordenadas
'----------------------
Dim x1, y1, x2, y2, x3, y3, p12, p13, p23 As Float 'defino variables para el calculo del perimetro


Print "Dame las coordenadas del 1er punto "
Input x1
Input y1
Print "Dame las coordenadas del 2do punto "
Input x2
Input y2
Print "Dame las coordenadas del 3er punto “"
Input x3
Input y3
' calculando la distancia entre el punto 1 y 2
p12 = distancia(x1, y1, x2, y2)
' calculando la distancia entre el punto 1 y 3
p13 = distancia(x1, y1, x3, y3)
' calculando la distancia entre el punto 2 y 3
p23 = distancia(x2, y2, x3, y3)
Print "El perimetro es ", p12 + p13 + p23


Si deseas usar funciones o subrutinas que esten definidas en otros formularios o módulos de tu programa, tendras que declararla como públicas, y usar el operador punto ".". Para mas detalle visita este enlace: Uso del Operador Punto

Descarga el cóodigo fuente de los ejemplo: enlace







A falta de donativos... un poco de publicidad