Memoria e puntatori. La memoria

Documenti analoghi
B8. Equazioni di secondo grado

1 Espressioni polinomiali

1 Equazioni e disequazioni di secondo grado

11. Rango di una matrice.

2 x = 64 (1) L esponente (x) a cui elevare la base (2) per ottenere il numero 64 è detto logaritmo (logaritmo in base 2 di 64), indicato così:

CORSO ZERO DI MATEMATICA

7. Derivate Definizione 1

, x 2. , x 3. è un equazione nella quale le incognite appaiono solo con esponente 1, ossia del tipo:

Integrale Improprio. f(x) dx =: Osserviamo che questa definizione ha senso dal momento che per ogni y è ben definito l integrale b

POTENZA CON ESPONENTE REALE

Laurea triennale in Scienze della Natura a.a. 2009/2010. Regole di Calcolo

Valutazione di una espressione. Espressioni. Espressioni semplici: variabili. Espressioni semplici: costanti

11. Rango di una matrice.

{ 3 x y=4. { x=2. Sistemi di equazioni

Unioni finite e numerabili di intervalli, il volume degli insiemi aperti

Equazioni. Definizioni e concetti generali. Incognita: Lettera (di solito X) alla quale e possibile sostituire dei valori numerici

Equazioni 1 grado. Definizioni Classificazione Risoluzione Esercizi

Materia: MATEMATICA Data: 5/04/2005

Esponenziali e logaritmi

Calcolo integrale in due e più variabili

Sottoprogrammi: Funzioni e Procedure

2 Generalità sulle matrici

2. Teoremi per eseguire operazioni con i limiti in forma determinata

Puntatori e gestione dinamica della memoria

Algebra delle Matrici

Il calcolo letterale

Il calcolo letterale

5.4 Il teorema fondamentale del calcolo integrale

Il calcolo letterale

1 Integrale delle funzioni a scala

Integrali definiti (nel senso di Riemann)

n volte m volte n+m volte n volte n volte n volte } = a n + n + n = a n m

SPAZI VETTORIALI. 1. Spazi e sottospazi vettoriali

I RADICALI. H La misura di un segmento non eá sempre esprimibile mediante un numero razionale; per esempio, se un

Corso di Analisi: Algebra di Base. 4^ Lezione. Radicali. Proprietà dei radicali. Equazioni irrazionali. Disequazioni irrazionali. Allegato Esercizi.

corrispondenza dal piano in sé, che ad ogni punto P del piano fa corrispondere il punto P' in

Determinanti e caratteristica di una matrice (M.S. Bernabei & H. Thaler

Esercizi di Informatica Teorica Pumping lemma e proprietà di

SUGLI INSIEMI. 1.Insiemi e operazioni su di essi

Vediamo quindi l elenco dei limiti fondamentali, il cui risultato daremo per noto d ora in avanti e lo utilizzeremo ogni volta che sarà necessario.

(somma inferiore n esima), (somma superiore n esima).

Integrali impropri in R

Corso di Modelli Matematici in Biologia Esame del 22 Gennaio 2018

{ 1, 2,3, 4,5,6,7,8,9,10,11,12, }

Problemi 24/11/ ) = n=

a cura di Luca Cabibbo e Walter Didimo

15. Cambiamenti di base in uno spazio vettoriale.

Funzioni razionali fratte

Dove siamo. Gli array - II. Array bidimensionali (matrici) Oggi. Array bidimensionali (matrici) Sintassi Java. Stefano Mizzaro 1

si definisce Funzione Integrale; si chiama funzione integrale in quanto il suo * x

IL CALCOLO LETTERALE: I MONOMI Conoscenze. per a = - 2 vale:

Introduzione alle disequazioni algebriche

UNITA 13. GLI ESPONENZIALI

Scrivere una funzione Octave con parametri a, b e p che esegue le seguenti operazioni:

{ } secondi pedici, appartenenti a 1, 2, 0 0 a

L offerta della singola impresa: l impresa e la massimizzazione del profitto

Esercizi di consolidamento

Matematica II. Un sistema lineare è un sistema di m equazioni lineari (cioè di primo grado) in n incognite x 1,, x n :

FUNZIONI CONTINUE A TRATTI E LORO INTEGRALI

Capitolo 2. Il problema del calcolo delle aree

Capitolo 5. Integrali. 5.1 Integrali di funzioni a gradinata

dr Valerio Curcio Le affinità omologiche Le affinità omologiche

IL CALCOLO LETTERALE: I MONOMI Conoscenze. per a = - 2 vale:

RAPPRESENTAZIONE GRAFICA DELLA PARABOLA a ( ) { } f con, è la parabola di equazione y = ax + bx + c. Vogliamo disegnarla. 2

Integrali su intervalli illimitati Criteri di convergenza 1 Integrali di funzioni non limitate Criteri di convergenza 2 Altri integrali impropri

Integrali impropri di funzioni di una variabile

MATEMATIKA OLASZ NYELVEN

Esercizi su spazi ed operatori lineari

3) Sia (X, d) uno spazio metrico. Dimostrare che è una distanza su X la funzione

Propagazione degli Errori e regressione lineare. Note e consigli d uso. -Termine covariante -- estrapolazione e/o interpolazione

Scrivere una funzione Octave con parametri a, b e p che esegue le seguenti operazioni:

fattibile con le tecniche elementari che imparerai in seguito. Ad esempio il polinomio

3. Funzioni iniettive, suriettive e biiettive (Ref p.14)

Appunti di Matematica 4 - Triangoli qualsiasi - Triangoli qualsiasi

Equazioni di 2 grado. Definizioni Equazioni incomplete Equazione completa Relazioni tra i coefficienti della equazione e le sue soluzioni Esercizi

Integrale di Riemann

- Appunti di Matematica 1 Licei Umanistici - - I polinomi - Polinomi

Esercitazioni di Statistica Matematica A Lezione 6. Applicazioni della legge dei grandi numeri e della formula di Chebicev. lim i!

TRASFORMAZIONI GEOMETRICHE

Scheda per il recupero 2

INSIEMI, RETTA REALE E PIANO CARTESIANO

Anno 1. Numeri reali: proprietà e applicazioni di uso comune

Appunti di Matematica 1 - I polinomi - Polinomi. I vari monomi che compongono il polinomio si chiamano termini del polinomio.

Integrali in senso generalizzato

Minimi quadrati e problemi di distanza minima

13 - Integrali Impropri

Unità Didattica N 3 Le inequazioni. Unità Didattica N 3 Le inequazioni

Area del Trapezoide. f(x) A f(a) f(b) f(x)

Il moto uniformemente accelerato

Calcolo letterale. 1) Operazioni con i monomi. a) La moltiplicazione. b) La divisione. c) Risolvi le seguenti espressioni con i monomi.

Esercizi svolti Limiti. Prof. Chirizzi Marco.

Appunti di calcolo integrale

LEZIONE 24. è lineare. Per la commutatività del prodotto scalare segue anche la linearità dell applicazione

calcolare la ragione q. Possiamo risolvere facilmente il problema ricordando la formula che dà il termine n-esimo di una progressione geometrica:

Assemblaggio degli Elementi: Soluzione del Problema Strutturale Discreto

INTEGRAL IMPROPRI. C.d.L in Fisica Lecce, a.a. 2011/ Le definizioni... pag Criteri di integrabilità... pag Esercizi... pag.

Integrali in senso generalizzato

