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

Da Gambas-it.org - Wikipedia.
Riga 1: Riga 1:
 
La ''dereferenziazione'' di una variabile di tipo ''Puntatore'' si ha quando si deve ''estrarre'' il valore contenuto nella variabile puntata dal puntatore (il più delle volte il contenutpo di 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()''.  |[[#Note|1]]|
 
La ''dereferenziazione'' di una variabile di tipo ''Puntatore'' si ha quando si deve ''estrarre'' il valore contenuto nella variabile puntata dal puntatore (il più delle volte il contenutpo di 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()''.  |[[#Note|1]]|
  
Per "''dereferenziare''" il ''Puntatore'', ossia per accedere alla locazione di memoria puntata, |[[#Note|2]]| è possibile usare:
+
"''Dereferenziare''" un ''Puntatore'' significa, dunque, accedere alla locazione di memoria da esso puntata; significa accedere al valore della variabile puntata dal ''Puntatore''.
 +
 
 +
Per "''dereferenziare''" il ''Puntatore'' |[[#Note|2]]| è 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'');
 
* 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 simili, 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 simili, a seconda del tipo.
  
  
Esempio:
+
===Dereferenziazione con i ''Memory Stream''===
'''Public''' Sub Button1_Click()
+
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''.
+
<BR>Il ''Puntatore'' sarà così dereferenziato usando i ''Memory Stream'':
  Dim datoInt, intDef As Integer
+
  '''Private''' Procedure Dereferenzia(p As Pointer)
  Dim byDef As Byte
 
  Dim datoPtr As Pointer
 
  Dim byPtr As Pointer
 
  Dim byStrm As Stream
 
 
  datoInt = 2
 
 
<Font Color= #006400>' ''Poniamo nel pointer "dato1Ptr" l'indirizzo che punta alla variabile Integer "datoInt":''</font>
 
    datoPtr = VarPtr(datoInt)
 
 
<Font Color= #006400>' ''Allochiamo memoria sufficiente:''</font>
 
  byPtr = Alloc(2)
 
 
<Font Color= #006400>' ''Supponiamo che venga usata una funzione esterna (ovviamente dichiarata con Extern, che qui si omette)
 
  '' ' la quale passi un dato byte alla variabile "byPtr", e che quindi possiamo raccogliere:''</font>
 
  funzione_esterna(param1, byPtr)
 
 
   
 
   
 +
  Dim j, b As Byte
 +
  Dim st As Stream
 
   
 
   
<Font Color= #006400>' ''Andiamo ora a "dereferenziare" i pointer, ossia ad estrarre i valori contenuti nelle variabili,
 
'' ' i cui indirizzi di memoria sono puntati dai precedenti puntatori.''</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>
+
  <Font Color=gray>' ''Generiamo la variabile di tipo "Stream" dal "Puntatore" che è stato passato con la chiamata della sub-procedura:''</font>
   byStrm = Memory byPtr For Read
+
   st = Memory p 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
 
 
   
 
   
 +
<Font Color=gray>' ''Riprendiamo l'esempio del paragrafo precedente, dove sono stati scritti 4 valori di tipo "byte"; e li andiamo ad "estrarre" leggendo dalla variabile di tipo "Stream":''</font>
 +
  For j = 0 To 3
 +
    Read #st, b
 +
    Print "---> ", b
 +
  Next
 
   
 
   
  <Font Color= #006400>' ''Andiamo quindi a mostrare i relativi dati:''</font>
+
  <Font Color=gray>' ''Chiudiamo il flusso:''</font>
   Print intDef
+
   st.Close
  Print byDef
 
 
   
 
   
<Font Color= #006400>' ''De-allochiamo la memoria precedentemente riservata e chiudiamo il flusso:''</font>
 
  free(byPtr)
 
  byStrm.Close
 
 
 
 
  '''End'''
 
  '''End'''
  
  
In quest'altro esempio andremo più semplicemente a dereferenziare lo stesso pointer con le due modalità sopra descritte:
+
===Dereferenziazione con le specifiche funzioni ''Byte@()'', ''Short@()'', ''Int@()'', etc.===
  '''Public''' Sub Button1_Click()
+
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 a As Byte
+
   Dim i As Integer        <FONT Color=B22222>' ''int i;''</font>
   Dim aPtr As Pointer
+
   Dim p As Pointer         <FONT Color=B22222>' ''int *p;''</font>
  Dim aSt As Stream
+
  Dim a1Post, a2Post As Byte
+
  i = 9999                <FONT Color=B22222>' ''i = 9999;''</font>
 
 
    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>
+
  <FONT Color=gray>' ''Assegnamo alla variabile di tipo "Puntatore" la variabile di tipo Intero "i".''
    a1Post = Byte@(aPtr)
+
  ' ''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>' ''e con i Memory-Stream:''</font>
 
    aSt = Memory aPtr For Read
 
    Read #aSt, a2Post
 
    aSt.Close
 
     
 
     
 
<Font Color= #006400>' ''Quindi leggiamo i due valori restituiti:''</font>
 
    Print "a1Post = "; a1Post
 
    Print "a2Post = "; a2Post
 
 
   
 
   
 +
<FONT Color=gray>' ''Dereferenziamo il "Puntatore" mediante la funzione di Gambas "int@()":</font>
 +
  Print "i = "; Int@(p)  <FONT Color=B22222>' ''printf("%d\n", *p);''</font>
 +
 
 
  '''End'''
 
  '''End'''
  
In console avremo coerentemente:
 
<BR>a1Post = 2
 
<BR>a2Post = 2
 
  
  
Riga 95: Riga 60:
 
=Note=
 
=Note=
 
[1] Se la variabile di tipo ''Puntatore'' deve puntare ad una variabile (o meglio: contenere l'indirizzo di memoria di una variabile) già presente e già valorizzata, allora si userà la funzione ''VarPtr''.
 
[1] Se la variabile di tipo ''Puntatore'' deve puntare ad una variabile (o meglio: contenere l'indirizzo di memoria di una variabile) già presente e già valorizzata, 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 si allocherà una parte di memoria mediante la funzione ''Alloc( )''.
+
<BR>Se la variabile di tipo ''Puntatore'' deve essere utilizzata per creare un variabile di tipo ''Stream'', nel quale successivamente scrivere dati, allora si allocherà una parte di memoria mediante la funzione ''Alloc( )''.
 
 
[2] ''Dereferenziare un Pointer'': accedere al valore della variabile puntata dal ''Puntatore''.
 

Versione delle 11:31, 8 nov 2014

La dereferenziazione di una variabile di tipo Puntatore si ha quando si deve estrarre il valore contenuto nella variabile puntata dal puntatore (il più delle volte il contenutpo di 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(). |1|

"Dereferenziare" un Puntatore significa, dunque, accedere alla locazione di memoria da esso puntata; significa accedere al valore della variabile puntata dal Puntatore.

Per "dereferenziare" il Puntatore |2| è 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 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

' Riprendiamo l'esempio del paragrafo precedente, dove sono stati scritti 4 valori di tipo "byte"; e li andiamo ad "estrarre" leggendo dalla 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


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

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


Note

[1] Se la variabile di tipo Puntatore deve puntare ad una variabile (o meglio: contenere l'indirizzo di memoria di una variabile) già presente e già valorizzata, 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 si allocherà una parte di memoria mediante la funzione Alloc( ).