Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 20-04-2010
Avatar de Caral
[Caral] Caral is offline
Miembro Premium
 
Registrado: ago 2006
Posts: 7.659
Poder: 25
Caral Va por buen camino
Funciones?, Procedimientos?

Hola
Como bien sabéis, de estas cosas no se pero se que algunos, muy pocos, sabéis un poco menos que yo, así que os quiero explicar, como novato, que aveces no necesariamente se tienen que hacer las cosas de una u otra manera, que se pueden hacer como le quede a uno mas cómodo, mas fácil de entender o incluso mas practico.
Sabemos que en internet, el Club y en muchos sitios encontramos funciones que nos hacen la vida mas simple, si claro, ya están hechas y para que romperse la cabeza.
Pues bien, muchas veces queremos, incluso por curiosidad, entenderlas pero no nos dan las neuronas, entonces a donde recurrimos, bueno, puede ser a un amigo, aun asi, recuerden, las neuronas no nos dan.
Bueno, según lo poco que he aprendido me gusta usar los procedimientos, incluso mas que las funciones, si ya se, en ciertos casos es inevitable, pero os quiero dar un simple ejemplo para que tratéis de entender que no necesariamente tenemos que menospreciar nos por no saber o poder tener claro el uso de las funciones teniendo en la mano a los procedimientos.
Primero hagamos una función, sencilla pero tediosa:
Creemos un form y coloquemos le tres edit y un botón.
Ahora pongamos una variable global, en este caso integer, asi:
Código Delphi [-]
var
  Form1: TForm1;
  VariableGlobal: integer;
implementation

Ahora creemos nuestra funcion, sencilla:
Código Delphi [-]
function suma(dato1,dato2:Integer; dato3:bool):bool;
begin
 if (dato1+dato2 = VariableGlobal) and (dato3 = true) then
     result := true
 else result := false;
end;
Tratemos de entender que hace esta cosa:
La función se llama suma, bueno, debería de sumar.
Tiene dos datos integer y un dato boleano.
Osea, los primeros son la ejecución y el tercero cumple un criterio.
Si el criterio es cierto, envía un resultado boleano, es lo que esperamos recibir de esta función.

Ahora veamos el desarrollo de la función:
Dice: SI el dato1 sumado al dato2, (integer, dentro de la variable) y el dato3 es verdadero (cumple un criterio) se disparara, enviando el resultado dentro de (result), muy obvio, el nombre lo dice.

Ahora veamos como funciona esta función, sencilla:
Usemos el boton y en el evento onclick ponemos esto:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
begin
 VariableGlobal := strtoint(Edit1.Text);
 if Suma(StrToInt(Edit2.Text),StrToInt(Edit3.Text),true) then
 ShowMessage('El resultado es '+Edit1.Text);
end

Tratemos de analizarlo:
La primera linea llama a la variable global e indica que es igual al edit1.
En la segunda linea dice:
SI (LLAMAMOS O NOS POSICIONAMOS EN LA FUNCIÓN SUMA) le eviamos los datos dentro del edit2 y el edit3 he indicamos que tiene que ser verdadero (TRUE), entonces, si se cumplió lo que indica la función, envia un mensaje en el que concatenamos el resultado, recordad (result) al edit1.

Como veis, esta sencilla función lo único que hizo fue comparar dos datos que al ser sumados den como resultado el tercer dato, de obtenerse el dato correcto enviara un mensaje.
Ojala todas las funciones fueran tan sencillas........

Bien, ahora veamos como se haría esto usando un procedimiento y si varia el resultado:
En el mismo form pongamos otro boton:
Creemos el procedimiento (suma1), al principio, donde estan todos, asi:

Código Delphi [-]
    procedure suma1;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);

Coloquemos un par de variables globales, en este caso una string, la llamamos x, otra boolean, la llamamos b asi:
Código Delphi [-]
var
  Form1: TForm1;
  x: String;
  b: boolean;
  VariableGlobal: integer;
implementation

Ahora hagamos nuestro procedimiento:
Código Delphi [-]
Procedure TForm1.suma1;
begin
  If FloatToStr(StrToFloat(Edit3.Text) + StrToFloat(Edit2.Text)) = Edit1.Text then
   begin
   x:= Edit1.Text;
   b:= true;
   end
   else
   b:= false;
end;

