fondamenti di informatica - disit.org · a cosa servono in pratica i puntatori • attraverso i...

37
Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 Fondamenti di Informatica AA 2016/2017 Eng. Ph.D. Michela Paolucci DISIT Lab http://www.disit.dinfo.unifi.it Department of Information Engineering, DINFO University of Florence Via S. Marta 3, 50139, Firenze, Italy tel: +39-055-2758515, fax: +39-055-2758570 [email protected]

Upload: ngothuan

Post on 15-Feb-2019

216 views

Category:

Documents


0 download

TRANSCRIPT

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017

Fondamenti di InformaticaAA 2016/2017

Eng. Ph.D. Michela Paolucci

DISIT Lab http://www.disit.dinfo.unifi.itDepartment of Information Engineering, DINFO

University of FlorenceVia S. Marta 3, 50139, Firenze, Italy

tel: +39-055-2758515, fax: [email protected]

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 2

DISIT Lab http://www.disit.dinfo.unifi.it

Department of Information Engineering, DINFO

University of FlorenceVia S. Marta 3, 50139, Firenze, Italy

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 3

• Il ricevimento si svolge su appuntamento contattando la

docente via email:

[email protected]

Orario del Corso e Ricevimento

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 4

• Enrico Vicario

• Fondamenti di programmazione.

Linguaggio C, strutture dati,

algoritmi elementari, C++

• Editore: Esculapio

• ISBN: 9788874884582

• NOTA: Queste slide integrano e non

sostituiscono quanto scritto sul libro di

testo.

Libro di testo

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 5

Pagina del Corso

http://www.disit.org/drupal/?q=node/7020

Qui trovate:

- AVVISI

- Slide del corso

- Approfondimenti

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 6

• Strutture dati e algoritmi elementari

• Liste

• Rappresentazione in forma sequenziale

• Rappresentazione collegata con array e indici

• Rappresentazione con puntatori

• Iterazione e ricorsione

• Cenni sugli alberi

Outline

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 7

…ancora sul concetto di puntatore…

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 8

• I puntatori sono delle variabili che mantengono il valore

dell’indirizzo di altre variabili o di altri puntatori

• Operatori: & e *

• Data la dichiarazione:

int *a, b=5;

• Per convenzione il valore iniziale di un puntatore è NULL. NULL è

una costante simbolica pari a 0

• Data una variabile è possibile risalire al suo indirizzo tramite

l’operatore unario &. Per esempio data la variabile intera b SE si

scrive &b, si intende fare riferimento all’indirizzo della variabile b.

Quindi si può anche scrivere la seguente assegnazione:

a = &b;

Concetto di puntatore

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 9

A cosa servono in pratica i puntatori• Attraverso i puntatori una funzione può restituire valori

multipli, così da superare il limite di un unico valore di

ritorno ottenuto con l’istruzione return

• Affinché la funzione restituisca un valore di tipo intero

(int) il parametro formale viene specificato del tipo

puntatore a intero.

Esempio:

void SommaP(int A, int B, int *C) {//variabili formali

*C = A + B;

return;

}

main() {

int a, b = 5, c = 2;

SommaP(b,c,&a); //variabili attuali

printf("A che valore punta a? %d", a); }

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 10

