BotonMenu
BotonIndice

Visita : conoce3000.com
Paypal : https://www.paypal.com/donate/?hosted_button_id=XY8TZ3MGN64GE

PASCAL CON FREE PASCAL

PASCAL CON FREE PASCAL

PASCAL CON FREE PASCAL


7. INTRODUCCIÓN A LOS PUNTEROS Y VARIABLES DINÁMICAS.
7.11. PUNTEROS A PROCEDIMIENTOS O FUNCIONES.
7. INTRODUCCIÓN A LOS PUNTEROS Y VARIABLES DINÁMICAS.
7.11. PUNTEROS A PROCEDIMIENTOS O FUNCIONES.
7. INTRODUCCIÓN A LOS PUNTEROS Y VARIABLES DINÁMICAS.
7.11. PUNTEROS A PROCEDIMIENTOS O FUNCIONES.

SIGUIENTE

SIGUIENTE

SIGUIENTE


‒ 1. Punteros a procedimientos o funciones.

En los capítulos anteriores se ha explicado el uso de punteros con variables dinámicas, en este capítulo se verá el uso de los punteros a procedimientos y funciones, para almacenar la dirección de memoria de un procedimiento o función.

Todo programa o aplicación siempre se coloca en la memoria RAM de la computadora, para que el microprocesador se encargue de ejecutarlo, el lugar o la dirección de memoria en donde se coloca el programa no es fácil de determinar, pero si es posible obtener la dirección de memoria de un procedimiento o una función, para luego almacenarlo en un puntero a procedimiento o función.

Los punteros a procedimientos y funciones, primero se definen como tipos de datos en la sección type del programa, usando para ello un identificador y después del símbolo igual, la definición del encabezado del procedimiento o función con sus respectivos parámetros. A continuación unos ejemplos:

Type
   TProc01=Procedure;
   TProc02=Procedure(A:integer);
   TFunc01=Function:boolean;
   TFunc02=Function(A,B:integer):boolean;

En estos ejemplos,TProc01 es un procedimiento sin parámetros, TProc02 con parámetros, TFunc01 sin parámetros, y TFunc02 con parámetros.

Una vez creado los tipos de datos para punteros a procedimientos y funciones, se pueden usar en una variable del siguiente modo.

Var
   A:TProc01;
   B:TProc02;
   C:TFunc01;
   D:TFunc02;

Aquí las variables A,B,C y D son punteros que podrán almacenar las direcciones de memoria de los procedimientos o funciones que coincidan con los tipos de datos TProc01, TProc02, TFunc01, TFunc02, en caso no coincidan el compilador nos advertirá de ese error.

Para que un procedimiento coincida con los tipos de datos a procedimientos o funciones, estos deben coincidir solamente en la cantidad de parámetros y los tipos de datos que estos usen.

El siguiente programa nos muestra un ejemplo del uso de los punteros a funciones y procedimientos:


Descargar
{$codepage UTF8}
Type
  TProc=Procedure(A:integer);
  TFunc=Function:boolean;

  Procedure MostrarA(A:integer);
    Begin
      Writeln(A)
    End;

  Procedure MostrarB(B:integer);
    Begin
      Writeln(B+5)
    End;

  Function FuncX:boolean;
    Begin
      FuncX:=true
    End;

Var MiProc:TProc;
    MiFunc:TFunc;

Begin
   MiProc:=@MostrarA;
   MiProc(5);
   MiProc:=@MostrarB;
   MiProc(5);
   MiFunc:=@FuncX;
   Writeln(MiFunc())
End.
Código fuente 39: Ejemplo punteros a procedimientos o funciones.
Descargar

En este ejemplo se puede observar que para colocar la dirección de memoria del procedimiento a usar en uno de los punteros MiProc y MiFunc se hace uso del operador @. Una vez obtenidos las direcciones de memoria de los procedimientos MostrarA y MostrarB, se pueden ejecutar con la variable MiProc, del mismo modo para la función Retorno pero con la variable MiFunc.

En el caso de que se tenga una función sin parámetros como es el caso de TFunc, para que el puntero se pueda pasar en un procedimiento que necesita el resultado de la función, entonces se debe colocar esta variable con dos paréntesis, tal como se esta usando la variable Mifunc con el procedimiento Writeln.

El ejemplo anterior es un ejemplo que nos ayuda a entender como funcionan los punteros a funciones o procedimientos. Pero la utilidad de esta característica se obtiene cuando los punteros a funciones o procedimientos, se usan como parámetros. Es decir se puede diseñar un procedimiento en una unidad aparte que admita como parámetro un puntero a una función o procedimiento, que después debe crearse para que este cambie su comportamiento. La siguiente unidad y su programa correspondiente muestran tal situación:


Descargar
Unit ListaPersonas;
Interface
 Types

   TPersona = Record
                 Nombre       : String;
                 Edad         : String;
                 altura       : double;
                 nacionalidad : String;
               End;

   TListaPersonas=Array of TPersona;
   TCriterio=function (A,B:TPersona):boolean;

   PROCEDURE IngresarDatos(Var lista:TListaPersonas);
   PROCEDURE Ordenar(Var lista:array of TPersona;Criterio:TCriterio);
   PROCEDURE Mostrar(Var lista:array of TPersona);

