Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una...

14
Linguaggio C: Strutture e Liste Concatenate Valeria Cardellini Corso di Calcolatori Elettronici A.A. 2018/19 Università degli Studi di Roma “Tor Vergata” Dipartimento di Ingegneria Civile e Ingegneria Informatica Argomenti q Struct q Definizione di lista in C q Operazioni su lista: inserimento, cancellazione, ricerca di un elemento Valeria Cardellini - CE 2018/19 1

Transcript of Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una...

Page 1: Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una struttura non riserva memoria, ma crea un nuovo tipo di dato q Le variabili di tipo

Linguaggio C: Strutture e Liste Concatenate

Valeria Cardellini

Corso di Calcolatori Elettronici A.A. 2018/19

Università degli Studi di Roma “Tor Vergata”

Dipartimento di Ingegneria Civile e Ingegneria Informatica

Argomenti

q  Struct q  Definizione di lista in C q  Operazioni su lista: inserimento, cancellazione,

ricerca di un elemento

Valeria Cardellini - CE 2018/19 1

Page 2: Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una struttura non riserva memoria, ma crea un nuovo tipo di dato q Le variabili di tipo

Struct

q  Una struttura (o struct) è un tipo di dato aggregato

q  E’ una collezione finita di variabili correlate (denominate campi o membri), in genere di tipo diverso, ognuna identificata da un nome

q  Sintassi struct [nome_etichetta] {"

"tipo1 nome_campo1;""tipo2 nome_campo2;""…"

} [nome_variabile];"

Valeria Cardellini - CE 2018/19 2

Struct: esempi

