In questo articolo cercherò di spiegare brevemente come utilizzare una variabile di tipo Pointer in STL.
E’ molto importante comprendere bene il funzionamento del tipo di dato Pointer, in quanto è praticamente l’unico modo che si ha a disposizione se si vuole creare una funzione che deve leggere, scrivere o modificare array di diverse dimensioni (vedi ad esempio questi articoli “Array Dinamico Incrementale“, “Copia di array elemento per elemento“, “Somma di due array elemento per elemento“).
Quando dichiariamo una variabile di tipo Pointer, stiamo praticamente dichiarando un puntatore che punta ad un area di memoria.
Ad esempio supponiamo di creare un funzione (che chiamo “prova_pointer”) che ha una sola variabile che chiamo “in_ptr”, e che il tipo di questa variabile sia Pointer. Essendo la variabile “in_ptr” della funzione di tipo Pointer, questo significa che quando la funzione viene richiamata può ricevere in ingresso una variabile di qualsiasi tipo. La variabile pointer “in_ptr” all’interno della funzione è semplicemente una variabile che punta all’area di memoria della variabile in ingresso.
Ad esempio:
In questo caso sto chiamando la funzione “prova_pointer” e sto mandando in ingresso una variabile intera (“intero1”). Come detto prima la variabile “in_ptr” all’interno della funzione punta all’area di memoria della variabile “intero1”.
Per capire come poter andare a leggere o scrivere in quell’area di memoria è prima necessario sapere la struttura del tipo di dato Pointer. Il tipo di dato Pointer utilizza 6 Byte e ha la seguente struttura:
Quindi i primi due Byte (ossia una word) rappresentano il numero del “Data Block” (DB Number) in cui si trova la variabile a cui punta il puntatore (nel nostro esempio il puntatore “in_ptr” punta all’indrizzo di “intero1”).
Gli ultimi 4 Byte (quindi 32bit, ossia una doubleWord) rappresentano invece l’area di memoria a cui punta il puntatore “in_ptr” all’interno del blocco dati in cui appunto si trova la variabile “intero1”. In questo esempio la variabile “intero1” non si trova all’interno di alcun blocco dati, pertanto DB number sarà uguale a zero.
Supponiamo (per fare un esempio molto semplice) che la funzione “prova_pointer” resetti tutti i bit della variabile in ingresso (quindi della variabile “intero1”). Per fare questo la funzione sarà:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | FUNCTION "prova_pointer" : Void { S7_Optimized_Access := 'FALSE' } VERSION : 0.1 VAR_INPUT in_ptr : Pointer; END_VAR VAR_TEMP number_DB : Word; END_VAR BEGIN NETWORK TITLE = L P##in_ptr; LAR1; L W[ AR1, P#0.0] ;// carico i primi due Byte del Pointer (che specificano il DB number) array_ptr su ACCU1 T #number_DB ;//salvo i primi due Byte del Pointer su number_DB L D[ AR1, P#2.0] ;//carico i byte 2,3,4,5 su ACCU1 ->indicano l'area di memoria a cui punto il puntatore LAR1 ;//trasferisco ACCU1 su AR1 L 0; //Carico 0 su ACCU1 OPN DB[ #number_DB] ;// Apro il DB relativo all'area di memoria a cui punta il puntatore T W[ AR1, P#0.0] ;//trasferisco 20 sull'area di memoria a cui punta il puntatore END_FUNCTION |