Sistemi di equazioni algebriche lineari. Una equazione algebrica lineare in n incognite si presenta nella forma:...

Transcript:

Memori e unttori In questo citolo vedimo come è ftt, e come viene ust, l memori. L memori si uò vedere come un rry di byte, in cui ogni vribile occu un certo numero di byte consecutivi. In C, è ossibile determinre si qunto szio occu un vribile, si l su osizione in questo vettore. In rticolre, è ossibile memorizzre l osizione (indirizzo) di un vribile in un ltr vribile. Le vribili che contengono indirizzi di memori sono dette vribili unttori. L memori 1. come si rresent l memori d lto livello 2. rresentzione iù recis, come vettore di celle 3. un esemio di lcune vribili in memori L memori di un clcoltore è un disositivo in cui è ossibile memorizzre dei dti. Ogni volt che si cre (dichir) un nuov vribile, viene riservt un re di memori in cui viene memorizzto il vlore dell vribile. In ltre role, un rte dell memori viene imiegto er l memorizzzione del vlore dell vribile. i c Per i rogrmmi iù semlici, si uò ensre ll memori come se fosse un lvgn: ogni volt che si dichir un vribile, si disegn un qudrto; ll interno di questo qudrto si uò scrivere (memorizzre) un vlore. 1

Il modello semlificto di memori come lvgn funzion bene solo er lcuni tii di rogrmmi. Esistono delle tecniche di rogrmmzione che richiedono un modello iù dettglito di come è ftt l memori. Per gli rgomenti che si vedrnno in questo corso, è sufficiente dire che l memori è un vettore di byte. Non ci interess l su dimensione. V notto che nche questo modello dell memori è un semlificzione, che comunque è sufficientemente reciso er gli rgomenti trttri in questo corso. Nel seguito, rresentimo l memori come nell figur ccnto, in cui ogni rettngolo è un byte. Gli indici di questo vettore verrnno scritti solo qundo necessri. 3 2 1 0 Ogni volt che si dichir un vribile, viene lloct (riservt) un zon di memori er ess. L grndezz di quest zon diende dl tio dell vribile: er esemio, le vribili di tio chr occuno un solo byte, mentre gli interi ne occuno 4. Il disegno mostr come otrebbe essere strutturt l memori se un rogrmm us un vribile inter e un vribile crttere b: l vribile occu quttro byte consecutivi nell memori, mentre l vribile b ne occu uno solo. Ogni volt che si ssegn d un vlore, questo viene scritto nei byte che le sono ssegnti. Ogni volt che il vlore di viene usto (er esemio er fre un stm del vlore di, come rintf("%d\n",);, o er fre un clcolo come b=+c;), il clcoltore v cercre il vlore in quei quttro byte. b x 12 2

Indirizzo, byte occuti e vlore di un vribile 1. vribile = insieme di celle consecutive 2. er sere quli celle sono occute d un vribile, ci bst sere qunte sono e l indirizzo dell rim 3. ci sono csi in cui serve sere queste cose 4. oertori & e sizeof 5. indirizzo e numero di byte si ossono nche stmre 6. differenz fr vlore e indirizzo 7. sizeof diende solo dl tio; er quest rgione, si uò usre nche sul tio 3

Le vribili C sono zone di memori. In ltre role, ogni vribile è un insieme di loczioni ll interno dell memori. Il numero di byte occuti d un vribile diende dl suo tio: un intero occu quttro osizioni, un crttere un osizione, un double otto, ecc. b 12 103 102 101 100 3 2 1 0 indirizzo di b dimensione di b dimensione di (4) indirizzo di (102) Se voglimo sere quli byte un vribile occu, ci servono due numeri: il rimo è l osizione del rimo byte occuto, il secondo è il numero di byte occuti. Il rimo numero viene detto indirizzo dell vribile. Se er esemio l vribile occu in memori le osizioni dll 1243 ll 1247, llor il suo indirizzo è il rimo di questi numeri, cioè 1243; quest vribile occu quttro loczioni, quindi il numero di byte occuti d è 4. Nei rogrmmi ftti fino questo momento, non er necessrio sere quli celle un vribile occu. Esistono erò delle situzioni in cui è invece necessrio. Per questo, il C mette disosizione delle rimitive che ermettono di trovre l indirizzo e il numero di byte occuti dlle vribili. Queste nozioni sono necessrie er esemio nel cso in cui il rogrmm deve gestire un numero di dti non noto riori, come si vedrà roosito degli rry e delle liste. indirizzo er sere l indirizzo di un vribile si us l oertore unrio &; in ltre role, se è un vribile, llor & è il suo indirizzo (l rim osizione di memori occut d ess); numero di byte occuti il numero di byte occuti d un vribile si trov con sizeof; quindi er esemio sizeof() è il numero di byte occuti dll vribile. 4

Il rogrmm seguente dichir tre vribili di diversi tii, ssegn dei vlori, e oi stm i loro indirizzi e il numero di byte che occuno. D notre che l indirizzo di un vribile, cosí come il numero di byte occuti, sono dei normli numeri, e si ossono quindi stmre. Nel cso dell indirizzo, si è scelto di stmrlo in esdecimle (usndo %x) m nche l stm in decimle vrebbe funzionto (d notre che gli indirizzi sono numeri unsigned, e quindi è comunque iù rorito stmrli usndo %u che %d). /* Stm indirizzo, occuzione di memori e vlore di lcune vribili. */ int min(void) { int ; chr b; flot c; =12; b= ; c=0.1243; rintf("l indirizzo di e %x, occu %d bytes, il suo vlore e %d\n", &, sizeof(), ); rintf("l indirizzo di b e %x, occu %d bytes, il suo vlore e %c\n", &b, sizeof(b), b); rintf("l indirizzo di c e %x, occu %d bytes, il suo vlore e %f\n", &c, sizeof(c), c); } return 0; È imortnte notre l differenz tr il vlore di un vribile e il suo indirizzo. L indirizzo di un vribile è l inizio dell zon di memori occut d un vribile, mentre il vlore di un vribile è il contenuto di tle zon. Altr osservzione: tutte l vribili di un certo tio occuno esttmente lo stesso numero di byte. Quindi, se e x sono interi, si uò essere certi che sizeof() è ugule sizeof(x). Per quest rgione, sizeof è stt definit in modo che oss vere come rmetro si il nome di un vribile che il nome di un tio. È quindi ossibile er esemio clcolre e stmre il vlore di sizeof(int), che coincide necessrimente con i vlori di sizeof di ogni vribile di tio int. Il rogrmm dimensione.c stm il numero di byte occuti dlle vribili di vri tii di dto. Il numero di byte occuti d un tio di dto uò cmbire ssndo clcoltori di tio diverso. Per esemio, un intero uò occure due, oure quttro, oure otto byte second del tio di clcoltore/sistem oertivo/comiltore usto. /* Szio occuto d vribili di un certo tio. */ int min() { rintf("il tio int occu %d bytes\n", sizeof(int) ); rintf("il tio chr occu %d bytes\n", sizeof(chr) ); 5

rintf("il tio flot occu %d bytes\n", sizeof(flot) ); rintf("il tio double occu %d bytes\n", sizeof(double) ); } return 0; Punttori 1. gli indirizzi non sono esttmente dei numeri 2. er esemio, int, ; e oi =&; gener un errore (wrning) 3. il tio di un indirizzo non è int 4. l indirizzo di un vribile int è di tio int * 5. quindi, int *; int ; e oi =&; non gener errori Nell gine recedente si è detto che l indirizzo, cosí come lo szio occuto d un vribile, sono dei semlici numeri. Questo è in reltà vero solo er il numero di byte occuti, che è relmente un numero intero. Per quello che rigurd l indirizzo, non è del tutto estto che si trtt di un numero. Per cire meglio questo ftto, ricordimo che un vribile, oltre d vere un zon di memori ssocit, h nche un tio. Per esemio, due vribili e b ossono entrmbe occure quttro byte in memori, m essere un di tio int e un di tio flot. Quello che cmbi non è l occuzione di memori, m il modo in cui questi quttro byte vengono interretti. Quest differenz si riflette nche sui tii degli indirizzi. Per esemio l indirizzo di un vribile di tio int non è un intero. È invece un vribile di un nuovo tio, il unttore intero. In rtic, questo si uò vedere immeditmente se si cerc di comilre il seguente rogrmm nocst.c. /* Dimostrzione che l indirizzo di un vribile non e un numero intero: comilndo questo rogrmm si gener un errore (wrning) di incomtibilit fr tii. */ int min() { int ; int b; b=&; } return 0; Comilndo, si ottiene un messggio di questo genere: nocst.c: In function min : nocst.c:12: wrning: ssignment mkes integer from ointer without cst Questo è il tiico errore che si ottiene qundo si cerc di ssegnre un vribile un vlore di un ltro tio (er esemio, ssegnndo un vribile inter un vlore rele). È quindi chiro che l istruzione b=& contiene un tenttivo di ssegnre un vribile inter un vlore di un tio non comtibile. Quindi, il tio dell esressione & non è comtibile con gli interi. 6