Puntatori e dati strutturati (1)main() {//esempio di struttura persona

struct persona pers, *p_pers;

pers.nome = "Matteo";

pers.cognome = "Fossi";

pers.indirizzo = "Via S.Marta";

pers.civico = 3;

printf("La struttura persona pers contiene i seguenti dati:\n");

printf("nome %s\ncognome %s\nindirizzo %s\ncivico %d\n", pers.nome,

pers.cognome, pers.indirizzo, pers.civico);

p_pers = &pers; //assegna un puntatore a pers

printf("\n\nIl puntatore p_pers punta alla struttura persona pers che contiene

i dati assegnati a pers:\n", p_pers->nome);

printf("nome %s\ncognome %s\nindirizzo %s\ncivico %d\n", p_pers->nome,

p_pers->cognome, p_pers->indirizzo, p_pers->civico);

}

struct persona { //definizione

char *nome;

char *cognome;

char *indirizzo;

int civico;

};

• L’operatore ‘.’ permette l’accesso ad un membro di una struttura (pers.nome)

• L’operatore ‘->’ permette l’accesso a un membro della struttura puntata dal

puntatore (p_pers->nome)

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 11

Puntatori e dati strutturati (2)

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 12

Concetto di doppio puntatore

(puntatore a puntatore) (1)• I puntatori sono delle variabili che mantengono il valore

dell’indirizzo di altre variabili o di altri puntatori

• Dichiarazione di un puntatore a un puntatore:

int **p;

Esempio:

int **p,*a, b=5;

a = &b;

p = &a;

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 13

Concetto di

doppio puntatore

(puntatore a

puntatore) (2)main(){

int **p,*a, b=5;

a = &b;

p = &a;

printf("Quanto vale il valore

puntato dal puntatore a cui

punta p? %d\n",**p);

}

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 14

• Strutture dati e algoritmi elementari

• Liste

• Rappresentazione in forma sequenziale

• Rappresentazione collegata con array e indici

• Rappresentazione collegata con puntatori

• Iterazione e ricorsione

• Cenni sugli alberi

Outline

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 15

Liste: rappresentazione collegata con

arrays e indici

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 16

Liste - Rappresentazione collegata

con array e indici (1)• La rappresentazione collegata con array e indici utilizza

ancora gli array per memorizzare i valori su un buffer

MA virtualizza la relazione di sequenza dei valori

• Il buffer è un array di records in cui ogni record

contiene:

• Un valore

• L’indice del record del buffer che contiene il

successivo valore della lista

struct record{

float value;

int next;

}

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 17

Liste - Rappresentazione collegata

con array e indici (2)• L’elemento in coda ha come

indice un valore illegale che

tipicamente coincide con la

dimensione del buffer stesso

• Anche i record non usati sono

concatenati attraverso gli indici

in modo da formare una lista dei

record disponibili (liberi o free)

• La presenza di tale lista

permette di eseguire la ricerca

di un record libero e

dell’inserimento di un nuovo

elemento nella lista con un

numero costante di operazioni

Il numero di operazioni non

dipende dalla dimensione della lista o

dal numero di elementi che essa

contiene

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 18

Liste - Rappresentazione collegata

con array e indici (3)• Rappresentazione della lista

{10., 20., 50.} in forma collegata

con indici su un buffer di

dimensione 5 in cui:

• i record 4 e 2 sono

concatenati sulla lista degli

elementi liberi

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 19

Liste - Rappresentazione collegata

con array e indici (4)• Configurazione iniziale della lista

in forma collegata con indici:

• first: contiene l’indice illegale

(size)

• Tutti i record del buffer sono

concatenati sulla lista degli

elementi liberi che ha origine

dall’indice free

struct list {

int first;

int free;

int size;

struct record *buffer;

}

Con:

struct record{

float value;

int next;

}

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 20

//inclusione librerie

#include <stdio.h>

typedef unsigned short int Boolean; //definizione di Boolean

#define TRUE 1

#define FALSE 0

//definizione delle strutture usate

struct record {

float value;

int next;

};

struct list {

int first;

int free;

int size;

struct record *buffer;

};

Liste - Rappresentazione collegata

con array e indici (5)

Struttura generale

del programma –

parte I

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 21

//dichiarazione delle funzioni

void init(struct list *ptr, int size);

Boolean pre_insert(struct list *ptr, float value);

Boolean suf_insert(struct list *ptr, float value);

Boolean ord_insert(struct list *ptr, float value);

void visit(struct list *ptr);

Boolean search(struct list *ptr, float value);

void getvalue(float *value_ptr);

void notify_selection_failure(char selection);

main(){

}

//definizione delle funzioni

Liste - Rappresentazione collegata

con array e indici (6)

Struttura generale

del programma –

parte II

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 22

main() {

struct list lista;

int size=5, res_search = FALSE;

float value;

char selection[10];

init(&lista, size);

printf("Digita uno dei seguenti caratteri\nper fare le operazioni sulla

lista collegata con array e puntatori:\n");

printf("-a per fare un inserimento in coda\n");

printf("-b per fare un inserimento in testa\n");

printf("-c per fare un inserimento ordinato\n");

printf("-d per fare una visita\n");

printf("-e per fare una ricerca\n");

printf("-x per uscire dal programma\n");

Boolean exit_required = FALSE;

int inserimento = 0;

do {…} while(exit_required == FALSE);

printf("Fine!");

}

Liste - Rappresentazione collegata

con array e indici (7)Struttura main()

void init(struct list *ptr, int size);

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 23

main() {

struct list lista; …

do {

case 'a': //inserimento in testa

getvalue(&value);

inserimento = pre_insert(&lista, value);

if (inserimento == FALSE)

printf("buffer pieno!");

break;

case 'b': //inserimento in coda

getvalue(&value);

inserimento = suf_insert(&lista, value);

if (inserimento == FALSE)

printf("buffer pieno!");

break;

…//altri casi…

} while(exit_required == FALSE);

printf("Fine!");

}

Liste - Rappresentazione collegata

con array e indici (8)Struttura

do{…} while() - Parte I

Nota: dichiarazione inserimento in testa

Boolean pre_insert(struct list *ptr, float val);

Nota: dichiarazione inserimento in coda

Boolean suf_insert(struct list *ptr, float val);

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 24

main() {

struct list lista; …

do {…//altri casi…

case 'c':

getvalue(&value); //inserimento ordinato

inserimento = ord_insert(&lista, value);

if (inserimento == FALSE)

printf("buffer pieno!");

break;

case 'd': //visita

visit(&lista);

break;

…//altri casi…

} while(exit_required == FALSE);

printf("Fine!"); }

Liste - Rappresentazione collegata

con array e indici (9)Struttura

do{…} while() - Parte II

Nota: dichiarazione inserimento ordinato

Boolean ord_insert(struct list *ptr, float val);

Nota: dichiarazione ricerca

void visit(struct list *ptr);

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 25

main() {

struct list lista; …

do {…//altri casi…

case 'e': //ricerca

getvalue(&value);

res_search = search(&lista, value);

if (res_search == TRUE)

printf("Trovato!");

else

printf("Niente, riprova!");

break;

case 'x': //uscita

exit_required = TRUE;

break;

default:

notify_selection_failure(selection[0]);

}

while(exit_required == FALSE); printf("Fine!"); }

Liste - Rappresentazione collegata

con array e indici (10)Struttura

do{…} while() - Parte III

Nota: dichiarazione ricerca

Boolean search(struct list *ptr, float value);

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 26

void init(struct list *ptr, int size){

/*Alloca il buffer e asserisce l'invariante della lista first ha il valore illegale

che indica la dimensione del buffer free indirizza il primo record (libero che

è zero) tutti i record sono concatenati a partire dal primo per

averli disponibili come record liberi*/

int count;

ptr->buffer = (struct record *)malloc(size * sizeof(struct record));

ptr->size = size;

ptr->first = ptr->size;

ptr->free = 0;

for (count = 0; count < ptr->size; count++)

ptr->buffer[count].next = count + 1;

}

Liste - Rappresentazione collegata

con array e indici (11)

Definizione

funzione init()

La funzione di libreria malloc() richiede al

sistema l’allocazione di un segmento di

memoria di dimensione determinata al

momento della chiamata e rende il puntatore

alla locazione della memoria a partire dalla

quale è stato riservato lo spazio

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 27

• Operazione di inserimento in testa su una lista in forma

collegata:

• Il record in testa alla lista degli elementi liberi viene

portato sulla lista degli elementi utili (free) e riceve il

nuovo valore inserito (valore 70.)

Liste - Rappresentazione collegata

con array e indici (12)

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 28

Liste - Rappresentazione collegata

con array e indici (13)

Definizione funzione

pre_insert()

Boolean pre_insert(struct list *ptr, float value){

/*Se la lista libera non è vuota: i) ne sgancia il primo elemento

ii) lo aggancia in testa alla lista dei valori

iii) ci memorizza il valore da inserire*/

int moved;

if (ptr->free != ptr->size) {

moved = ptr->free;

ptr->free = ((ptr->buffer)[ptr->free]).next;

ptr->buffer[moved].value = value;

ptr->buffer[moved].next = ptr->first;

ptr->first = moved;

return TRUE;

}

else

return FALSE;

}

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 29

Liste - Rappresentazione collegata

con array e indici (14)

Definizione funzione

inserimento in coda:

suf_insert()

Boolean suf_insert(struct list *ptr, float value){

/*Se la lista libera NON è vuota: i) sgancia il primo elemento della lista libera

ii) lo aggancia in coda alla lista dei valori; iii) ci copia sopra il valore da inserire; iv)

attribuisce il valore illegale al successore.

SE la lista libera E' VUOTA: rende FALSE*/

int moved, *position_ptr;

if (ptr->free!=ptr->size){

moved = ptr->free;

ptr->free = ((ptr->buffer)[ptr->free]).next;

position_ptr = &ptr->first;

while (*position_ptr != ptr->size)//cerca l’ultimo elemento in lista, che ha next=5

position_ptr = &((ptr->buffer)[*position_ptr].next);

*position_ptr = moved; //memoriza l’ultimo elemento della lista in *position_ptr

ptr->buffer[*position_ptr].value = value; //nell’elemento con quell’indice scrive…

ptr->buffer[*position_ptr].next= ptr->size;

return TRUE;

} else

return FALSE;

}

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 30

• Inserimento in coda. Sulla lista 20 -> 10 -> 50 viene inserito in

coda il valore 70:

• Il puntatore position_ptr contiene inzialmente l’indirizzo

dell’indice first (a)

• position_ptr viene avanzato fino a contenere l’indirizzo del

campo next dell’ultimo record della lista (b,c,d)

• Su tale elemento si effettua l’inserimento

Liste - Rappresentazione collegata

con array e indici (15)

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 31

Boolean ord_insert(struct list *ptr, float value) {

/*i) Assume che la lista sia ordinata; ii) inserisce il nuovo elemento in ordine. Nota:

è analoga alla funzione di inserimento in coda a parte l'aggiunta di una seconda

condizione sul while e uno swap nell'inserimento finale*/

int moved, *position_ptr;

if (ptr->free != ptr->size) {

moved = ptr->free; //dove dovro’ scrivere

ptr->free = ((ptr->buffer)[ptr->free]).next;

position_ptr = &ptr->first;

while (*position_ptr != ptr->size && ptr->buffer[*position_ptr].value < value){

position_ptr = &(ptr->buffer[*position_ptr].next); //valore che mettero’

//nel next dell’elemento che vado ad aggìungere

}

ptr->buffer[moved].value = value;

ptr->buffer[moved].next = *position_ptr;

*position_ptr = moved;

return TRUE;

}

else

return FALSE;

}

Liste - Rappresentazione collegata

con array e indici (16)

Definizione funzione

ord_insert()

Il ciclo while serve per

indirizzare il record su cui

deve essere fatto l’inserimento

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 32

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 33

void visit(struct list *ptr) {

int position;

position = ptr->first;

while (position != ptr->size) {

printf("valore: %f\n", ptr->buffer[position].value);

position = ptr->buffer[position].next;

}

}

Liste - Rappresentazione collegata

con array e indici (17)

Definizione funzione

visit()

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 34

Boolean search(struct list *ptr, float value) {

int position;

Boolean found;

position = ptr->first;

found = FALSE;

while (found == FALSE && position != ptr->size) {

if (ptr->buffer[position].value == value)

found = TRUE;

else

position = ptr->buffer[position].next;

}

return found;

}

Liste - Rappresentazione collegata

con array e indici (18)

Definizione funzione

search()

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 35

void getvalue(float *value_ptr) {

//acquisisce un float da tastiera (passaggio per puntatore)

printf("Inserisci un valore: ");

scanf("%f", value_ptr);

}

void notify_selection_failure(char selection) {

//notifica il fallimento della selezione

printf("\n%c Selezione non legale!!", selection);

}

Liste - Rappresentazione collegata

con array e indici (19)

Definizione funzioni

getvalue() e

notify_selection_failure(…)

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017 36

Lista in forma collegata: osservazioni (1)

• La lista in forma collegata mediante indici:

• A) mantiene il limite del dimensionamento statico del

buffer:

• Svantaggio: Non permette di adattare la memoria

allocata alla dimensione effettiva della sequenza

rappresentata nel corso della computazione

• Vantaggio: evita il bisogno di allocare e rilasciare

memoria ad ogni operazione di inserimento e

cancellazione (come vedremo avverrà invece nelle

liste in forma collegata con puntatori), riducendo

l’interazione con il sistema operativo e quindi

aumentando sostanzialmente l’efficienza e

l’affidabilità

• B) Non permette l’accesso diretto ai vari elementi

Fondamenti di Informatica, Univ. Firenze, Michela Paolucci 2016-2017

Fondamenti di InformaticaEng. Ph.D. Michela Paolucci

DISIT Lab http://www.disit.dinfo.unifi.it/Department of Information Engineering, DINFO

University of FlorenceVia S. Marta 3, 50139, Firenze, Italy

tel: +39-055-2758515, fax: [email protected]