APPUNTI SUL LINGUAGGIO C Strutture Dati e Puntatori

Slides:



Advertisements
Presentazioni simili
Puntatori Linguaggio C.
Advertisements

Introduzione al linguaggio C Dr. Francesco Fabozzi Corso di Informatica.
Unità Didattica 3 Linguaggio C
Prof.ssa Chiara Petrioli -- corso di programmazione 1, a.a. 2006/2007 Corso di Programmazione 1 a.a.2006/2007 Prof.ssa Chiara Petrioli Corso di Laurea.
1 Elementi DI INFORMATICA Università degli Studi di Cagliari Corso di Laurea in Ingegneria Elettronica Linguaggio C A.A. 2011/2012
Fondamenti di Informatica A - Massimo Bertozzi I PUNTATORI.
1 ELEMENTI DI INFORMATICA Università degli Studi di Cagliari Corso di Laurea in Ingegneria Elettronica Linguaggio C A.A. 2011/2012
Fondamenti di Informatica A - Massimo Bertozzi LE RAPPRESENTAZIONI CONCATENATE.
.  I tipi di dati non primitivi sono gli array, le struct e le union.  Gli array sono degli aggregati di variabili dello stesso tipo.  La dichiarazione.
Allocazione dinamica VLA, malloc() e dintorni. Rappresentazione di sequenze.... È molto comune dover rappresentare sequenze di elementi tutti dello stesso.
Process synchronization
Gestione della memoria
ELEMENTI DI INFORMATICA
Ereditarietà Uno dei principi della programmazione orientata agli oggetti (OOP) è il riuso Le classi dovrebbero essere progettate come componenti riutilizzabili.
Java: concetti e costrutti base
Introduzione al linguaggio C
Struct, enum, Puntatori e Array dinamici
Il linguaggio C Strutture Moreno Marzolla
10. Programmazione Ricorsiva Ing. Simona Colucci
Process synchronization
Process synchronization
L’AMBIENTE CODE BLOCKS E L’IO
Tipo di dato: array Un array è un tipo di dato usato per memorizzare una collezione di variabili dello stesso tipo. Per memorizzare una collezione di 7.
Ambienti di Programmazione per il Software di Base
Vettori dinamici Definiremo la classe vector.
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
© 2007 SEI-Società Editrice Internazionale, Apogeo
Alberi n-ary Lezioni di C.
APPUNTI SUL LINGUAGGIO C
APPUNTI SUL LINGUAGGIO C
Gestione di un banco di magliette
Process synchronization
Gestione di un ristorante
Corso di Laurea Ingegneria Informatica Fondamenti di Informatica
APPUNTI SUL LINGUAGGIO C
comprensione e modifica di codice
APPUNTI SUL LINGUAGGIO C Implementazioni di Liste Concatenate
La struttura dei primi programma in C
APPUNTI SUL LINGUAGGIO C Esercizi su File e Alberi Binari
Le stringhe in C++ Laboratorio 26 Aprile Dott. Serena Villata
Lucidi della Pof.ssa Pazienza
APPUNTI SUL LINGUAGGIO C
APPUNTI SUL LINGUAGGIO C
APPUNTI SUL LINGUAGGIO C
APPUNTI SUL LINGUAGGIO C Allocazione dinamica della memoria
LINGUAGGIO C Alberi e livelli
APPUNTI SUL LINGUAGGIO C Simulazione Prima Prova Intermedia
Programmazione e Laboratorio di Programmazione
Corso di Algoritmi e Strutture Dati APPUNTI SUL LINGUAGGIO C
APPUNTI SUL LINGUAGGIO C
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Array e Stringhe Linguaggio C.
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Programmazione e Laboratorio di Programmazione
Transcript della presentazione:

APPUNTI SUL LINGUAGGIO C Strutture Dati e Puntatori Corso di Algoritmi e Strutture Dati APPUNTI SUL LINGUAGGIO C Strutture Dati e Puntatori

Tipi di dato int, double, char, “boolean”, … Tipi di dati complessi : Tipi di dato elementare: int, double, char, “boolean”, … Tipi di dati complessi : Array monodimensionali Array multidimensionali Puntatori Struct (record)