L regol generle sui unttori è l seguente: l indirizzo di un vribile di un tio T è di tio T *, che viene detto tio unttore T. Dto che è un intero, il suo indirizzo è di tio int *, ossi di tio unttore int. A rim vist, quest differenz di tii uò sembrre un rticolrità inutile del C. Il motivo er cui è invece necessri risulterà chir nel seguito. Per ogni tio che è ossibile definire in C, d esso viene ssocito il corrisondente tio unttore, che è nche esso un tio. Per esemio, dto che in C esiste il tio int, esiste utomticmente nche il tio unttore d int, che si denot con int *. È imortnte notre che questo è un tio come tutti gli ltri. È quindi ossibile definire delle vribili di tio unttore intero, nel seguente modo: int *; Dl momento che gli indirizzi di vribili sono di tio unttore (l tio dell vribile), nell vribile si uò mettere l indirizzo di un vribile di tio int. Quest oerzione ssegn un vribile di tio unttore intero il vlore dell indirizzo di un vribile inter, che è nche esso un unttore intero. Quindi, l istruzione =& non gener nessun errore di incomtibilitè fr tii. L comilzione del rogrmm nocstunt.c, rogrmm del resto inutile, non gener nessun errore. Si riort qui sotto il testo del rogrmm. /* Un vribile definit di tio int * e un unttore intero. Anche l indirizzo di un vribile inter e un unttore intero. Quindi, =& non gener nessun errore, erche e & sono dello stesso identico tio. */ int min() { int ; int *; =&; } return 0; Se voglimo memorizzre l indirizzo di un vribile di tio int in un ltr vribile, quest ultim deve essere dichirt non come int (nche se gli indirizzi sembrno essere interi), m come unttore intero int *. Lo stesso vle er tutti gli ltri tii. Questo discorso vle nche er gli ltri tii definiti in C. Per esemio, l indirizzo di un vribile flot v messo in un vribile di tio flot *, mentre l indirizzo di un vribile chr v messo in un vribile chr *. Si noti che, in ogni cso, l indirizzo di un vribile è comunque un numero intero (nche se l vribile contiene un vlore rele!) Il rogrmm seguente ltri.c contiene delle vribili unttore tii diversi d int /* Le vribili flot* contengono indirizzi di vribili flot. Lo stesso er chr* */ int min() { flot f; 7

flot *; chr c; chr *t; =&f; c=&t; } return 0; Dichirzioni di vribili di tio unttore 1. qundo si dichirno iù vribili unttori insieme, * v rietuto su tutte 2. trnne qundo si us tyedef Risetto lle vribili di tutti gli ltri tii, le dichirzioni di vribili di tio unttore hnno delle regole diverse. Inftti, mentre er tutti gli ltri tii si uò fre: Tio, b, c; e questo dichir tre vribili di tio Tio, nel cso dei unttori il risultto è differente. L dichirzione: int *, b, c; H come risultto che l sol vribile è un unttore intero, mentre b e c sono vribili intere. Per dichirre tutte e tre le vribili come unttori, occorre fre: int *, *b, *c; ossi, si deve mettere l sterisco * dvnti ognun delle vribili. L regol er l dichirzione dei unttori è semlicemente che un sterisco dvnti un vribile dichir l vribile (e solo quell) come un unttore. Quindi, se si f: flot *x, y, *z; le vribili x e z sono unttori flot, dto che sono recedute d un sterisco. L vribile y invece, non vendo * dvnti, non è un unttore m un vribile di tio flot. Eventuli szi fr il nome del tio, l sterisco, l vribile e le virgole sono ignorti. Un cos imortnte d notre è che nel cso in cui si definisce un tio unttore usndo l tyedef, in nuovo tio segue invece l regol generle. In ltre role, se si f: tyedef int * unt; unt, b, c; Allor il tio unt è equivlente l tio int *. L unic differenz è che l dichirzione delle vribili, b e c le definisce tutte e tre del tio unt, ossi sono tutte e tre unttori interi. 8

Vlore e indirizzo 1. tutte le vribili hnno vlore e indirizzo 2. questo vle nche er i unttori 3. er i unttori, sono entrmbi indirizzi di memori 4. sono comunque due cose diverse Tutte le vribili hnno un vlore e un indirizzo. Quest regol vle nche er le vribili unttore: nche loro hnno un indirizzo (l zon di memori in sui si trovno) e un vlore (quello che è memorizzto). Quello che le rende diverse è il ftto che il vlore in esso memorizzto è su volt un indirizzo. In ltre role, le vribili unttore sono semre zone di memori in cui viene memorizzto un numero. Mentre le vribili intere e reli contengono vlori interi e reli, il vlore memorizzto in un vribile unttore è un numero che indic un osizione di memori. Anche se il vlore di un vribile unttore e il suo indirizzo sono entrmbe osizioni di memori, sono comunque due cose diverse: l indirizzo è l osizione inizile dell memori occut, mentre il vlore è quello che si trov memorizzto, che su volt un indirizzo di memori (in generle, uno diverso). Il seguente rogrmm vlind.c illustr l differenz. /* Vlore e indirizzo sono diversi. */ int min() { int =60; int *; =&; rintf("&=%x =%x\n", &, ); rintf("&=%x =%x\n", &, ); } return 0; Questo rogrmm stm indirizzo e vlore er le due vribili e. Tutte le vribili hnno un indirizzo (l osizione in memori) e un vlore (quello che c è memorizzto). Questo vle quindi si er, che è un vribile inter, che er, che è un unttore. 9

