Differenze tra le versioni di "Variabili di tipo Puntatore e loro dereferenziazione"

Da Gambas-it.org - Wikipedia.
(Nuova pagina: Per porre l'indirizzo di memoria di una variabile qualsiasi in una variabile di tipo Puntatore (''As Pointer''), si utilizza la funzione ''VarPtr''. variabile_puntatore = VarPtr(vari...)
 
 
(26 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
Per porre l'indirizzo di memoria di una variabile qualsiasi in una variabile di tipo Puntatore (''As Pointer''), si utilizza la funzione ''VarPtr''.
+
La ''dereferenziazione'' di una variabile di tipo ''Puntatore'' si ha quando si deve ''estrarre'' il valore contenuto nella variabile puntata da ''Puntatore'' (il più delle volte tale ''Puntatore'' viene passato da una funzione esterna); oppure uno o più valori contenuti in un'area di memoria riservata precedentemente allocata con la funzione "Alloc()".   [<SUP>[[#Note|nota 1]]</sup>]
  
variabile_puntatore = VarPtr(variabile_da_puntare)
+
"''Dereferenziare''" un ''Puntatore'' significa, dunque, accedere alla locazione di memoria da esso puntata, per ottenere il valore contenuto dalla variabile puntata dal ''Puntatore''. La variabile di tipo ''Puntatore'', infatti, restituisce l'indirizzo di memoria di una variabile - se è stata usata la funzione "VarPtr()" - oppure di una area di memoria allocata (riservata), se è stata utilizzata la funzione "Alloc()".
 +
<BR>Il ''Puntatore'', così, ci consente di accedere alla variabile puntata oppure all'area di memoria allocata, al fine di leggervi o scrivervi dati-byte.
  
Successivamente, per ''dereferenziare''{[[#Note|1]]} il pointer, ossia per estrarre il valore contenuto nella variabile puntata dal puntatore, è possibile usare:
+
Per "''dereferenziare''" il ''Puntatore'' è possibile usare:
* i Memory-Stream in lettura (soprattutto se è stata utilizzata una zona riservata di memoria con la funzione ''Alloc'', e l'indirizzo è stato passato alla variabile pointer da una funzione esterna richiamata con ''Extern'');
+
* i ''Memory-Stream'' in lettura (soprattutto se è stata utilizzata una zona riservata di memoria con la funzione "Alloc()", e l'indirizzo è stato passato alla variabile di tipo ''Puntatore'' da una funzione esterna richiamata con ''Extern'');
* più brevemente una specifica funzione che restituisca il valore memorizzato all'indirizzo specificato dal Puntatore{[[#Note|2]]}: Int@, Byte@, Float@, etc, a seconda del tipo.
+
* più brevemente una specifica funzione di Gambas che restituisca il valore memorizzato all'indirizzo specificato dal Puntatore ("Int@()", "Byte@()", "Float@()" e le altre simili a seconda del tipo).
  
  
Esempio:
+
===Dereferenziazione con i ''Memory Stream''===
 
+
Per fare questo esempio pratico, poniamo il caso che venga passata ad una sub-procedura una variabili di tipo ''Puntatore'', che punta ad un'area di memoria precedentemente riservata con la funzione "Alloc()" e nella quale siano stati scritti quattro valori di tipo ''Byte''.
''<Font Color= #006400>' Gambas class file''</font>
+
<BR>Il ''Puntatore'' sarà così dereferenziato usando i ''Memory Stream'':
 +
Private Procedure Dereferenzia(p As Pointer)
 
   
 
   
 +
  Dim j, b As Byte
 +
  Dim st As Stream
 
   
 
   
  '''Public''' Sub Button1_Click()
+
  <Font Color=gray>' ''Generiamo la variabile di tipo "Stream" dal "Puntatore" che è stato passato con la chiamata della sub-procedura:''</font>
 +
  st = Memory p For Read
 
   
 
   
  Dim datoInt, intDef As Integer
+
<Font Color=gray>' ''Vengono estratti, in questo esempio, 4 byte leggendo la variabile di tipo "Stream":''</font>
   Dim byDef As Byte
+
   For j = 0 To 3
  Dim datoPtr As Pointer
+
    Read #st, b
  Dim byPtr As Pointer
+
    Print "---> ", b
   Dim byStrm As Stream
+
   Next
 
   
 
   
  datoInt = 2
+
<Font Color=gray>' ''Chiudiamo il flusso:''</font>
 +
  st.Close
 
   
 
   
  ''<Font Color= #006400>' poniamo nel pointer "dato1Ptr" l'indirizzo che punta alla variabile Integer "datoInt":''</font>
+
  End
    datoPtr = VarPtr(datoInt)
+
 
 +
 
 +
===Dereferenziazione con le specifiche funzioni "Byte@()", "Short@()", "Int@()", etc.===
 +
In questo semplice esempio il ''Puntatore'' sarà dereferenziato con le funzioni specifiche di Gambas. Faremo un confronto con il linguaggio C.
 +
Public Sub Main()
 
   
 
   
''<Font Color= #006400>' Allochiamo memoria sufficiente:''</font>
+
  Dim i As Integer        <FONT Color=B22222>' ''int i;''</font>
  byPtr = Alloc(2)
+
  Dim p As Pointer        <FONT Color=B22222>' ''int *p;''</font>
 
   
 
   
   ''<Font Color= #006400>' supponiamo che venga usata una funzione esterna (ovviamente dichiarata con Extern, che qui si omette)
+
   i = 9999                <FONT Color=B22222>' ''i = 9999;''</font>
'' ' la quale passi un dato byte alla variabile "byPtr", e che quindi possiamo raccogliere:''</font>
 
  funzione_esterna(param1, byPtr)
 
 
   
 
   
 +
<FONT Color=gray>' ''Assegnamo alla variabile di tipo "Puntatore" la variabile di tipo Intero "i".''
 +
' ''Il "Puntatore", così, punta alla variabile "i", accedendo all'area di memoria della variabile:''</font>
 +
  p = VarPtr(i)          <FONT Color=B22222>' ''p = &i;''</font>
 
   
 
   
  ''<Font Color= #006400>' Andiamo ora a "dereferenziare" i pointer, ossia ad estrarre i valori contenuti nelle variabili,
+
<FONT Color=gray>' ''Dereferenziamo il "Puntatore" mediante la funzione di Gambas "int@()":</font>
'' ' i cui indirizzi di memoria sono puntati dai precedenti puntatori.''</font>
+
  Print "i = "; Int@(p)   <FONT Color=B22222>' ''printf("%d\n", *p);''</font>
 
 
''<Font Color= #006400>' Dereferenziamo il pointer "datoPtr" con la funzione specifica "Int@":''</font>
 
  intDef = Int@(datoPtr)
 
 
''<Font Color= #006400>' Dereferenziamo ora il pointer "byPtr" con i "Memory-Stream":''</font>
 
  byStrm = Memory byPtr For Read
 
''<Font Color= #006400>' Leggiamo quindi la variabile di tipo "stream", e poniamo il valore nella variabile di tipo byte:''</font>
 
  Read #byStrm, byDef
 
 
   
 
   
 +
End
 +
Quando l'area di memoria puntata contiene due o più dati, se ci si intende spostare all'interno di essa - senza voler utilizzare i ''Memory Stream'' -, si provvederà ad aggiungere all'indirizzo di memoria, contenuto dal ''Puntatore'' uno o più unità utili a raggiungere il primo dato-byte del valore da leggere.
 +
 +
Esempio:
 +
Public Sub Main()
 
   
 
   
''<Font Color= #006400>' Andiamo quindi a mostrare i relativi dati:''</font>
+
  Dim p As Pointer
  Print intDef
+
  Dim st As Stream
  Print byDef
 
 
    
 
    
'''End'''
+
  p = Alloc(SizeOf(gb.Byte), 8)
 
+
  st = Memory p For Write
 
+
  Write #st, 3333 As Short
In quest'altro esempio andremo più semplicemente a dereferenziare lo stesso pointer con le due modalità sopra descritte:
+
  Write #st, 555555 As Integer
 
+
  st.Close
''<Font Color= #006400>' Gambas class file''</font>
 
 
   
 
   
 +
<FONT Color=gray>' ''Dereferenzia il "Puntatore" e legge i dati-byte (cominciando dall'indice 0 dell'area di memoria allocata) che costituiscono lo dato "Short", previsto sopra nel codice:''</font>
 +
  Print Short@(p)
 
   
 
   
  '''Public''' Sub Button1_Click()
+
  <FONT Color=gray>' ''Aggiunge due unità, per poter superare nel flusso di memoria i dati che costituiscono il tipo di dato "Short", così da raggiungere il primo dato-byte del dato "Integer":''</font>
+
  Print Int@(<FONT Color=#B22222>p <B>+ 2</b></font>)
  Dim a As Byte
+
 
  Dim aPtr As Pointer
+
  Free(p)
  Dim aSt As Stream
 
  Dim a1Post, a2Post As Byte
 
 
 
    a = 2
 
 
 
''<Font Color= #006400>' poniamo nella variabile pointer l'indirizzo della variabile byte "a":''</font>
 
    aPtr = VarPtr(a)
 
   
 
   
 
''<Font Color= #006400>' Dereferenziamo il Pointer:''</font>
 
 
''<Font Color= #006400>' con la funzione specifica "Byte@":''</font>
 
    a1Post = Byte@(aPtr)
 
     
 
''<Font Color= #006400>' e con i Memory-Stream:''</font>
 
    aSt = Memory aPtr For Read
 
    Read #aSt, a2Post
 
     
 
     
 
''<Font Color= #006400>' quindi leggiamo i due valori restituiti:''</font>
 
    Print "a1Post = "; a1Post
 
    Print "a2Post = "; a2Post
 
 
   
 
   
  '''End'''
+
  End
  
In console avremo coerentemente:
 
<BR>a1Post = 2
 
<BR>a2Post = 2
 
  
 +
==Dereferenziare senza Memory-Stream un Puntatore ad una Struttura, passato da una funzione esterna==
 +
Per quest'argomento rimandiamo alla specifica pagina presente nella WIKI:
 +
<BR>[[Dereferenziare senza Memory-Stream un Puntatore ad una Struttura, passato da una funzione esterna]].
  
  
----
 
===Note===
 
[1] ''Dereferenziare un Pointer'': accedere al valore della variabile puntata dal puntatore.
 
  
[2] Per restare come riferimento al Forum di Gambas-it.org, vedere anche questa discussione sui [http://www.gambas-it.org/smf/index.php?topic=586.0 puntatori].
+
=Note=
 +
[1] Se la variabile di tipo ''Puntatore'' deve puntare ad una variabile ad un tipo fondamentale (o meglio: contenere l'indirizzo di memoria di una variabile) già dichiarata, allora si userà la funzione "VarPtr()".
 +
<BR>Se la variabile di tipo ''Puntatore'' deve essere utilizzata per creare un variabile di tipo ''Stream'', nel quale successivamente scrivere dati, allora sarà opportuno allocare una parte di memoria mediante la funzione "Alloc()".

Versione attuale delle 09:39, 5 ago 2023

La dereferenziazione di una variabile di tipo Puntatore si ha quando si deve estrarre il valore contenuto nella variabile puntata da Puntatore (il più delle volte tale Puntatore viene passato da una funzione esterna); oppure uno o più valori contenuti in un'area di memoria riservata precedentemente allocata con la funzione "Alloc()". [nota 1]

"Dereferenziare" un Puntatore significa, dunque, accedere alla locazione di memoria da esso puntata, per ottenere il valore contenuto dalla variabile puntata dal Puntatore. La variabile di tipo Puntatore, infatti, restituisce l'indirizzo di memoria di una variabile - se è stata usata la funzione "VarPtr()" - oppure di una area di memoria allocata (riservata), se è stata utilizzata la funzione "Alloc()".
Il Puntatore, così, ci consente di accedere alla variabile puntata oppure all'area di memoria allocata, al fine di leggervi o scrivervi dati-byte.

Per "dereferenziare" il Puntatore è possibile usare:

  • i Memory-Stream in lettura (soprattutto se è stata utilizzata una zona riservata di memoria con la funzione "Alloc()", e l'indirizzo è stato passato alla variabile di tipo Puntatore da una funzione esterna richiamata con Extern);
  • più brevemente una specifica funzione di Gambas che restituisca il valore memorizzato all'indirizzo specificato dal Puntatore ("Int@()", "Byte@()", "Float@()" e le altre simili a seconda del tipo).


Dereferenziazione con i Memory Stream

Per fare questo esempio pratico, poniamo il caso che venga passata ad una sub-procedura una variabili di tipo Puntatore, che punta ad un'area di memoria precedentemente riservata con la funzione "Alloc()" e nella quale siano stati scritti quattro valori di tipo Byte.
Il Puntatore sarà così dereferenziato usando i Memory Stream:

Private Procedure Dereferenzia(p As Pointer)

 Dim j, b As Byte
 Dim st As Stream

' Generiamo la variabile di tipo "Stream" dal "Puntatore" che è stato passato con la chiamata della sub-procedura:
 st = Memory p For Read

' Vengono estratti, in questo esempio, 4 byte leggendo la variabile di tipo "Stream":
 For j = 0 To 3
   Read #st, b
   Print "---> ", b
 Next

' Chiudiamo il flusso:
 st.Close

End


Dereferenziazione con le specifiche funzioni "Byte@()", "Short@()", "Int@()", etc.

In questo semplice esempio il Puntatore sarà dereferenziato con le funzioni specifiche di Gambas. Faremo un confronto con il linguaggio C.

Public Sub Main()

 Dim i As Integer        ' int i;
 Dim p As Pointer        ' int *p;

 i = 9999                ' i = 9999;

' Assegnamo alla variabile di tipo "Puntatore" la variabile di tipo Intero "i".
' Il "Puntatore", così, punta alla variabile "i", accedendo all'area di memoria della variabile:
 p = VarPtr(i)           ' p = &i;

' Dereferenziamo il "Puntatore" mediante la funzione di Gambas "int@()":
 Print "i = "; Int@(p)   ' printf("%d\n", *p);

End

Quando l'area di memoria puntata contiene due o più dati, se ci si intende spostare all'interno di essa - senza voler utilizzare i Memory Stream -, si provvederà ad aggiungere all'indirizzo di memoria, contenuto dal Puntatore uno o più unità utili a raggiungere il primo dato-byte del valore da leggere.

Esempio:

Public Sub Main()

 Dim p As Pointer
 Dim st As Stream
 
 p = Alloc(SizeOf(gb.Byte), 8)
 st = Memory p For Write
 Write #st, 3333 As Short
 Write #st, 555555 As Integer
 st.Close

' Dereferenzia il "Puntatore" e legge i dati-byte (cominciando dall'indice 0 dell'area di memoria allocata) che costituiscono lo dato "Short", previsto sopra nel codice:
 Print Short@(p)

' Aggiunge due unità, per poter superare nel flusso di memoria i dati che costituiscono il tipo di dato "Short", così da raggiungere il primo dato-byte del dato "Integer":
 Print Int@(p + 2)
  
 Free(p)

End


Dereferenziare senza Memory-Stream un Puntatore ad una Struttura, passato da una funzione esterna

Per quest'argomento rimandiamo alla specifica pagina presente nella WIKI:
Dereferenziare senza Memory-Stream un Puntatore ad una Struttura, passato da una funzione esterna.


Note

[1] Se la variabile di tipo Puntatore deve puntare ad una variabile ad un tipo fondamentale (o meglio: contenere l'indirizzo di memoria di una variabile) già dichiarata, allora si userà la funzione "VarPtr()".
Se la variabile di tipo Puntatore deve essere utilizzata per creare un variabile di tipo Stream, nel quale successivamente scrivere dati, allora sarà opportuno allocare una parte di memoria mediante la funzione "Alloc()".