Bienvenidos a Iseries Venezuela

Las mejores prácticas, recursos, tips, enlaces, videos y artículos para informáticos relacionados con el Iseries y el As/400 lenguajes de programación RPG, ILE RPG y SQL.

The best practices, resources, tips, links, videoes and articles for computer related to the Iseries and the As/400 languages of programming RPG, ILE RPG and SQL.

Tuesday, August 23, 2022

Pointers (Apuntadores) en RPGLE ¿Que son y para que sirven?

                       

Un apuntador o "pointer" es una variable que contiene la direccion de almacenamiento en memoria de otra variable o de un procedure. En la siguiente imagen tenemos un ejemplo hipotético de almacenamiento en memoria.

 

 

 

Supongamos que tenemos una variable tipo char declarada de 70 posiciones.

 A esa variable la llamaremos: mitexto char(70)

mitexto, según la siguiente imagen, comienza en la dirección de memoria:0000

Aunque en nuestro código de programación podemos manipular la varible mitexto, en realidad no sabemos en cual dirección de memoria es almacenada la data que contiene y, a decir verdad, a nadie le interesa saberlo a menos que, conocer su dirección en memoria y manipularla tuviese alguna utilidad.


En Rpgle Free la variable apuntador se declara asi:
dcl-s Apuntador pointer;

En Rpg No free:  D    Apuntador  S      *  //el asterisco indica que es tipo apuntador

Una variable tipo pointer puede contener la dirección en memoria de una variable o de un procedure

Para declarar un apuntador que apunta a un procedure: 

RPGLE NO Free: se agrega en la declaracion de la variable tipo apuntador la palabra clave PROCPTR

RPGLE FREE: se agrega la palabra clave POINTER(*PROC) en lugar de pointer

Un  apuntador que es utilizado para "apuntar a la dirección" de  una variable,  una estructura de datos o a un arreglo se denomina "Basing Pointer". 

 Veamos algunos de los beneficios que aporta utilizar apuntadores:

 

Utilidad del uso de apuntadores (pointers)

1.-Asignar a dos o mas variables la misma area de memoria.

     Veamos el siguiente ejemplo:  

     Queremos asignar a la variable miotrotexto el valor de la variable mitexto.

      Dcl-s mitexto char(70)  inz('Hola Mundo') ;

      Dcl-s miotrotexto char(50) based(Apuntador);

      Dcl-s Apuntador pointer;

    Apuntador = %Addr(mitexto);      //Addr es derivado de Address

   Las variables mitexto y miotrotexto comparten la misma area de memoria.

   El apuntador ocupa 16 bytes y mitexto ocupa 70 bytes. Totaliza 86 bytes.

   Normalmente  programariamos: miotrotexto = mitexto;

   Sin apuntadores estamos ocupando120 bytes, es decir, mas espacio en memoria. 

Esto también aplica para asignar la misma area de memoria entre estructuras de datos, entre arreglos y entre estructuras de datos y arreglos.

En el siguiente ejemplo, tenemos una estructura de datos que tiene el saldo de los ultimos tres meses y un arreglo de tres elementos. Inicializamos la estructura de datos con valores en los tres saldos y supongamos que necesitamos trasladar esos valores al arreglo de tres posiciones.

--------Declaraciones-------------

          Dcl-DS Saldos 

             Saldo1    zoned(15:2) inz(123.45);

             Saldo2    zoned(15:2) inz(567.88);

             Saldo3    zoned(15:2) inz(730.90);

          End-Ds Saldos;

          Dcl-s Arreglo zoned(15:2) dim(3) Based(ApuntadorArr);

          Dcl-s ApuntadorArr pointer;
 
        ------Operaciones con Apuntadores---------

        ApuntadorArr = %addr(Saldos);

        Ahora la estructura de datos y el arreglo "contienen la misma data".


 2.-Mover una variable desde un área de memoria a otra.

    Apuntador += 6;

   Esta operación cambia el valor de la variable miotrotexto. (del punto 1)

   Ahora miotrotexto contiene "Mundo". Se ha desplazado el inicio del espacio de    memoria asignado a la variable miotrotexto, seis posiciones a la derecha. 

  Tambien se puede restar posiciones. Si queremos asignar a miotrotexto el valor anterior colocamos:   

    Apuntador -=6;

 

3.- Se puede llamar a un procedure utilizando apuntadores.

  El apuntador que apunta a un  procedure se puede pasar como parámetro a otros procedures. Con este método varios procedures pueden llamar a programas de servicio o procedures que realizan calculos o procesamientos comunes  (calculo de fechas, etc) y se puede ahorra codigo.

 Encontrarán declaraciones de procedures y apuntadores como esta:

D ProcessRow      PR                  EXTPROC(Proc_Ptr)      

D Proc_Ptr            S                   *   PROCPTR INZ(*NULL)
 
En lugar de colocar "un nombre de procedure" en la keyword EXTPROC se coloca el apuntador al procedure que se desea invocar.
 
El apuntador Proc_Ptr se inicializaria con un parámetro de entrada que contendria el valor al apuntador del procedure que se desea ejecutar. 
 
ProcessRow seria un nombre generico que aplica a  cualquier procedure que se ejecute (segun el apuntador recibido en el parametro de entrada) al hacer 
callp ProcessRow

 En el siguiente enlace encontrarán una explicacion detallada de esta opción.  

Procedure Pointers

 

Operaciones con Apuntadores.

  1-Pueden inicializarse los apuntadores con *NULL.  inz(*NULL)  


  2-%Alloc  reserva un espacio de memoria. Otro proceso no lo podra usar.

   Dcl-s ApuntadorA  pointer(*)

   ApuntadorA = %alloc(200);  //reserva 200 Bytes de memoria

 

  3.-Dealloc permite liberar el espacio de memoria que se habia reservado.

     dealloc ApuntadorA; 

     dealloc(n) ApuntadorA; //libera el espacio de memoria y le coloca *NULL

     dealloc(e);  //Pemite monitorear si hay error preguntando por %error

     If %error;

4.-%STR permite almacenar información de un apuntador basing point. Es decir, de un apuntador que apunta variables y estructuras de datos, no procedures.

%str(Apuntador1:20) = 'Hola Mundo'; 

Esto indica inicializar un máximo de 20 posiciones con el texto "Hola Mundo"

     ---------------

A continuación dejo varios enlaces de interés sobre este tema.


Enlaces de interes.

https://www.ibm.com/docs/en/i/7.3?topic=type-examples 

Stackoverflow-Memory Address

https://www.scottklement.com/rpg/pointers.html

https://www.itjungle.com/2010/09/15/fhg091510-story02/

https://www.mcpressonline.com/programming/rpg/techtip-rpg-iv-pointerstheyre-easy

 https://www.ibm.com/docs/en/i/7.4?topic=string-str-used-get-null-terminated

 

        

     Si te pareció interesante, reenvíalo a un amigo haciendo click en el sobrecito que está al final del artículo o en el enlace de Linkedin que está encima de este mensaje.  El conocimiento es valioso, compártelo. 

    Autor: Ing. Liliana Suárez

No comments: