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

Da Gambas-it.org - Wikipedia.
 
(19 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''. |[[#Note|1]]|
+
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|2]]| 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: 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''===
'''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'':
 +
Private Procedure Dereferenzia(p As Pointer)
 
   
 
   
   Dim datoInt, intDef As Integer
+
   Dim j, b As Byte
  Dim byDef As Byte
+
   Dim st As Stream
   Dim datoPtr As Pointer
 
  Dim byPtr As Pointer
 
  Dim byStrm As Stream
 
 
   
 
   
  datoInt = 2
+
<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
 
   
 
   
  <Font Color= #006400>' ''Poniamo nel pointer "dato1Ptr" l'indirizzo che punta alla variabile Integer "datoInt":''</font>
+
  <Font Color=gray>' ''Vengono estratti, in questo esempio, 4 byte leggendo la variabile di tipo "Stream":''</font>
     datoPtr = VarPtr(datoInt)
+
  For j = 0 To 3
 +
    Read #st, b
 +
     Print "---> ", b
 +
  Next
 
   
 
   
  <Font Color= #006400>' ''Allochiamo memoria sufficiente:''</font>
+
  <Font Color=gray>' ''Chiudiamo il flusso:''</font>
  byPtr = Alloc(2)
+
  st.Close
 
   
 
   
  <Font Color= #006400>' ''Supponiamo che venga usata una funzione esterna (ovviamente dichiarata con Extern, che qui si omette)
+
  End
'' ' la quale passi un dato byte alla variabile "byPtr", e che quindi possiamo raccogliere:''</font>
+
 
  funzione_esterna(param1, byPtr)
+
 
 +
===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        <FONT Color=B22222>' ''int i;''</font>
 +
  Dim p As Pointer        <FONT Color=B22222>' ''int *p;''</font>
 
   
 
   
<Font Color= #006400>' ''Andiamo ora a "dereferenziare" i pointer, ossia ad estrarre i valori contenuti nelle variabili,
+
  i = 9999                <FONT Color=B22222>' ''i = 9999;''</font>
'' ' 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>' ''Assegnamo alla variabile di tipo "Puntatore" la variabile di tipo Intero "i".''
  byStrm = Memory byPtr For Read
+
' ''Il "Puntatore", così, punta alla variabile "i", accedendo all'area di memoria della variabile:''</font>
<Font Color= #006400>' ''Leggiamo quindi la variabile di tipo "stream", e poniamo il valore nella variabile di tipo byte:''</font>
+
  p = VarPtr(i)          <FONT Color=B22222>' ''p = &i;''</font>
  Read #byStrm, byDef
 
 
   
 
   
 +
<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>
 
   
 
   
  <Font Color= #006400>' ''Andiamo quindi a mostrare i relativi dati:''</font>
+
  End
  Print intDef
+
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.
  Print byDef
+
 
 +
Esempio:
 +
Public Sub Main()
 
   
 
   
<Font Color= #006400>' ''De-allochiamo la memoria precedentemente riservata:''</font>
+
  Dim p As Pointer
  free(byPtr)
+
  Dim st As Stream
 
    
 
    
'''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
'''Public''' Sub Button1_Click()
+
  st.Close
 
   
 
   
  Dim a As Byte
+
  <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>
  Dim aPtr As Pointer
+
  Print Short@(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>
+
  <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>
    a1Post = Byte@(aPtr)
+
  Print Int@(<FONT Color=#B22222>p <B>+ 2</b></font>)
     
+
 
<Font Color= #006400>' ''e con i Memory-Stream:''</font>
+
  Free(p)
    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==
===Dereferenziare senza Memory-Stream un pointer ad una Struttura, passato da una funzione esterna===
 
 
Per quest'argomento rimandiamo alla specifica pagina presente nella WIKI:
 
Per quest'argomento rimandiamo alla specifica pagina presente nella WIKI:
<BR>[[Dereferenziare_senza_Memory-Stream_un_pointer_ad_una_Struttura%2C_passato_da_una_funzione_esterna|Dereferenziare senza Memory-Stream un pointer ad una Struttura, passato da una funzione esterna]].
+
<BR>[[Dereferenziare senza Memory-Stream un Puntatore ad una Struttura, passato da una funzione esterna]].
  
  
  
 
=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 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 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 sarà opportuno allocare una parte di memoria mediante la funzione "Alloc()".
 
 
[2] ''Dereferenziare un Pointer'': accedere al valore della variabile puntata dal puntatore.
 

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()".