Como funciona un Funcion
#21
Escrito 11 diciembre 2008 - 08:08
Esperaré pacientemente
#22
Escrito 11 diciembre 2008 - 08:14
Hola
Que bueno, eso si me da mucha mas claridad en el asunto.
Hombre, Maestro, como me ayudas.
Gracias amigo.
Saludos
Vamos amigo, eso de Maestro me queda grande, pero si insistes me puedes decir maistro
Jejeje, qué obsesión de preguntar cosas en las que si puedo ayudar justo cuando no estoy
Esperaré pacientemente
Pues que esperas para hacer tu comentario amiguita, yo nomas contesto a lo loco y ni se de que estamos hablando jajajaja
Salud OS
#23
Escrito 11 diciembre 2008 - 08:18
Imagina que a un problema lo partes en pedacitoss más chicos y ahora cada parte resuelve algún hecho concreto del problema. De este modo el problema general se divide en porciones más simples y fáciles de entender.
Ese es uno de los propósitos de las funciones y procedimientos: concentrar en una rutina (sentencias) alguna funcionalidad, o utilidad de modo que con invocar a dicha función o procedimiento consigamos armar un problema mayor.
Otra cosa que sería muy útil mencionar y aclarar que entre los parámetros de entrada podemos encontrarnos con algo como esto:
function Nombre(dato1, datoN: tipo; var datoM: tipo_M): tipo; ...
Ese parámetro datoM es tanto como de entrada como de salida. Se trata de un parámetro especial: nos permite que una función nos regrese otro valor más. Los procedimientos no regresan ningún valor, pero gracias a éste tipo de parámetro es posible devolver un valor.
Este parámetro por lo general es para "notificar" que algo ha cambiado dentro de la sentencia. Se lo suele emplear para variables de control.
Los parámetros se clasifican en dos: Parámetros por referencia, y parámetros por valor. Los de valor son los comunes de siempre, los que no tienen el "var". Se llaman "por valor" porque en realidad lo que hace el compilador es "copiar" el valor de la variable o constante del parámetro y trabajar dentro de la función con dicha copia. Una vez que la función termina, el valor de los parámetros queda como están: no cambian. Supongamos que datoM sea "por valor", y que se pasa el valor 5... al finalizar la función seguiremos teniendo ese 5.
En cambio, los parámetros por referencia son aquellos en donde ves el "var". Lo que hace el compilador es trabajar con la variable exacta, por tanto se hace referencia a dicha zona de memoria. Si dentro de la función se cambia el valor de la variable, al finalizar no recuperaremos el valor original. Ahora en cambio, digamos que datoM es por referencia, al finalizar es posible que no sea 5, sino 8000 o vaya a saber uno.
Por ello he dicho que por lo general estos tipos de parámetros se emplean para "comunicar" que algo ha cambiado dentro de la función, son variables de "control". No se los suele usar como un dato de entrada. Puedes ver un ejemplo de uso de esta función en el evento OnCloseQuery, y en OnClose. Si te fijas, puedes cambiar el valor de CanClose y Action... dependiendo de como sea el valor final que obtengan, se hará una u otra cosa.
Saludos,
#24
Escrito 11 diciembre 2008 - 08:22
.....
delphi
function Nombre(dato1, datoN: tipo; var datoM: tipo_M): tipo; ...
Ese parámetro datoM es tanto como de entrada como de salida. Se trata de un parámetro especial: nos permite que una función nos regrese otro valor más. Los procedimientos no regresan ningún valor, pero gracias a éste tipo de parámetro es posible devolver un valor.
Este parámetro por lo general es para "notificar" que algo ha cambiado dentro de la sentencia. Se lo suele emplear para variables de control.
Los parámetros se clasifican en dos: Parámetros por referencia, y parámetros por valor. Los de valor son los comunes de siempre, los que no tienen el "var". Se llaman "por valor" porque en realidad lo que hace el compilador es "copiar" el valor de la variable o constante del parámetro y trabajar dentro de la función con dicha copia. Una vez que la función termina, el valor de los parámetros queda como están: no cambian. Supongamos que datoM sea "por valor", y que se pasa el valor 5... al finalizar la función seguiremos teniendo ese 5.
En cambio, los parámetros por referencia son aquellos en donde ves el "var". Lo que hace el compilador es trabajar con la variable exacta, por tanto se hace referencia a dicha zona de memoria. Si dentro de la función se cambia el valor de la variable, al finalizar no recuperaremos el valor original. Ahora en cambio, digamos que datoM es por referencia, al finalizar es posible que no sea 5, sino 8000 o vaya a saber uno.
Por ello he dicho que por lo general estos tipos de parámetros se emplean para "comunicar" que algo ha cambiado dentro de la función, son variables de "control". No se los suele usar como un dato de entrada. Puedes ver un ejemplo de uso de esta función en el evento OnCloseQuery, y en OnClose. Si te fijas, puedes cambiar el valor de CanClose y Action... dependiendo de como sea el valor final que obtengan, se hará una u otra cosa.
Saludos,
Algún mini ejemplo que lo ilustre mucho mejor ?
#25
Escrito 11 diciembre 2008 - 08:31
Los procedimientos no regresan ningún valor,
Perdón pero mas bien un procedimiento no puede asignarle un tipo de dato y a las funciones si se les asigna un tipo de dato. sin embargo los procedimientos si pueden tener variables que regresan un valor, pero se usan de manera distinta, veamos....
procedure suma(dato1,dato2:integer; var dato3:integer); begin dato3 := dato1+dato2; end; procedure TForm1.Button1Click(Sender: TObject); var uno,dos,tres: integer; begin uno := 3; dos := 5; suma(uno,dos,tres); showmessage(inttostr(tres)); end;
Salud OS
#26
Escrito 11 diciembre 2008 - 08:43
Aqui las diferencias entre una función y un procedimiento.
procedure suma(dato1,dato2:integer; var dato3:integer); begin dato3 := dato1+dato2; end; function resta(dato1,dato2:integer):integer; begin result := dato2-dato1; end; procedure TForm1.Button1Click(Sender: TObject); var uno,dos,tres: integer; begin uno := 3; dos := 5; suma(uno,dos,tres); //procedimiento showmessage(inttostr(tres)); tres := resta(uno,dos); //función showmessage(inttostr(tres)); end;
Espero que sea mas claro aún el asunto
Salud OS
#27
Escrito 11 diciembre 2008 - 09:07
Deseamos Lanzar un cohete al espacio (cualquier similitud con algún hilo es pura concidencia ), y una de las funciones que necesitamos es la de determinar si es posible lanzar el cohete.
Entonces un programador hace algo como esto:
function PuedeLanzarCohete(NumeroCohete, Peso, Tamanno, CapacidadCombustible: integer): boolean; var CoheteValido: boolean; begin CoheteValido := ValidarCohete(NumeroCohete); // Aquí se llama a una función! if CoheteValido then begin result := (CapacidadCombustible <= (0.5 * Peso)) AND ((Peso/Tamanno) <= 1.5) // Para poder lanzar el cohete, la capacidad del combustible debe ser cuanto mucho // la mitad del peso y la proporción entre el Peso y el Tamaño no debe ser mayor a 1.5 end result := False; // No se puede lanzar el cohete end;
Esta función les sirve, y el programador puede usarla sin problemas. Entonces cuando hace esto:
var Puede: boolean; UnPeso, UnTamanno, UnaCapacidad: integer; ... UnPeso := 5000; unTamanno := 3400; UnaCapacidad := 2600; ... Puede := PuedeLanzarCohete(1,UnPeso,UnTamanno,UnaCapacidad);
Al finalizar la función, estas variables (UnPeso, UnTamanno, UnaCapacidad conservarán sus respectivos valores.
Pero supongamos que ahora, a los desarrolladores les gustaría saber porqué motivo no se puede lanzar. La función no puede regresar dos valores mediante "result". ¿La solución?: declarar un parámetro más anteponiendo el "var". Digamos que ahora queda así:
function PuedeLanzarCohete(NumeroCohete, Peso, Tamanno, CapacidadCombustible: integer; var EstadoError: integer): boolean; var CoheteValido: boolean; begin CoheteValido := ValidarCohete(NumeroCohete); if CoheteValido then begin EstadoError := 0; // No hay error result := True; if (CapacidadCombustible > (0.5 * Peso) then begin EstadoError := EstadoError + 1; result := False; end; if ((Peso/Tamanno) > 1.5) then begin EstadoError := EstadoError + 2; result := False; end; end else result := False; end;
Como puede verse, dentro de la función el parámetro EstadoError se lo trata como una variable más. Se ha diseñado esta variable para que asume cuatro resultados:
0 -> no hay error
1 -> se debe únicamente a un exceso en la capacidad de combustible
2 -> se debe únicamente a un exceso en el peso respecto al tamaño
3 -> se debe a las dos anteriores (1 + 2);
Ahora se declara una nueva variable global, le damos un valor (para pruebas) y ejecutamos la función:
var Error: integer; ... Error := 5; Puede := PuedeLanzarCohete(1,UnPeso, UnTamanno, UnaCapacidad, Error);
Cuando finalize la rutina, todas las variables "UnXXX" no se modificarán, seguirán con los mismos valores (5000,3400,2600), pero "Error" se ve modificado puesto que se trata de un parámetro por referencia. Inicialmente le habíamos dado un valor 5, pero ahora si comprobamos su valor nos damos conque es 1.
De este modo podemos tomar una decisión y mejorar nuestro programa:
Case Error of: 1: QuitarPesoCombustible(...); 2: QuitarPeso(...); 3: begin ResidennarCohete(...) end; else Lanzar(...); end; ...
Espero que con este mini ejemplo se entienda mejor.
Saludos,
PD: Las fórmulas son inventadas. No son representaciones de la realidad... para estar seguros consultar a la NASA
#28
Escrito 11 diciembre 2008 - 11:25
Te agradezco muchisimo tu tiempo para explicarlo, sinceramente disfruto aprendiendo mucho de tus hilos
#29
Escrito 12 diciembre 2008 - 06:37
Amiguito Delphius, me queda PERFECTAMENTE claro
Te agradezco muchisimo tu tiempo para explicarlo, sinceramente disfruto aprendiendo mucho de tus hilos
Muchas gracias,
Disfruté mucho escribiendo el post y quise ser breve pero demostrativo de los conceptos.
Lo que si sería bueno es analizar si realmente no confundí "parámetros por referencia" con "parámetros por valor". La diferencia en un sentido práctico la manejo, lo que no estoy totalmente seguro es si los nombres son los correctos. Tiendo a confundirlos (¡Y esto es algo básico en programación !). ¿Los var son los llamados por referencia? ¿O es alrrevez?
Saludos,
#30
Escrito 12 diciembre 2008 - 07:27
Los parametros por referencia son los var, y se llaman asi debido a que la funcion lo que recibe es la referencia de memoria (puntero) donde reside la variable, por eso se puede modificar. Los parametros por valor reciben es el contenido de la direccion de memoria y lo carga en otro bloque.
Ahora quien se lanza con una de recursividad?? jejeje
#31
Escrito 12 diciembre 2008 - 08:49
Muchas gracias Eduardo,ok, esa si me la se...
Los parametros por referencia son los var, y se llaman asi debido a que la funcion lo que recibe es la referencia de memoria (puntero) donde reside la variable, por eso se puede modificar. Los parametros por valor reciben es el contenido de la direccion de memoria y lo carga en otro bloque.
Ahora quien se lanza con una de recursividad?? jejeje
Normalmente dudo de eso... no se porqué tiendo a confundirlos.
¡Por Dios! ¡Pero si es algo elemental y fundamental!
Que lo tiró... parece que el sector de mi cerebro donde se encontraba este dato está defectuoso. ¡ScanDisk!
Saludos,
#32
Escrito 12 diciembre 2008 - 09:02
#33
Escrito 12 diciembre 2008 - 10:00
Pues la recursividad no es mas que una funcion que se llama a si misma.
Por ejemplo la funcion factorial*:
function factorial(x: Integer): Integer; begin if x = 1 then Result:= 1 else Result:= x * factorial(x-1); end;
*Para todo número natural n, se llama n factorial o factorial de n al producto de todos los naturales desde 1 hasta n:
*Aunque el factorial de 0 es 1 en la función anterior no lo pongo por simplicidad
En la función anterior se pueden ver las dos características principales de una función recursiva:
- Se llama a si misma
- Existe una condición (que se debe de cumplir siempre) que termina el proceso.
No siempre es fácil ni aconsejable usar la recursividad, pero hay problemas cuya solución parece ideal para usar recursividad, como por ejemplo el factorial, búsqueda de ficheros en subdirectorios, etc ...
#34
Escrito 12 diciembre 2008 - 10:07
PD: No, no es la pila(batería) del Bios
#35
Escrito 12 diciembre 2008 - 11:22
function Fibonachi(N: integer): integer; begin if N < 2 then result := N else result := Fibonachi(N - 1) + Fibonachi(N - 2); end;
No lo corrí, pero si está todo bien debería andar . Ya no recuerdo estos ejercicios bien del todo.
Saludos,
#36
Escrito 14 diciembre 2008 - 11:04
Es decir por ejemplo una funcion que recibe dos parametros y debe retornar 3 valores diferentes
function MiFuncion(Param1,Param2:alguntipo):integer,double,tdatetime; begin //Lo que tenga que hacer end;
#37
Escrito 15 diciembre 2008 - 07:28
#38
Escrito 15 diciembre 2008 - 07:54
O tambien se puede declarar un tipo record y usarlo como resultado de la funcion.Hasta donde llegan mis conocimientos eso no se puede, para poder retornar mas de un valor puedes utilizar los parametros por referencia
Me explico
type TResultado = record Entero: Integer; Doble: double, Fecha: TDatetime; end; function MiFuncion(Param1,Param2:alguntipo): TResultado; begin //Lo que tenga que hacer end; // Y usarioamos la funcion asi: var Resultado: TResultado; begin Resultado:= MiFuncion(P1,P2); ShowMessage('El entero es: ' + IntToStr(Resultado.Entero)); ShowMessage('La fecha es: ' + DateToStr(Resultado.Fecha)); end;
#39
Escrito 15 diciembre 2008 - 08:28
#40
Escrito 15 diciembre 2008 - 09:37
Solo complementando lo publicado por seoane, pues tenia la duda de como era que se debian regresar los valores me puse a hacer varias alternativas y era mas facil de lo que pense .
function MiFuncion(Param1,Param2:integer): TResultado; begin Result.Entero := 102; Result.Doble := 12345; Result.Fecha := Now; end; procedure TForm1.Button1Click(Sender: TObject); var Resultado: TResultado; begin Resultado := MiFuncion(122,132); ShowMessage('El entero es: ' + IntToStr(Resultado.Entero)); ShowMessage('El doble es: ' + IntToStr(Resultado.Doble)); ShowMessage('La fecha es: ' + DateToStr(Resultado.Fecha)); end;
Salud OS