Corso di Programmazione 1
a.a.2006/2007
Prof.ssa Chiara Petrioli
Corso di Laurea in Informatica
Università degli Studi “La Sapienza”
(lezioni 12-15)
Puntatori e ricorsione
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Puntatori
I puntatori sono delle variabili che come
valore contengono
deglidevono
indirizzi
Variabili di tipo puntatore
essere di
e inizializzate
memoriadichiarate
Es.
int * countPtr; /*dichiarazoine*/
int count;
float * fcountPtr;
Il nome di una variabile intera (es. count) fa
count contiene
un _valore_
intero
direttamente
riferimento ad
un valore intero;
countPtr = &count; /*inizializzazione*/
Una variabile puntatore fa indirettamente riferimento
fcountPtr=NULL;
int *countPtr;
ad un valore intero (deriferimento).
/*NULL è una costante simbolica predefinita
In molti file
di intestazione
incluso stdio.h.
Se
 La variabile
countPtr
contiene
l’indirizzo
una variabile puntatore è inizializzata a NULL non
di una locazione
memoria
che contiene
punta ad alcunadi
locazione
di memoria*/
un valore intero.
5
2340
countPtr
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
2340
Operatore di indirizzo
& (operatore unario di indirizzo) restituisce
l’indirizzo di memoria associato al suo
operando;
int y=5;
int *yPtr;
yPtr=&y;
3200
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
5
y
Operatore di indirizzo
& deve essere
applicato ad una
variabile. Non
& (operatore unario
di indirizzo)
restituisce
Può essere applicato a costanti, espressioni o
l’indirizzo di amemoria
associato
al suo
variabili dichiarate
con la specifica
di classe
di memoria register
operando;
int y=5;
int *yPtr;
yPtr=&y;
5
3200
3200
y
yPtr
Viene allocata memoria per la variabile puntatore
yPtr. Nella locazione di yPtr viene memorizzato
Prof.ssa Chiara
Petrioli -- corsoassociato
di
l’indirizzo
di memoria
alla variabile y
programmazione 1, a.a. 2006/2007
Operatore di deriferimento
L’operatore * (detto operatore di
deriferimento o di risoluzione dell’indirizzo)
consente di accedere al valore contenuto
nella locazione di memoria puntata da una
variabile puntatore
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Operatore di deriferimento
L’operatore * (detto operatore di
deriferimento o di risoluzione dell’indirizzo)
consente di accedere al valore contenuto
nella locazione di memoria puntata da una
variabile puntatore
*yPtr è il valore contenuto nella
locazione di memoria il cui
indirizzo è memorizzato in yPtr
3200
5
5
3200
yPtr
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
y
Esempio
La specifica di conversione %p
di printf consente di stampare
in output indirizzi di locazioni di
memoria
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Esempio
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Precedenza degli operatori
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Chiamata per riferimento delle
funzioni
Come può essere realizzata in C?
Se vogliamo poter modificare il contenuto
di una variabile x con cui invochiamo una
funzione e far sì che tali modifiche
permangano anche all’uscita dalla
funzione possiamo usare come parametro
formale un puntatore (quindi passare lalla
funzione l’indirizzo di x)…
Un esempio..
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Esempio
/*eleva al cubo una variabile usando una chiamata per
valore*/
#include <stdio.h>
int cubeByValue(int);
main()
{
int number =5;
printf(“Il valore originale del numero è: %d\n”,number);
number=cubeByValue(number);
printf(“il nuovo valore del numero è: %d\n”,number);
return 0;
}
int cubeByValue(int n)
Il valore originale del numero è: 5
Il nuovo valore del numero è: 125
{
return n*n*n;
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
}
Cosa succede in memoria…
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Cosa succede in memoria…
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Cosa succede in memoria…
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Esempio 2
/*eleva al cubo una variabile usando una chiamata per
riferimento*/
#include <stdio.h>
void cubeByReference(int *);
main()
{
int number =5;
printf(“Il valore originale del numero è: %d\n”,number);
cubeByReference(&number);
printf(“il nuovo valore del numero è: %d\n”,number);
return 0;
}
void cubeByReference(int *nPtr)
Il valore originale del numero è: 5
Il nuovo valore del numero è: 125
{
*nPtr=(*nPtr)*(*nPtr)*(*nPtr);
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
}
Cosa succede in memoria…
int number=5;
cubeByReference(&number);
number
5
6200
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Cosa succede in memoria…
int number=5;
cubeByReference(&number);
number
6200
5
Viene copiato in nPtr il valore
dell’argomento con cui è stata
invocata la funzione
&number OVVERO l’indirizzo
della locazione di memoria della
variabile number OVVERO 6200
Invochiamo la funzione cubeByReference
6200
Viene allocata memoria
per la variabile puntatore
nPtr
void cubeByReference(int *nPtr)
{
*nPtr=(*nPtr)*(*nPtr)*(*nPtr);
}
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Cosa succede in memoria…
int number=5;
cubeByReference(&number);
number
5
6200
*nPtr è il valore contenuto
nella locazione di memoria
puntata da nPtr
5
L’istruzione quindi dice di
elevare al cubo 5 e di memorizzare
il valore risultante nella locazione di
memoria puntata da nPtr
Invochiamo la funzione cubeByReference
6200
Si esegue l’istruzione
*nPtr=(*nPtr)*(*nPtr)*(*nPtr);
void cubeByReference(int *nPtr)
{
*nPtr=(*nPtr)*(*nPtr)*(*nPtr);
}
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Cosa succede in memoria…
int number=5;
cubeByReference(&number);
number
125
5
6200
L’istruzione quindi dice di
elevare al cubo 5 e di memorizzare
il valore risultante nella locazione di
memoria puntata da nPtr
Il cubo di 5 è 125
Invochiamo la funzione cubeByReference
6200
void cubeByReference(int *nPtr)
{
*nPtr=(*nPtr)*(*nPtr)*(*nPtr);
}
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Cosa succede in memoria…
int number=5;
cubeByReference(&number);
printf(“il nuovo valore del numero è:
%d\n”,number);
return 0;
number
125
5
Si stampa il valore di number
 125
