Una cosa alla volta. &numPtr esprime l'indirizzo
di numPtr. L'indirezione di un indirizzo (cioè
l'asterisco davanti a "qualcosa" che esprime un indirizzo)
restituisce il valore memorizzato a quell'indirizzo. Pertanto,
*&numPtr esprime il valore memorizzato all'indirizzo
di numPtr. Cioè il valore contenuto in numPtr.
Cioè l'indirizzo di numero. Simpatico, vero?
Quale significato ha l'espressione **numPtr?
Nessuno! Infatti *numPtr esprime il valore memorizzato
all'indirizzo puntato da numPtr, cioè il valore
di numero. Applicare una indirezione (il primo asterisco)
a detto valore non ha alcun senso, perché il contenuto
di numero non è un indirizzo. Per di più
numero è un float, mentre gli indirizzi
sono sempre numeri interi. Il compilatore ignora l'asterisco di
troppo.
E l'espressione *numero?
Nessuno! Di fatto, si ricade nel caso precedente, poiché
*numPtr equivale a numero e **numPtr,
pertanto, equivale a *numero.
E l'espressione &*numPtr?
Allora: numPtr esprime l'indirizzo di numero,
quindi la sua indirezione *numPtr rappresenta il contenuto
di numero. L'indirizzo del contenuto di numero
è... l'indirizzo di numero, quindi &*numPtr
equivale a numPtr (e a *&numPtr). Buffo...
&*numPtr e numPtr sono la stessa cosa?
Evidentemente sì, come si vede dalla risposta precedente.
Cosa restituisce l'espressione &&numero?
&&numero restituisce... una segnalazione d'errore
del compilatore. Infatti &numero, espressione lecita,
rappresenta l'indirizzo di numero, ma che senso può
avere parlare dell'indirizzo dell'indirizzo di numero?
Attenzione: numPtr contiene l'indirizzo di numero,
ma l'indirizzo dell'indirizzo di numero non può
essere considerato sinonimo dell'indirizzo di numPtr.
E l'espressione &&numPtr?
Anche &&numPtr è un'espressione illecita.
L'indirizzo dell'indirizzo di una variabile (puntatore o no) non
esiste...
Cosa accade se si esegue *numPtr = 21.75?
Viene modificato il contenuto di numero. Infatti numPtr
rappresenta l'indirizzo di numero, cioè punta
all'area di memoria assegnata a numero; *numPtr
rappresenta numero nel senso che restituisce il contenuto
dell'area di memoria occupata da numero. Un'operazione
effettuata sull'indirezione di un puntatore è sempre, a
tutti gli effetti, effettuata sulla locazione di memoria a cui
esso punta.
Cosa accade se si esegue numPtr = 0x24A6?
Si assegna un nuovo valore a numPtr, questo è
evidente. L'effetto (forse meno evidente a prima vista) è
che ora numPtr non punta più a numero, ma a ciò
che si trova all'indirizzo 0x24A6. Qualsiasi cosa
sia memorizzata a quell'indirizzo, se referenziata mediante numPtr
(cioè mediante la sua indirezione), viene trattata come
se fosse un float.
E se si esegue &numPtr = 0xAF2B?
Si ottiene, ancora una volta, un errore in compilazione. Infatti
&numPtr restituisce l'indirizzo di numPtr,
il quale, ovviamente, non può essere modificato in quanto
stabilito dal compilatore.