typedef < tipo > < nuovo_nome_tipo > ; Il C permette di definire esplicitamente nomi nuovi per i tipi di dati, tramite la parola chiave typedef. L'uso di typedef consente di rendere il codice più leggibile. Il formato dell'istruzione typedef è il seguente: typedef < tipo > < nuovo_nome_tipo > ; in questo modo assegnamo al tipo tipo il nuovo nome nuovo_nome_tipo. Da questo momento in avanti potremo riferirci al tipo di dato tipo sia con il nome tipo sia con il nome nuovo_nome_tipo. Es: typedef int intero; intero i; /* definisce una variabile i di tipo int. */

Stringhe Una stringa è un vettore di caratteri che contiene il carattere terminatore '\0' che indica che i successivi caratteri non sono significativi. L E S T R I N G H \0 I caratteri compresi fra il primo e il carattere '\0' sono quelli significativi della stringa. Dal momento che questo è il modo per indicare dove la stringa finisce, questo carattere deve apparire almeno una volta nel vettore.

Stringhe Es. #define Dim 5 … char ch[Dim]; char s[]=“prova”; p r o v a \0 v r o p s[0] s[1] s[2] s[3] s[4] s[5]

Formattazione della stringa da parte del compilatore char s[]=“Esempio"; char str[100]; scanf(“%s”,str); // inserisco da input esempio E S E M P I O \0

Dichiarazione e inizializzazione dei vettori I vettori occupano dello spazio in memoria. Il programmatore specificherà il tipo di ogni elemento e il numero di quelli richiesti da ognuno dei vettori, così che il computer possa riservare l’appropriata quantità di memoria. #define M 3 #define N 2 ... int c[M]; int l[N]; int vet[5] = {1, 2, 3, 4, 5}; float r[] = {1.4, 3.2, 5.4 } /* viene allocato un vettore di tre elementi */ È possibile inizializzare un array in fase di dichiarazione. In questo caso, per un vettore, la specifica delle dimensioni è opzionale.

Dichiarazione e inizializzazione dei vettori I vettori occupano dello spazio in memoria. Il programmatore specificherà il tipo di ogni elemento e il numero di quelli richiesti da ognuno dei vettori, così che il computer possa riservare l’appropriata quantità di memoria. #define M 3 #define N 2 ... int c[M]; int l[N]; char vet[] = “blu”; char r[] = {‘b’, ‘l’, ‘u’, ‘\0’ } È possibile inizializzare una stringa in fase di dichiarazione a carico dell’utente. In questo caso, bisogna indicare anche \0

Formattazione della stringa da parte dell’utente char str[100]; char a; int i=0; // inserisco da input esempio for (i=0; i<7; i++) { scanf(“%c”,&a); str[i]=a; } str[i] = “/0”; E S E M P I O \0

Stringhe Il C non ha un sistema semplice per costruire le stringhe, così le seguenti assegnazioni non sono valide: char nome[50], cognome[50], nomecognome[50]; nome = "Mario" /* illegale */ cognome = "Rossi" /* illegale */ nomecognome = "Sig."+firstname+lastname /* illegale */ Comunque esiste una libreria di routines per il trattamento delle stringhe ("<string.h >").

Libreria <string.h> #include <string.h> int strcmp(char *string1, char *string2) - Confronta string1 e string. void strcpy(char *string1, char *string2) - Copia string2 in stringl. char *strerror(int errnum) - Ottiene il messaggio di errore corrispondente al numero di errore specificato. int strlen(char *string) - Determina la lunghezza di una stringa. char *strncat(char *string1, char *string2, size_t n) - Aggiunge "n" caratteri di string2 in string1. int strncmp(char *string1, char *string2, size_t n) - Confronta i primi "n" caratteri di due stringhe. char *strncpy(char *string1, char *string2, size_t n) - Copia i primi "n" char *strnset(char *string, char c, size_t n) - Setta i primi "n" caratteri di string a "c". char *strrchr(char *string, char c) - Cerca l'ultima occorrenza del carattere "c" in string.

Struct (record) Le strutture sono collezioni di variabili correlate sotto un unico nome. Le strutture possono contenere variabili di diversi tipi di dato (contrariamente ai vettori, che contengono soltanto elementi dello stesso tipo di dato) Le strutture sono un tipo di dato derivato (sono cioè costruite usando oggetti di altri tipi).

