Vai - Puntatori

I puntatori in Go sono facili e divertenti da imparare. Alcune attività di programmazione Go vengono eseguite più facilmente con i puntatori e altre attività, come la chiamata per riferimento, non possono essere eseguite senza utilizzare i puntatori. Quindi diventa necessario imparare i puntatori per diventare un perfetto programmatore Go.

Come sapete, ogni variabile è una posizione di memoria e ogni posizione di memoria ha il suo indirizzo definito a cui è possibile accedere utilizzando l'operatore e commerciale (&), che denota un indirizzo in memoria. Considera il seguente esempio, che stamperà l'indirizzo delle variabili definite:

package main

import "fmt"

func main() {
   var a int = 10   
   fmt.Printf("Address of a variable: %x\n", &a  )
}

Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:

Address of a variable: 10328000

Quindi hai capito cos'è l'indirizzo di memoria e come accedervi. Vediamo ora cosa sono i puntatori.

Cosa sono i puntatori?

UN pointerè una variabile il cui valore è l'indirizzo di un'altra variabile, cioè l'indirizzo diretto della posizione di memoria. Come qualsiasi variabile o costante, è necessario dichiarare un puntatore prima di poterlo utilizzare per memorizzare qualsiasi indirizzo di variabile. La forma generale di una dichiarazione di variabile puntatore è:

var var_name *var-type

Qui, typeè il tipo base del puntatore; deve essere un tipo di dati C valido evar-nameè il nome della variabile del puntatore. L'asterisco * che hai usato per dichiarare un puntatore è lo stesso asterisco che usi per la moltiplicazione. Tuttavia, in questa istruzione l'asterisco viene utilizzato per designare una variabile come puntatore. Di seguito sono riportate le dichiarazioni di puntatore valide:

var ip *int        /* pointer to an integer */
var fp *float32    /* pointer to a float */

Il tipo di dati effettivo del valore di tutti i puntatori, se intero, float o altro, è lo stesso, un numero esadecimale lungo che rappresenta un indirizzo di memoria. L'unica differenza tra i puntatori di diversi tipi di dati è il tipo di dati della variabile o della costante a cui punta il puntatore.

Come usare i puntatori?

Ci sono alcune operazioni importanti, che eseguiamo frequentemente con i puntatori: (a) definiamo variabili puntatore, (b) assegniamo l'indirizzo di una variabile a un puntatore e (c) accediamo al valore all'indirizzo memorizzato nella variabile puntatore .

Tutte queste operazioni vengono eseguite utilizzando l'operatore unario * che restituisce il valore della variabile situata all'indirizzo specificato dal suo operando. L'esempio seguente mostra come eseguire queste operazioni:

package main

import "fmt"

func main() {
   var a int = 20   /* actual variable declaration */
   var ip *int      /* pointer variable declaration */

   ip = &a  /* store address of a in pointer variable*/

   fmt.Printf("Address of a variable: %x\n", &a  )

   /* address stored in pointer variable */
   fmt.Printf("Address stored in ip variable: %x\n", ip )

   /* access the value using the pointer */
   fmt.Printf("Value of *ip variable: %d\n", *ip )
}

Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:

Address of var variable: 10328000
Address stored in ip variable: 10328000
Value of *ip variable: 20

Nessun puntatore in Go

Il compilatore Go assegna un valore Nil a una variabile puntatore nel caso in cui non si abbia un indirizzo esatto da assegnare. Questo viene fatto al momento della dichiarazione della variabile. Un puntatore a cui è assegnato zero è chiamato anil puntatore.

Il puntatore nil è una costante con un valore zero definito in diverse librerie standard. Considera il seguente programma:

package main

import "fmt"

func main() {
   var  ptr *int

   fmt.Printf("The value of ptr is : %x\n", ptr  )
}

Quando il codice precedente viene compilato ed eseguito, produce il seguente risultato:

The value of ptr is 0

Nella maggior parte dei sistemi operativi, ai programmi non è consentito accedere alla memoria all'indirizzo 0 perché tale memoria è riservata dal sistema operativo. Tuttavia, l'indirizzo di memoria 0 ha un significato speciale; segnala che il puntatore non è destinato a puntare a una posizione di memoria accessibile. Ma per convenzione, se un puntatore contiene il valore nil (zero), si presume che punti a nulla.

Per verificare la presenza di un puntatore nullo puoi usare un'istruzione if come segue:

if(ptr != nil)     /* succeeds if p is not nil */
if(ptr == nil)    /* succeeds if p is null */

Vai puntatori in dettaglio

I puntatori hanno molti ma semplici concetti e sono molto importanti per la programmazione Go. I seguenti concetti di puntatori dovrebbero essere chiari a un programmatore Go:

Suor n Concetto e descrizione
1 Vai: matrice di puntatori

È possibile definire array per contenere un numero di puntatori.

2 Vai: puntatore al puntatore

Go ti consente di avere un puntatore su un puntatore e così via.

3 Passaggio di puntatori a funzioni in Go

Il passaggio di un argomento per riferimento o per indirizzo consente entrambi di modificare l'argomento passato nella funzione chiamante dalla funzione chiamata.