Università dell’Insubria
Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese
Corso di Laurea in Informatica
Anno Accademico 2004/05
Laboratorio di Linguaggi
lezione IV
Marco Tarini
Laboratorio di Linguaggi
• docente: Marco Tarini
e-mail: [email protected]
• ricevimento: Martedì 14:30 - 17:30
o anche su appuntamento
• libro di testo consigliato:
Kelley Al, Pohl Ira:
"C Didattica e Programmazione" ("A Book on C")
quarta edizione - anche la terza va bene
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: operazioni a basso livello
Esercizio:
un numero in
virgola mobile
a doppia precisione
di solito, ma dipende
dall'implementazione
• Sappiamo che un double occupa 8 bytes.
• Dato un double, quale è il valore di questi 8
bytes?
• Per esempio, quali 8 bytes compongono il
valore 3.14159256 ?
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: operazioni a basso livello
• A casa, provate questo programma, e scopriamo:
– quali sono gli 8 bytes che compongono il double 3.14159256
– quali sono gli 8 bytes che compongono il double 6.022 x 1023
• e, adattando il programma agli interi:
– quali sono i 4 bytes che compongono l'int +1000000
– quali sono i 4 bytes che compongono l'int +1
– quali sono i 4 bytes che compongono l'int -1
• a seconda di quale architettura viene usata, potremmo
trovare risposte diverse!
– domanda: sarebbe potuto succedere in Java?
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori
• Molto potenti...
– vettori di dimensione determinata dinamicamente
– passaggio di parametri per riferimento
• in un linguaggio che prevede passaggio solo per copia
– possibilità di scrivere codici più efficienti
– controllo diretto delle risorse, a basso livello
– strutture dati flessibili
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori
• Molto potenti...
"Ad un grande potere corrisponde una
grande responsabilità."
– lo zio di Spiderman
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: pasticci
• memory leak
(“falla di memoria”)
int una_funzione ()
{
int *un_puntatore;
/* alloco un vettore di 100 interi */
un_puntatore = (int*)calloc( 100, sizeof(int));
/* uso il vettore */
...
/* fine della funzione */
return 0;
}
Manca la deallocazione! ( free(un_puntatore); )
All'uscita della funzione il puntatore "un_puntatore" è perso per sempre, e
con lui la possibilità di liberare ("sprenotare", per così dire) la memoria.
Ogni volta che si accede a questa funzione, si perdono (leak) 100x4 bytes di
memoria
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: pasticci
• un altro caso di memory leak
...
int *un_puntatore;
/* alloco un vettore di 100 interi */
un_puntatore = (int*)calloc( 100, sizeof(int));
/* uso il vettore */
...
/* rialloco un altro vettore */
un_puntatore = (int*)calloc( 100, sizeof(int));
Manca la deallocazione! ( free(un_puntatore); )
Anche qui, il puntatore "un_puntatore" è perso per sempre, e
con lui la possibilità di liberare ("sprenotare", per così dire) la memoria.
Ogni volta che si accede a questa funzione, si perdono (leak) 100x4 bytes di
memoria
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: pasticci
• un altro caso di memory leak
...
int *un_puntatore, i;
/* alloco un vettore di 100 interi */
un_puntatore = (int*)calloc( 100, sizeof(int));
/* uso il vettore */
...
/* rialloco un altro vettore */
un_puntatore = &i;
Manca la deallocazione! ( free(un_puntatore); )
Anche qui, il puntatore "un_puntatore" è perso per sempre, e
con lui la possibilità di liberare ("sprenotare", per così dire) la memoria.
Ogni volta che si accede a questa funzione, si perdono (leak) 100x4 bytes di
memoria
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: pasticci
• stale pointer (“puntatore andato a male”)
/* funzione che restituisce un puntatore ad un
intero */
int* una_funzione ()
{
int *punt;
int x=10;
...
return &x; /* restituisci il puntatore
che punta alla variabile x */
}
la variabile x non sopravvive al termine della funzione!
l'indirizzo di memoria &x non è più valido allora!
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: pasticci
• dereferenced NULL
int *punt = NULL;
* punt = 10;
Errore, ma nessun disastro,
il sistema se ne accorge in run time (hopefully)...
L’esecuzione terimina (con un segmentation fault)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: pasticci
• dangling pointers
(puntatori penzolanti)
int *punt ;
* punt = 10;
chissà in che locazione verrà scritto quel dieci...
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: pasticci
• overrun screw
(indicizzare oltre i boundaries)
int *punt = (int*) calloc(5,sizeof(int));
punt[5] = 10;
chissà in che locazione verrà scritto quel dieci...
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: pasticci
• overrun screw
(indicizzare oltre i boundaries)
int punt[ 5 ];
punt[5] = 10;
chissà in che locazione verrà scritto quel dieci...
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: pasticci
• fandango on core
(andare con un puntatore oltre i boundaries)
int *punt = (int*) malloc(sizeof(int));
*
punt[5]
punt
++; = 10;
* punt = 10;
chissà in che locazione verrà scritto quel dieci...
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: pasticci
• uso dopo deallocazione
int *punt = (int*) calloc(10,sizeof(int));
...
free(punt);
* punt = 10;
chissà in che locazione verrà scritto quel dieci...
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: pasticci
• altro errore comune ...
/* funzione che restituisce un puntatore ad un intero
*/
int* una_funzione ()
{
int x;
x=10;
...
free( &x ); /* libera la memoria usata da x (?) */
}
le variabili allocate staticamente (in maniera automatica)
vengono anche disallocate automaticamente alla fine del blocco!
regola d’oro:
free va usato solo con i puntatori restituiti da malloc / calloc
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Puntatori: pasticci
• altro errore comune : aliasing bug
...
int *x, *y;
/* alloco px */
x= (int*) malloc(sizeof(int));
/* assegno y = x. Ora x e y puntano allo stesso
blocco di memoria */
y = x;
/* uso x */
...
/* libero x */
free( x );
/* uso y */
*y = 10;
medicina: meglio usare un solo puntatore per ogni blocco di memoria allocato
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Ripasso costrutti base:
Istruzioni di Controllo del Flusso
nozioni di
sintassi e semantica
(intuitivamente, non formalmente)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
if then else
• costrutto condizionale
if (<expression>)
<statement1>
else <statement2>
Come gia’ detto,
esegue statement1 (il ramo then)
sse l’espressione risulta diversa da zero
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
<statement>
• Esempi di <statement>s:
y = x + 10;
nota: punto e virgola...
{
y = x + 10;
z = 4;
};
niente punto-e-virgola!
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
if then else
• costrutto condizionale
if (<expression>)
<statement1>
else <statement2>
if (x) y = x + 10; else y = 20;
if (x==2) {y = x + 10; ... }
else y = 20;
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Lo sapevate che...
• In C, quasi tutti gli statement sono anche espressioni?
• Ad esempio, l’assegnamento
x = y
e’ anche un’espressione, che vale il valore assegnato
(e ha anche il suo tipo)
• Cio’ consente di scrivere, per esempio:
int x,y,z;
x = y = z = 10 ;
(non solo e’ coinciso, ma e’ anche efficiente,
come da filosofia C)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
if then else: trappole
• errore di sintassi (non compila, innocuo)
if (x==2) {y = x + 10; ... };
else y = 20;
• errore nella guardia (compila: errore “cattivo”. Cosa fa?)
if (x=2) { y = x + 10; ... };
• punto-e-virgola di troppo
(compila: errore “cattivo”. Cosa fa?)
if (x==2); { y = x + 10; ... };
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
for
• costrutto iterativo
for (<expr0>;<expr1>;<expr2>) <stat>
for (i=0,j=10;(j>20) &&(i<5);
i++, j--) {
vect[i]+=10;
printf(“%d”, vect[i]);
}
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
while
• ciclo while
while (<expr0>) <stat>
while (i<N && a[i]< 1000) i = i + 1;
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
do while
• ciclo do-while
do <stat> while (<expr0>)
do
{
printf("Immettere un valore intero pari\n");
scanf("%d",&a); /* leggi il numero a da tastiera */
}
while(a%2);
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
switch
• costrutto condizionale a più vie
switch (<expr0>) {
case <const1>: <stat1> break;
...
case <const2>: <stat2> break;
}
switch (ch){
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
default :
}
cont_a++; break;
cont_e++; break;
cont_i++; break;
cont_o++; break;
cont_u++; break;
cont_car++;
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
switch
• senza break: fall trought
switch (oggi){
case LUN: ... /* gestisci il caso LUN */
break;
case MAR: ... /* gestisci il caso MAR */
break;
case SAB: ... /* operazioni solo per il SAB */
/* FALL TROUGHT */
case DOM: ... /* gestisci per il SAB e la DOM */
break;
default : ... /* gestisci gli altri casi */
}
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
labels e goto
• salti non strutturati
– di solito, simbolo di cattiva programmazione
• (programmi spaghetti)
– perlomeno, non eleganti
<label>:
goto <label>;
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
labels e goto
• ad esempio:
i=0;
while (i <= NUM)
printf("%d \n",++i);
...
• equivalente a:
i=0;
INIZIO : if (i>NUM) goto FINE;
printf("%d \n",++i);
goto INIZIO;
FINE :
...
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
break e continue
• utilizzabili in tutti i cicli
– for, while, do-while
• break
= esci dal ciclo
– (vai alla prima iterazione dopo il ciclo)
• continue = interrompi l’iterazone corrente
– vai all’inizio della prossima iterazione
– (dove, per prima cosa, la guardia di uscita dal ciclo viene testata)
Marco Tarini ‧ Laboratorio di Linguaggi ‧
2004/05 ‧ Università dell’Insubria
Scarica

lucidi