Ora, nella giusta filosofia hacker tali puntatori vengono usati per scrivere e leggere in altre “funzioni” di Gambas aventi comunque loro precipue modalità?
Per quel che riguarda il C l'uso dei Puntatori nei codici, scritti in questo linguaggio, è estremamente frequente. A volte vi sono funzioni che richiedono, come parametri, proprio dei Puntatori; e moltre volte ritornano un Puntatore.
...ma come si fa a leggere o a scrivere in un'area riservata, puntata da una variabile di tipo Puntatore ? Gambas usa uno stratagemma, rappresentato dai "Memory Stream".
Ad esempio per scrivere in un Puntatore (rectius: all'interno di un'area puntata da un Puntatore), dopo aver generato una variabile di tipo Stream dal Puntatore, si utilizza questa variabile per scriverci dentro. Fatto ciò, però, alla funzione esterna, che pretende che sia passato come argomento un Puntatore, si passerà la varibile di tipo Puntatore e non la variabile Stream (da essa generata e da noi utilizzata per scrivere nell'area riservata di memoria).
Insomma, va tenuto a mente che sostanzialmente il Puntatore punta ad un'area riservata di memoria, nella quale - con Gambas - è possibile leggere o scrivere mediante i Memory Stream.
Un'area riservata di memoria può essere definita con la funzione: alloc(), e vi si potrà - ad esempio - scrivere secondo questa procedura astratta:
Public Sub Main()
Dim p As Pointer
Dim st As Stream
' Riserviamo un'area di memoria di 64 byte, il cui indirizzo è puntato dalla variabile "p":
p = Alloc(64)
' Generiamo dalla variabile "Puntatore" una variabile di tipo "Stream", ad esempio per scrivere nell'area riservata:
st = Memory p For Write
' Scriviamo dunque dentro l'area riservata di memoria, come se agissimo in un File:
Write #st, "Gambas\x0AGambas"
' Chiudiamo il flusso:
st.Close
' Qui, ad esempio, passiamo il puntatore alla funzione esterna che richiede come argomento un Puntatore
' ad un'area di memoria riservata, nella quale sia stata scritta la stringa di cui sopra:
Funzione_Esterna(p)
' Poiché abbiamo allocato 64 byte di memoria, ora, che non serve più, la liberiamo:
Free(p)
End
Per generare, invece, un Puntatore da un altro tipo di variabile (quindi per creare un Puntatore che punta all'indirizzo di memoria di una variabile), si fa uso della funzione: VarPtr() .
Più in generale i Puntatori ci consentono, anche in Gambas, di operare all'interno di un'area di memoria, allocata da noi oppure allocata da un'altra risorsa. Vediamo al riguardo questo semplice esempio.
Leggiamo e cambiamo un carattere di una stringa contenuta in una variabile di tipo Stringa:
Public Sub Main()
Dim p As Pointer
Dim st As Stream
Dim s As String
Dim j, b As Byte
' Assegnamo del testo alla variabile di tipo "String":
s = "gambas"
' Assegnamo l'indirizzo di memoria della variabile "s" ad una variabile di tipo Puntatore:
p = VarPtr(s)
' Generiamo dalla variabile "Puntatore" una variabile di tipo "Stream" in lettura ed in scrittura:
st = Memory p For Read Write
' Andiamo a vedere mediante la variabile di tipo "Stream" i valori presenti all'interno
' dell'area di memoria della variabile "s", puntata dal puntatore:
For j = 0 To String.Len(s) - 1
Read #st, b
Print Hex(b), b, Chr(b)
Next
' Scriviamo ora un valore (ad esempio il carattere di "fine riga a capo") nel quarto byte
' (di indice 3) dell'area di memoria puntata dalla variabile "s", a sua volta puntata dal puntatore:
Seek #st, 3
Write #st, &0A As Byte
' Chiudiamo il flusso:
st.Close
' ...vediamo direttamente dalla variabile stringa "s" la modifica apportata:
Print s
End
Ciao vuott,
scusa per il ritardo nel rispondere alla tua interessantissima lezione, purtroppo ho avuto da fare ed è da non molto che mi sono messo a studiarla.
Vediamo quindi se ho capito, ma ho forti dubbi:
Il puntatore nasce principalmente per permetterci di usare librerie pronte scritte in C.
Visto che ci sono i puntatori coloro i quali conoscendo il C e sanno come usarli ne approfittano per il codice “interno”.
Anche chi non conosce il C può usufruirne all'interno come mi hai fatto vedere nella seconda dimostrazione pratica.
Mi stavo chiedendo se quando noi passiamo i valori a una funzione, che se non sbaglio in Gambas vengono passati per valore, in realtà Gambas non usi un puntatore. Se fosse vero Gambas ci fa usare i puntatori ma ce lo nasconde e invece se li passiamo per riferimento?
Io comunque ho difficoltà ad immaginarmeli in quanto essi se capisco bene sono al contempo “indirizzo” e “contenitore”.
Se una variabile diciamo così normale la possiamo paragonare ad una scatola (di varie misure in base al tipo) con un'etichetta di indirizzo, il puntatore cosa è? E' un locomotore (indirizzo) che si può trascinare dei vagoni che all'occorrenza riempe?
Per meglio comprendere il tuo esempio (il secondo) ho provato a riprodurlo in codice “normale” ma ottengo un errore puoi per favore dirmi dove sbaglio?
Dim c, s As String
Dim j, b As Byte
s = "gambas"
For j = 1 To String.Len(s)
c = Mid$(s, j, 1)
'b = CByte(c) ' Type mismatch: wanted Byte, got String instead
'Print Hex(b), b, c
Next
c = Mid$(s, 4, 1)
s = Replace$(s, c, Chr$(10))
Print s
Parliamoci chiaro mi rendo conto di approfittare molto delle tue abilità e se non rispondi ti capisco benissimo.
Se però mi rispondi sappi che io apprezzo molto.
Ciao e scusa anche la mia testa dura.
:ciao:
...essi se capisco bene sono al contempo “indirizzo” e “contenitore”.
Se una variabile diciamo così normale la possiamo paragonare ad una scatola (di varie misure in base al tipo) con un'etichetta di indirizzo, il puntatore cosa è? E' un locomotore (indirizzo) che si può trascinare dei vagoni che all'occorrenza riempe?
......restando alla tua similitudine, poniamo il caso che la scatola della variabile "normale" è posta sul terzo ripiano di una credenza alla 4a posizione fra le altre scatole di quel ripiano. Ebbene, il Puntatore, è una scatola nella quale c'è un foglietto sul quale c'è scritto: "Se prendi la scatola posta sul terzo ripiano alla 4a posizione fra le altre scatole di quel ripiano, al suo interno troverai un valore.". Oppure, se vuoi, possiamo dire che Genova è la variabile "normale" che contiene persone e palazzi ed il porto. Il Puntatore è il cartello stradale che indica la strada
< km 100 Genova]
...o meglio una mappa che indica le coordinate geografiche del centro della città.
ottengo un errore puoi per favore dirmi dove sbaglio?
Ti ha risposto bene l'amico TopFuel: la funzione Mid() ti restituisce semplicemente un carattere. Per gestire questo carattere con la funzione CByte(), devi convertirlo mediante la funzione Asc() nel corrispondente valore numerico ASCII.
Insomma così:
......
c = Mid$(s, j, 1)
b = CByte(Asc(c))
......
Grazie vuott,
Ti svelo perché sono a porre in questo modo certe domande.
Devi sapere che sono ormai più di 15 giorni (10 in realtà poi il primo intoppo) che con alacrità mi sono messo a scrivere un manualetto. Lo so di non sapere ma è anche vero che se uno in Linux non trova quel che vorrebbe trovare l'unica via che ha è quella di farlo lui.
Comunque mi sono detto “ora inizio e poi vediamo... se qualcosa non capisco ho due chance; chiedo; se mi viene risposto uso la risposta nel manuale, altrimenti lascio in sospeso e poi quando proporrò il tutto spero in un aiutino”. Mi sono già arenato sui chiamiamoli così Dati Aggregati & C e come vengono usati in Gambas.
In realtà ci sarebbe anche una terza via “rinunciare” ma questo è contrario ai miei principi.
Non fraintendere non sono così avanti, sono solo alla carrellata iniziale l'infarinatura prima di partire!
Questa cosa è mirata a persone che non hanno mai programmato, che mi guarderei bene dal scrivere qualcosa di diverso e spero non venga interpretato come un atto di presunzione.
Mi servirà anche, se non sopratutto, per confrontarmi con me stesso e quello che so o credo di sapere (poco in verità).
Ad esempio essendo io rimasto al calduccio di Office il massimo di abilità era l'uso dell'oggetto application. Quando avevo bisogno di memorizzare i dati avevo a disposizione le tabelle di access o excel lo so che anche se disegnate in quella forma in realtà sono astrazioni e quindi bisogna aprire la mente ma... ti agevolavano di molto il compito lasciandoti nell'ignoranza.
Allego quello che ho scritto fin'ora tanto per dare l'idea di quali sarebbero le mie intenzioni.
Il fil rouge è la programmazione BASC in Gambas e via via indicare alcune lezioni e/o discussioni per approfondire.
Viene perfetto come esempio quanto tu hai appena scritto sui puntatori e la lezione a cui rimandi che non può che essere chiara anche a uno alle prime armi.
Per tornare invece a bomba puoi spiegarmi il motivo ultimo (oltre al piacere di provare tutte le vie) per cui converrebbe utilizzare un puntatore rispetto al BASIC (se puoi lasciarmi passare la semplificazione)?
@Top Fuel
ciao e grazie,
inserendo questo codice suggerito da te e da vuott a me col la 3.6.0 funziona e ottengo lo stesso output del puntatore. Se hai provato con val() non appare nulla anche a me (era l'unica prova fatta in precedenza).
Dim c, s As String
Dim j, b As Byte
s = "gambas"
For j = 1 To String.Len(s)
c = Mid$(s, j, 1)
'b = CByte(Asc(c))
b = CByte(String.Code(c))
Print Hex(b), b, c
Next
c = Mid$(s, 4, 1)
s = Replace$(s, c, Chr$(10))
Print s
:ciao: