Sei sulla pagina 1di 30

1

TUTORATO di LINGUAGGI 1
dott. Enrico Vianello

martedì 19 ottobre 2010


TUTORATO di LINGUAGGI I 2
informazioni utili i puntatori

Docente: dott. Enrico Vianello


Orario: il MARTEDI’ dalle 11.30 alle 13.30
Aula: INFO 1

Materiale: per ricevere:


• IL MATERIALE UTILIZZATO DURANTE LE LEZIONI
(DISPENSE, ESERCIZI, ...)
• AVVISI DI CAMBIO DI ORARIO/RINVIO DELLE LEZIONI
inviare una e-mail all’indirizzo:
enrico.vianello@student.unife.it
con oggetto:
TUTORATO DI LINGUAGGI 1

per accedere alla propria casella di posta:

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 3
informazioni utili i puntatori

PROGRAMMA
RIPASSO linguaggio C PUNTATORI
STRINGHE INPUT/OUTPUT
STRUTTURE DATI FILE
LISTE
TABELLE HASH ALBERI
STACK
AD & ADT
esercizi in preparazione allo scritto
correzione esercizio d’esame

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
4

I PUNTATORI
nel linguaggio C

lezione #1

martedì 19 ottobre 2010


TUTORATO di LINGUAGGI I 5
informazioni utili i puntatori

PREMESSA

• Dichiarare una variabile significa riservare una zona di


memoria composta da diverse celle

• Il numero di celle dipende dal tipo di dato (int 2 byte,


float 4 byte, …)

• Ogni cella di memoria ha un indirizzo fisico e:

– il nome della variabile indica il contenuto della cella di


memoria

– l’operatore & permette di ottenere l’indirizzo di memoria della


cella associata alla variabile cui l’operatore è applicato

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 6
informazioni utili i puntatori

VARIABILI E INDIRIZZI

int var 1
&var 2
3 var
4

• Supponiamo che la dichiarazione riservi la zona di memoria


all’indirizzo 3
• var indica il contenuto della cella di memoria
• &var indica l’indirizzo della cella di memoria

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 7
informazioni utili i puntatori

PUNTATORE

int var 1
&var 2
3 var
4

• È un tipo di dato che ammette tra i suoi valori un indirizzo di memoria


– La zona di memoria viene detta “puntata” dalla variabile puntatore
– La variabile puntatore viene detto che “punta” ad una cella di memoria

• Quando dichiaro un puntatore devo anche specificare che tipo di dato


viene ospitato nella cella puntata

• Sintassi:
int *p;

• Una variabile puntatore occupa solitamente 2 byte o 4 byte a seconda


delle architetture

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 8
informazioni utili i puntatori

SIGNIFICATO

int *p &p
1
2
3 p
4

• p è una variabile come tutte le altre quindi


– p indica il contenuto della cella di memoria
– &p indica l’indirizzo di memoria che contiene il puntatore

• Quello che caratterizza una variabile di tipo puntatore è il fatto che il


suo valore è esso stesso un indirizzo di memoria

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 9
informazioni utili i puntatori

DEFERENZIAZIONE

• Ad una variabile di tipo puntatore posso applicare l’operatore di


deferenziazione *

• *p indica il contenuto della cella puntata da p

• Se p è un puntatore ad un intero allora *p è una semplice


variabile intera

int *p;

*p=5; /* OK. *p è un intero */


p=5; /* errore. p è un puntatore */

• Attenzione! Il simbolo * lo uso


sia nella dichiarazione che nella
deferenziazione

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 10
informazioni utili i puntatori

VALORIZZAZIONE DI UN PUNTATORE

• Un puntatore non può assumere qualunque valore


- Essendo il suo valore un indirizzo di memoria deve puntare ad
una zona ammessa
- Un programma può accedere solo alle celle di memoria di sua
competenza

mappa della memoria

Quando eseguiamo un programma il sistema operativo gli dedica una


parte della memoria disponibile.

Questo blocco è diviso in quattro parti:


■ Il segmento di codice (il programma vero e proprio)
■ Il segmento dati (tutte le variabili che sono fuori da ogni funzione)
■ Lo stack dati (serve ad es. per il passaggio dei parametri alle
funzioni)
■ Lo heap (una zona di memoria "libera" che può essere richiesta dal
programma tramite le funzioni di allocazione dinamica - malloc).

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 11
informazioni utili i puntatori

VALORIZZAZIONE DI UN PUNTATORE

• Ad un puntatore è quindi possibile assegnare:


- L’indirizzo di una variabile attraverso l’operatore &
- Il valore null
- L’indirizzo di una zona di memoria appositamente creata con la
funzione malloc

&x 1 5 x
int x;
int *p; &p 2
x=5; 3 1 p
p=&x; /* *p vale 5 */ 4

• Ad una variabile puntatore non viene mai assegnata


una costante!

Al momento della dichiarazione un puntatore punta a NULL:


- NULL è una parola chiave del C che indica una zona di memoria non
significativa
p null

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 12
informazioni utili i puntatori

malloc()

• Nella libreria <mem.h> è definita la funzione malloc


– Riceve in ingresso la dimensione in byte della cella puntata
– Crea una zona di memoria nello heap
– Restituisce il puntatore alla zona di memoria creata
void *malloc(size_t size);

int *p; heap


*p = 30
p=malloc(sizeof(int));
*p=30;
free(p);
stack
p
void free(void *pointer);

QUANDO SI USA?
La variabile puntatore è utile:
– Per il passaggio dei parametri tra sottoprogrammi
– Nella gestione delle strutture dati dinamiche (liste, alberi)

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 13
informazioni utili i puntatori

PUNTATORE A TIPI COMPLESSI struct

• È possibile dichiarare un puntatore anche a tipi di dati complessi


come le struct :
typedef struct {
int giorno,mese,anno;
typedef struct { }Data;
char cognome[30];
char nome [30];
Data data_di_nascita;
char codice_fiscale [12];
} dati_anagrafici;

dati_anagrafici *p;

• Accesso ai campi della struttura. Due notazioni equivalenti:


(*p).data_di_nascita.giorno
(*p).cognome[0]

• oppure
p->data_di_nascita.giorno
p->cognome[0]

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 14
informazioni utili i puntatori

EFFETTI COLLATERALI
• Quando due puntatori puntano alla stessa cella di memoria
possiamo avere una modifica non voluta della variabili puntate:

int *p,*q;
int x,y;

p=&x;
q=&y;

*p=3; /*x vale 3*/


*q=5; /*y vale 5*/

p=q; /*p punta a y*/


*q=7; /*anche p vale 7*/

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 15
informazioni utili i puntatori

PUNTATORI ED ARGOMENTI A FUNZIONE

• il C passa alle funzioni gli argomenti per valore

void scambia(int x, int y)


{
int temp;

temp = x;
x = y;
y = temp;
}
• la chiamata scambia(a,b) , con a e b variabili intere
correttamente inizializzate, funziona?

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 16
informazioni utili i puntatori

PUNTATORI ED ARGOMENTI A FUNZIONE

• il C passa alle funzioni gli argomenti per valore

void scambia(int x, int y)


{
int temp;

temp = x;
x = y;
y = temp;
}
• la chiamata scambia(a,b) , con a e b variabili intere
correttamente inizializzate, funziona?

NO! A causa della chiamata per valore, la funzione non può


alterare gli argomenti a e b nella routine chiamante.

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 17
informazioni utili i puntatori

PUNTATORI ED ARGOMENTI A FUNZIONE

• il modo per ottenere l’effetto desiderato è:

void scambia(int* px, int* py)


{
int temp;

temp = *px;
*px = *py;
*py = temp;
}

• la chiamata scambia(&a,&b) funziona!

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 18
informazioni utili i puntatori

PUNTATORI ED ARGOMENTI A FUNZIONE

• il modo per ottenere l’effetto desiderato è:

void scambia(int* px, int* py)


{
int temp; nel chiamante

temp = *px; a:
*px = *py;
*py = temp; b:
}

• la chiamata scambia(&a,&b) funziona! nella funzione scambia()

px:

py:

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 19
informazioni utili i puntatori

PUNTATORI ED ARGOMENTI A FUNZIONE

• ..e questo funziona?

void scambia(int* px, int* py)


{
int* temp;

temp = px;
px = py;
py = temp;
}

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 20
informazioni utili i puntatori

PUNTATORI ED ARGOMENTI A FUNZIONE

• ..e questo funziona?

void scambia(int* px, int* py)


{
int* temp; nel chiamante

temp = px; a:
px = py;
py = temp; b:
}

NO! perchè -->


nella funzione scambia()
cambiano solo i riferimenti
all’interno di scambia(), px:
a e b restano gli stessi
py:

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 21
informazioni utili i puntatori

PUNTATORI & ARRAY


• Dichiarare un array significa dichiarare una variabile puntatore
che punta al primo elemento dell’array

int vett[10];

• vett è una variabile di tipo puntatore ad intero e il suo valore è


la cella di memoria in cui è memorizzato vett[0]

• il seguente codice esegue una copia dell’array b in a?