60 eff15 eff14 eff13 eff12 (indirizzo di ) eff11 eff10 eff0f eff0e eff0d eff0c eff0b (indirizzo di ) Qundo si esegue il rogrmm, viene cret un zon di memori er ognun delle vribili. In questo cso, viene cret un zon er ed un zon er. Nell figur sinistr si vede un ossibile stto dell memori doo che le vribili sono stte crete. Qundo si ssegn d il vlore 60, questo vlore viene scritto nell su osizione di memori. Qundo si esegue l istruzione =&, l indirizzo di viene scritto in. Qundo si fnno queste figure di esemio, è bene scrivere dei vlori di esemio er le osizioni di memori. In quest figur, er esemio, l osizione inizile di è eff0b. Si trtt ovvimente di un vlore di esemio: l osizione effettiv dell vribile viene determint soltnto qundo si esegue il rogrmm. In ogni cso, il numero che dice l osizione inizile di viene memorizzto in. eff0b 60 eff12 (indirizzo di ) eff0b (indirizzo di ) Quello che verrebbe stmto, in questo cso, è: &=eff0b =3c &=eff12 =eff0b Il rimo vlore delle due righe è l indirizzo delle due vribili. I due indirizzi sono necessrimente diversi, dl momento che ogni vribile occu un su zon di memori divers d quelle delle ltre. Il secondo numero stmto è il vlore delle due vribili. Il vlore memorizzto in, nel nostro cso, è 60, che viene stmto in esdecimle. Nell second rig, il secondo numero stmto è il vlore memorizzto nell vribile. Dto che in bbimo messo l indirizzo di (qundo bbimo eseguito l istruzione =&) viene stmto unto l indirizzo di. L vribile, come tutte le vribili, h si un indirizzo che un vlore. Soltnto che, differenz di, il vlore di è su volt un indirizzo (in questo cso, quello di ). Il ftto che il vlore di un vribile unttore si un indirizzo uò volte cusre confusione. Bst erò disegnre lo stto dell memori er chirire l situzione. 10

Fccimo or un reciszione sull rresentzione grfic dell memori. Nell figur di sor bbimo messo dei vlori numerici di esemio er rresentre gli indirizzi delle vribili (eff0b er l indirizzo di e eff12 er l indirizzo di ). V tenuto semre resente che questi sono solo indirizzi di esemio: se si esegue il rogrmm un second volt, otrebbero venire stmti degli indirizzi diversi, er esemio ffb02 ed ffb12. Nel seguito, si mettono comunque dei vlori secifici er gli indirizzi, m v tenuto resente che si trtt solo di vlori di esemio. L figur qui ccnto mostr un rresentzione grfic divers, che non h questo roblem. Per indicre che un unttore contiene un certo indirizzo, mettimo un frecci che termin con l loczione quell indirizzo. Per esemio, l istruzione =& mette in l indirizzo di. Questo si uò rresentre come un frecci che rte dlle loczioni occute d e unt ll rim loczione occut d. Quest rresentzione grfic ermette di fr cire qule è l indirizzo memorizzto in un vribile unttore senz dover scrivere vlori numerici di esemio er gli indirizzi. Quest rresentzione risult rticolrmente comod er visulizzre lo stto dell memori qundo si eseguono rogrmmi che contengono molti unttori. 60 Usre l oggetto untto 1. se è un unttore, llor * è come se fosse un vribile 2. esemio di uso dell oertore * 3. cos succede in memori qundo si esegue un rogrmm con unttori 4. rresentzione degli indirizzi con freccie Come si è visto, l oertore & trov l indirizzo di un vribile. In C esiste nche l oertore inverso, che ermette di ccedere ll zon di memori definit d un unttore. Questo oertore è l sterisco *. Il simbolo viene quindi usto in due modi distinti: er definire un tio unttore un tio (esemio: int *), e er definire l oggetto ssocito un indirizzo, di cui or rlimo. L regol generle è: se è un vribile di tio unttore intero, si uò ensre * come un vribile di tio intero. È quindi ossibile er esemio stmre il vlore di *, oure usre questo vlore ll interno di esressioni come fosse un intero (er esemio, 12+*-2 è un esressione erfettmente vlid). È nche ossibile memorizzre dei vlori in quest vribile: er esemio, *=34; è un istruzione vlid. Nel seguente rogrmm vrunt.c, l vribile e l esressione * sono esttmente equivlenti. Le loro zone di memori sono le stesse, e quindi usre/cmbire il loro vlore gener esttmente gli stessi risultti. 11

/* Se si ssegn l indirizzo di, llor * ed sono l stess cos. */ int min() { int =60; int *; /* qui * indic che e un unttore e non un intero */ =&; /* l indirizzo di v in */ /* modifiche d sono modifiche * */ =12; rintf("=%d *=%d\n",, *); /* qui ----^ l oertore * indic che l vribile non e m l zon di memori indict d */ /* modifiche * sono modifiche d */ *=24312; rintf("=%d *=%d\n",, *); } return 0; Qundo si usno i unttori, è molto fcile fre confusione fr oggetti untti e i loro unttori. Un unttore è un indirizzo di memori, mentre l oggetto untto è l zon di memori che inizi con l indirizzo, ed è grnde qunto bst er contenere il tio corrisondente. D ltr rte, le vribili di tio unttore sono nche esse vribili, ossi zone di memori. L differenz fr un vribile int e un vribile di tio unttore intero è che l rim contiene un vlore intero, mentre l second contiene un indirizzo, e in rticolre l indirizzo inizile dell zon di memori ssocit un intero. 12

60 eff15 eff14 eff13 eff12 (indirizzo di ) eff11 eff10 eff0f eff0e eff0d eff0c eff0b (indirizzo di ) Considerimo l rresentzione dell memori come rry, e vedimo cos succede se si esegue il rogrmm di sor. In quest figur, e nelle successive, rresentimo solo l rte dell memori che ci interess. Nel vettore sono stti messi dei vlori numerici er gli indici. Questi vlori sono ovvimente dei numeri di esemio: ogni esecuzione, l osizione in memori di un vribile uò cmbire. In questo esemio, e nei successivi, si f l iotesi che i unttori sino rresentbili con quttro byte. Questo viene ftto solo i fini dell esemio: non esiste nessun grnzi che lo szio occuto d un unttore bbi questo vlore (in generle, fre delle ssunzioni sullo szio occuto dlle vribili di un certo tio è un errore di rogrmmzione). Nell dichirzione di viene nche ssegnto il vlore 60, che viene quindi memorizzto nell corrisondente re di memori. Non viene invece dto nessun vlore inizile, er cui il suo vlore non è determinto. 13

L ssegnzione dell indirizzo di f sí che nell vribile veng mess l rim osizione di memori occut d. Nel cso dell esemio, in si mette il vlore ef00b. Nell figur lto si vede lo stto dell memori doo ver eseguito l istruzione =&. L esressione * rresent l zon di memori che cominci con l indirizzo memorizzto in. In questo cso, l vribile contiene il vlore eff0b, quindi * rresent l zon di memori che cominci con eff0b. Inoltre, è un vribile di unttore intero, quindi * rresent un intero, che è grnde quttro byte. Si uò ensre che * è un vribile inter (grnde quindi quttro byte) l cui zon di memori inizi d eff0b. eff0b 60 eff12 (indirizzo di ) eff0b (indirizzo di ) 60 Nell figur lto si vede lo stesso stto dell memori usndo l rresentzione con freccie. Il risultto finle è ovvimente lo stesso: dto che l frecci indic che l vribile contiene l indirizzo di, qundo si modific/stm * viene modificto/stmto il vlore memorizzto in. Nell rresentzione con freccie, * indic quindi l zon di memori in cui termin l frecci che inizi in. Tutto questo rgionmento ermette di concludere che, ovunque si us *, questo è equivlente d, nel rogrmm di sor. V notto che, se un certo unto si cmbi il vlore di, questo non funzion iù. Per esemio, se si f =&b dove b è un ltr vribile inter, llor * divent equivlente b. 14