Tratemos de analizarlo, dice:
SI el contenido del edit3 sumado al contenido del edit2 es igual al edit1 entonces X (variable global) es igual al edit1 y b (variable boolean) es verdadera (true), de lo contrario (else) es falsa.

Veamos como llamaríamos a este procedimiento y que nos devuelve como resultado:
Usemos el evento onclick del segundo boton, asi:
Código Delphi [-]
procedure TForm1.Button2Click(Sender: TObject);
begin
  suma1;
   If b = True then
  Showmessage('El resultado es ' + x);
end;

Que hace:
Llamamos al procedimiento suma1.
Si coinciden los datos con los del procedimiento entonces comprueba que la variable b sea verdadera y nos envia un mensaje que contiene el resultado dentro de la variable global X.

Si ejecutáis el programa veréis que tanto el uso de la función como el del procedimiento envía Exactamente lo mismo y hacen la misma comprobación.

Este solo es un ejercicio para que los novatos como yo no os desaniméis y veáis que se pueden hacer las cosas de muchas maneras, por lo menos a mi me parece.

Espero os sea de utilidad.
Saludos
__________________
Siempre Novato
Responder Con Cita
  #2  
Antiguo 20-04-2010
ioco ioco is offline
Miembro
 
Registrado: ene 2010
Posts: 42
Poder: 0
ioco Va por buen camino
Gracias por tu aporte Caral ^^ a los que empezamos hace poco a programar siempre nos van bien este tipo de textos

Para complementar tu post con más opciones, añadiré otra posible manera de realizar el procedimiento que comentas:

Código Delphi [-]
Procedure TForm1.suma1(num1,num2,sumado: String; OUT x: String; OUT b: Boolean);
begin
  If StrToFloat(num1)+StrToFloat(num2)=StrToFloat(sumado) then
    begin
      x:= sumado;
      b:= true;
    end
  else
    b:= false;
end;

Este procedimiento es exactamente igual que el tuyo, pero utilizando parámetros al igual que en la función de más arriba.

Así, mediante los parámetros hacemos que el procedimiento sea más versátil y sirva para cualquier otro conjunto de datos (3 strings de entrada para los sumandos y el resultado a comprobar, 1 string de salida y 1 booleano de salida.

Un saludo.
Responder Con Cita
  #3  
Antiguo 20-04-2010
Avatar de Caral
[Caral] Caral is offline
Miembro Premium
 
Registrado: ago 2006
Posts: 7.659
Poder: 25
Caral Va por buen camino
Hola
Gracias por el aporte, muy interesante.
Espero que alguien mas se anime, siempre es bueno ver mas opciones.
Saludos
__________________
Siempre Novato
Responder Con Cita
  #4  
Antiguo 20-04-2010
LuisAlf:: LuisAlf:: is offline
Miembro
 
Registrado: nov 2009
Posts: 60
Poder: 15
LuisAlf:: Va por buen camino
Interesante....

hOLA Ioco....

Disculpa, no puedes explicar mas a fondo el procedimiento que pones con parametros....

La verdad no se como es eso lo de OUT....si podrias explicarlo como funciona y como se manda a llamar tal procedimiento...

Saludos...

Última edición por LuisAlf:: fecha: 20-04-2010 a las 21:16:35. Razón: escritura
Responder Con Cita
  #5  
Antiguo 20-04-2010
Avatar de Caral
[Caral] Caral is offline
Miembro Premium
 
Registrado: ago 2006
Posts: 7.659
Poder: 25
Caral Va por buen camino
Hola
Segun lo que entiendo y que me corrija ioco OUT indica que las variables traspasan el procedimiento.
Para que este procedimiento funcione se tiene que tratar casi como una funcion.
Hay que declarar el procedimiento completo, donde estan los otros asi:
Código Delphi [-]
    procedure suma1;
    procedure suma2(num1,num2,sumado: String; OUT x: String; OUT b: Boolean);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);

Colocas las variables globales:
Código Delphi [-]
var
  Form1: TForm1;
  x: String;
  b: boolean;
implementation

Luego haces el procedimiento de ioco, asi:
Código Delphi [-]
Procedure TForm1.suma2(num1,num2,sumado: String; OUT x: String; OUT b: Boolean);
begin
  If StrToFloat(num1)+StrToFloat(num2)=StrToFloat(sumado) then
    begin
      x:= sumado;
      b:= true;
    end
  else
    b:= false;