Tipi di dato Struct (record) Puntatori Liste concatenate

In C i record si definiscono mediante il costrutto struct. Struct (record) In C i record si definiscono mediante il costrutto struct. La parola chiave struct introduce la definizione della struttura, e l’identificatore persona è la structure tag (l’etichetta della struttura) /* definizione del record persona */ struct persona { stringa nome; stringa cognome; stringa CF; int eta; } ... /* dichiarazione di variabili di tipo persona */ struct persona pino,gino,nina; Le variabili dichiarate all’interno delle parentesi graffe della definizione sono i campi della struttura.

In C i record si definiscono mediante il costrutto struct. Struct (record) In C i record si definiscono mediante il costrutto struct. /* definizione del record persona */ struct persona { stringa nome; stringa cognome; stringa CF; int eta; } ... /* dichiarazione di variabili di tipo persona */ struct persona pino,gino,nina; Per dichiarare le variabili di quel tipo struttura bisogna utilizzare l’etichetta della struttura con anteposta la parola chiave struct

Per accedere a un campo del record si usa l’operatore punto. Struct (record) Per accedere a un campo del record si usa l’operatore punto. struct <nome_record> { <tipo> nome1; <tipo> nome2; … <tipo> nome3; } struct <nome_record> st; … st.nome2;