Tio dei unttori 1. erchè i unttori non sono interi? 2. erchè ltrimenti non so in che modo * v interretto (è un intero? un crttere?) 3. lterntiv ossibile m non ust: * con due rgomenti Nelle gine recedenti bbimo visto come i unttori sino effettivmente dei numeri. Si distinguono di numeri interi solo er il ftto che il loro vlore indic l indirizzo di un loczione, ossi indic un osizione dell memori. Ci si otrebbe questo unto chiedere erchè 1. i tii unttori sono di tio diverso dgli interi? 2. i unttori non hnno tutti lo stesso tio? In effetti, il tio di un unttore è un cos che uò venire fcilmente scvlct: er esemio, un rogrmm in cui x è un intero e è un unttore uò contenere l istruzione x=; oure =x;. Il comiltore roduce un messggio di vvertimento (wrning), m l comilzione h successo. Lo stesso vle er l distinzione fr unttori due tii diversi: se è un unttore intero e t è un unttore rele, llor le istruzioni =t e t= sono mmesse, nche se si gener un wrning in comilzione. Il rogrmm tiiunt.c contiene lcuni esemi di ssegnzioni fr tii diversi. /* Assegnzioni fr tii sbgliti. */ int min() { int x; int *; flot *t; x=; /* ssegnzione vribile int * di vlore int */ t=x; /* ssegnzione vribile flot * di vlore int */ =t; /* ssegnzione vribile int * di vlore flot * */ } return 0; Si noti nche che i messggi di errore ossono fcilmente venire eliminti con il cst. A questo unto, ci si chiede come mi i unttori non sono semlicemente di tio int. Il motivo è che in questo modo, non srebbe chiro qule è il tio dell esressione *. Inftti, se è semlicemente un intero, llor * otrebbe essere su volt un intero, oure un crttere, oure un rele, ecc. In ltre role, se i unttori fossero interi, llor le istruzioni =&c, =&x e =&f srebbero tutte ccettbili nche se fosse intero, m c, x e f sono un crttere, un intero e un rele. A questo unto non srebbe iù ossibile scrivere semlicemente *, erchè otrebbe untre un crttere, un intero, oure un rele. Scrivendo * non srebbe ossibile cire qule è il tio di quest esressione, e quindi non si cirebbe nemmeno qule è l zon di memori cui il unttore si riferisce (se fosse un unttore crttere, llor srebbe un zon grnde 1, se fosse un unttore intero l zon srebbe grnde 4, ecc). 15

Provimo immginre un vrinte del C in cui i unttori sino semlicemente di tio intero. Considerimo il seguente codice. /* Quello che segue non e codice C corretto. */ int min() { int x; flot g; x=925434; g=*x / 2; } return 0; L esressione *x / 2 dice che devo rendere l oggetto untto d x e dividere er due questo vlore. Però non dice qule è il tio di *x. Quest esressione otrebbe quindi venire interrett in (lmeno) tre modi: 1. rendi il byte che st ll inidirizzo scritto in x, e dividilo er due; 2. rendi i quttro byte rtire dll indirizzo che st scritto in x, e interret questi quttro byte come un intero; dividilo er due usndo l divisione fr interi; 3. rendi gli stessi quttro byte, e interretli come un numero flot; dividi questo numero usndo l divisione fr reli. Il risultto srebbe diverso: nel rimo cso si rende il rimo byte invece dei rimi quttro; il secondo e il terzo cso sono diversi erchè numeri reli e numeri interi, nche se occuno lo stesso szio, sono rresentti in modo diverso (in iù, il risultto è nche diverso erchè sono diverse le regole dell divisione fr interi e fr reli). Tutto questo serve dire: il unttore h un tio, ltrimenti srebbe imossibile cire il tio di *, e quindi cire qunto è grnde e come v interrett l zon di memori untt d. Un ossibile lterntiv ll soluzione dei tii sui unttori srebbe stt quell di definire l oertore di oggetto untto * come un oertore binrio, il cui rimo rgomento è il unttore e il secondo è il tio dell oggetto untto. In ltre role, i unttori non vrebbero bisogno dei tii se, er rendere l oggetto untto d un vribile, dovessi fre *(,int) se voglio un intero, *(,flot) se voglio un flot, ecc. Non è erò quest l soluzione seguit in C. Coi del vlore e coi dell indirizzo 1. differenz fr b= e =&, in rtic 2. b= signific: coi il vlore di in b; non ci sono iù relzioni fr e b doo l coi 3. =& coi l indirizzo: nche se è un coi, or * e sono l stess cos 4. cos succede in memori 16

Il seguente rogrmm cmbi.c f cire l differenz fr ssegnre il vlore di un vribile (b=) e ssegnre il suo indirizzo (=&). /* Effetti del cmbimento di un vribile. */ int min(void) { int ; int b; int *; =1; /* vle 1 */ b=; /* il vlore di viene coito in b */ =&; /* l indirizzo di viene messo in */ =12; /* viene cmbito */ /* qunto vlgono b e * questo unto? */ rintf("* vle %d\n", *); rintf("b vle %d\n", b); } return 0; Assegnre b il vlore di signific semlicemente che il vlore di viene coito nell zon di memori di b. D questo momento in oi, non esiste nessun ssocizione fr e b. In rticolre, se si cmbi il vlore di, questo non si riflette sul vlore di b. È come fotocoire un documento e oi fre delle modifiche solo sull originle: chirmente, l coi non viene modifict utomticmente. Nel cso dell ssegnzione dell indirizzo, qundo si f =&, d questo momento in oi, * e sono relmente l stess zon di memori. Quindi, d questo momento in oi, ogni modific su cmbi nche * e vicevers. Nell esemio dell documento fotocoito, è come se usssimo due nomi diversi er indicre lo stesso documento: dto che il documento è semre lo stesso, qundo modifico uno dei due sto modificndo nche l ltro. Quest ssocizione ermne fino che il vlore di non viene cmbito. Attenzione! L seguente ffermzione è sbglit: ffermzione errt: doo ver ftto =12 il vlore di * viene ggiornto di conseguenz in modo utomtico 17

b 1 1 Inftti, quest ffermzione resuone che e * sino due vribili memorizzte in due zone di memori diverse, e che oi è il clcoltore che si reoccu di fr sí che i loro vlori sino sincronizzti. Questo non è ssolutmente vero: qundo si memorizz 12 in, questo vlore non viene coito in *. Quello che invece succede è che * h l stess zon di memori di e quindi il suo vlore non uò che essere lo stesso. L figur qui ccnto mostr lo stto dell memori subito doo l ssegnzione =&. In questo momento, i vlori di e b coincidono semlicemente erchè il vlore di è stto coito in b e non è stto iù modificto; invece, il vlore di * e di coincidono erchè sono esttmente l stess re di memori. Qundo si f l modific =12 del vlore di, l rte di memori modifict è solo quell in cui è memorizzto. L situzione divent quindi come nell figur qui finco. È chiro che il vlore di b non è stto lterto, visto che è memorizzto in un zon di memori differente. D ltr rte, il vlore di è l indirizzo di, e quindi * e stnno nell stess zon di memori. Quindi, il vlore di * è quello memorizzto in quest zon, e quindi 12. b 1 In conclusione, ossimo dire che l differenz fr ssegnre il vlore di un vribile come in b= e ssegnre il suo indirizzo come in =& è che, nel rimo cso, un volt coito il vlore le due vribili vnno ognun er l su strd, nel secondo cso l elemento untto * coincide con l vribile, e quindi cmbi insieme ll vribile. 12 Punttori indefiniti 1. i unttori sono inizilmente indefiniti, come tutte l vribili 2. cos succede qundo si us un unttore indefinito 3. non si devono usre unttori indefiniti 18