end;
Y luego lo llamas asi:
Código Delphi [-]
procedure TForm1.Button3Click(Sender: TObject);
begin
   suma2(Edit2.Text,edit3.Text,edit1.Text,x,b);
  If b = True then
  Showmessage('El resultado es ' + x);
end;
Como ves, en vez de que sea el procedimiento el que contenga los datos, es al llamarlo que se los indicas.
Saludos
__________________
Siempre Novato

Última edición por Caral fecha: 20-04-2010 a las 21:44:21.
Responder Con Cita
  #6  
Antiguo 20-04-2010
Avatar de AzidRain
[AzidRain] AzidRain is offline
Miembro Premium
 
Registrado: sep 2005
Ubicación: Córdoba, Veracruz, México
Posts: 2.914
Poder: 21
AzidRain Va camino a la fama
Cara,las funciones o procedimientos son meramente estructuras que el lenguaje nos ofrece, hay algunos donde todo método de clase es una función. Delphi es de los pocos que aún permite la existencia de ambos. En lenguaje C no existen por ejemplo los procedimientos si una funcion no tiene que devolver nada la hacemos igual a nil y punto.

Aquí nuestro querido Delphi nos dá oportunidad de usar "procedures" como funciones que no tienen por que devolver algo o bien funciones.
Al final es lo mismp hacer un función que siempre devuelve nil (que en efecto del Delphise puede hacer) una que devuelve algo.
Mas que nada es cuetión de estilos.
__________________
AKA "El animalito" ||Cordobés a mucha honra||
Responder Con Cita
  #7  
Antiguo 20-04-2010
Avatar de movorack
[movorack] movorack is offline
Miguel A. Valero
 
Registrado: feb 2007
Ubicación: Bogotá - Colombia
Posts: 1.346
Poder: 20
movorack Va camino a la famamovorack Va camino a la fama
Si bien es cuestión de estilos... es bueno que nuestros estilos se acomoden a los estandares... al momento de que otra persona lea nuestro codigo se sentirá mas familiarizado.

Código Delphi [-]
x := sumar(100, 100);
personalmente... aquí entiendo que existe una asignación a X... haga lo que haga la función...

Código Delphi [-]
sumar(100, 100, x);
encambio aquí... no me deja muy claro que se está asignando un valor a X... podria ser perfectamente un parametro mas... tendria que ver la definición del procedimiento para entender que no es así...
__________________
Buena caza y buen remar... http://mivaler.blogspot.com
Responder Con Cita
  #8  
Antiguo 20-04-2010
Avatar de Lord Delfos
Lord Delfos Lord Delfos is offline
Miembro
 
Registrado: ene 2008
Ubicación: Tandil, Argentina
Posts: 558
Poder: 17
Lord Delfos Va por buen camino
Cita:
Empezado por LuisAlf:: Ver Mensaje
La verdad no se como es eso lo de OUT....si podrias explicarlo como funciona y como se manda a llamar tal procedimiento...
Bueno, habría que esperar a que ioco lo explique... pero le quiero ganar de mano y sumar otro post a mi favor

Hay dos maneras de pasar parámetros a un procedimiento/función:

[1] Por referencia (usando "var").
[2] Por valor (sin escribir nada).

Cuando uno pasa un parámetro por referencia, la variable que se pasa conserva el valor que se le haya dado adentro del procedimiento. Por ejemplo:

Código Delphi [-]
procedure HagoAlgo(var UnaVariable: Integer);
begin
  UnaVariable:= 22;
end;

var Pepito: Integer;

begin
  Pepito:= 4;
  HagoAlgo(Pepito);
  //Ahora Pepito vale 22.
end;

Al pasar por valor, en cambio, uno lo que pasa es una copia de la variable original. Así, si el procedimiento que la recibe la modifica, mi variable original no es modificada, porque lo que se modifica es una copia, no el original. Por ejemplo:

Código Delphi [-]
procedure HagoAlgo(UnaVariable: Integer); <-- sin el "var"
begin
  UnaVariable:= 22; <-- Modifica una copia de "Pepito", no el original.
end;

var Pepito: Integer;

begin
  Pepito:= 4;
  HagoAlgo(Pepito);
  //Pepito sigue valiendo 4.
end;

Ahora bien, en Delphi hay otros dos tipos de parámetros:

