Qual è il significato di * e & se applicato ai nomi delle variabili?

In C ++, qual è la differenza tra:

void func(MyType&); // declaration //... MyType * ptr; func(*ptr); // compiler doesnt give error func(ptr); // compiler gives error i thought & represents memory address so // this statement should correct as ptr is only a pointer // or address of some real var. 

L’ operatore prefisso unario & , quando applicato a un object, fornisce l’ indirizzo dell’object: &obj .
Il modificatore di tipo & , quando applicato a una variabile che sta per essere dichiarata, modificherà il tipo della variabile come un tipo di riferimento : int& .

Lo stesso vale per * : quando viene applicato come operatore di un prefisso unario a un puntatore, esso verrà dereferenziato al puntatore, rendendo l’object riferito a: *ptr .
Se usato come modificatore di tipo per una variabile che sta per essere dichiarata, * modificherà il tipo in modo che sia un puntatore : int* .

In modo simile, il modificatore di tipo [] applicato a una variabile dichiarata modificherà il tipo della variabile su un array, mentre l’ operatore di binario in binario [] applicato a un object di tipo array accederà a uno degli oggetti secondari dell’array.


Non è utile che i modificatori di tipo si applichino alla variabile dichiarata , non al tipo con cui sono dichiarati. Ad esempio, questo

 int *p, **pp, i, a[10], &r = i; 

definisce un puntatore int , un puntatore a un puntatore a un int , un int vanilla, un array di 10 int e un riferimento int . (Quest’ultimo viene immediatamente inizializzato, perché non è ansible avere un riferimento non inizializzato.) Si noti che i modificatori di tipo appartengono sintatticamente alla variabile dichiarata di cui stanno modificando il tipo, non al tipo della variabile dichiarata. Tuttavia, i modificatori di tipo ( * e & ) modificano il tipo di variabile.
Nel seguente caso, tuttavia, con p , i e presumibilmente variabili che sono già state dichiarate

 *pp = &i; a[0] = i; 

* e & sono un prefisso unario per gli operatori che indirizzano il dereferenziamento di pp e producono l’indirizzo di i , mentre [] restituisce il primo object int dell’array a .

Il fatto che C e C ++ non si preoccupino degli spazi bianchi attorno ai modificatori di tipo e che questo abbia portato a campi diversi quando si tratta di posizionarli non rende davvero le cose più facili.
Alcune persone posizionano i modificatori di tipo vicino al tipo. Sostengono che modifica il tipo e quindi dovrebbe andare lì:

 int* ptr; 

Lo svantaggio è che questo diventa confuso quando si dichiarano diversi oggetti. Questo

 int* a, b; 

definisce a essere un puntatore a int , ma b essere un int . Ecco perché alcune persone preferiscono scrivere

 int *ptr; int *a, *b; 

Suggerisco semplicemente di non dichiarare più oggetti nella stessa dichiarazione. IMO che rende il codice più facile da leggere. Inoltre, ti lascia libero di scegliere una delle due convention.


Per complicare ulteriormente le cose, oltre ai modificatori di tipo e agli operatori di prefisso unario & e * , ci sono anche gli operatori di infissi binari & e * , che significa “AND bit a bit” e “moltiplicazione”. E per aggiungere la beffa al danno, in C ++ è ansible sovraccaricare sia il prefisso unario sia le varianti binarie di questi operatori (e l’ infisso binario [] ) per i tipi definiti dall’utente ed essere completamente liberi per quanto riguarda la loro semantica.

MyType e rappresenta un / riferimento /, una bestia completamente diversa ai puntatori. Se il tuo prototipo di funzione fosse

func (MyType);

lavoreresti con una copia dell’argomento all’interno della funzione. Con

func (MyType &);

stai lavorando con l’object stesso (vale a dire, lo stesso object sia nel campo chiamato che nell’ambito chiamato). In questo caso, è come lavorare con un puntatore ma usando la stessa syntax “punto” come per gli oggetti.

Naturalmente, questa è una spiegazione superficiale e semplicistica. Per me, mentre stringevo le zen profonde sotto i puntatori, i riferimenti e il resto dell’orda ci sono voluti anni.