struct <nome_record> { <tipo> nome1; <tipo> nome2; … Struct (record) Se abbiamo un puntatore al record possiamo accedere ai sui campi attraverso l’operatore ->. struct <nome_record> { <tipo> nome1; <tipo> nome2; … <tipo> nome3; } struct <nome_record> *st; … st->nome2;

Struct (record) ... struct persona tizio; struct persona *p; struct persona amici[10]; scanf(“%s”, tizio.nome); tizio.eta++; printf(“%s”, amici[3].cognome); p = &tizio; printf(“%s”,p->cognome);

Definizioni alternative di record Ci sono vari modi per definire record oltre quello visto. /* dichiarazione di variabili record contestuale alla definizione del record corrispondente */ struct contocorrente { int numero; char cognome[20]; char indirizzo[30]; long int saldo; } uno,due,tre;

Definizioni alternative di record Ci sono vari modi per definire record oltre quello visto. /* dichiarazione di variabili record senza definizione del record corrispondente */ struct { int codice; char descrizione[20]; float dato; } a,b,c;

Definizioni alternative di record Ci sono vari modi per definire record oltre quello visto. /* definizione di tipi di record mediante il costrutto typedef */ typedef struct { char nome[20]; char cognome[20]; char CF[16]; int eta; } persona; … persona maria, marco;

È permessa la nidificazione di record. Proprietà dei record È permessa la nidificazione di record. struct persona { char nome[20]; char cognome[20]; struct { int giorno; int mese; int anno; } datanascita; char indirizzo[20]; } squadra[20]; ... printf(“%d”,squadra[2].datanascita.anno);

È permesso l’autoriferimento mediante i puntatori. Proprietà dei record È permesso l’autoriferimento mediante i puntatori. struct persona { char nome[20]; char cognome[20]; struct persona *coniuge; } io; struct elemento { int info; struct elemento *next; } lista;

Inizializzare i record struct card { char face[20]; char suit[20]; } … struct card a = {“Three”, “Hearts”};

Allocazione dinamica della memoria L'allocazione dinamica della memoria consente una efficace gestione della memoria a tempo di esecuzione. Si usa generalmente per la gestione di dati di cui non è nota a priori la dimensione. In ANSI C ci sono quattro funzioni per gestire dinamicamente la memoria: • malloc • calloc • realloc • free Queste funzioni sono contenute nella libreria: stdlib.h

Allocazione dinamica della memoria Operativamente la gestione avviene mediante l’uso di puntatori e della costante simbolica predefinita NULL (che vale 0 ed è definita nella libreria stdio.h). La costante NULL serve a gestire la situazione in cui un puntatore non punta a nessuna locazione di memoria.

void *malloc( size_t size ) Alloca in maniera dinamica una zona di memoria della dimensione specificata in numero di byte. Restituisce un puntatore di tipo void all'area di memoria allocata. Se non c'è sufficiente quantità di memoria, restituisce NULL. Viene sempre seguita da una operazione di "casting" per restituire un puntatore del tipo desiderato. void *malloc( size_t size )

size_t sizeof(<variabile o tipo>) Malloc Si usa in genere insieme alla funzione C sizeof che restituisce la dimensione in numero di byte di una variabile o di un tipo. size_t sizeof(<variabile o tipo>)

Malloc #include <stdio.h> #include <stdlib.h> ... typedef struct { char nome[20]; char cognome[20]; int telefono; } persona; .... /* definizione puntatori */ int *p, *q; persona *tizio;

/* allocazione dinamica di memoria */ p=(int*)malloc(sizeof(int)); q=(int*)malloc(sizeof(*q)); tizio=(persona*)malloc(sizeof(persona)); if (tizio==NULL) printf("Out of memory"); Ho allocato una cella di memoria per contenere un intero Ho allocato una cella di memoria per contenere un intero Ho allocato una cella di memoria per contenere una struttura di tipo persona

Malloc /* allocazione dinamica di memoria */ p=(int*)malloc(sizeof(int)); q=(int*)malloc(sizeof(*q)); tizio=(persona*)malloc(sizeof(persona)); if (tizio==NULL) printf("Out of memory"); ... /* uso delle variabili allocate */ scanf("%d",p); scanf("%d",q); printf("%d\n",*p + *q); tizio->telefono=1733; printf("%d",tizio->telefono);

Calloc e Realloc La calloc alloca in maniera dinamica una zona di memoria per memorizzare n oggetti della dimensione specificata. La realloc rialloca uno spazio di memoria precedentemente allocato con una calloc o malloc (si usa in genere per modificare dimensione e/o tipo di un'area di memoria già allocata).

Calloc e Realloc void *calloc( size_t n_elem, size_t elem_size ) In entrambi i casi viene restituito un puntatore di tipo void all'area di memoria (ri)allocata. Se non c'è sufficiente quantità di memoria, viene restituito NULL. void *calloc( size_t n_elem, size_t elem_size ) void *realloc( void *p, size_t size )

Calloc e Realloc ... typedef struct { char nome[20]; char cognome[20]; int telefono; } persona; int matricola; } studente; .... persona *pp, *grp; studente *ps;

/* allocazione dinamica di una persona */ pp=(persona*)malloc(sizeof(persona)); pp->telefono=77; /* allocazione dinamica di 10 persone */ grp=(persona*)calloc(10,sizeof(persona)); if (!grp) printf("Out of memory"); Ho allocato 10 celle di memoria che conterranno strutture di tipo persona.

/* riallocazione dinamica di pp */ ps=(studente*)realloc(pp,sizeof(studente)); ps->matricola=888; printf("%d%d",ps->matricola,ps->telefono); ... Ho riallocato la cella di memoria che conteneva una struttura di tipo persona (puntata da pp).

Calloc e Realloc /* allocazione dinamica di 10 persone */ grp=(persona*)calloc(10,sizeof(persona)); if (!grp) printf("Out of memory"); /* allocazione dinamica di una persona */ pp=(persona*)malloc(sizeof(persona)); pp->telefono=77; /* riallocazione dinamica di pp */ ps=(studente*)realloc(pp,sizeof(studente)); ps->matricola=888; printf("%d%d",ps->matricola,ps->telefono); ...

Free void *free( void *p ) Rilascia una zona di memoria precedentemente allocata con una malloc, una calloc o una realloc. N.B.: andrebbe sempre usata prima della fine del programma su ogni variabile allocata dinamicamente. void *free( void *p )

Free ... typedef struct { char nome[20]; char cognome[20]; int telefono; } persona; .... /* definizione puntatori */ int *p, *q; persona *pp, *grp;

Free /* allocazione dinamica di memoria */ p=(int*)malloc(sizeof(int)); q=(int*)malloc(sizeof(*q)); pp=(persona*)malloc(sizeof(persona)); grp=(persona*)calloc(10,sizeof(persona)); ... /* rilascio della memoria allocata */ free(p); free(q); free(pp); free(gpr);

Le strutture dati Fino ad ora sono state introdotte strutture dati statiche (dimensione fissa a priori come vettori e record); in C ci sono strumenti per creare e gestire strutture dati dinamiche, la cui dimensione è una variabile gestita dall’utente. Un uso combinato di record e puntatori e una sapiente gestione dell’allocazione dinamica della memoria, permettono la costruzione e gestione di realtà complesse, di tipi di dato astratto.

Le Liste Concatenate Una lista concatenata è una collezione lineare di strutture connesse da puntatori, detti link (anelli o collegamenti), da cui il termine concatenata. Elemento Elemento Elemento

Le Liste Concatenate I nodi di una lista sono strutture ricorsive: una struttura contenente un membro di tipo puntatore, che fa riferimento a una struttura dello stesso tipo di quella in cui è contenuto. Elemento

Le Liste Concatenate Ci saranno sue nodi particolari: un puntatore al primo elemento e l’ultimo nodo punterà a NULL. Elemento

Le Liste Concatenate Ci saranno sue nodi particolari: un puntatore al primo elemento e l’ultimo nodo punterà a NULL. NULL Elemento

Le Liste Concatenate /**************** Direttive ***************/ #include <stdio.h> #include <stdlib.h> #define FALSE 0 #define TRUE 1

Le Liste Concatenate /************ Definizione tipi ************/ typedef int tipoelem; typedef struct elem *plist; typedef struct elem { int info; plist next; } elist; //typedef < tipo > < nuovo_nome_tipo >;

Le Liste Concatenate elist info plist info

Le Liste Concatenate /*********** Prototipi funzioni ***********/ /*restituisce la lista vuota*/ plist init(); /*verifica se una lista è vuota*/ int empty(plist); /*aggiunge un elemento in testa alla lista e restituisce la lista risultato*/ plist cons(plist, tipoelem); /*stampa tutta la lista*/ void stampa(plist);

Le Liste Concatenate /*********** Prototipi funzioni ***********/ /*restituisce il primo elemento della lista*/ tipoelem car(plist); /*toglie il primo elemento della lista e restituisce la lista risultato*/ plist cdr(plist);

Le Liste Concatenate temp plist init() NULL NULL l ? int empty(plist l)

Le Liste Concatenate /********** Definizione funzioni **********/ plist init() { plist temp; temp = NULL; return(temp); } int empty(plist l) { if (!l) return (TRUE); else return (FALSE);

Le Liste Concatenate plist cons(plist l, tipoelem e) temp l e tipoelem car(plist l) l info

Le Liste Concatenate plist cons(plist l, tipoelem e) { plist temp; temp = (plist)malloc(sizeof(elist)); temp->info = e; temp->next = l; return(temp); } tipoelem car(plist l) { return(l->info);

Le Liste Concatenate plist cdr(plist l) l temp temp l

Le Liste Concatenate plist cdr(plist l) l temp l

Le Liste Concatenate plist cdr(plist l) { plist temp; if (empty(l)) return(l); temp = l; l=l->next; free(temp); return(l); }

Le Liste Concatenate void stampa(plist l) l

Le Liste Concatenate void stampa(plist l) { printf("("); while (l) { printf("%d",l->info); printf(")"); l = l->next; } printf(")\n");

Le Liste Concatenate /********** Programma principale **********/ main() { int scelta; boolean continua=TRUE; tipoelem e; plist l; l=init();

Le Liste Concatenate while (continua) { /**** Stampa Menu Operazioni ****/ printf("--------Menu--------\n"); printf("1) Cons\n"); printf("2) Car\n"); printf("3) Cdr\n"); printf("4) Empty\n"); printf("5) Stampa\n"); printf("6) Esci\n"); printf("Scelta:"); scanf("%d",&scelta);

switch(scelta) { case 1: printf("Elemento:"); scanf("%d",&e); l=cons(l,e); break; case 2: if (empty(l)) printf("Vuota!\n"); else { printf("1^ elemento:"); printf("%d\n",car(l)); } break;

case 3: if (empty(l)) printf("Vuota!\n"); else l=cdr(l); break; case 4: else printf("Piena!\n"); break; case 5: stampa(l); break; default: continua=FALSE; break; }

APPUNTI SUL LINGUAGGIO C Corso di Algoritmi e strutture Dati APPUNTI SUL LINGUAGGIO C Strutture dati FINE