[1] El paso por constante (con la palabra "const").
[2] El paso por salida (con la palabra "out").

El paso por constante es útil para pasar algo que no queremos que se modifique (es decir, que pasaríamos por valor) pero que mide mucho como para dejar que el compilador haga una copia de la variable antes de pasarla. Al usar "const" lo que el compilador hace es pasar la variable original, pero controla que no se quiera hacer ninguna modificación. Por ejemplo:

Código Delphi [-]
procedure HagoAlgo(const UnaVariable: Integer);
begin
  UnaVariable:= 22; <-- Error de compilación, no se permite modificar la variable.
end;

Es útil cuando pasamos strings o arreglos, que son muy grandes como andar copiándolos. Hace al código más eficiente... por supuesto, siempre y cuando no quiéramos modificarlos.

El paso por salida sirve para indicar que lo que tenga la variable adentro es irrelevante y que se va a sobreescribir con otro valor. En sí es un paso por referencia (como con "var"), pero sirve para que el que use la función/procedimiento sepa que si hay algo en la variable, más vale que esté destruido antes de llamar a la función, sino las cosas pueden salir mal. Por ejemplo:

Código Delphi [-]
procedure HagoAlgo(out UnaVariable: TObject);
begin
  UnaVariable:= TObject.Create;
  UnaVariable.TalCosa:= 4;
end;

var Pepito: TObject;

begin
  //Hago mil cosas con Pepito
  HagoAlgo(Pepito);
  //La sonamos. HagoAlgo crea el objeto, pero mi variable Pepito ya estaba creada y entonces tengo un goteo de memoria, porque creé un objeto "arriba" de otro.
end;

Lo correcto sería:

begin
  //Hago mil cosas con Pepito
  Pepito.Free; <-- Destruyo pepito
  HagoAlgo(Pepito);
end;

Saludongos.
Responder Con Cita
  #9  
Antiguo 20-04-2010
ioco ioco is offline
Miembro
 
Registrado: ene 2010
Posts: 42
Poder: 0
ioco Va por buen camino
Me dejaste a medio post Lord Delfos (si esque soy lentísimo escribiendo jaja)

Muy bien explicado, queda incluso más claro que en lo que estaba escribiendo yo ya que me estaba haciendo un lío en cómo organizar el texto xD

A todo esto comentar que lo que dice movorack de acomodarse a los estándares creo que es bastante conveniente, sobretodo cuando querramos que otros lean nuestro código (cada cual que escriba como quiera para sí mismo, pero para con los demás tenemos que tener un mínimo de consideración ).

Así, debemos plantearnos cómo se va a usar lo que estamos implementando y adecuarlo un poquito jeje.