q  Dati anagrafici di una persona struct dati_anagrafici {" char cognome[20];" char nome[20];" int eta;" char codice_fiscale[15];"};"

q  Punto geometrico struct punto {" int x, y;"};"

Valeria Cardellini - CE 2018/19 3

Page 3: Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una struttura non riserva memoria, ma crea un nuovo tipo di dato q Le variabili di tipo

Struct: dichiarazione

q  La dichiarazione di una struttura non riserva memoria, ma crea un nuovo tipo di dato

q  Le variabili di tipo struct sono dichiarate nello stesso modo delle variabili di altro tipo ❍  Esempio struct punto p1, p2;"

q  La dichiarazione di una variabile di tipo struct può essere contestuale alla dichiarazione del tipo ❍  Esempio struct punto {" int x, y; /* x e y sono i due campi, scalari di tipo int */"} p1, p2;"❍  p1 e p2 sono due variabili di tipo punto"

Valeria Cardellini - CE 2018/19 4

Operazioni su struct

q  Inizializzare una variabile struct ❍  Con valore costanti (tra parentesi graffe) ❍  Esempio: struct punto p1 = {2, 5};"

q  Assegnare variabili di tipo struct a variabili dello stesso tipo ❍  Copia del valore di tutti i campi

q  Rilevare l’indirizzo di una variabile di tipo struct q  Conoscere la dimensione di una struct

❍  Tramite sizeof"q  Accedere ai campi di una struct

q  È possibile dichiarare un puntatore a struct ❍  Es: struct punto *p3;"

Valeria Cardellini - CE 2018/19 5

Page 4: Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una struttura non riserva memoria, ma crea un nuovo tipo di dato q Le variabili di tipo

Accedere ai campi di struct

q  Per accedere ai singoli campi di una variabile di tipo struct due notazioni:

1.  Operatore . o campo di struttura struct dati_anagrafici pers1;"pers1.eta = 21;"

2.  Operatore -> o puntatore a struttura ❍  L’operatore -> permette l’accesso ai campi di una

struttura per mezzo di un costrutto della forma <puntatore a struttura> -> <nome campo> "

❍  Esempio struct dati_anagrafici *pers2;"pers2->eta = 40; equivale a (*pers2).eta = 40;"

Valeria Cardellini - CE 2018/19 6

cognome nome eta codice_fiscale

pers2

Gestione e passaggio di strutture

q  A differenza degli array, il nome della variabile di tipo struct rappresenta la struttura nel suo complesso

q  E’ possibile: ❍  Assegnare una variabile di tipo struct ad un’altra

ü Esempio: p2 = p1; ❍  Far restituire una variabile di tipo struct ad una funzione ❍  Passare ad una funzione una variabile di tipo struct come

parametro significa passarne una copia ❍  Per passare una struttura per riferimento, occorre

passare alla funzione l’indirizzo della variabile di tipo struct

Valeria Cardellini - CE 2018/19 7

Page 5: Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una struttura non riserva memoria, ma crea un nuovo tipo di dato q Le variabili di tipo

typedef

q  Dichiara il nome di un nuovo tipo di dato (in realtà un’abbreviazione o pseudonimo) a partire da altri tipi (scalari, aggregati, ...) ❍  Sintassi typedef tipoEsistente nuovoTipo;

q  La dichiarazione di tipo è identica alla definizione di una variabile, ma è preceduta dalla clausola typedef

q  Esempio: typedef char string[30];"string parola;"❍  Definisce la variabile parola di tipo string, cioè di tipo

char[30]"

Valeria Cardellini - CE 2018/19 8

Struct annidate

q  Un campo di una struttura può a sua volta essere una struct"❍  L’accesso ai campi interni richiede l’indicazione del

“percorso” da seguire:"typedef struct {" int giorno;" int mese;" int anno;" } Data;"" typedef struct {" char *cognome;" char *nome;" int eta;" Data data_nascita;" char *codice_fiscale;" } dati_anagrafici;

Valeria Cardellini - CE 2018/19 9

Codice sorgente: struct_annidata.c

Page 6: Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una struttura non riserva memoria, ma crea un nuovo tipo di dato q Le variabili di tipo

Lista concatenata

q  Struttura dati in cui ogni nodo ha un collegamento (link) ad un altro nodo: lista concatenata (linked list)

q  Il collegamento è un puntatore con l’indirizzo di memoria dell’altro nodo ❍  Si accede alla lista per mezzo di un puntatore al suo

primo nodo (head) ❍  Si accede ai nodi successivi per mezzo del puntatore

memorizzato in ogni nodo ❍  Il puntatore dell’ultimo nodo è impostato a NULL

q  In una lista i dati sono memorizzati in modo dinamico

Valeria Cardellini - CE 2018/19 10

31 18 25

head

Strutture auto-referenzianti

q  Definiamo il nodo di una lista (il tipo del dato non è specificato) struct listNode {" <type> data; // Ogni nodo contiene un dato" struct listNode *next; // Puntatore al prossimo nodo"};"❍  next è un puntatore al tipo di oggetto che si sta

dichiarando ❍  Struttura auto-referenziante (self-referencing): la

struttura contiene un puntatore ad una struttura dello stesso tipo

Valeria Cardellini - CE 2018/19 11

Page 7: Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una struttura non riserva memoria, ma crea un nuovo tipo di dato q Le variabili di tipo

Esempio: strutture auto-referenzianti

q  Esempio: struct listNode {" int data; // Ogni nodo contiene un intero" struct listNode *next; // Puntatore al prossimo nodo"} x, y, z;""x.data = 1;"y.data = 2;"z.data = 3;"x.next = &y; "y.next = &z; "z.next = NULL;""

Valeria Cardellini - CE 2018/19 12

1 2 3

x y z

data next data next data next

Esempio: strutture auto-referenzianti

q  Attenzione: i nodi delle liste concatenate non sono generalmente memorizzati in modo contiguo struct listNode *ptr = &x; "/* ptr punta alla struttura x */"ptr++; " "/* ptr punta alla locazione di memoria " ptr + sizeof(x) */"ptr = ptr->next; "/* ptr punta ad y */"

Valeria Cardellini - CE 2018/19 13

Page 8: Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una struttura non riserva memoria, ma crea un nuovo tipo di dato q Le variabili di tipo

Tipo di dato lista

typedef <tipo> dataType; // definito dal programmatore "struct listNode { " dataType data; " struct listNode *next; "};"typedef struct listNode ListNode;" // sinonimo di struct listNode"typedef ListNode *List; " // sinonimo di ListNode * ""In modo equivalente: typedef <tipo> dataType; // definito dal programmatore "typedef struct listNode { " dataType data; " struct listNode *next; "} ListNode;"typedef ListNode *List;" Valeria Cardellini - CE 2018/19 14

Codice sorgente: lista_concatenata.c

Tipo di dato lista

In modo equivalente: typedef <tipo> dataType; // definito dal programmatore "typedef struct ListNode *List;"typedef struct listNode { " dataType data; " List next; "} ListNode;""

In modo equivalente: typedef <tipo> dataType; // definito dal programmatore "typedef struct listNode ListNode;"typedef struct ListNode *List;"struct listNode { " dataType data; " List next; "};"

Valeria Cardellini - CE 2018/19 15

Codice sorgente: lista_concatenata.c

Page 9: Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una struttura non riserva memoria, ma crea un nuovo tipo di dato q Le variabili di tipo

Allocazione di memoria

q  Se head è una variabile di tipo List (List head;) chiamando la funzione malloc"head = (List)malloc(sizeof(listNode)); oppure "head = (List)malloc(sizeof(*head)); ❍  Si ottiene dal sistema una porzione di memoria adeguata a

contenere un listNode e si assegna l’indirizzo a head ""

Valeria Cardellini - CE 2018/19 16

Creazione di una lista con un nodo

typedef char itemType; "... "List newNode(itemType value) { " List head; " head = (List)malloc(sizeof(listNode)); " if (head != NULL) { " head->item = value; " head->next = NULL; " }" else " printf("%c not inserted. No memory available.\n", value);" return head; "}"

Valeria Cardellini - CE 2018/19 17

a

Assumendo value = ‘a’

Page 10: Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una struttura non riserva memoria, ma crea un nuovo tipo di dato q Le variabili di tipo

Creazione di un nodo ed inserimento in testa

q  Si crea la nuova struct listNode da inserire in testa q  Si memorizza il valore nel nuovo nodo q  Si fa puntare il nuovo nodo alla precedente testa della lista q  Si fa puntare la testa della lista al nuovo nodo

Valeria Cardellini - CE 2018/19 18

b

Assumendo di inserire ‘b’ come nuovo elemento

a

a

b new

Creazione di un nodo ed inserimento in testa

void insertHead(List *s, char value)"{" List new;" new = malloc(sizeof(ListNode));" if (new != NULL) { /* Is space available? */" new->data = value;" new->next = *s;" *s = new;" }" else" printf("%c not inserted. No memory available.\n", value);"}

Valeria Cardellini - CE 2018/19 19

Codice sorgente: lista_concatenata.c

Page 11: Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una struttura non riserva memoria, ma crea un nuovo tipo di dato q Le variabili di tipo

Rimozione dalla testa della lista

q  Si salva il puntatore al primo nodo da rimuovere q  Si preleva il valore dell’elemento q  Si fa puntare la testa della lista al secondo nodo q  Si dealloca lo spazio del primo nodo

Valeria Cardellini - CE 2018/19 20

b a

value

b temp

b a

Rimozione dalla testa della lista

char deleteHead(List *s)"{" List temp;" char value;""

temp = *s;""

if (temp != NULL) {" value = temp->data;" *s = temp->next;" free(temp);" return value;" }" return '\0';"}"

Valeria Cardellini - CE 2018/19 21

Codice sorgente: lista_concatenata.c

Page 12: Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una struttura non riserva memoria, ma crea un nuovo tipo di dato q Le variabili di tipo

Creazione di un nodo ed inserimento ordinato

q  Inserimento ordinato dei valori ❍  In un ciclo, occorre scorrere la lista fino a trovare il nodo

prima del quale deve essere inserito il nuovo nodo, ossia fin quando il valore da inserire risulta maggiore del valore del nodo corrente ü Si usano due puntatori, previous e current, che puntano

rispettivamente al nodo precedente e al nodo corrente ❍  Se la lista è vuota, rendere il nuovo nodo come testa e

restituirlo, altrimenti inserire il nuovo nodo tra previous e current

Valeria Cardellini - CE 2018/19 22

Creazione di un nodo ed inserimento ordinato

/* Insert a new value into the list in sorted order */"void insertSorted(List *s, char value) {" List new, previous, current; "" new = malloc(sizeof(ListNode)); /* Create node */" if (new != NULL) { /* Is space available? */" new->data = value;" new->next = NULL;" previous = NULL;" current = *s;"" /* Loop to find the correct location in the list */" while (current != NULL && value > current->data) {" previous = current; /* walk to ... */" current = current->next; /* ... next node */" }" "

Valeria Cardellini - CE 2018/19 23

Codice sorgente: lista_concatenata.c

Page 13: Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una struttura non riserva memoria, ma crea un nuovo tipo di dato q Le variabili di tipo

Creazione di un nodo ed inserimento ordinato

/* Insert new node at beginning of list */" if (previous == NULL) {" new->next = *s;" *s = new;" }" else { /* Insert new node between previous and current */" previous->next = new;" new->next = current;" }" }" else" printf("%c not inserted. No memory available.\n", value);"}"

Valeria Cardellini - CE 2018/19 24

Codice sorgente: lista_concatenata.c

Rimozione di un nodo

q  Rimozione di un nodo ❍  Se è da rimuovere la testa della lista

ü Si preleva il valore del nodo ü Si salva il puntatore al nodo da rimuovere ü Si fa puntare la testa della lista al secondo nodo ü Si dealloca lo spazio del primo nodo

❍  Altrimenti, in un ciclo occorre scorrere la lista fino a trovare il nodo da rimuovere ü Si usano due puntatori, previous e current, che puntano

rispettivamente al nodo precedente e al nodo corrente ❍  Se il nodo viene trovato

ü Si salva il puntatore al nodo da rimuovere ü Si fa puntare il nodo precedente al nodo successivo a quello

da rimuovere ü Si dealloca lo spazio del nodo

Valeria Cardellini - CE 2018/19 25 Codice sorgente: lista_concatenata.c

Page 14: Linguaggio C: Strutture e Liste Concatenate · Struct: dichiarazione q La dichiarazione di una struttura non riserva memoria, ma crea un nuovo tipo di dato q Le variabili di tipo

Rimozione di un nodo

/* Delete a list element and return the deleted value */"char delete(List *s, char value)"{" List previous, current, temp; "" /* Delete first node */" if (value == (*s)->data) {" temp = *s; /* Hold onto node being removed */" *s = (*s)->next; /* De-thread the node */" free(temp); /* Free the de-threaded node */" return value;" }" else {" previous = *s;" current = (*s)->next;"" "

Valeria Cardellini - CE 2018/19 26

Codice sorgente: lista_concatenata.c

Rimozione di un nodo

/* Loop to find the correct location in the list */" while (current != NULL && current->data != value) {" previous = current; /* walk to ... */" current = current->next; /* ... next node */" }"" /* Delete node at current */" if (current != NULL) {" temp = current;" previous->next = current->next;" free(temp);" return value;" } " }"" return '\0';"}""

Valeria Cardellini - CE 2018/19 27

Codice sorgente: lista_concatenata.c