Negli esemi visti fino d or, i unttori venivno usti soltnto er memorizzre indirizzi di vribili. In generle, un unttore è un vribile che contiene un indirizzo di memori. Qundo si definisce un vribile di tio unttore, er esemio con int *;, si cre un vribile il cui contenuto è un indirizzo di memori. Se non si ssegn un vlore quest vribile, il suo contenuto è indefinito, quindi non è ossibile sere riori qule indirizzo è scritto in. Usre il vlore di *, oure memorizzre un vlore in * roduce un risultto indefinito, ossi non è ossibile sere riori cos succede (il risultto uò cmbire di volt in volt). Questo vviene erchè il vlore inizile (indefinito) di uò essere l indirizzo di un qulsisi zon di memori, che uò essere o no ssocit un ltr vribile del rogrmm, e uò nche essere un osizione di memori cui il rogrmm non uò ccedere. Per usre un vribile unttore, è necessrio che conteng l indirizzo di un zon di memori su cui simo sicuri che: 1. il sistem oertivo ci ermette di ccedere; 2. non viene modifict dl rogrmm in modo insettto. Considerimo il rogrmm nomlloc.c riortto qui sotto, che non segue queste regole. int min() { int ; int *; =3; *=12; rintf("%d\n", ); } return 0; Il rogrmm non risett l regol sul vlore di un unttore, che dovrebbe essere l indirizzo di un zon di memori in cui simo certi di oter ccedere senz roblemi. Al contrrio, il vlore di è indeterminto come tutte le vribili che non sono stte inizilizzte. Considerimo or cos uò succedere qundo si esegue questo rogrmm. 19

L figur qui ccnto mostr un ossibile cso in cui il vlore inizile di (su cui, come si è detto, non si uò vere lcun controllo) è l indirizzo di un zon di memori cui il rogrmm non uò ccedere. eff0 eff0 zon di memori non ccessibile l rogrmm Qundo si esegue l istruzione *=12, viene ftto un tenttivo di mettere il vlore 12 nell zon di memori il cui indirizzo si trov in. A second del tio di sistem oertivo che si st usndo, uò venire generto un errore in esecuzione oure si uò rodurre un blocco dell intero sistem oertivo (nel qul cso, il comuter v rivvito). L figur qui ccnto mostr un ltro ossibile cso: quello in cui il vlore contenuto in csulmente risult essere l indirizzo di un ltr vribile del rogrmm. Si trtt chirmente di un cso molto oco robbile. Quello che succede è che *=12 mette il vlore 12 nell zon di memori dell vribile. Qundo oi si v stmre, viene quindi stmto il vlore 12. 12A0 * Dl momento che l vribile contenev il vlore 3, e il rogrmm non esegue oerzioni di ssegnmento su, ci si setterebbe l stm del vlore 3. L stm di 12 è quindi un risultto non tteso. 12A0 20

12A0 12A0 * Questo cso è simile l recedente, soltnto che l zon di memori il cui indirizzo inizile si trov in si sovrone soltnto rzilmente con l zon di memori in cui è memorizzto. In questo cso, viene stmto un vlore che diende d come i numeri sono rresentti in memori, m tiicmente non è nè 12 è 3. D notre che tutte e tre le situzioni di sor sono ossibili, e non è nemmeno ossibile revedere riori qule delle tre si verific in un cert esecuzione. Il roblem è quindi chiro: i rogrmmi che si scrivono devono comortrsi semre nello stesso modo, e non fre ogni volt un cos divers. Alloczione di memori 1. quli zone di memori si ossono usre (riservte d uso esclusivo del rogrmm) 2. funzione mlloc: dà un zon di memori con queste crtteristiche 3. esemio di crezione di memori er contenere un intero 4. vle ncor l regol che * è un vribile inter, m si uò usre solo se quest zon di memori è stt riservt Un unttore è un vribile che contiene un indirizzo di memori. Finor, bbimo usto i unttori solo er memorizzre in essi le osizioni di ltre vribili. In reltà, è ossibile memorizzre in un unttore un vlore qulsisi. D ltr rte, qundo si us * dove è un unttore, occorre essere certi che l zon di memori untt d si oss utilizzre, ossi: 1. il sistem oertivo ci ermette di ccedere quest zon; 2. il contenuto di quest zon non viene modifict dl rogrmm in modo insettto. L unico modo er relizzre queste due condizioni visto fino d or è stto quello di memorizzre in l indirizzo di un vribile con istruzioni del tio di =&. In questo cso, inftti, si è sicuri che l zon di memori è ccessibile l rogrmm, dto che è l zon di memori di un su vribile; inoltre, non uò venire modifict dl rogrmm, meno che non si fccino delle modifiche su. Esiste erò un ltro meccnismo che soddisf questi due requisiti, ed è quello di chiedere l sistem oertivo di riservre un nuov zon di memori. In ltre role, si chim un funzione che cre un nuov zon di memori e ne restituisce l indirizzo inizile. Quest funzione grntisce che: 21

1. l zon di memori è ccessibile l rogrmm; 2. se si creno nuove vribili (er esemio con un chimt di funzione), non srnno memorizzte in quest zone; 3. ogni nuov chimt ll funzione cre un zon di memori nuov, distint dlle recedenti. Il rimo unto grntisce che il rogrmm uò effettivmente usre queste loczioni di memori. Il secondo e il terzo unto dicono che non ci srnno ltre vribili o ltri unttori che sono ssociti utomticmente ll stess zon di memori. Questo serve grntire che l zon di memori non verrà cmbit insetttmente dll modific di un vribile che non vevmo messo in relzione con quell zon. L funzione che cre un nuov zon di memori si chim mlloc. H un rgomento, che è il numero di byte che l zon d llocre deve contenere. Per esemio mlloc(10) ssegn l rogrmm un nuov zon di memori grnde 10 byte. Il vlore di ritorno di quest funzione è l indirizzo inizile di quest zon. Quindi, mlloc(10), oltre crere un zon di 10 byte, restituisce l indirizzo del rimo di questi byte, cioè l indirizzo iù bsso in quest zon. Il rogrmm lloc.c cre un zon di memori lrg bbstnz d contenere un intero. L indirizzo di ritorno viene ssegnto ll vribile di tio unttore intero. /* Alloczione di memori. */ #include<stdlib.h> int min(void) { int *; =mlloc(sizeof(int)); *=12; (*)++; rintf("* vle %d\n", *); } return 0; 22

