Operatori relativi ai puntatori: accedono alla memoria e dereferenziano le posizioni di memoria (2023)

  • Articolo

Gli operatori puntatore consentono di prendere l'indirizzo di una variabile (&), dereferenziare un puntatore (*), confrontare i valori dei puntatori e aggiungere o sottrarre puntatori e numeri interi.

Utilizzare i seguenti operatori per lavorare con i puntatori:

  • Unariooperatore: per ottenere l'indirizzo di una variabile
  • Unario* (indicazione indiretta del puntatore)operatore: per ottenere la variabile puntata da un puntatore
  • IL-> (accesso membri)E[] (accesso all'elemento)operatori
  • Operatori aritmetici+, -, ++ e --
  • Operatori di confronto==, !=, <, >, <= e >=

Per informazioni sui tipi di puntatore, vedereTipi di puntatori.

Nota

Qualsiasi operazione con i puntatori richiede un filepericolosocontesto. Il codice che contiene blocchi unsafe deve essere compilato con il fileConsenti blocchi non sicuriopzione del compilatore.

Indirizzo dell'operatore &

L'unario&operatore restituisce l'indirizzo del suo operando:

(Video) Tecniche di Programmazione - Prof. Iocchi - Lezione 09 (20 marzo 2018)

non sicuro{ int numero = 27; int* pointerToNumber = &numero; Console.WriteLine($"Valore della variabile: {numero}"); Console.WriteLine($"Indirizzo della variabile: {(long)pointerToNumber:X}");}// L'output è simile a:// Valore della variabile: 27// Indirizzo della variabile: 6C1457DBD4

L'operando di&operatore deve essere una variabile fissa.Fissole variabili sono variabili che risiedono in posizioni di memoria che non sono interessate dal funzionamento dinetturbino. Nell'esempio precedente, la variabile localenumeroè una variabile fissa, perché risiede nello stack. Vengono chiamate le variabili che risiedono in posizioni di archiviazione che possono essere interessate dal Garbage Collector (ad esempio, trasferite).mobilevariabili. I campi oggetto e gli elementi dell'array sono esempi di variabili mobili. Puoi ottenere l'indirizzo di una variabile mobile se lo "aggiusti" o "blocchi" con adichiarazione fissa. L'indirizzo ottenuto è valido solo all'interno del blocco di afissodichiarazione. L'esempio seguente mostra come utilizzare afissodichiarazione e il&operatore:

non sicuro{ byte[] byte = { 1, 2, 3 }; fixed (byte* pointerToFirst = &bytes[0]) { // L'indirizzo memorizzato in pointerToFirst // è valido solo all'interno di questo blocco di istruzioni fixed. }}

Non puoi ottenere l'indirizzo di una costante o di un valore.

Per ulteriori informazioni sulle variabili fisse e mobili, vedere ilVariabili fisse e mobilisezione delSpecifica del linguaggio C#.

Il binario&operatore calcola ilAND logicodei suoi operandi booleani o ilAND logico bit a bitdei suoi operandi interi.

Operatore di riferimento indiretto del puntatore *

L'operatore di indirezione del puntatore unario*ottiene la variabile a cui punta il suo operando. È anche noto come operatore di dereferenziazione. L'operando di*l'operatore deve essere di tipo puntatore.

non sicuro{ carattere lettera = 'A'; char* pointerToLetter = &letter; Console.WriteLine($"Valore della variabile `letter`: {letter}"); Console.WriteLine($"Indirizzo della variabile `letter`: {(long)pointerToLetter:X}"); *pointerToLettera = 'Z'; Console.WriteLine($"Valore della variabile `letter` dopo l'aggiornamento: {letter}");}// L'output è simile a:// Valore della variabile `letter`: A// Indirizzo della variabile `letter` : DCB977DDF4// Valore della variabile `lettera` dopo l'aggiornamento: Z

Non puoi applicare il*operatore a un'espressione di tipovuoto*.

Il binario*operatore calcola ilProdottodei suoi operandi numerici.

Operatore di accesso ai membri del puntatore ->

IL->operatore combinapuntatore indirettoEaccesso dei membri. Cioè, seXè un puntatore di tipoT*Esiè un membro accessibile di typeT, espressione della forma

x->y

è equivalente a

(Video) Lezione 14a Fondamenti di Informatica

(*x).y

Nell'esempio seguente viene illustrato l'utilizzo di->operatore:

public struct Coords{ public int X; public int Y; public override string ToString() => $"({X}, {Y})";}public class PointerMemberAccessExample{ public static unsafe void Main() { Coords coords; Coordinate* p = &coordinate; p->X = 3; p->Y = 4; Console.WriteLine(p->ToString()); // output: (3, 4) }}

Non puoi applicare il->operatore a un'espressione di tipovuoto*.

Operatore di accesso all'elemento puntatore []

Per un'espressionePdi un tipo puntatore, un accesso elemento puntatore del formp[n]viene valutato come*(p+n), DoveNdeve essere di un tipo convertibile in modo implicito inint,uint,lungo, OTesta. Per informazioni sul comportamento del+operatore con i puntatori, vedere ilAggiunta o sottrazione di un valore integrale a o da un puntatoresezione.

L'esempio seguente mostra come accedere agli elementi dell'array con un puntatore e il[]operatore:

unsafe{ char* pointerToChars = stackalloc char[123]; for (int i = 65; i < 123; i++) { pointerToChars[i] = (char)i; } Console.Write("Lettere maiuscole: "); for (int i = 65; i < 91; i++) { Console.Write(pointerToChars[i]); }}// Output:// Lettere maiuscole: ABCDEFGHIJKLMNOPQRSTUVWXYZ

Nell'esempio precedente, aespressione stackallocalloca un blocco di memoria nello stack.

Nota

L'operatore di accesso all'elemento puntatore non verifica la presenza di errori fuori limite.

Non puoi usare[]per l'accesso all'elemento puntatore con un'espressione di tipovuoto*.

(Video) Sistemi di Calcolo, Prof. Demetrescu - lezione 08 (27 Ott. 2016)

Puoi anche usare il[]operatore peraccesso all'elemento dell'array o all'indicizzatore.

Operatori aritmetici puntatori

È possibile eseguire le seguenti operazioni aritmetiche con i puntatori:

  • Aggiungere o sottrarre un valore integrale a o da un puntatore
  • Sottrai due puntatori
  • Incrementa o decrementa un puntatore

Non è possibile eseguire tali operazioni con puntatori di tipovuoto*.

Per informazioni sulle operazioni aritmetiche supportate con tipi numerici, vedereOperatori aritmetici.

Aggiunta o sottrazione di un valore integrale a o da un puntatore

Per un puntatorePdi tipoT*e un'espressioneNdi un tipo implicitamente convertibile inint,uint,lungo, OTesta, l'addizione e la sottrazione sono definite come segue:

  • Entrambip + nEn + ple espressioni producono un puntatore di tipoT*che risulta dall'addizionen * dimensionedi(T)all'indirizzo indicato daP.
  • ILp - nespressione produce un puntatore di tipoT*che risulta dalla sottrazionen * dimensionedi(T)dall'indirizzo fornito daP.

ILoperatore sizeofottiene la dimensione di un tipo in byte.

Nell'esempio seguente viene illustrato l'utilizzo di+operatore con un puntatore:

unsafe{ const int Count = 3; int[] numeri = new int[Conteggio] { 10, 20, 30 }; fixed (int* pointerToFirst = &numbers[0]) { int* pointerToLast = pointerToFirst + (Count - 1); Console.WriteLine($"Valore {*pointerToFirst} all'indirizzo {(long)pointerToFirst}"); Console.WriteLine($"Valore {*pointerToLast} all'indirizzo {(long)pointerToLast}"); }}// L'output è simile a:// Valore 10 all'indirizzo 1818345918136// Valore 30 all'indirizzo 1818345918144

Sottrazione del puntatore

Per due puntatorip1Ep2di tipoT*, l'espressionep1 - ​​​​p2produce la differenza tra gli indirizzi dati dap1Ep2diviso perdimensionedi(T). Il tipo di risultato èlungo. Questo è,p1 - ​​​​p2è calcolato come((lungo)(p1) - (lungo)(p2)) / sizeof(T).

L'esempio seguente mostra la sottrazione del puntatore:

(Video) Tecniche di Programmazione - Prof. Iocchi - Lezione 12 (27 marzo 2018)

unsafe{ int* numeri = stackalloc int[] { 0, 1, 2, 3, 4, 5 }; int* p1 = &numeri[1]; int* p2 = &numeri[5]; Console.WriteLine(p2 - p1); // uscita: 4}

Incremento e decremento del puntatore

IL++operatore di incrementoaggiunge1 al suo operando puntatore. IL--operatore di decrementosottrae1 dal suo operando puntatore.

Entrambi gli operatori sono supportati in due forme: postfix (p++EP--) e prefisso (++pagE--P). Il risultato dip++EP--è il valore diP Primal'operazione. Il risultato di++pagE--Pè il valore diP Dopol'operazione.

L'esempio seguente mostra il comportamento di entrambi gli operatori di incremento postfisso e prefisso:

unsafe{ int* numeri = stackalloc int[] { 0, 1, 2 }; int* p1 = &numeri[0]; int* p2 = p1; Console.WriteLine($"Prima dell'operazione: p1 - {(lungo)p1}, p2 - {(lungo)p2}"); Console.WriteLine($"Incremento suffisso di p1: {(long)(p1++)}"); Console.WriteLine($"Incremento prefisso di p2: {(long)(++p2)}"); Console.WriteLine($"Dopo l'operazione: p1 - {(long)p1}, p2 - {(long)p2}");}// L'output è simile a// Prima dell'operazione: p1 - 816489946512, p2 - 816489946512// Incremento suffisso di p1: 816489946512// Incremento prefisso di p2: 816489946516// Dopo operazione: p1 - 816489946516, p2 - 816489946516

Operatori di confronto puntatore

Puoi usare il==,!=,<,>,<=, E>=operatori per confrontare operandi di qualsiasi tipo di puntatore, inclusivuoto*. Questi operatori confrontano gli indirizzi forniti dai due operandi come se fossero numeri interi senza segno.

Per informazioni sul comportamento di tali operatori per operandi di altri tipi, vedere ilOperatori di uguaglianzaEOperatori di confrontoarticoli.

Precedenza dell'operatore

L'elenco seguente ordina gli operatori relativi ai puntatori a partire dalla precedenza più alta fino a quella più bassa:

  • Incremento suffissox++e decrementoX--operatori e il->E[]operatori
  • Incremento del prefisso++ xe decremento--Xoperatori e il&E*operatori
  • Additivo+E-operatori
  • Confronto<,>,<=, E>=operatori
  • Uguaglianza==E!=operatori

Usa le parentesi,(), per modificare l'ordine di valutazione imposto dalla precedenza dell'operatore.

Per l'elenco completo degli operatori C# ordinati per livello di precedenza, vedere ilPrecedenza dell'operatoresezione delOperatori C#articolo.

Sovraccaricabilità dell'operatore

Un tipo definito dall'utente non può eseguire l'overload degli operatori relativi al puntatore&,*,->, E[].

(Video) Lezione 12: Gestione dei Puntatori - Linguaggio C [CORSO COMPLETO]

Specifica del linguaggio C#

Per ulteriori informazioni, vedere le seguenti sezioni delSpecifica del linguaggio C#:

  • Variabili fisse e mobili
  • L'indirizzo dell'operatore
  • Puntatore indiretto
  • Accesso membro puntatore
  • Accesso all'elemento puntatore
  • Aritmetica del puntatore
  • Incremento e decremento del puntatore
  • Confronto puntatore

Guarda anche

  • Riferimento C#
  • Operatori ed espressioni C#
  • Codice non sicuro, tipi di puntatore e puntatori a funzione
  • parola chiave non sicura
  • dichiarazione fissa
  • espressione stackalloc
  • operatore sizeof

Videos

1. AWS re:Invent 2021 - Keynote with Peter DeSantis
(AWS Events)
2. Tecniche di Programmazione - Prof. Iocchi - Lezione 28 (10 maggio 2018)
(Video DIAG - Sapienza, Università di Roma)
3. Amministrare Gnu/Linux 1 - Giuseppe Forestan
(Stefano Spagnolo)
4. Dev WorkSpace #19・2ª puntata Minicorso Funzioni e Oggetti JavaScript
(The Communities Bay)
5. CS50 2015 - Week 7, continued
(CS50)
6. Advisory Council Meeting, 25 September 2014, Paris
(Google Videos)

References

Top Articles
Latest Posts
Article information

Author: Frankie Dare

Last Updated: 08/29/2023

Views: 5571

Rating: 4.2 / 5 (53 voted)

Reviews: 92% of readers found this page helpful

Author information

Name: Frankie Dare

Birthday: 2000-01-27

Address: Suite 313 45115 Caridad Freeway, Port Barabaraville, MS 66713

Phone: +3769542039359

Job: Sales Manager

Hobby: Baton twirling, Stand-up comedy, Leather crafting, Rugby, tabletop games, Jigsaw puzzles, Air sports

Introduction: My name is Frankie Dare, I am a funny, beautiful, proud, fair, pleasant, cheerful, enthusiastic person who loves writing and wants to share my knowledge and understanding with you.