- Programmazione » Programmazione » Guida C - Manuale programmazione con articoli e risorse interessanti
I puntatori: complicazioni
PUNTATORI
I puntatori sono, dunque, strumenti appropriati alla
manipolazione ad alto livello degli indirizzi delle
variabili. C'è proprio bisogno di preoccuparsi dei
registri della CPU e di tutte le contorsioni possibili tra
indirizzi seg:off e indirizzi lineari? Eh, sì... un
poco è necessario; ora si tratta di capire il
perché.
Poco fa abbiamo ipotizzato che l'indirizzo di
numero e di numPtr fossero,
rispettivamente, FFE6 e FFE4. A prescindere
dai valori, realisitci ma puramente ipotetici, è
interessante notare che si tratta di due unsigned
int. In effetti, per visualizzarli correttamente,
abbiamo passato a printf() stringhe contenenti
%X, lo specificatore di formato per gli interi in
formato esadecimale. Che significa tutto
ciò?
Significa che il valore memorizzato in numPtr (e
in qualsiasi altro puntatore[11]) è una word,
occupa 16 bit e si differenzia da un generico intero senza
segno per il solo fatto che esprime un indirizzo di memoria.
E' evidente, alla luce di quanto appena affermato, che
l'indirizzo memorizzato in numPtr è un
offset: come tutti i valori a 16 bit esso è gestito
dalla CPU in uno dei suoi registri e può variare tra 0
e 65535. Un puntatore come numPtr esprime allora, in
byte, la distanza di una variabile da... che cosa?
Dall'indirizzo contenuto in un altro registro della CPU,
gestito automaticamente dal compilatore.
Con qualche semplificazione possiamo dire che il
compilatore, durante la traduzione del sorgente in linguaggio
macchina, stabilisce quanto spazio il programma ha a
disposizione per gestire i propri dati e a quale distanza
dall'inizio del codice eseguibile deve avere inizio
l'area riservata ai dati. Dette informazioni sono
memorizzate in una tabella, collocata in testa al file
eseguibile, che il sistema operativo utilizza per caricare
l'opportuno valore in un apposito registro della CPU.
Questo registro contiene la parte segmento dell'indirizzo
espresso da ogni puntatore dichiarato come
numPtr.
Nella maggior parte dei casi l'esistenza dei registri di
segmento è del tutto trasparente al programmatore, il
quale non ha alcun bisogno di proccuparsene, in quanto
compilatore, linker e sistema operativo svolgono
automaticamente tutte le operazioni necessarie alla loro
gestione. Nello scrivere un programma è di solito
sufficiente lavorare con i puntatori proprio come abbiamo
visto negli esempi che coinvolgono numero e
numPtr: gli operatori "*" e
"&" sono caratterizzati da una
notevole potenza operativa.