Qui ccnto vedimo lo stto inizile dell memori: l vribile unttore non contiene nessun vlore significtivo, e nel rogrmm non sono definite ltre vribili. L rim istruzione del rogrmm è l chimt ll funzione mlloc. In rticolre, l rgomento è sizeof(int), quindi l istruzione =mlloc(sizeof(int)) cre un zon di memori bbstnz grnde d contenere un intero, e l indirizzo inizile di quest zon viene restituito e memorizzto nell vribile unttore. 12A00 zon di memori riservt d mlloc Nell figur si vede lo stto dell memori doo quest chimt: l funzione mlloc h riservto un zon di memori di quttro byte (iotizzimo come semre che un intero è rresentto con quttro byte) er il rogrmm; l vribile contiene l indirizzo dell rim loczione di quest zon. 12A00 23

Possimo or usre l notzione frecci er indicre qule è l indirizzo memorizzto nell vribile. Si ricordi che l notzione con l frecci è semlicemente un trucco grfico er rendere iù chire l figure che rigurdno i unttori, m che quello che in effetti si trov scritto nelle vribili unttore è un indirizzo, ossi un numero, e che l vribili unttore, er il resto, si comortno come tutte le vribili normli. zon di memori riservt d mlloc Un osservzione imortnte: l vribile unttore contiene l indirizzo di un zon di memori grnde qunto bst er contenere un intero. Inoltre, l vribile è di tio unttore intero. Quindi, si uò ncor ensre * come ll vribile inter l cui zon di memori è quell identifict dll unt dell frecci del disegno di sor. Il ltre role, doo ver ftto =mlloc(sizeof(int)), è come se vessimo creto un nuov vribile di tio intero *, che ossimo quindi usre come un qulsisi ltr vribile inter: ossimo er esemio ssegnre d ess un vlore con *=12, incrementrl con (*)++, e stmre il suo vlore con rintf("* vle %d\n", *); (il motivo delle rentesi er (*)++ srà chirito iù vnti). Il unto fondmentle d ricordre è che è ossibile crere un zon di memori si dichirndo un vribile che chimndo l funzione mlloc. In quest ultimo cso, il risultto dell funzione v memorizzto in un unttore. Rissumendo, l regol generle è: se è un vribile unttore intero, llor * è come se fosse un vribile inter. Quest vribile si uò erò usre soltnto se in c è un indirizzo di memori di un zon che si uò usre. Questo vviene soltnto se: l zon di memori è stt riservt con mlloc, oure l zon di memori corrisonde un vribile. Il seguente rogrmm duemlloc.c mostr due ossibili modi di mettere in un vribile unttore degli indirizzi di zone di memori che si ossono usre. /* Alloczione di memori. */ #include<stdlib.h> int min(void) { int *, *q; int ; 24

=mlloc(sizeof(int)); *=12; (*)=(*)+12; q=&; *q=4; (*q)=(*q)+4; rintf("vlori di * e *q: %d e %d\n", *, *q); } return 0; L indirizzo che viene memorizzto in è il vlore di ritorno di mlloc, quindi l indirizzo di un zon di memori che è riservt dll funzione mlloc. Nell vribile q viene invece memorizzto l indirizzo dell vribile. Si noti che quest oerzione f sí che le modifiche *q sino nche modifiche d, dto che l zon di memori è l stess. Risetto ll esemio di rim nomlloc.c, in cui l vribile unttore è indetermint, qui l modific d è revedibile, ed vviene tutte le volte (l cos d evitre è quell in cui il comortmento di un rogrmm diend d vlori inizili non determinti). il vlore NULL Zone di memori inccessibili Si consideri il seguente rogrmm incc.c. Cos viene stmto? #include<stdlib.h> int min() { int *; =mlloc(sizeof(int)); *=12; =mlloc(sizeof(int)); rintf("%d\n", *); } return 0; Per trovre l soluzione roblemi di questo genere, occorre disegnre l evoluzione dello stto dell memori qundo si esegue il rogrmm. Si usno ovvimente dei vlori di esemio er le osizioni di memori, dl momento che i vlori estti vengono determinti solo qundo si esegue il rogrmm. 25

L fingur qui ccnto mostr lo stto dell memori doo l crezione dell vribile: l unic zon di memori ttulmente riservt è quell che corrisonde. Il vlore in ess contenut è tuttor indefinito. eff0b eff11 eff11 eff0b Doo ver effettuto l oerzione di lloczione, viene cret un zon di memori, e il suo indirizzo viene memorizzto in. Lo stto dell memori è quindi come quello qui sinistr. L istruzione *=12 mette il vlore 12 nell zon di memori che er stt lloct. Lo stto dell memori doo quest oerzione è riortto qui destr. 12 eff11 eff11 eff0b 26

A questo unto viene ftt l second mlloc. L regol dell lloczione di memori dice che l zon di memori che viene restituit è un zon che il rogrmm uò usre, e che non è già ust. Quindi, l zon di memori riservt d mlloc non uò essere nè l zon di memori di un vribile nè un zon che è stt già lloct in recedenz. L situzione che si viene crere è quindi che bbimo un second zon di memori riservt, il cui indirizzo inizile viene scritto in. In ltre role, contiene l indirizzo dell zon di memori che è stt lloct con l second chimt ll funzione mlloc. 12 eff16 eff16 eff11 eff0b Cos viene stmto? L istruzione rintf("%d\n", *) stm il contenuto dell zon di memori che è stt lloct dll second chimt ll funzione mlloc. D ltr rte, nessun vlore è stto memorizzto in quest zon. Il vlore che viene stmto diende quindi di vlori inizili dell memori, ossi è indefinito. Quello che vle er le vribili, ossi che il loro vlore è indefinito finchè un vlore non viene memorizzto in esso, continu vlere. Un ltr osservzione imortnte che si uè fre su questo rogrmm è che non è iù ossibile ccedere ll rim zon di memori, quell cret dll rim chimt di mlloc. Inftti, l unico modo er ccedere un zon di memori è quello di conoscere il suo indirizzo, m l indirizzo di quest zon er stto memorizzto in e oi sovrscritto. Il rogrmm non uò quindi sere qule è l indirizzo di quest zon, e non uò quindi ccedere d ess. Si noti che è ossibile ccedere un zon di memori scrivendo nel rogrmm =0xeff11: l indirizzo eff11 è inftti soltnto un vlore di esemio: il vlore di ritorno effettivo dell rim chimt mlloc viene determinto soltnto in esecuzione, e iù esecuzioni dello stesso rogrmm in genere roducono risultti diversi. Tutto questo dice che, se il vlore di ritorno dell chimt mlloc viene erso, non c è iù modo er ccedere ll zon di memori che er stt riservt. Nell rresentzione con freccie, l evoluzione dell memori è l seguente. 27

Crezione dell vribile Doo l rim mlloc 12 12 Doo l istruzione *=12 Doo l second mlloc Pssggio di un unttore un funzione 1. si uò ssre l indirizzo di un vribile un funzione 2. effetti dell modific ) del vlore dell zon di memori untt, e b) del vlore del rmetro formle stesso 3. cos succede in memori 28

