Condividi tramite


Tipi di puntatori (Guida per programmatori C#)

In un contesto unsafe, un tipo può essere un tipo di puntatore, un tipo di valore o un tipo di riferimento. La dichiarazione di un tipo di puntatore può assumere uno dei seguenti formati:

type* identifier;
void* identifier; //allowed but not recommended

I tipi seguenti possono essere tipi di puntatore:

I tipi di puntatore non ereditano da object. Non sono inoltre previste conversioni tra essi e object. Con i puntatori non sono inoltre supportate le operazioni di boxing e unboxing. È tuttavia possibile eseguire conversioni tra tipi di puntatore diversi e tra tipi di puntatore e tipi integrali.

Quando si dichiarano più puntatori nella stessa dichiarazione, l'asterisco (*) viene scritto solo con il tipo sottostante. Non viene utilizzato come prefisso di ogni nome di puntatore. Di seguito è riportato un esempio.

int* p1, p2, p3;   // Ok
int *p1, *p2, *p3;   // Invalid in C#

Un puntatore non può puntare a un riferimento o a struct che contiene riferimenti, perché un riferimento a un oggetto può essere sottoposto a procedure di Garbage Collection anche se un puntatore punta a esso. Il Garbage Collector non tiene traccia degli altri tipi di puntatore che puntano all'oggetto.

Il valore della variabile del puntatore di tipo myType* è l'indirizzo di una variabile di tipo myType. Di seguito sono riportati alcuni esempi di dichiarazioni di tipi di puntatore:

Esempio

Descrizione

int* p

p è un puntatore a un Integer.

int** p

p è un puntatore a un puntatore a un Integer.

int*[] p

p è una matrice unidimensionale di puntatori a Integer.

char* p

p è un puntatore a un carattere.

void* p

p è un puntatore a un tipo sconosciuto.

Per accedere al contenuto nella posizione a cui punta la variabile del puntatore, è possibile utilizzare *, ovvero l'operatore di riferimento indiretto a puntatore. Si consideri ad esempio la seguente dichiarazione:

int* myVariable;

L'espressione *myVariable indica la variabile int individuata all'indirizzo contenuto in myVariable.

Esistono vari esempi dei puntatori negli argomenti Istruzione fixed (Riferimenti per C#) e Conversioni di puntatori (Guida per programmatori C#). Nell'esempio seguente viene illustrata la necessità della parola chiave unsafe e dell'istruzione fixed e come incrementare un puntatore interno. È possibile incollare il codice nella funzione Main di un'applicazione console per eseguirlo. Ricordarsi di abilitare il codice unsafe in Progettazione progetti. Scegliere Progetto, Proprietà nella barra dei menu e quindi selezionare Consenti codice di tipo unsafe nella scheda Compilazione).

// Normal pointer to an object.
int[] a = new int[5] {10, 20, 30, 40, 50};
// Must be in unsafe code to use interior pointers.
unsafe
{
    // Must pin object on heap so that it doesn't move while using interior pointers.
    fixed (int* p = &a[0])
    {
        // p is pinned as well as object, so create another pointer to show incrementing it.
        int* p2 = p;
        Console.WriteLine(*p2);
        // Incrementing p2 bumps the pointer by four bytes due to its type ...
        p2 += 1;
        Console.WriteLine(*p2);
        p2 += 1;
        Console.WriteLine(*p2);
        Console.WriteLine("--------");
        Console.WriteLine(*p);
        // Deferencing p and incrementing changes the value of a[0] ...
        *p += 1;
        Console.WriteLine(*p);
        *p += 1;
        Console.WriteLine(*p);
    }
}

Console.WriteLine("--------");
Console.WriteLine(a[0]);
Console.ReadLine();

// Output:
//10
//20
//30
//--------
//10
//11
//12
//--------
//12

Non è possibile applicare l'operatore di riferimento indiretto a un puntatore di tipo void*. È tuttavia possibile eseguire un cast per convertire un puntatore void in qualsiasi altro tipo e viceversa.

Un puntatore può essere null. Se l'operatore di riferimento indiretto viene applicato a un puntatore Null, si otterrà un comportamento definito dall'implementazione.

Tenere presente che il passaggio di puntatori tra metodi può generare un comportamento non definito, ad esempio se un puntatore viene restituito a una variabile locale tramite un parametro Out o Ref oppure come risultato della funzione. Se il puntatore è stato impostato in un blocco fisso, la variabile a cui punta potrebbe non essere più fissa.

Nella tabella riportata di seguito sono elencati gli operatori e le istruzioni che è possibile utilizzare con i puntatori in un contesto unsafe:

Operatore/istruzione

Utilizzo

*

Esegue il riferimento indiretto al puntatore.

->

Accede a un membro di struct tramite un puntatore.

[]

Indicizza un puntatore.

&

Ottiene l'indirizzo di una variabile.

++ e --

Incrementa e decrementa puntatori.

+ e -

Utilizza l'aritmetica dei puntatori.

==, !=, <, >, <= e >=

Confronta puntatori.

stackalloc

Alloca memoria nello stack.

Istruzione fixed

Corregge temporaneamente una variabile per consentire di trovarne l'indirizzo.

Specifiche del linguaggio C#

Per altre informazioni, vedere la Specifiche del linguaggio C#. La specifica del linguaggio costituisce il riferimento ufficiale principale per la sintassi e l'uso di C#.

Vedere anche

Riferimenti

Codice unsafe e puntatori (Guida per programmatori C#)

Conversioni di puntatori (Guida per programmatori C#)

Espressioni puntatore (Guida per programmatori C#)

unsafe (Riferimenti per C#)

Istruzione fixed (Riferimenti per C#)

stackalloc (Riferimenti per C#)

Boxing e unboxing (Guida per programmatori C#)

Concetti

Guida per programmatori C#

Altre risorse

Tipi (Riferimenti per C#)