Añadiré que se puede pasar los parámetros por referencia tanto en procedimientos como los del ejemplo, como en funciones (así podemos usar var, const y out en parámetros de una función tal que así:

Código Delphi [-]
function TrySuma(num1,num2:integer; out resultadoSuma:integer):boolean;

con una función así (similar a las funciones de conversión de formato de delphi del estilo TryStrToInt) obtenemos un valor booleano como resultado de la función pero a la vez guardaríamos el resultado de la suma en otra variable.

PD: para mas info sobre esto último consultar las funciones del estilo mencionado en la ayuda ya que no viene a cuento la implementación

Última edición por ioco fecha: 20-04-2010 a las 23:40:14.
Responder Con Cita
  #10  
Antiguo 20-04-2010
Avatar de Lord Delfos
Lord Delfos Lord Delfos is offline
Miembro
 
Registrado: ene 2008
Ubicación: Tandil, Argentina
Posts: 558
Poder: 17
Lord Delfos Va por buen camino
Cita:
Empezado por movorack Ver Mensaje
Código Delphi [-]
sumar(100, 100, x);
encambio aquí... no me deja muy claro que se está asignando un valor a X... podria ser perfectamente un parametro mas... tendria que ver la definición del procedimiento para entender que no es así...
Entiendo tu punto. En realidad ahí es donde entra el paso con "out". Aclara que el parámetro es para salida exclusivamente... Pero sí, puede prestarse a confusión, es cierto.
Responder Con Cita
  #11  
Antiguo 20-04-2010
Avatar de Caral
[Caral] Caral is offline
Miembro Premium
 
Registrado: ago 2006
Posts: 7.659
Poder: 25
Caral Va por buen camino
Hola
Estos son los hilos a los que se les saca provecho, aquí el que no aprende es por que no quiere.
Sois unos maestros señores.
Saludos
__________________
Siempre Novato

Última edición por Caral fecha: 20-04-2010 a las 23:46:37.
Responder Con Cita
  #12  
Antiguo 21-04-2010
Avatar de Ñuño Martínez
Ñuño Martínez Ñuño Martínez is offline
Moderador
 
Registrado: jul 2006
Ubicación: Ciudad Catedral, Españistán
Posts: 6.000
Poder: 25
Ñuño Martínez Tiene un aura espectacularÑuño Martínez Tiene un aura espectacular
Los parámetros OUT tienen su utilidad; por ejemplo, para aquellas funciones o ecuaciones matemáticas que tienen más de una solución como es el caso de las ecuaciones de segundo grado:

Código Delphi [-]
(* Devuelve los ceros de una ecuación de segundo grado en la forma
    aX^2 + bX + c = 0.
   Los valores se devuelven en los parámetros X1 y X2.
   Devuelve FALSE si la función no tiene ningún cero para ningún X. *)
  FUNCTION EcuacionGrado2 (a, b, c: REAL; OUT x1, x2: REAL): BOOLEAN;
  VAR
    Delta: REAL;
  BEGIN
    RESULT := FALSE
  { Comprueba que el divisor no sea cero. }
    IF (2 * a) <> 0 THEN
      BEGIN
      { Comprueba que no se intentará obtener la raíz de un valor negativo. }
        Delta := (b * b) - (4 * a * c);
        IF Delta >= 0 THEN
          BEGIN
          { Resuelve la ecuación. }
            RESULT := TRUE;
            Delta := sqrt (Delta);
            b := b * (-1);
            x1 := (b + Delta) / (2 * a);
            x2 := (b - Delta) / (2 * a);
          END;
      END;
  END;
__________________
Proyectos actuales --> Allegro 5 Pascal ¡y Delphi!|MinGRo Game Engine
Responder Con Cita
  #13  
Antiguo 21-04-2010
Avatar de José Luis Garcí
[José Luis Garcí] José Luis Garcí is offline
Miembro Premium
 
Registrado: may 2003
Ubicación: Las Palmas de G.C.
Posts: 1.372
Poder: 22
José Luis Garcí Va camino a la fama
Según me dijo mi amigo Jesús Cuando me enseñaba Clipper, ahi multitud de maneras de llegar a un mismo resultado, lo importante es primero llegar y luego ir mejorando hasta que llegues más rápido. Era un verdadero visionario, ya que también me decía un proceso que ahora ocupa un minuto, y nos parece rápido mañana ocupara diez segundos y nos desesperara. (se refería a la cada vez mayor rapidez de los procesadores, y que aún así el cliente con el paso del tiempo, aunque mete más datos, pretende que el proceso tarde meno)s.
__________________
Un saludo desde Canarias, "El abuelo Cebolleta"
Responder Con Cita
  #14  
Antiguo 21-04-2010
Avatar de Lord Delfos
Lord Delfos Lord Delfos is offline
Miembro
 
Registrado: ene 2008
Ubicación: Tandil, Argentina
Posts: 558
Poder: 17
Lord Delfos Va por buen camino
Cita:
Empezado por José Luis Garcí Ver Mensaje
Era un verdadero visionario, ya que también me decía un proceso que ahora ocupa un minuto, y nos parece rápido mañana ocupara diez segundos y nos desesperara. (se refería a la cada vez mayor rapidez de los procesadores, y que aún así el cliente con el paso del tiempo, aunque mete más datos, pretende que el proceso tarde meno)s.
¡Qué gran verdad! Uno se acostumbra, ¿viste?
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Definición de procedimientos y/o funciones mauqu Varios 2 27-08-2007 16:00:19
Procedimientos y funciones en formularios MDI joumont OOP 9 05-03-2007 21:21:34
Sobre procedimientos y funciones Perrero80 OOP 3 17-05-2006 11:55:42
Definir funciones y procedimientos en FastReport???? burasu Impresión 1 16-05-2005 21:47:37
Procedimientos y funciones en paquetes MARIOR Varios 2 08-01-2004 23:50:51


La franja horaria es GMT +2. Ahora son las 14:28:05.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi