(FC in STL) Array dinamico incrementale

Si vuole creare una funzione che riceve in ingresso il primo elemento dell’array e la dimensione (dell’array) e che riempie in maniera incrementale gli elementi dell’array, ovvero –> arrray_in[0]=0, array_in[1]=1, array_in[2]=2, … array_in[n]=n.

L’unico modo in cui è possibile accedere e modificare gli elementi di array (che possono avere dimensioni diverse) attraverso l’utilizzo di una sola funzione è quello di usare i puntatori. Quindi l’ingresso della funzione è una variabile di tipo Pointer, e questa variabile punta all’area di memoria relativa al primo elemento dell’array (ovvero quando richiamo la funzione l’ingresso sarà semplicemente il primo elemento dell’array). Ricordiamo che il tipo di dato Pointer utilizza 6 Byte, e la struttura è la seguente:

Pointer

Quindi i primi due Byte (ossia una word) rappresentano il numero del “Data Block” (DB Number) in cui si trova l’array a cui punta il puntatore (che nell’esempio è stato chiamato Array_ptr).
Gli ultimi 4 Byte (quindi 32bit, ossia una doubleWord) rappresentano invece l’area di memoria a cui punta il puntatore Array_ptr all’interno del blocco dati in cui appunto si trova l’array.

Per ulteriori chiarimenti sull’utilizzo di variabili di tipo Pointer (in STL) guarda questo articolo

La funzione che consente di eseguire quanto detto sopra (con descrizione di ogni passaggio) è la seguente:

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
28
29
30
31
32
33
34
35
FUNCTION "array_dinamico_incrementale" : Void
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      Array_ptr : Any;
      dim : Int;
   END_VAR
 
   VAR_TEMP 
      numb_db : Word;
      count1 : Int;
   END_VAR
 
 
BEGIN
NETWORK
TITLE = 
 L  P##Array_ptr  //Array_ptr è un Input di tipo Pointer
      LAR1
      L W [ AR1 , P#0.0 ] // Carico su ACCU1 i primi due Byte del Pointer Array_ptr che rappresentano il numero del blocco dati (DB_number)
      T     #numb_db     //trasferisco ACCU1 su numb_db per riutilizzarlo dopo quando devo aprire il blocco dati
      L D [ AR1 , P#2.0 ] // carico su ACCU1 i byte 2,3,4,5 (ossia 32bit) che corrispondono all'area di memoria a cui punta il puntatore Array_ptr all'intero del DB
      LAR1 // carico l'indizizzo precedente su AR1
      L     #dim //carico su ACCU1 la dimensione dell'array a cui punta il puntatore Array_ptr
inizio : T  #count1 // inizio un  loop
      L     #dim
      L     #count1
      -I                      // faccio la differenza tra dim e count1 per avere array[0]=0,  array[1]=1, altrimenti avrei array[0]=dim-1, array[1]=dim-2 ecc..
      OPN DB [ #numb_db] //apro il blocco dati DB dove è presente l'array a cui punta il puntatore Array_ptr
      T W [ AR1 , P#0.0 ] // trasferisco il valore contenuto in ACCU1 (che sarebbe dim-count1) all'indirizzo corrispondente ad array[dim-count1], quindi array[0]=0, array[1]=1, ..
      +AR1  P#2.0 // "incremento" AR1 di 2 byte, ossia nel ciclo successivo del loop, l'indirizzo in AR1 è quello dell'elemento immediatamente successivo dell'array
      L     #count1
      LOOP  inizio  //ripeto il loop fino a quando ACCU1, ossia count1>0 (ad ogni ciclo di loop count1 viene decrementato di 1)
 
END_FUNCTION

La prima parte (quella prima del loop) è semplice da capire se si è letto e capito l’articolo precedentemente indicato.

Nella seconda parte carico la dimensione dell’array (variabile #dim in ingresso) su ACCU1, inizializzo la variabile intera count1 (count1=dim) e inizio il loop (ad ogni ciclo del loop la variabile count1 viene decrementata di 1). Inoltre mi assicuro all’interno del loop di aprire il Blocco dati dove è contenuto l’array a cui punta il puntatore Array_ptr (faccio questa operazione con OPN DB [ #numb_db]).

Per capire meglio analizziamo direttamente quello che avviene nei primi tre cicli del loop e nell’ultimo.

Primo Ciclo:
count1=dim, trasferisco la differenza tra dim e count1 (quindi dim-count1=0) sull’aria di memoria salvata su AR1
(T W [ AR1 , P#0.0 ], che corrisponde all’area di memoria del primo elemento dell’array all’interno del blocco dati). Quindi array_in[0]=0. Poi incremento di 2 Byte AR1 (+AR1 P#2.0), quindi nel ciclo successivo del loop l’indirizzo in AR1 è quello dell’elemento immediatamente successivo dell’array. Nota: incremento di 2 Byte se l’array è un array di interi o di word.

Nota: incremento di 2 Byte se l’array è un array di interi o di word.

Secondo Ciclo:
count1=count1-1, trasferisco la differenza tra dim e count1 (quindi dim-count1=1) sull’aria di memoria salvata su AR1 (che corrisponde all’area di memoria del secondo elemento dell’array all’interno del blocco dati). Quindi array_in[1]=1. Poi incremento di 2 Byte AR1 (quindi nel ciclo successivo del loop l’indirizzo in AR1 è quello del terzo elemento dell’array).

Terzo Ciclo:
count1=count1-1, trasferisco la differenza tra dim e count1 (quindi dim-count1=2) sull’aria di memoria salvata su AR1 (che corrisponde all’area di memoria del terzo elemento dell’array all’interno del blocco dati). Quindi array_in[2]=2. Poi incremento di 2 Byte AR1 (quindi nel ciclo successivo del loop l’indirizzo in AR1 è quello del quarto elemento dell’array).


Ultimo Ciclo:
count1=count1-1, trasferisco la differenza tra dim e count1 (quindi dim-count1=dim-1) sull’aria di memoria salvata su AR1 (che corrisponde all’area di memoria dell’ultimo dell’array all’interno del blocco dati). Quindi array_in[dim-1]=dim-1.

You may also like...


Warning: count(): Parameter must be an array or an object that implements Countable in /membri/fabioplc/wp-includes/class-wp-comment-query.php on line 399
Menu Title