31.05.2013 Views

Tricky C - Si® @lbert Site

Tricky C - Si® @lbert Site

Tricky C - Si® @lbert Site

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

20 - <strong>Tricky</strong> C<br />

h) Cosa accade se si esegue *numPtr = 21.75?<br />

i) Cosa accade se si esegue numPtr = 0x24A6?<br />

j) E se si esegue &numPtr = 0xAF2B?<br />

Provate a rispondere prima di leggere le risposte nelle righe che seguono!<br />

a) Una cosa alla volta. &numPtr esprime l'indirizzo di numPtr. L'indirezione di un indirizzo<br />

(cioè l'asterisco davanti a "qualcosa" che esprime un indirizzo) restituisce il valore memorizzato a<br />

quell'indirizzo. Pertanto, *&numPtr esprime il valore memorizzato all'indirizzo di numPtr. Cioè il<br />

valore contenuto in numPtr. Cioè l'indirizzo di numero. Simpatico, vero?<br />

b) Nessuno! Infatti *numPtr esprime il valore memorizzato all'indirizzo puntato da numPtr,<br />

cioè il valore di numero. Applicare una indirezione (il primo asterisco) a detto valore non ha alcun<br />

senso, perché il contenuto di numero non è un indirizzo. Per di più numero è un float, mentre gli<br />

indirizzi sono sempre numeri interi. Il compilatore ignora l'asterisco di troppo.<br />

c) Nessuno! Di fatto, si ricade nel caso precedente, poiché *numPtr equivale a numero e<br />

**numPtr, pertanto, equivale a *numero.<br />

d) Allora: numPtr esprime l'indirizzo di numero, quindi la sua indirezione *numPtr<br />

rappresenta il contenuto di numero. L'indirizzo del contenuto di numero è... l'indirizzo di numero,<br />

quindi &*numPtr equivale a numPtr (e a *&numPtr). Buffo...<br />

e) Evidentemente sì, come si vede dalla risposta precedente.<br />

f) &&numero restituisce... una segnalazione d'errore del compilatore. Infatti &numero,<br />

espressione lecita, rappresenta l'indirizzo di numero, ma che senso può avere parlare dell'indirizzo<br />

dell'indirizzo di numero? Attenzione: numPtr contiene l'indirizzo di numero, ma l'indirizzo<br />

dell'indirizzo di numero non può essere considerato sinonimo dell'indirizzo di numPtr.<br />

g) Anche &&numPtr è un'espressione illecita. L'indirizzo dell'indirizzo di una variabile<br />

(puntatore o no) non esiste...<br />

h) Viene modificato il contenuto di numero. Infatti numPtr rappresenta l'indirizzo di<br />

numero, cioè punta all'area di memoria assegnata a numero; *numPtr rappresenta numero nel senso<br />

che restituisce il contenuto dell'area di memoria occupata da numero. Un'operazione effettuata<br />

sull'indirezione di un puntatore è sempre, a tutti gli effetti, effettuata sulla locazione di memoria a cui esso<br />

punta.<br />

i) Si assegna un nuovo valore a numPtr, questo è evidente. L'effetto (forse meno evidente a<br />

prima vista) è che ora numPtr non punta più a numero, ma a ciò che si trova all'indirizzo 0x24A6.<br />

Qualsiasi cosa sia memorizzata a quell'indirizzo, se referenziata mediante numPtr (cioè mediante la sua<br />

indirezione), viene trattata come se fosse un float.<br />

j) Si ottiene, ancora una volta, un errore in compilazione. Infatti &numPtr restituisce l'indirizzo<br />

di numPtr, il quale, ovviamente, non può essere modificato in quanto stabilito dal compilatore.<br />

C o m p l i c a z i o n i<br />

I puntatori sono, dunque, strumenti appropriati alla manipolazione ad alto livello degli indirizzi<br />

delle variabili. C'è proprio bisogno di preoccuparsi dei registri della CPU e di tutte le contorsioni possibili<br />

tra indirizzi seg:off e indirizzi lineari? Eh, sì... un poco è necessario; ora si tratta di capire il perché.<br />

Poco fa abbiamo ipotizzato che l'indirizzo di numero e di numPtr fossero,<br />

rispettivamente, FFE6 e FFE4. A prescindere dai valori, realisitci ma puramente ipotetici, è interessante<br />

notare che si tratta di due unsigned int. In effetti, per visualizzarli correttamente, abbiamo passato a<br />

printf() stringhe contenenti %X, lo specificatore di formato per gli interi in formato esadecimale. Che<br />

significa tutto ciò?

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!