Implementation

  PROCEDURE IngresarDatos(Var lista:TListaPersonas);
   Var n,i:integer;
   Begin
    Write('Ingrese numero de registros a procesar : ');Readln(n);
    Setlength(lista,n);
    for i:=0 to High(lista) do
      Begin
        Writeln('Registro #',i+1);
        Write('Nombre       : ');Readln(lista[i].Nombre);
        Write('Edad         : ');Readln(lista[i].Edad);
        Write('Altura       : ');Readln(lista[i].Altura);
        Write('Nacionalidad : ');Readln(lista[i].Nacionalidad);
    End;
   End;

  PROCEDURE Ordenar(Var lista:array of TPersona;Criterio:TCriterio);
  Var
    i,j:integer;
    aux:Tpersona;
   Begin
   Writeln('ordenando');
   For i:=1 to High(lista) do
    Begin
       aux:=lista[i];
       j:=i-1;
       While ( (j>=0) and Criterio(lista[j],aux)) do
          Begin
             lista[j+1]:= lista[j];
             j := j - 1;
          End;
        lista[j+1]:=aux;
    End;
   End;

  PROCEDURE Mostrar(Var lista:array of TPersona);
   Var i:longint;
   Begin
    Writeln('Mostrando arreglo ordenado ');
    for i:=0 to High(lista) do
    Begin
      Writeln('Registro #',i);
      Writeln('Nombre       : ',lista[i].Nombre);
      Writeln('Edad         : ',lista[i].Edad);
      Writeln('Altura       : ',lista[i].Altura:4:2);
      Writeln('Nacionalidad : ',lista[i].Nacionalidad);
    End;
   End;
End.
Código fuente 40: Unidad Lista Personas que ordena deacuerdo a un puntero de función TCriterio.
Descargar


Descargar
{$codepage UTF8}
Uses ListaPersonas;
VAR personas : array of TPersona;
    COrdenar:TCriterio;

Function CriterioOrdenar(a,b:TPersona):boolean;
 Begin
   CriterioOrdenar:=a.Nombre>b.Nombre
 End;

BEGIN
 COrdenar:=@CriterioOrdenar; 
 IngresarDatos(personas);
 Ordenar(personas,COrdenar);
 Mostrar(personas);
 Write('Presione enter para terminar ...');
 Readln  
END.
Código fuente 41: El programa que hace uso de TPersona, con la funcion CriterioOrdenar.
Descargar

Tal como se puede observar el procedimiento Ordenar hace uso de un parámetro que es un puntero a un procedimiento o función, que es TCriterio. Este parámetro permitirá ordenar la lista de personas dependiendo de como se diseñe la función que se pasará como parametro, al procedimiento ordenar.

El uso de punteros a procedimientos o funciones tiene sus limitaciones, no se pueden usar procedimientos o funciones que estén dentro de una función o procedimiento, es decir el compilador no lo permitirá. El siguiente ejemplo explica tal situación.


Descargar
{$codepage UTF8}
Type
  TProc=Procedure(A:integer);

  Procedure PAfuera(A:integer);
     Begin
       Writeln('Esto esta afuera ',A)
     End;

  Procedure MostrarA(A:integer);
    Var P:TProc;

    Procedure PDentro(A:integer);
     Begin
       Writeln('Esto esta dentro ',A)
     End;

    Begin
      Writeln(A);
      P:=@PAfuera;
      //P:=@PDentro;
      P(5);
    End;

Var MiProc:TProc;

Begin
   MiProc:=@MostrarA;
   MiProc(5)
End.
Código fuente 42: Uso de punteros a funciones o procedmientos dentro de una rutina.
Descargar

En el ejemplo se puede observar que la asignación del procedimiento PDentro, esta comentando. La razón de esto es evidente ya que el compilador no permitirá compilar el programa, ya que el procedimiento PDentro esta declarado dentro del procedimiento MostrarA, el compilador compilará el programa sólo si el procedimiento que se asigna a la variable P, este fuera de MostrarA.


Última revisión: 23/12/2013.



SIGUIENTE
SIGUIENTE
SIGUIENTE


 
‒ Comentarios y sugerencias.

Agradezco de antemano, todo comentario, sugerencia, y donativo a través de , que ayude a mejorar los contenidos educativos de Conoce 3000. Además, cualquier pregunta o duda que tengas lo puedes hacer por este medio. Pero, todo contenido que pueda resultar ofensivo, malicioso, racista, sexista, discriminatorio, obsceno, vulgar será eliminado. Para clases particulares contactame por whatsapp al 📲 (+51) 999 264 073








PORTADA |  INTERESANTE |  APUNTES |  LIBROS |  GALERIA


Creative Commons License


Todos los textos, imágenes y videos de Conoce3000 estan colocados bajo una licencia : Creative Commons Reconocimiento-NoComercial 3.0 Unported License.