6200
Si ritorna il controllo al main che esegue
la prossima istruzione
6200
La memoria allocata per
nPtr viene rilasciata
void cubeByReference(int *nPtr)
{
*nPtr=(*nPtr)*(*nPtr)*(*nPtr);
}
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Cosa succede in memoria…
Passaggio per valore evita di compromettere i valori delle variabili
con cui sono invocate le funzioni (spesso non si vogliono modificare
tali valori)
Passaggio parametri per riferimento evita di dover allocare, ad ogni invocazione
di funzione, memoria per copiare quantità di dati di input grandi che possono
dover essere passati alla funzione
esempio: se la funzione ha come input un vettore abbiamo bisogno
solo di un parametro di tipo puntatore in cui copiare la locazione di
memoria associata al primo elemento del vettore
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Qualificatore const
Consente di specificare che il valore di una
particolare variabile NON dovrà essere
modificato
Il compilatore intercetterà qualsiasi tentativo di
modificare una variabile che sia stata dichiarata
const e, nel caso in cui tale variabile sia
modificata, darà un errore o un warning.
 serve a proteggere da errori
nell’implementazione del codice rendere più
facile il debugging
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Modi di passare un puntatore a una
funzione
‘Puntatore variabile a dati variabili’
– i dati possono essere modificati attraverso il
puntatore
– Il valore della variabile puntatore potrà essere
modificato in modo che il puntatore possa fare
riferimento ad altri dati
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Esempio
#include <stdio.h>
void convertToUppercase (char *);
main()
{
char string[ ]=“caratteri”;
printf(“la stringa prima della conversione è %s\n”,string);
convertToUppercase(string); /*converte le lettere minuscole della stringa in
maiuscole*/
printf(“dopo la conversione la stringa è %s\n”,string);
return 0;
}
void convertToUppercase(char *s)
{
Vengono modificati i caratteri della
while (*s != ‘\0’)
Stringa.
{
s punta a caratteri diversi della stringa
if (*s >= ‘a’ && *s<= ‘z’)
durante l’esecuzione della funzione
*s-=32;
++s;
}
La stringa prima della conversione è:pippo
}
Prof.ssaDopo
Chiara Petrioli
-- corso di
la conversione
la stringa è PIPPO
programmazione 1, a.a. 2006/2007
Altri casi…
Puntatore variabile a dati costanti (i dati non possono essere
modificati)
#include <stdio.h>
void printCharacters (const char *);
main()
{
char string [ ]=“stampa i caratteri”;
printf (“la stringa è:\n”);
printCharacters (string);
putchar(‘\n’);
return 0;
}
void printCharacters(const char *s)
{
for (;*s!=‘\0’;s++)
putchar(*s);
}
la stringa è:
Prof.ssa Chiara Petrioli -- stampa
corso di
i caratteri
programmazione 1, a.a. 2006/2007
Altri casi…
Puntatore costante a dati variabili
– il puntatore fa sempre riferimento alla stessa
locazione di memoria
– Tramite il puntatore si può cambiare il valore della
locazione di memoria
int *const ptr;
Puntatore costante a dati costanti
– il puntatore fa sempre riferimento alla stessa
locazione di memoria
– Il valore della locazione di memoria non può essere
modificato
const int *const ptr;
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Esempio
#include <stdio.h>
main ()
{
int x=5,y;
const int *const ptr=&x;
Cannot modify a const object
*ptr=7;
Cannot modify a const object
ptr=&y;
return 0;
}
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Bubblesort (versione 2)
#include <stdio.h>
#define SIZE 10
void bubbleSort(int *,const int);
void swap (int *,int*);
main()
{
int i,a[SIZE]={2,6,4,8,10,12,89,68,45,37};
printf(“ordine originale \n”);
for (i=0;i<=SIZE-1;i++)
printf(“%d”,a[i]);
bubbleSort (a,SIZE);
printf(“dati in ordine crescente \n”);
for (i=0;i<=SIZE-1;i++)
printf(“%d”,a[i]);
printf(“\n”);
return 0;
}
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Bubblesort
void bubbleSort(int *array, const int size)
{
int pass,j;
for (pass=1;pass <=size-1;pass++)
for (j=0;j<=size-2;j++)
if(array[j]>array[j+1])
swap(&array[j],&array[j+1]);
}
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Swap
void swap (int *element1Ptr, int
*element2Ptr)
{
int temp;
temp=*element1Ptr;
*element1Ptr=*element2Ptr;
*element2Ptr=temp;
}
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Prof.ssa Chiara Petrioli -- corso di
programmazione 1, a.a. 2006/2007
Scarica

LEZ_11_temp - TWiki