I puntatori Puntatore Definizione Assegnazione
Transcript
I puntatori Puntatore Definizione Assegnazione
2
Puntatore
I puntatori
Ver. 2.4
E’ una variabile che contiene l’indirizzo di
memoria di un oggetto (variabile o costante)
Esempio
p è un puntatore e “punta”
12
A55
x
alla variabile x che in
...
A54
questo esempio ha indirizzo
...
di memoria A55)
A53
int x=12;
x:A55
...
A52
12
p
A55
A51
...
A50
A55
p
© 2010 - Claudio Fornaro - Corso di programmazione in C
3
Definizione
Sintassi
tipo *nomeVariabile;
Esempi
int *punt;
char x, *p, *q, y;
x e y sono variabili di tipo char
p e q sono variabili di tipo puntatore-a-char
4
Assegnazione
Ad un puntatore si possono assegnare solo
indirizzi di memoria o il valore NULL che indica
che il puntatore non punta a nulla
La costante 0 in un contesto dove è atteso un
puntatore (inizializzazione e assegnamento di
un puntatore, confronto con un puntatore)
viene convertita in NULL dal compilatore
L’operatore di indirizzo ‘&’ (“ampersand”)
calcola l’indirizzo di memoria di una variabile
(si dice che ne restituisce il puntatore)
int *p = &x; inizializza p con l’indirizzo di x
assegna a p l’indirizzo di y
p = &y;
5
Utilizzo
6
Utilizzo
Si accede all’oggetto puntato da un puntatore
per mezzo dell’operatore ‘*’ detto
operatore di deriferimento (“dereference”)
o di indirezione (“indirection”)
int x=12, *p = &x; p “punta a” x
*p = 24;
x ora vale 24
*p += 6;
x ora vale 30
p è il puntatore
*p è l’oggetto puntato (qui è x)
Sia p sia *p sono L-value modificabili, ossia
sono un “qualcosa” (variabile, elemento di
vettore, …) a cui si può assegnare un valore
L’operatore ‘*’ ha priorità superiore a quella
degli operatori matematici
x = 6 * *p; equivale a: x = 6 * (*p);
Per visualizzare il valore di un puntatore si
può utilizzare la direttiva %p in una printf
Si noti che la sintassi per indicare l’oggetto
puntato e quella della definizione del puntatore
sono identiche: *p
7
Tipi e puntatori
L’informazione relativa al tipo è necessaria per
permettere ai puntatori di conoscere la
dimensione dell’oggetto puntato (usata
nell’aritmetica dei puntatori)
Poiché oggetti di tipo diverso possono avere
dimensione diversa, l’assegnazione tra
puntatori di tipo diverso è in genere errata e il
compilatore genera un warning
int *p, x=12;
long *q, y=26;
p = &x; OK!
q = &y; OK!
q = p; NO! Warning
q = &x; NO! Warning
8
Puntatori a void
Sono puntatori generici e non possono essere
dereferenziati (non si può scrivere *p),
possono essere utilizzati solo come contenitori
temporanei di valori di tipo puntatore (a
qualsiasi tipo)
void *h;
Non serve il cast (void *) per copiare un
puntatore non-void in un puntatore void
h = p; (supponendo ad esempio int *p)
Qualsiasi tipo di puntatore può essere
confrontato con un puntatore a void
NULL è definito come: (void *)0
9
Puntatori a void
10
Puntatori e vettori
Per dereferenziare il valore di un puntatore a
void è necessario assegnarlo ad un puntatore
al tipo appropriato (non void) per poter
conoscere la dimensione dell’oggetto puntato
Può essere necessario il cast (tipo *) per
copiare un puntatore void in un puntatore
non-void (i compilatori C non lo richiedono, i
compilatori C++ sì).
In riferimento all’esempio precedente:
int *q;
q = h;
OK, compilatore C
q = (int *)h; OK, compilatore C++
*q = 23;
x ora contiene 23
Il nome (senza parentesi) di un vettore-di-T
è un valore costante di tipo puntatore-a-T,
corrisponde all’indirizzo di memoria del primo
elemento di vettore
int vett[100];
int *p;
p = vett;
l’indirizzo di memoria di vett viene messo in
p, equivale a scrivere: p = &vett[0] (le
parentesi hanno priorità maggiore di &)
11
Puntatori e vettori
Attenzione:
vett = p; NO!
Non si può assegnare un valore a vett in
quanto NON è una variabile puntatore, ma un
“sinonimo” di un indirizzo di memoria
Gli indirizzi di memoria sono valori costanti
stabiliti dal compilatore, non sono variabili e
quindi non hanno uno spazio in memoria
modificabile per contenere un valore
Il termine “puntatore” viene comunemente (e
impropriamente) usato al posto di “indirizzo di
memoria” (es. “&a dà il puntatore ad a”)
12
Equivalenza puntatori e vettori
Una variabile di tipo puntatore-a-T, assegnata
in modo che punti a (cioè contenga l’indirizzo
di) un oggetto di tipo vettore-di-T , può essere
utilizzata come se fosse un vettore-di-T
int vett[25];
int *p = vett;
vett:
p
Ad esempio, qui p[3] equivale a vett[3]
Il compilatore internamente trasforma le
espressioni con notazione vettoriale [] in
espressioni con i puntatori
13
Aritmetica dei puntatori
Aritmetica dei puntatori
Quando un puntatore punta ad un vettore,
gli può essere sommato un valore intero N, il
risultato è l’indirizzo di memoria dell’elemento
di posizione N del vettore
vett:
32
15
23
55
32
14
11
L’istruzione p++ porta p a puntare a vett[1]
(ne contiene l’indirizzo) quindi ora p punta a
vett[1] e p[3] corrisponde a vett[4]
vett:
27
32
p
Equivalenza puntatori e vettori
55
32
11
27
p+3
E’ lecito sottrarre un valore N ad un puntatore
se l’elemento puntato risultante fa ancora parte
del vettore (nell’esempio precedente p-1
punta a vett[0])
15
23
p
p+3
p
punta a (contiene l'indirizzo di) vett
p+3
punta a (produce l'indir. di) vett[3]
*(p+3) equivale a vett[3]
15
Il nome di un vettore può essere utilizzato
come puntatore costante :
*(vett+2) equivale a: vett[2]
vett++
è un errore (vett è costante!)
Il nome di un vettore di T (es. int) che
dovrebbe essere una costante di tipo
puntatore-a-vettore-di-T (o meglio
indirizzo-di-vettore-di-T ), in C “decade” al
tipo puntatore-a-T
Grazie al decadimento vett è visto come
puntatore (costante) a int e punta al suo
primo elemento e vett+1 punta a vett[1]
16
Equivalenza puntatori e vettori
Senza il decadimento, vett+1 punterebbe al
primo byte dopo la fine di vett
Eccezioni:
vett in un sizeof (descritto altrove) non decade
e per questo dà la dimensione dell’intero vettore,
non quella del primo elemento
&vett inibisce il decadimento e produce una
quantità costante di tipo puntatore-a-vettore-di-int
17
Equivalenza puntatori e vettori
Una variabile di tipo puntatore-a-T non “sa”
se il valore (scalare) a cui punta è singolo o è
l’elemento di un vettore, lo sa solo il
programmatore e sta a questi utilizzarlo in
modo coerente
int x = 10, vett[10], *p, *q;
p = &x;
p++; NO! Non esiste l’oggetto puntato da p+1
q = p+1; NO! Idem
p = vett;
p++;
SI’! Ora p punta a vett[1]
q = p+1; SI’! Ora q punta a vett[2]
18
Aritmetica dei puntatori
Attenzione che il puntatore non “sfori” i limiti
del vettore (lo standard non richiede che il
compilatore faccia controlli, molti compilatori
lo offrono opzionalmente, ma ciò riduce le
prestazioni)
E’ lecito che un puntatore punti a quello che
sarebbe l’elemento del vettore successivo
all’ultimo, ma questo puntatore può essere
utilizzato solo per calcolare la differenza tra
puntatori (vedere prossima slide)
19
Aritmetica dei puntatori
Due puntatori a elementi dello stesso vettore
possono essere sottratti, il valore ottenuto +
1 è il numero di elementi del vettore compresi
tra quelli puntati dai due puntatori (inclusi):
p = &vett[4];
q = &vett[10];
d = q-p+1; 7: numero degli elementi
dalla posizione 4 alla
posizione 10 inclusi
Due puntatori possono essere confrontati
solo se fanno parte dello stesso vettore oppure
uno dei due è NULL (o 0)
20
Priorità dell’operatore *
Dalla tabella delle priorità si vede che
l’operatore di deriferimento * ha priorità quasi
massima, inferiore solo alle parentesi (e a ‘->’
e a ‘.’) e associatività da destra a sinistra
Quindi, considerando che gli operatori * e ++
hanno stessa priorità e associatività da D a S:
*p++ equivale a *(p++) incrementa p
*++p equivale a *(++p) incrementa p
++*p equivale a ++(*p) incrementa *p
inoltre:
(*p)++
incrementa *p
*p+1 equivale a (*p)+1 e non a *(p+1)
Copia di stringhe
21
1a versione
3a versione
La stringa y viene copiata in x
char x[30], y[30], *t=x, *s=y;
gets(y);
while ( (*t = *s) != '\0')
{
t++;
s++;
}
printf("%s\n", x);
Il '\0' viene copiato nel ciclo stesso
Nota: != '\0' può essere omesso
22
2a versione
La stringa y viene copiata in x
char x[30], y[30], *t=x, *s=y;
int i=0;
gets(y);
while (s[i] != '\0')
{
t[i] = s[i];
i++;
}
t[i] = '\0';
printf("%s\n", x);
Il '\0' viene copiato fuori dal ciclo
Qui s e t vengono inutilmente usati come
semplici sinonimi di x e y, non come puntatori
Copia di stringhe
Copia di stringhe
23
La stringa y viene copiata in x
char x[30], y[30], *t=x, *s=y;
int i=0;
gets(y);
while ((t[i] = s[i]) != '\0')
i++;
printf("%s\n", x);
Il '\0' viene copiato nel ciclo stesso
Qui s e t vengono inutilmente usati come
semplici sinonimi di x e y, non come puntatori
Nota: non si può scrivere t[i] = s[i++]
nella condizione del while (side effect)
Copia di stringhe
4a versione
La stringa y viene copiata in x
char x[30], y[30], *t=x, *s=y;
gets(y);
while (*t++ = *s++)
;
printf("%s\n", x);
Il '\0' viene copiato nel ciclo stesso
Nota: l‘istruzione nulla è più chiara se scritta
in una riga a sé stante
24
25
Puntatori e stringhe
Puntatori e stringhe
Si noti la differenza tra le seguenti definizioni:
26
char str[100];
RISERVA spazio per contenere i caratteri, è una
variabile e il suo contenuto può essere modificato
char *s;
NON RISERVA spazio per contenere i caratteri,
quindi per essere utilizzata come stringa le si deve
assegnare una stringa “vera”:
Assegnazione di una stringa variabile:
s = str;
scanf("%s", s);
Si considerino i seguenti esempi:
SI’
Assegnazione di una stringa costante:
s = "salve";
scanf("%s", s);
NO
char str[] = "ciao";
E’ l’inizializzazione di una variabile stringa:
il compilatore riserva memoria per str e vi copia i
caratteri di "ciao"; la stringa costante "ciao"
non esiste in memoria: è stata usata dal
compilatore per inizializzare la stringa str, ma
esiste in memoria la stringa variabile "ciao"
str[0]='m'; SI’
char *s = "hello";
E’ l’inizializzazione di una variabile puntatore:
il compilatore determina l’indirizzo della stringa
costante "hello" (che esiste in memoria) e lo
assegna alla variabile puntatore s
s[0]='b';
NO! "hello" è costante!
27
Puntatori e stringhe
Si considerino i seguenti esempi (cont.):
s = "salve";
E’ l’assegnazione ad una variabile puntatore: il
compilatore determina l’indirizzo della stringa
costante "salve" (che esiste in memoria) e lo
assegna alla variabile puntatore s
s[4]='o';
NO! "salve" è costante!
s = str;
E’ l’assegnazione ad una variabile puntatore: il
compilatore determina l’indirizzo della stringa
variabile str (che esiste in memoria) e lo assegna
alla variabile puntatore s
s[0]='m';
SI’
28
Puntatori e stringhe
Noti i puntatori, si possono completare le
informazioni già date sulle funzioni relative
alle stringhe aggiungendo quanto segue:
le funzioni di copia di stringhe strcpy, strncpy,
strcat e strncat restituiscono il puntatore alla
stringa di destinazione
le funzioni di parsing strchr, strrchr, strstr,
strpbrk e strtok restituiscono il puntatore
all’oggetto cercato o NULL se non lo trovano
29
Funzioni sui blocchi di byte
Funzioni sui blocchi di byte
Blocchi di byte: sequenze di byte (caratteri)
qualsiasi, il carattere di codice ASCII 0 ('\0')
è un carattere normale e non viene utilizzato
come terminatore (non c’è alcun terminatore)
Una porzione di memoria (allocata in qualsiasi
modo) viene trattata come generico blocco di
byte da alcune funzioni contenute in
<string.h>
Per riservare una porzione di memoria si può
definire una variabile o una stringa o utilizzare
la funzione malloc (trattata in altre slide)
Nelle seguenti funzioni, s (source) e
t (target ) sono puntatori a blocchi di byte
Puntatori const
31
Puntatore variabile a valore costante
}
30
int const *p;
sono equivalenti
const int *p;
p è una variabile di tipo puntatore-a-costante
(a un oggetto costante di tipo int)
const int x, y;
const int *p; puntatore-a-costante
p = &x; SI’, p è una variabile
p = &y; SI’, p è una variabile
*p = 13; NO, *p è costante
memcpy(t,s,n)
copia n byte da s a t
memmove(t,s,n)
copia n byte da s a t
(i blocchi possono anche essere sovrapposti)
memcmp(s,t,n)
confronta byte per byte secondo il codice
ASCII i primi n byte di s e di t, il valore
restituito è un int come quello della strcmp
memchr(s,c,n)
cerca il byte c tra i primi n byte di s, dà NULL
se non lo trova o il puntatore ad esso se trova
memset(s,c,n)
copia il byte c in tutti i primi n byte di s
Puntatori const
32
Puntatore variabile a valore costante
L’assegnazione di un valore di tipo puntatorea-costante (l’indirizzo di un valore costante) ad
una variabile di tipo puntatore-a-variabile
genera un Warning del compilatore perché
permette di by-passare la restrizione (const)
const int x = 12;
int y = 10;
int *p;
puntatore-a-variabile
const int *q; puntatore-a-costante
p = &x;
Warning
*p = 5;
non dà errore
q = &x;
OK
*p = 5;
dà errore
Puntatori const
33
Esercizi
Puntatore costante a valore variabile
34
int * const p;
p è una costante di tipo puntatore-a-variabile
(a un oggetto variabile di tipo int)
Le costanti possono essere solo inizializzate
int x, y;
int * const p = &x; inizializzazione
*p = 13; SI’, *p è una variabile
p = &y; NO, p è una costante
1.
2.
3.
4.
Si scriva un programma che chieda una
stringa all’utente e conti quanti siano i
caratteri che la costituiscono, NON si usi la
funzione strlen della libreria standard.
Scrivere un programma che verifichi se la
stringa data in input è palindroma o no
Scrivere un programma che chieda n valori
interi (massimo 100), li collochi in un vettore e
inverta il vettore (scambiando il primo
elemento con l'ultimo, il secondo con il
penultimo, etc.). Si usi la notazione vettoriale.
Come il precedente, ma si usino i puntatori.
35
Esercizi
5.
6.
7.
Scrivere un programma che data una stringa
in input dica se la stessa contiene almeno una
‘A’ tra i primi 10 caratteri.
Si scriva un programma che chieda all’utente
2 stringhe e concateni la seconda alla fine
della prima, NON si usi la funzione strcat
della libreria standard, si usino i puntatori e
non la notazione vettoriale. Attenzione a
terminarla con il carattere ‘\0’.
Si scriva un programma che chieda all’utente
2 stringhe e indichi se la seconda è uguale
alla parte terminale della prima.
36
Esercizi
Scrivere un programma che chieda N valori
(massimo 100), li collochi in un vettore e li
ordini in senso crescente (senza usare vettori
ausiliari).
9. Scrivere un programma che verifichi se la
stringa data è composta di due parti uguali,
trascurando il carattere centrale se la
lunghezza è dispari (es. “CiaoCiao”,
“CiaoXCiao”).
10. Scrivere un programma che date 2 stringhe in
input indichi quante volte la più corta è
contenuta nella più lunga.
8.
37
38
Esercizi
Vettori di puntatori
11. Scrivere
un programma che legga da un file
un testo e spezzi su più righe quelle più
lunghe di N caratteri (N chiesto all’utente). Le
righe si possono spezzare solo dove c’è uno
spazio (che non va riportato nella riga
successiva). L’output deve essere salvato in
un altro file.
Gli elementi di questi vettori sono puntatori
int *vett[10];
definisce un vettore di 10 puntatori a int (le
[ ] hanno priorità maggiore dell’operatore *)
Esempio di inizializzazione
int a, b, c;
int *vett[10]={NULL};
vett[0]=&a;
vett[1]=&b;
vett[2]=&c;
I valori da vett[3] a vett[9] sono tutti
NULL in quanto è stato inizializzato il primo
elemento (i successivi sono automaticamente
a 0 e 0 viene convertito in NULL)
39
Vettori di puntatori
Esempio di inizializzazione errata
int a, b, c;
int *vett[10]={&a, &b, &c};
E’ errato perché questi inizializzatori sono
indirizzi di variabili automatiche (descritto in
altre slide). Se le variabili fossero invece di
classe static sarebbe stato corretto, per
queste variabili i valori di vett si devono
assegnare come visto nell’esempio precedente
40
Puntatori a puntatori
Variabili che contengono l'indirizzo di memoria
di un puntatore
Esempio
int a, *b, **c;
a = 12;
b = &a;
c = &b;
Il puntatore c punta ad una variabile (b) che
punta ad un int (a)
a:B4A
b:A5B
c:5D6
A5B
B4A
12
41
Puntatori a puntatori
42
Puntatori e matrici
Esempio
int a=10, b=20, c=30;
int *v[3], int **w;
v[0]=&a; v[1]=&b; v[2]=&c;
w = v;
w++;
v è un vettore di puntatori, cioè è l'indirizzo di
memoria (“puntatore”) di un puntatore, quindi
v+1 è l'indirizzo del secondo puntatore del
vettore v (ossia è pari a &v[1], punta a b)
Anche w è un puntatore ad un puntatore,
quando viene incrementato, punta al
puntatore successivo, come v
Una matrice è un vettore di vettori e quindi,
considerando che l’associatività di [] è da
sinistra a destra, si ha che:
int Mx[7][5];
definisce un vettore di 7 elementi
ciascuno delle quali è un vettore di 5 int
Gli elementi del vettore Mx sono i 7 vettori
identificati da Mx[i]; quindi Mx[i] è l’indirizzo
di memoria di ciascuno dei 7 vettori di 5 int
Poiché in seguito al decadimento il nome di un
vettore-di-T ha tipo puntatore-a-T, anche gli
Mx[i] non sono di tipo vettore-di-int ma
decadono al tipo puntatore-a-int, (essendo
indirizzi, non si può assegnare loro un valore)
43
Puntatori e matrici
Il “decadimento” del tipo del nome di un
vettore a puntatore può avvenire 1 sola volta
Allora il tipo di una matrice decade a
puntatore-a-vettore-di-T e non a puntatore-aT (quindi incrementando questo puntatore si
punta al vettore di 5 int successivo)
Mx non è di tipo puntatore-a-int come:
int *p
Mx non è di tipo puntatore-a-puntatore-a-int:
int **p
Mx è di tipo puntatore-a-vettore-di-5-int
come: int (*p)[5]
quindi Mx+1 punta al secondo vettore di 5 int
44
Puntatori e matrici
Nella definizione di puntatore seguente
int (*p)[5]
è necessario che la dimensione delle colonne
(5) sia specificata perché definisce un
puntatore-a-vettore-di-cinque-interi
Poiché Mx è un puntatore-a-vettore-di-5-interi
(e non un puntatore ad un intero), allora:
Mx+1 punta all’elemento successivo, ossia al
successivo vettore di 5 interi (la seconda riga
della matrice): Mx+1 aggiunge all’indirizzo di
Mx il numero corretto di byte per puntare al
secondo vettore di 5 int
45
Puntatori e matrici
Puntatori e matrici
Ricapitolando:
46
Mx[1][2]
è un valore scalare
è di tipo int
è modificabile
Mx[1][2]+1 somma 1 al contenuto di Mx[1][2]
Mx[1]
è l’indirizzo di un vettore di 5 int
è di tipo puntatore-a-int (“decade”)
Ricapitolando (continuazione):
Mx
non è modificabile
Mx[1]+1 punta a Mx[1][1]
è l’indirizzo di un vettore di 7 vettori di 5 int
è di tipo puntatore-a-vettore-di-int (“decade
una volta sola”), più precisamente è un
puntatore-a-vettore-di-5-int (senza il 5 nel tipo
il compilatore non saprebbe di quanti byte
spostarsi per puntare al vettore-di-5-int
successivo quando si scrive Mx+1)
non è modificabile
Mx+1 è l’indirizzo di memoria di Mx[1]
47
Puntatori e matrici
Si notino le differenze tra:
int *p;
puntatore-a-int
int (*q)[5]; puntatore-a-vett-di-5-int
Poiché Mx è un puntatore-a-vettore-di-5-int:
p = Mx;
è errata
q = Mx;
è corretta e q+1 è l’indirizzo del secondo vettore di
5 elementi (equivale a Mx[1])
p = &Mx[0][0];
è corretta e p è l’indirizzo del primo elemento dei
Mx[0]
48
Vettori di stringhe
Essendo una stringa un vettore di caratteri,
un vettore di stringhe è in realtà un vettore di
vettori di caratteri, cioè una matrice di char
char str[4][20]={"uno", "due"};
definisce un vettore di 4 stringhe di 20 char
Le 4 stringhe sono identificate da str[i]
str:
str[0] u n o \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
str[1] d u e \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
str[2]\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
str[3]\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
49
Vettori di puntatori e matrici
Vettori di puntatori e matrici
Si notino le differenze tra:
char a[4][8]={"un","otto","sei"};
char *b[4]={"un","otto","sei"};
a:
b:
un\000000
otto\0000
sei\00000
\00000000
50
un\0
otto\0
NULL
a[2] = "hello";
ERRORE: a[2]non è un puntatore
strcpy(a[2], "hello");
CORRETTO
b[2] = "hello";
CORRETTO: b[2] è una variabile puntatore a cui
viene assegnato l’indirizzo di memoria di una stringa
costante
sei\0
a[i]è l’indirizzo costante della riga i di a, tale
riga è una stringa variabile di 8 char
b[i] è una variabile puntatore con l’indirizzo
della riga i, stringa costante di 4 caratteri: ad
esempio b[2] contiene l’indirizzo di "sei\0"
strcpy(b[2], "hello");
ERRORE: b[2] punta a una stringa costante
Entrambi a[1][0] e b[1][0] sono il carattere 'c'
a[1][0]='m'; SI’! L’oggetto puntato da a[1] è una
b[1][0]='m'; NO! L’oggetto puntato da b[1] è una
stringa variabile
stringa costante
51
52
Const per puntatori a puntatori
Const per puntatori a puntatori
1.
2.
3.
int** x;
x è una variabile di tipo puntatore
a un puntatore variabile
a un oggetto variabile di tipo int
const int** x;
x è una variabile di tipo puntatore
a un puntatore variabile
a un oggetto costante di tipo int
int ** const x;
x è una costante di tipo puntatore
a un puntatore variabile
a un oggetto variabile di tipo int
4.
5.
6.
int * const * x
x è una variabile di tipo puntatore
a un puntatore costante
a un oggetto variabile di tipo int
const int * const * x
x è una variabile di tipo puntatore
a un puntatore costante
a un oggetto costante di tipo int
const int * const * const x
x è una costante di tipo puntatore
a un puntatore costante
a un oggetto costante di tipo int
53
Homework 7
Scrivere un programma che legga da un file al
massimo un certo numero MAXRIGHE di righe di
testo e le memorizzi in una matrice di caratteri
(MAXRIGHE x 100), una riga del file per
ciascuna riga della matrice.
Si definisca un vettore di puntatori a carattere e
lo si inizializzi in modo che il primo puntatore
punti alla prima riga, il secondo alla seconda,
ecc. Si ordinino le stringhe scambiando tra di
loro solo i puntatori e le si visualizzino ordinate.
Facoltativo: misurare il rapporto tra il tempo
necessario per ordinare scambiando le stringhe
e scambiando i puntatori.
54
Homework 7 (esempio)
prima
Nel mezzo del cammin di nostra vita
mi ritrovai per una selva oscura
ché la diritta via era smarrita.
Ahi quanto a dir qual era è cosa dura
esta selva selvaggia e aspra e forte
dopo
Nel mezzo del cammin di nostra vita
mi ritrovai per una selva oscura
ché la diritta via era smarrita.
Ahi quanto a dir qual era è cosa dura
esta selva selvaggia e aspra e forte
• a cui il sistema operativo permette di accedere
• che non viene modificata inaspettatamente
Finora abbiamo visto un modo per soddisfare questi requisiti: assegnare ad un
puntatore l’indirizzo di ...