L rim liczione dei unttori è quello del ssggio dei rmetri un funzione. Qundo si ss un numero un funzione, quello che succede in effetti è che: 1. si cre un nuov vribile con il nome del rmetro formle; 2. in quest nuov vribile si coi il vlore del rmetro ttule; 3. si esegue il coro dell funzione. Questo signific che, se si chim un funzione ssndo un vribile come rmetro, quello che viene in effetti usto dll funzione è il vlore dell vribile, che viene coito in un zon di memori nuov (il rmetro formle). Se quindi si modific il rmetro formle, queste modifiche vengono ftte nell nuov zon di memori, distint d quell del rmetro ttule. Quindi, il rogrmm che h chimto l funzione non vede le modifiche, semlicemente erchè le modifiche non sono stte ftt in un zon di memori che corrisonde un su vribile. Vedimo or cos succede se si ss un unttore d un funzione. Considerimo il seguente rogrmm ssggio.c, in cui l funzione esemio rende come rmetri un intero e un unttore intero. /* Un funzione che riceve un unttore e un intero. */ #define NULL 0 void esemio(int, int *b) { =12; *b=3; } b=null; int min() { int x; int y; int *z; x=10; y=43; z=&y; rintf("vlori: x=%d y=%d z=%x\n", x, y, z); esemio(x, z); rintf("vlori: x=%d y=%d z=%x\n", x, y, z); } return 0; L funzione esemio f tre cose: cmbi il vlore dell vribile inter =12;, cmbi il vlore dell oggetto untto dl unttore *b=3;, e cmbi nche il vlore del unttore stesso b=null. Comilndo ed eseguendo il rogrmm si ottiene l seguente stm: 29

Vlori: x=10 y=43 z=bffff448 Vlori: x=10 y=3 z=bffff448 Questo signific che i vlori di x e z non sono cmbiti, mentre quello di y sí. Per cire questo comortmento, vedimo lo stto dell memori sso er sso. Stto dell memori rim dell chimt funzione: x, y e z sono tre vribili, ognun ssocit un zon di memori. Il vlore di z è l indirizzo di y. In ltre role, nell vribile z è memorizzt l osizione di memori in cui y inizi. z y 43 x 10 30

Stto dell memori ll inizio dell esecuzione dell funzione. Sono stte crete due nuove vribili e b, in cui sono stti coiti i vlori degli rgomenti con cui è stt chimt l funzione. In questo cso, l funzione è stt chimt con esemio(x,z). Quindi, nell vribile è stto messo il vlore di x, cioè 10. Nell vribile b è stto messo il vlore di z. Si noti che il vlore di z non è 43; il vlore di z è l indirizzo cui è memorizzt l vribile y. Questo vlore viene coito in b, che quindi or contiene l indirizzo dell vribile y. y z 10 43 b x 10 31

12 Durnte l esecuzione dell funzione, viene messo il vlore 12 nell vribile. L second istruzione mette 3 nell zon di memori untt d b. Dl momento che b unt ll zon di memori in cui è memorizzto y, l situzione ll fine delle rime due istruzioni è quell riortt qui ccnto. z b y 3 x 10 32

L ultim istruzione dell funzione mette NULL nel unttore b. All fine dell esecuzione dell funzione l situzione è quindi quell ccnto. A questo unto, l funzione termin e le vribili e b vengono dellocte. Vedimo or cos è successo lle vribili del rogrmm rincile. Le vribili x e z non sono stte cmbite. L unic vribile che h subito un cmbimento è y. L siegzione è or chir: le vribili x e z non sono stte cmbite semlicemente erchè i loro vlori sono stti coiti in e b, e i cmbimenti sono stti ftti sulle zone di memori che corrisondono lle nuove vribili e b. Il vlore di y è invece diverso. Questo vviene erchè l funzione esemio conosce l indirizzo in cui è memorizzt, erchè è quello che st scritto in b (mentre er esemio di x conosce solo il vlore). Se l indirizzo di un vribile è noto, è ossibile cmbire il suo vlore semlicemente con un istruzione *indirizzo=nuovo_vlore;. Questo è esttmente quello che si è ftto con l istruzione *b=3: si mette il vlore 3 nell memori untt d b. Dto che b contiene l indirizzo di y, quest istruzione mette 3 nell vribile y. y z x 12 NULL 3 10 b Si noti che l istruzione *b=3 non lter il vlore di b, m solo quello dell memori untt d b. Le modifiche che vengono oi ftte b (ossi b=null;) sono modifiche un vribile locle di esemio, er cui non vengono viste dl rogrmm rincile. Volendo rissumere, dimo l regol generle sul ssggio dei rmeteri: 1. qundo si ss un vribile, il suo vlore viene coito, er cui le modifiche ftte ll interno dell rocedur non hnno effetto sulle vribili del rogrmm rincile; 2. qundo si ss un indirizzo, l funzione è in grdo di modificre il contenuto dell zon di memori che rte d quell indirizzo; le modifiche sono quindi modifiche zone di memori in cui ci sono vribili del rogrmm rincile. Volendo essere ncor iù rtici, l regol è che se si ss un vribile normlmente llor le modifiche ftte nell funzione non hnno effetto; se si ss un indirizzo con &vribile e oi si us * nell funzione, le modifiche sono viste dl rogrmm rincile. Quest regol si ottiene semlicemente licndo l regol generle di crezione di nuove vribili nelle funzione e il significto dei unttori. È semre bene erò ricordre il erchè le cose funzionno in questo modo, ltrimenti situzioni iù comlesse (er esemio, unttori unttori) otrebbero risultre incomrensibili. 33

Punttori unttori 1. i unttori sono vribili come tutte le ltre 2. quindi, si uò determinre il loro indirizzo 3. differenz fr indirizzo e vlore Abbimo già visto come l indirizzo di un vribile si un numero, che è quindi ossible memorizzre in un vribile. Si è nche visto come il tio di un indirizzo diende dl tio dell oggetto untto. Un vribile di tio unttore è nche ess un vribile, er cui è un zone di memori, er cui si uò trovre il suo indirizzo usndo l oertore &. Per essere recisi, il unttore è un vribile con un tio, er cui il suo indirizzo è (seguendo l regol generle) un unttore un unttore. Per memorizzre er esemio l indirizzo di un unttore intero in un vribile, quest deve essere si tio unttore unttore intero. Questo tio si scrive int **. Il seguente rogrmm untunt.c memorizz in un vribile l indirizzo dell vribile inter, e oi trov l indirizzo di e lo memorizz nell vribile. /* Un esemio di unttore unttore. */ int min() { int ; int *; int **; =9; =&; =&; rintf("indirizzo di =%x, vlore=%x\n", &, ); rintf("indirizzo di =%x, vlore=%x\n", &, ); rintf("indirizzo di =%x, vlore=%x\n", &, ); } return 0; Quello che si ottiene eseguendo il rogrmm è un stm del genere: Indirizzo di =bffff444, vlore=bffff448 Indirizzo di =bffff448, vlore=bffff44c Indirizzo di =bffff44c, vlore=9 A rte il vlore di, tutti gli ltri sono indirizzi, er cui il loro vlore non è noto riori. In un ltr esecuzione del rogrmm si otrebbero ottenere numeri diversi. Quello che erò vle semre è che il vlore dell vribile coincide con l indirizzo dell vribile, e che il vlore di coincide con l indirizzo di. 34

L figur qui ccnto mostr un rresentzione dell memori: contiene l indirizzo di, e su volt contiene l indirizzo di. Dto il vlore di è chiro che è ossibile ccedere l vlore di : bst seguire i unttori, ossi rim trovre il vlore di *, che è l indirizzo di, e questo ermette di trovre il vlore di usndo ncor l oertore *. Quindi, dto, il vlore di si uò trovre con **. 9 In questo modo si uò nche ssgnre un vlore ll vribile usndo : bst usre un istruzione del tio ** =. 35