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:
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:
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.
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.