int a[10], b[10];


a = b;

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 22
informazioni utili i puntatori

ARITMETICA DEGLI INDIRIZZI

int i;
int vett[10];
int *p;

• vett si comporta come un puntatore “fisso”

• vett[i] equivale a *(vett+i)

• *(p+i) equivale a p[i]

• p=vett equivale a p=&vett[0]

• p=vett+i equivale a p=&vett[i]

• (p+i) - (p+j) = valore intero pari al numero di elementi


(interi) tra i e j

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 23
informazioni utili i puntatori

ESERCIZIO 1
Dati i seguenti tipi complessi:
typedef struct { typedef struct {
char cognome[30]; int giorno,mese,anno;
char nome [30]; } Data;
Data data_di_nascita;
char codice_fiscale [16];
} dati_anagrafici;

E i seguenti vettori:
#define LUN_NOME 6
char nome[LUN_NOME] = {‘C’, ‘I’, ‘C’, ‘C’, ‘I’, ‘O’};
#define LUN_COGNOME 8
char cognome[LUN_COGNOME] = {‘G’, ‘R’, ‘A’, ‘Z’, ‘I’, ‘A’, ‘N’, ‘I’};
#define LUN_CODICEF 16
char codice[LUN_CODICEF] = {‘C’, ‘C’, ‘G’, ‘R’, ‘Z’, ‘N’, ‘8’, ‘1’, ‘C’,
‘0’, ‘1’, ‘O’, ‘A’, ‘5’, ‘P’, ‘E’};

inizializzare una variabile p di tipo puntatore a struttura,


impostando come data di nascita ’03/03/1981’

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 24
informazioni utili i puntatori

ESERCIZIO 1

int main() {
int i;
dati_anagrafici *p;

p = (dati_anagrafici*)malloc(sizeof(dati_anagrafici));
for (i=0; i<LUN_NOME; i++)
p->nome[i] = nome[i];
for (i=0; i<LUN_COGNOME; i++)
p->cognome[i] = cognome[i];
for (i=0; i<LUN_CODICEF; i++)
p->codice_fiscale[i] = codice[i];
p->data_di_nascita.giorno = 3;
p->data_di_nascita.mese = 3;
p->data_di_nascita.anno = 1981;
return 0;
}

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 25
informazioni utili i puntatori

ESERCIZIO 2
Scrivere il codice della funzione:

void conta_cifre(char* input, int size_i, int* output);


che conta il numero di occorrenze di caratteri numerici ‘0’ ... ‘9’
all’interno del vettore di caratteri input di dimensione size_i
Il totale delle occorrenze va restituito nella variabile output

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 26
informazioni utili i puntatori

ESERCIZIO 2

void conta_cifre(char* input, int size_i, int* output) {


int pos = 0;

while (pos<size_i) {
if (isdigit(input[pos])) //oppure confrontiamo ASCII
*output = *output+1;
pos++;
}
}

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 27
informazioni utili i puntatori

RIASSUMENDO...

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 28
informazioni utili i puntatori

PUNTATORI A PUNTATORI - MATRICI - VETTORI DI PUNTATORI


I puntatori sono variabili quindi possiamo memorizzarli come tali:
int *matrix1[TOTALE];
array di puntatori a intero (TOTALE * sizeof(int*) già allocati + puntatore all’array)

int **matrix2;
puntatore a puntatore (allocato solo un puntatore - 4byte)

int matrix3[TOTALE][TOTALE];
array di array - matrice (già completamente allocata, matrix3[i,j] accede a
una porzione di memoria valida)

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 29
informazioni utili i puntatori

ESERCIZIO 3
Scrivere il codice della funzione:

void sort(int* input, int size_i, int* output);

che ordina gli elementi interi dell’array input di dimensione size_i

il vettore ordinato va restituito nella variabile output


output in input viene ricevuto = null

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010
TUTORATO di LINGUAGGI I 30
informazioni utili i puntatori

ESERCIZIO 3 void scambia(int* px, int* py) {


int temp;
temp = *px;
*px = *py;
*py = temp;
}

void sort(int* input, int size_i, int* output) {


int* vtmp;
int i=0,j;

vtmp = (int*)malloc(size_i*sizeof(int));
while (i<(size_i-1)) {
j=0;
*(output+i) = *(input+i);
while (j<(size_i)) {
if ( (*(input+j)) < (*(input+i)) )
*(output+i) = *(input+j);
j++;
}
i++;
}
}

TUTORATO di LINGUAGGI 1 - a.a. 2010 - 2011 - Lezione 1


martedì 19 ottobre 2010

Potrebbero piacerti anche