(FC in STL) Copia di array elemento per elemento

Creazione di una funzione che copia elemento per elemento il contenuto di un array (nell’esempio sotto “array1”) in un altro array (“array2”).

La funzione che vado a creare avrà due variabili di tipo Pointer (“array1_ptr” che è la variabile in ingresso, e “array2_ptr” che è dichiarata come variabile di output) e una variabile intera (variabile “dim” dichiarata come input) che rappresenta la dimensione minima tra i due array. Ovviamente le due variabili Pointer puntano all’indirizzo di memoria del primo elemento dei rispettivi array (vedi questi articoli “Utilizzo di variabili Pointer”,“Array dinamico incrementale”).
Lo scopo di questa funzione è quello di copiare elemento per elemento il contenuto dell’array1 (ossia l’array a cui punta il puntatore “array1_ptr”) sull’array2 (ossia l’array a cui punta il puntatore “array2_ptr”).

La funzione spiegata passaggio per 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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
FUNCTION "copia_array1_in_array_2_dinamico_pointer_1" : Void
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      array1_ptr : Pointer;
      dim : Int;
   END_VAR
 
   VAR_OUTPUT 
      array2_ptr : Pointer;
   END_VAR
 
   VAR_TEMP 
      numb_db_array1 : Word;
      numb_db_array2 : Word;
      save_ar2 : DWord;
      count1 : Int;
   END_VAR
 
 
BEGIN
NETWORK
TITLE = 
//funzione che copia il contenuto di array1 in array2, dim è la dimensione dell'array più piccolo
      L P##array1_ptr;  //carica il Pointer array1_ptr in ACCU1
      LAR1; //carica il contenuto di ACCU1 su AR1
      L W[ AR1, P#0.0] ;// Carico su ACCU1 i primi due Byte del Pointer array1_ptr che rappresentano il numero del blocco dati (DB_number)
      T #numb_db_array1;//trasferisco ACCU1 su numb_db_array1 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 array1_ptr all'intero del DB
      LAR1;// carico l'indizizzo precedente su AR1
 
//salvo ar2 su doubleword e lo ripristino a fine funzione (questo perchè AR2 è utilizzato dal processore e non ripristinarlo può causare problemi)
      TAR2;
      T #save_ar2;
 
      L P##array2_ptr;
      LAR2;// carico l'indizizzo del puntatore su AR2
      L W[ AR2, P#0.0];// Carico su ACCU1 i primi due Byte del Pointer array2_ptr che rappresentano il numero del blocco dati (DB_number)
      T #numb_db_array2;//trasferisco ACCU1 su numb_db_array2 per riutilizzarlo dopo quando devo aprire il blocco dati
      L D[ AR2, 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 array2_ptr all'intero del DB
      LAR2;// carico l'indizizzo precedente su AR2
 
      L #dim;//carico su ACCU1 la più piccola dimensione tra i due array (dim è un input della funzione)
inizio:      T #count1 ;// inizio un  loop
      OPN DB[ #numb_db_array1];//apro il blocco dati DB dove è presente l'array a cui punta il puntatore array1_ptr
      L W[ AR1, P#0.0];//carico su ACCU1 l'elemento array1[dim-count1] (dove l'array1 è un array di interi o Word a cui punta array1_ptr)
      OPN DB[ #numb_db_array2];//apro il blocco dati DB dove è presente l'array a cui punta il puntatore array2_ptr
      T W[ AR2, P#0.0];// trasferisco il valore presente in ACCU1 su array2[dim-count1], cioè array2[dim-count1]=array1[dim-count1]
      +AR1 P#2.0;// "incremento" AR1 di 2 byte, ossia nel ciclo successivo del loop l'indirizzo in AR1 è quello della word immediatamente succesiva (elemento successivo)
      +AR2 P#2.0;//come sopra ma per AR2
      L #count1;
      LOOP inizio;//ripeto il loop fino a quando ACCU1, ossia count1>0 (ad ogni ciclo di loop count1 viene decrementato di 1)
 
      L #save_ar2;
      LAR2;//ripristino AR2 precedentemente salvato  
 
END_FUNCTION

Si potrebbe anche evitare di usare AR2 utilizzando due variabili temporanee che salvano rispettivamente l’indirizzo dell’array1 e dell’array2 all’interno dei rispettivi DB. Definendo quindi le variabili “#indirizzo_array1” e “#indirizzo_array2”, posso modificare la funzione sopra e ho quindi:

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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
FUNCTION "Prova" : Void
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
   VAR_INPUT 
      array1_ptr : Pointer;
      dim : Int;
   END_VAR
 
   VAR_OUTPUT 
      array2_ptr : Pointer;
   END_VAR
 
   VAR_TEMP 
      num_db1 : Word;
      num_db2 : Word;
      indirizzo_array1 : DWord;
      indirizzo_array2 : DWord;
      count1 : Int;
      int_tmp1 : Int;
      int_tmp2 : Int;
   END_VAR
 
 
BEGIN
NETWORK
TITLE = 
      L P##array1_ptr;
      LAR1;
      L W[ AR1, P#0.0];
      T #num_db1;
      L D[ AR1, P#2.0];
      T #indirizzo_array1;
 
 
      L P##array2_ptr;
      LAR1;
      L W[ AR1, P#0.0];
      T #num_db2;
      L D[ AR1, P#2.0];
      T #indirizzo_array2;
      L #dim;
 
inizio:      T #count1;
      L #indirizzo_array1;
      LAR1;
      OPN DB[ #num_db1];
      L W[ AR1, P#0.0];
      T #int_tmp1;
      +AR1 P#2.0;
      TAR1;
      T #indirizzo_array1;
 
      L #indirizzo_array2;
      LAR1;
      L #int_tmp1;
      OPN DB[ #num_db2];
      T W[ AR1, P#0.0];
      +AR1 P#2.0;
      TAR1;
      T #indirizzo_array2;
      L #count1;
      LOOP inizio;
 
END_FUNCTION

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