I puntatori e l allocazione dinamica di memoria

Documenti analoghi
I puntatori e l allocazione dinamica di memoria

Unità Didattica 4 Linguaggio C. Vettori. Puntatori. Funzioni: passaggio di parametri per indirizzo.

Allocazione dinamica della memoria

Gestione dinamica della memoria

L Allocazione Dinamica della Memoria

Allocazione Dinamica. Allocazione Statica. malloc() La funzione malloc()

I puntatori e l allocazione dinamica di memoria. Esercizi risolti

La gestione della memoria dinamica Heap

L'allocazione dinamica della memoria

Struct, enum, Puntatori e Array dinamici

Uso avanzato dei puntatori Allocazione dinamica della memoria

Ogni variabile in C è una astrazione di una cella di memoria a cui corrisponde un nome, un contenuto e un indirizzo.

Il linguaggio C. Puntatori e dintorni

Il linguaggio C Strutture

Esercitazione 11. Liste semplici

Strutture Dati Dinamiche

Puntatori. Un puntatore contiene un numero che indica la locazione di memoria dove è presente la variabile puntata

Allocazione dinamica della memoria: calloc() Se T è il nomed di un tipo, la chiamata calloc(n, sizeof(t)) è equivalente a malloc(n * sizeof(t))

Le strutture. Una struttura C è una collezione di variabili di uno o più tipi, raggruppate sotto un nome comune.

Definizione Allocazione e deallocazione di variabili Allocazione e deallocazione di vettori

! Per quanto sappiamo finora, in C le variabili sono sempre definite staticamente

Introduzione al linguaggio C Puntatori

Esercizi di programmazione in linguaggio C English Dictionary

Lezione 8 Struct e qsort

Allocazione della memoria. Allocazione dinamica della memoria. Allocazione della memoria. Allocazione automatica

5. Quinta esercitazione autoguidata: liste semplici

Allocazione dinamica della memoria

Stringhe e allocazione dinamica della memoria

Sommario PREFAZIONE...XI CAPITOLO 1: INTRODUZIONE AI COMPUTER, A INTERNET E AL WEB... 1 CAPITOLO 2: INTRODUZIONE ALLA PROGRAMMAZIONE IN C...

Le strutture. Una struttura C è una collezione di variabili di uno o più tipi, raggruppate sotto un nome comune.

Programmazione I - Laboratorio

Unità Didattica 5 Linguaggio C. Stringhe. Accesso a file ASCII. Strutture.

Sommario FONDAMENTI DI INFORMATICA 1. Il tipo FILE. Passaggio da standard I/O. LINGUAGGIO C Gestione dei file

giapresente( ) leggi( ) char * strstr(char * cs, char * ct) NULL

Linguaggio C. Esercizio 1

Gestione di files Motivazioni

Programmazione di base

GESTIONE DEI FILE IN C. Docente: Giorgio Giacinto AA 2008/2009

Array. Maurizio Palesi Salvatore Serrano. In C si possono definire tipi strutturati Vi sono due costruttori fondamentali

ARRAY E STRINGHE. ESERCIZIO 2 Scrivere un programma che calcola il numero di doppie e di dittonghi (2 vocali vicine) presenti in una stringa.

Linguaggi di programmazione + laboratorio a.a. 2012/2013

Consideriamo un vettore allocato dinamicamente

Problema. Vettori e matrici. Vettori. Vettori

Esercizio 1: funzione con valore di ritorno di tipo puntatore

Le basi del linguaggio Java

Esercizio 2 (punti 7) Dato il seguente programma C: #include <stdio.h> int swap(int * nome, int length);

Strutture Dinamiche. Fondamenti di Informatica

ELEMENTI DI INFORMATICA L-B. Ing. Claudia Chiusoli

Introduzione al C. Unità Gestione Dinamica della Memoria

Programmazione I - Laboratorio

Allocazione statica della memoria

Esercizio 2: Algebra dei Puntatori e Puntatori a Puntatori

I puntatori. Un puntatore è una variabile che contiene l indirizzo di un altra variabile. puntatore

File e puntatori a file

Linguaggio C: PUNTATORI

Informatica 1. Prova di recupero 21 Settembre 2001

Esercitazione 12. Esercizi di Ricapitolazione

Puntatori. Unità 6. Domenico Daniele Bloisi. Corso di Fondamenti di Informatica Ingegneria delle Comunicazioni BCOR Ingegneria Elettronica BELR

Espressione di chiamata di funzione

Puntatori. Unità 6. Corso di Laboratorio di Informatica Ingegneria Clinica BCLR. Domenico Daniele Bloisi

4 Le liste collegate 4.0. Le liste collegate. 4 Le liste collegate Rappresentazione di liste 4.1 Rappresentazione di liste

Un esempio per iniziare. Il controllo del programma in C. Altri cenni su printf() Esercizi (printf) printf( 8!=%d, fatt);

Fondamenti di Informatica 2

Caratteri e stringhe

Vettori di caratteri. Caratteri e stringhe. Stringhe in C. Vettori di caratteri. char saluto[10] ; B u o n g i o r n o 4. Esempio.

Le funzioni, e le istruzioni di input/output

Funzioni. (Passaggio dei parametri per riferimento) Passaggio dei parametri

Complementi. - Ridefinizione di tipo - - Costrutto switch - - Programmazione su più file - - Parametri della funzione main - Funzione system -

Esercizi C su array e matrici

Linguaggio C. tipi di dati definiti dall utente. Università degli Studi di Brescia. Docente: Massimiliano Giacomin

Caratteri e stringhe. Vettori di caratteri. Il tipo stringa Terminatore nullo Input/output di stringhe Politecnico di Torino 1

Non ci sono vincoli sul tipo degli elementi di un vettore Possiamo dunque avere anche vettori di

1 (6) 2 (7) 3 (7) 4 (7) 5 (6)

Il linguaggio C. Notate che...

Lezione 21 e 22. Valentina Ciriani ( ) Laboratorio di programmazione. Laboratorio di programmazione. Lezione 21 e 22

Fondamenti di Informatica T-1, 2014/2015 Modulo 2. Prova d Esame 2A di Martedì 29 Gennaio 2015 tempo a disposizione 2h

Programmazione. Laboratorio. Roberto Cordone DI - Università degli Studi di Milano

Il linguaggio C. Puntatori e dintorni

Esercizio 1. Esercizio 1 - Soluzione

Fondamenti di Informatica AA 2016/2017

ERRATA CORRIGE. void SvuotaBuffer(void); void SvuotaBuffer(void) { if(getchar()!=10) {svuotabuffer();} }

PROVA SCRITTA DEL CORSO DI CORSO DI LAUREA IN INGEGNERIA BIOMEDICA ED ELETTRICA 9/6/2008

Gestione dei file. Stefano Ferrari. Università degli Studi di Milano Programmazione. anno accademico

Input/output da file I/O ANSI e I/O UNIX FLUSSI E FILE FLUSSI FLUSSI di TESTO FLUSSI BINARI FILE

Esercizio 1: calcolo insieme intersezione

Le librerie standard. ! La libreria standard del C è in realtà un insieme di librerie

Allocazione dinamica

Strategie di programmazione

Compendio sottoinsieme del C++ a comune col C. (Libreria standard, Input/Output, Costanti, Dichiarazioni e typedef, Memoria Dinamica)

Laboratorio di Programmazione: Linguaggio C Lezione 21 del 19 maggio 2014

Prova di Laboratorio del [ Corso A-B di Programmazione (A.A. 2004/05) Esempio: Media Modalità di consegna:

Implementazione di Liste puntate

Esercizio n.1 FONDAMENTI DI INFORMATICA 1. Esercizio n.2. Soluzione. LINGUAGGIO C Funzioni e gestione file: esercitazione

Appunti tratti dal videocorso on-line di Algoritmi e Programmazione Avanzata By ALeXio

Il puntatore. Il puntatore

Informatica 1. Corso di Laurea Triennale in Matematica. Gianluca Rossi

Array Tipi di dato semplici e strutturati strutturati array elementi omogenei numero d ordine indice lunghezza dimensione

ESECUZIONE DI PROGRAMMI C SU MACCHINE REALI. Docente: Giorgio Giacinto AA 2008/2009. formalizzazione degli algoritmi in linguaggio C

Linguaggio C. Generalità sulle Funzioni. Variabili locali e globali. Passaggio di parametri per valore.

Transcript:

I puntatori e l allocazione dinamica di memoria

Allocazione dinamica di memoria L allocazione delle variabili Allocazione e rilascio espliciti di memoria Le funzioni malloc e free 2

Allocazione dinamica di memoria

Allocare = collocare in memoria Allocare una variabile significa associare alla variabile una porzione di memoria (in cui collocare i dati) L allocazione avviene in modo Permanente, per le variabili globali (definite, nel file C, al di fuori da funzioni) Temporaneo, per le variabili locali e I parametri formali (definiti all interno delle funzioni). Una variabile locale viene Allocata alla chiamata della funzione De-allocata all uscita dalla funzione 4

Programma in esecuzione e memoria #define MAX 100 struct studente ; struct studente dati[maxn]; int main(void) char nomefile[maxriga]; FILE *fp; void ordinastudenti( struct studente el[], int n) int i, j, max; ; RAM (1 GB) 5

Programma in memoria #define MAX 100 struct studente ; struct studente dati[maxn]; int main(void) char nomefile[maxriga]; FILE *fp; void ordinastudenti( struct studente el[], int n) int i, j, max; ; RAM (1 GB) 6

Programma in memoria #define MAX 100 struct studente ; struct studente dati[maxn]; int main(void) char nomefile[maxriga]; FILE *fp; void ordinastudenti( struct studente el[], int n) int i, j, max; ; Codice (istruzioni) RAM (1 GB) 7

Programma in memoria #define MAX 100 struct studente ; struct studente dati[maxn]; int main(void) char nomefile[maxriga]; FILE *fp; void ordinastudenti( struct studente el[], int n) int i, j, max; ; Codice (istruzioni) RAM (1 GB) 8

Programma in memoria #define MAX 100 struct studente ; struct studente dati[maxn]; int main(void) char nomefile[maxriga]; FILE *fp; void ordinastudenti( struct studente el[], int n) int i, j, max; ; Codice (istruzioni) Variabili globali RAM (1 GB) 9

Programma in memoria #define MAX 100 struct studente ; struct studente dati[maxn]; int main(void) char nomefile[maxriga]; FILE *fp; void ordinastudenti( struct studente el[], int n) int i, j, max; ; Codice (istruzioni) Variabili globali RAM (1 GB) 10

Programma in memoria #define MAX 100 struct studente ; struct studente dati[maxn]; int main(void) char nomefile[maxriga]; FILE *fp; void ordinastudenti( struct studente el[], int n) int i, j, max; ; Codice (istruzioni) Variabili globali Variabili locali e parametri (formali) RAM (1 GB) 11

Programma in memoria #define MAX 100 struct studente ; In memoria (virtualmente) struct durante studente tutta l esecuzione dati[maxn]; int main(void) del programma char nomefile[maxriga]; FILE *fp; void ordinastudenti( struct studente el[], int n) int i, j, max; ; Codice (istruzioni) Variabili globali Variabili locali e parametri (formali) RAM (1 GB) 12

Programma in memoria #define MAX 100 struct studente ; struct studente dati[maxn]; int main(void) char nomefile[maxriga]; FILE *fp; In memoria (virtualmente) durante l esecuzione della void ordinastudenti( struct studente el[], int n) int i, j, max; ; relativa funzione: allocate e de-allocate automaticamente Codice (istruzioni) Variabili globali Variabili locali e parametri (formali) RAM (1 GB) 13

Programma in memoria #define MAX 100 struct studente ; struct La quantità studente di memoria dati[maxn]; int allocare main(void) è determinata dal programmatore: char nomefile[maxriga]; - Istruzioni FILE *fp; void - Dimensione ordinastudenti( dei vettori struct studente el[], int n) int i, j, max; ; - Tipo e numero delle variabili Codice (istruzioni) Variabili globali Variabili locali e parametri (formali) RAM (1 GB) 14

Allocazione dinamica di memoria

Cosa manca? Osservazione: manca un modo per poter decidere, durante l esecuzione di un programma Creazione un dato Dimensionamento di un vettore Soluzione: istruzioni per allocare e de-allocare dati (memoria) in modo esplicito In funzione di dati forniti da chi esegue il programma Allocazioni e de-allocazioni sono (ovviamente) previste dall autore del programma 16

Come allocare in modo esplicito? Il C fornisce un meccanismo di allocazione e deallocazione esplicito, basato su puntatori Allocare = chiedere memoria (al Sistema Operativo) e ottenerla (se c è abbastanza memoria disponibile) De-allocare = rilasciare (restituire) la memoria precedentemente ottenuta (in modo che il S.O. possa riutilizzarla) Alla memoria allocata si accede tramite puntatore, cioè indirizzo+tipo L allocazione esplicita viene detta dinamica, per il modo (non statico) di gestione 17

Programma in memoria int main(void) int *p = malloc(); /* p usato come vettore */ free(p); p Codice (istruzioni) Variabili globali Variabili locali e parametri (formali) Memoria dinamica RAM (1 GB) 18

Programma in memoria int main(void) int *p = malloc(); /* p usato come vettore */ free(p); p Codice (istruzioni) Allocazione Variabili globali Variabili locali e parametri (formali) RAM (1 GB) 19

Programma in memoria int main(void) int *p = malloc(); /* p usato come vettore */ free(p); p Codice (istruzioni) Rilascio (de-allocazione) Variabili globali Variabili locali e parametri (formali) RAM (1 GB) 20

Allocazione dinamica di memoria

Allocazione mediante malloc (1/3) La memoria in C viene allocata dinamicamente tramite la funzione malloc (e altre, quali calloc, realloc, ) La funzione di libreria malloc ha un prototipo simile al seguente void* malloc (int dimensione); Dimensione è il numero (intero) di byte da allocare Il valore di ritorno è un puntatore Indirizzo iniziale della memoria allocata (NULL se non c è memoria disponibile) tipo void *, tale da poter essere assegnato a qualunque tipo di puntatore 22

Allocazione mediante malloc (2/3) Per usarla occorre includere <stdlib.h> Per utilizzare correttamente malloc occorre richiedere una quantità di memoria compatibile col puntatore cui sarà assegnato il risultato (cioè la variabile generata dinamicamente) 23

Allocazione mediante malloc (3/3) Solitamente si ricorre all operatore sizeof per determinare la dimensione (in byte) di un dato. Per generare una variabile dinamica di tipo <tipo>, da assegnare a p (<tipo> *p), sono possibili 2 schemi Per ottenere una variabile scalare o struct p = malloc (sizeof (<tipo>)); Per ottenere un vettore di n elementi p = malloc (n*sizeof (<tipo>)); 24

Esempio: variabile dinamica singola struct studente char cognome[max], nome[max]; int matricola; struct studente *link; ; struct studente *creastud ( char *cognome, char *nome, int matricola ) struct studente *s; s = malloc (sizeof (struct studente)); if (s==null) return NULL; strcpy(s->cognome,cognome); strcpy(s->nome,nome); s->matricola = matricola; s->link = NULL; return s; ; 25

Esempio: variabile dinamica singola struct studente char cognome[max], nome[max]; int matricola; struct studente *link; ; struct studente *creastud ( char *cognome, char *nome, int matricola ) struct studente *s; s = malloc (sizeof (struct studente)); if (s==null) return NULL; strcpy(s->cognome,cognome); strcpy(s->nome,nome); Si potrebbe scrivere anche: s->matricola = matricola; s->link = NULL; return s = s; malloc (sizeof *s); ; 26

Esempio: vettore dinamico int *punt; int n; scanf ( %d, &n); punt = malloc(n*sizeof(int)); if (punt == NULL) printf ( Errore di allocazione\n ); else 27

Esempio: vettore dinamico int *punt; int n; scanf ( %d, &n); punt = malloc(n*sizeof(int)); if (punt == NULL) printf ( Errore di allocazione\n ); punt è un vettore dinamico di n interi else 28

De-allocazione mediante free (1/2) La memoria allocata dinamicamente viene restituita tramite la funzione free La funzione di libreria free ha un prototipo simile al seguente void free (void* p); p punta alla memoria (precedentemente allocata) da liberare La funzione non ritorna risultato 29

De-allocazione mediante free (2/2) Per usarla occorre includere <stdlib.h> La funzione free viene di solito chiamata quando è terminato il lavoro sulla variabile dinamica, affinchè la memoria possa essere riutilizzata 30

Esempio: vettore dinamico int *punt; int i, n; scanf ( %d, &n); punt = malloc(n*sizeof(int)); for (i=0; i<n; i++) punt[i] = ; free(punt); 31

I puntatori e l allocazione dinamica di memoria

Strutture dati dinamiche Vettori dinamici Matrici dinamiche Liste 2

Strutture dati dinamiche

Vettore dinamico Si dice vettore dinamico un vettore la cui dimensione è nota solo in fase di esecuzione del programma Soluzione Puntatore, sfruttando la dualità puntatore-vettore Allocazione mediante malloc Rilascio mediante free Per il resto, non cambia nulla rispetto al vettore sovradimensionato in modo statico 4

Esempio Acquisire da tastiera una serie di numeri reali, e memorizzarli in un vettore Stamparli successivamente in ordine inverso a quello di acquisizione La quantità di numeri non è nota al programmatore, né sovradimensionabile, ma è acquisita come primo dato da tastiera 5

Esempio Acquisire da tastiera una serie di numeri reali, e memorizzarli in un vettore Stamparli successivamente in ordine inverso a quello di acquisizione La quantità di numeri non è nota al programmatore, né sovradimensionabile, ma è acquisita come primo dato da tastiera Attenzione! Per creare un vettore dinamico occorre conoscerne la dimensione prima di iniziare ad utilizzarlo. Se il numero di dati (ignoto) fosse segnalato da un terminatore (es. input del valore 0), non si potrebbe usare un vettore dinamico 6

Soluzione (1/2) float *v; int N, i; InvertiOrdine.c printf( Quanti elementi vuoi inserire? "); scanf( %d,&n); /* alloca vettore */ v = malloc (N*(sizeof (float))); if (v==null) exit; 7

Soluzione (2/2) /* input */ printf("inserisci %d elementi\n, N); InvertiOrdine.c for (i=0; i<n; i++) printf("elemento %d: ", i+1) ; scanf("%f", &v[i]) ; /* output */ printf( Dati in ordine inverso\n ); for (i=n-1; i>=0; i--) printf("elemento %d: %f\n", i+1, v[i]); /* libera memoria dinamica */ free(v); 8

Strutture dati dinamiche

Matrice dinamica (1/2) Si dice matrice dinamica una matrice la cui dimensione è nota solo in fase di esecuzione del programma Soluzione 1 (meno flessibile): vettore dinamico e organizzazione manuale di righe e colonne su vettore 10

Matrice dinamica (2/2) Soluzione 2: vettore dinamico di puntatori a righe (o dualmente vettore di puntatori a colonne) Puntatore, sfruttando la dualità puntatore-vettore Allocazione dinamica del vettore di puntatori Iterazione di allocazione delle righe Per il resto, non cambia nulla rispetto alla matrice sovradimensionata in modo statico 11

Esempio Acquisire da tastiera una matrice di numeri reali, e memorizzarli in un vettore Stampare successivamente la matrice trasposta (righe e colonne scambiate di ruolo) Le dimensioni della matrice (righe e colonne) non sono note al programmatore, né sovradimensionabili, ma sono acquisite come primo dato da tastiera 12

Soluzione con vettore dinamico (1/2) float *v; int nr,nc,i,j; printf( Dimensioni (NR NC): "); scanf( %d%d, &nr, &nc); v = malloc (nr*nc*(sizeof (float))); if (v==null) exit; /* input */ for (i=0; i<nr; i++) printf("inserisci riga %d\n, i); for (j=0; j<nc; j++) scanf("%f", &v[nc*i+j]); matricetraspostavettdyn.c 13

Soluzione con vettore dinamico (2/2) /* output */ printf( Matrice trasposta\n ); for (j=0; j<nc; j++) for (i=0; i<nr; i++) printf("%6.2f, v[nc*i+j]); printf( \n ); /* libera memoria dinamica */ free(v); matricetraspostavettdyn.c 14

Soluzione con matrice dinamica (1/3) float **v; int nr,nc,i,j; matricetraspostamatdyn.c printf( Dimensioni (NR NC): "); scanf( %d%d, &nr, &nc); /* allocazione vettore di puntatori */ v = malloc (nr*sizeof (float *)); if (v==null) exit; 15

Soluzione con matrice dinamica (2/3) /* allocazione righe e input */ for (i=0; i<nr; i++) printf("inserisci riga %d\n, i); v[i] = malloc (nc*sizeof (float)); if (v[i]==null) exit; for (j=0; j<nc; j++) scanf("%f", &(v[i][j])); matricetraspostamatdyn.c 16

Soluzione con matrice dinamica (3/3) /* output */ printf( Matrice trasposta\n ); for (j=0; j<nc; j++) for (i=0; i<nr; i++) printf("%6.2f, v[i][j]); printf( \n ); /* libera memoria dinamica */ free(v); matricetraspostamatdyn.c 17

Strutture dati dinamiche

Lista concatenata (1/2) Una lista è una struttura dati dinamica concatenata in cui Ogni elemento conosce il successivo Esiste un elemento iniziale (testa) e uno finale (coda) della lista Si possono fare inserimenti, ricerche, estrazioni ed altre operazioni 19

Lista concatenata (2/2) Le liste non sono fornite dal linguaggio C come tipo predefinito, ma possono essere realizzate mediante strutture ricorsive La trattazione delle liste è al di la degli obiettivi di questo corso. Vediamo un esempio semplice 20

Esercizio: problema di Giuseppe Flavio N oggetti sono disposti in cerchio. Per semplicità gli oggetti sono numerati da 1 a N (N viene acquisito da tastiera) Si elimina un oggetto ogni M (in senso antiorario) e si richiude il cerchio Quale oggetto rimane per ultimo? Con quale ordine si eliminano gli oggetti? 21

Giuseppe Flavio dinamico: soluzione (1/2) struct oggetto int numero; GiuseppeFlavioDyn.c struct oggetto *succ; ; int main(void) int i, N, M; struct oggetto *p, *x; /* genera primo oggetto */ p=malloc(sizeof *p); p->numero=1; p->succ=p; x=p; /* x punta al primo oggetto */ printf( N = ); scanf( %d, &N); printf( M = ); scanf( %d, &M); 22

Giuseppe Flavio dinamico: soluzione (2/2) for (i=2; i<=n; i++) x = (x->succ = malloc(sizeof *x)); x->numero = i; x->succ = p; p=x; /* p punta all ultimo */ while (p!= p->succ) for (i=1; i<m; i++) p = p->succ; printf( Eliminato n.%d\n, p->succ->numero); x = p->succ; p->succ = p->succ->succ; free(x); printf( Ultimo n.%d\n, p->numero); GiuseppeFlavioDyn.c 23

I puntatori e l allocazione dinamica di memoria

Esercizi proposti Esercizio Mini-Editor 2

Esercizi proposti

Esercizio Mini-Editor Sia dato un file testo, contenente un certo numero (non noto) di righe, aventi ognuna non più di 80 caratteri (a-capo incluso) Si realizzi in C un programma che, acquisito da tastiera il nome del file, lo legga, immagazzinandone il contenuto in una opportuna struttura dati in memoria, quindi effettui mediante presentazione a menu (con comandi ricevuto da tastiera) una tra le operazioni seguenti 4

Esercizio Mini-Editor : menu Ricerca di una stringa nel testo (contando quante volte compare) Ricerca (stringa x) e sostituzione (con stringa y): ogni occorrenza di x nel testo viene sostituita da y Visualizza (da i a j): visualizza le righe dalla i- esima alla j-esima (incluse) Salva: salva il testo su un file (il cui nome va acquisito da tastiera Esci: fine del programma 5

Struttura dati (1/2) Vettore dinamico di stringhe (o matrice dinamica di caratteri) È necessario in quanto occorre immagazzinare tutti i dati, sui cui fare più elaborazioni. Sarebbe possibile operare sulle singole righe, secondo lo schema (input manipolazione output), solo riscrivendo, per ogni comando, il risultato su un file (temporaneo) intermedio La dimensione del vettore non è nota, ma può essere calcolata mediante una lettura preliminare del file 6

Struttura dati (2/2) Per ogni riga del file si alloca dinamicamente una stringa La riga viene acquisita in un vettore (sovradimensionato) di lunghezza fissa Successivamente si alloca il vettore dinamico e vi si copia la riga di caratteri La ricerca/sostituzione può richiedere una nuova stringa (di lunghezza diversa) 7

Algoritmo Input dei dati (tutti) da file a vettore Iterazione di esecuzione di comandi menu = selezione dei possibili comandi, riconosciuti dal primo carattere (selezione a switch) formato r <stringa>: ricerca <stringa> s <x> <y>: sostituisci <x> con <y> f <i> <j>: salva su file <f> da riga <i> a riga <j> (se <f> è stdout visualizza su video) u: uscita dal programma (fine) Per semplicità si omettono controlli di errore su apertura file e fallita allocazione di memoria 8

Mini-Editor (1/7) const int MAXRIGA=80; char **testo; int nrighe; int leggipagina(char *nomefile); int menu(void); void cerca (char *s); void sostituisci (char *s0, char *s1); void stampa (char *nomefile, int i, int j); int main(void) char nomefile[maxriga]; printf( nome file in ingresso: ); scanf( %s, nomefile); leggipagina(nomefile); while (menu()!=0); minieditor.c 9

Mini-Editor (1/7) const int MAXRIGA=80; char **testo; int nrighe; int leggipagina(char *nomefile); int menu(void); void cerca (char *s); Variabili globali, visibili a tutte le funzioni void sostituisci (char *s0, char *s1); void stampa (char *nomefile, int i, int j); int main(void) char nomefile[maxriga]; printf( nome file in ingresso: ); scanf( %s, nomefile); leggipagina(nomefile); while (menu()!=0); minieditor.c 10

Mini-Editor (2/7) int leggipagina(char *nomefile) FILE *fp; minieditor.c char s[maxriga+1]; /* +1 per \0 */ int i; fp = fopen(nomefile, r ); /* iterazione di conteggio righe */ for (i=0; fgets(s,maxriga,fp)!=null;i++); nrighe = i; /* chiude e riapre file */ fclose(fp); fp = fopen(nomefile, r ); /* alloca vettore dinamico */ testo = malloc(nrighe*sizeof(char *)); 11

Mini-Editor (3/7) int leggipagina(char *nomefile) FILE *fp; minieditor.c char s[maxriga+1]; /* +1 per \0 */ int i; /* leggi righe */ for (i=0; i<nrighe; i++) fgets(s,maxriga,fp); if (s[strlen(s)-1]== \n ) s[strlen(s)-1] = \0 ; testo[i]=malloc((strlen(s)+1)*sizeof(char)); strcpy(testo[i],s); 12

Mini-Editor (3/7) int leggipagina(char *nomefile) FILE *fp; char s[maxriga+1]; /* +1 per \0 */ int i; /* leggi righe */ for (i=0; i<nrighe; i++) fgets(s,maxriga,fp); if (s[strlen(s)-1]== \n ) s[strlen(s)-1] = \0 ; Lettura riga su stringa locale (la stessa per tutte le righe) minieditor.c testo[i]=malloc((strlen(s)+1)*sizeof(char)); strcpy(testo[i],s); 13

Mini-Editor (3/7) int leggipagina(char *nomefile) FILE *fp; char s[maxriga+1]; /* +1 per \0 */ int i; /* leggi righe */ Elimina eventuale a-capo for (i=0; i<nrighe; i++) fgets(s,maxriga,fp); if (s[strlen(s)-1]== \n ) s[strlen(s)-1] = \0 ; testo[i]=malloc((strlen(s)+1)*sizeof(char)); strcpy(testo[i],s); minieditor.c 14

Mini-Editor (3/7) int leggipagina(char *nomefile) FILE *fp; char s[maxriga+1]; /* +1 per \0 */ int i; Alloca i-esima riga (della /* leggi righe */ lunghezza corretta) e copia for (i=0; i<nrighe; contenuto i++) fgets(s,maxriga,fp); if (s[strlen(s)-1]== \n ) s[strlen(s)-1] = \0 ; testo[i]=malloc((strlen(s)+1)*sizeof(char)); strcpy(testo[i],s); minieditor.c 15

Mini-Editor (4/7) int menu (void) char com[maxriga], s0[maxriga], s1[maxriga]; int i, j; printf( comando (r/s/f/u): ); gets(com); switch(com[0]) case r :sscanf(com, r %s,s0); cerca(s0); break; case s :sscanf(com, s %s%s,s0,s1); sostituisci(s0,s1); break; case f :sscanf(com, f %s%d%d,s0,&i,&j); stampa(s0,i,j); break; case u : return 0; return 1; minieditor.c 16

Mini-Editor (5/7) void cerca (char *s) int i, conta; minieditor.c char *riga; for (i=0; i<nrighe; i++) riga = testo[i]; conta=0; while ((riga=strstr(riga,s))!=null) conta++; riga++; if (conta>0) printf( Trovato %d volta/e in riga %d\n, conta, i); 17

Mini-Editor (5/7) void Evita cerca stringa (char appena *s) trovata, incrementando riga al carattere successivo. Si accettano int i, conta; sovrapposizioni. char *riga; Es. for aa (i=0; viene i<nrighe; trovato 2 volte i++) in xaaay riga = testo[i]; conta=0; while ((riga=strstr(riga,s))!=null) conta++; riga++; if (conta>0) printf( Trovato %d volta/e in riga %d\n, conta, i); minieditor.c 18

Mini-Editor (6/7) void sostituisci (char *s0, char *s1) int i,l,l0=strlen(s0),l1=strlen(s1); char *riga, *nuova; for (i=0; i<nrighe; i++) riga = testo[i]; while ((riga=strstr(riga,s0))!=null) l = strlen(testo[i])+l1-l0; nuova = malloc((l+1)*sizeof(char)); strncpy(nuova,testo[i],riga-testo[i]); nuova[riga-testo[i]]= \0 ; strcat(nuova,s1); strcat(nuova,riga+l0); free(testo[i]); riga=testo[i]=nuova; minieditor.c 19

Mini-Editor (6/7) void sostituisci (char *s0, char *s1) int i,l,l0=strlen(s0),l1=strlen(s1); char *riga, *nuova; for (i=0; i<nrighe; i++) riga = testo[i]; while ((riga=strstr(riga,s0))!=null) l = strlen(testo[i])+l1-l0; nuova = malloc((l+1)*sizeof(char)); strncpy(nuova,testo[i],riga-testo[i]); nuova[riga-testo[i]]= \0 ; strcat(nuova,s1); strcat(nuova,riga+l0); free(testo[i]); riga=testo[i]=nuova; Puntatore a stringa iniziale o a sottostringa trovata in essa minieditor.c 20

Mini-Editor (6/7) void sostituisci (char *s0, char *s1) int i,l,l0=strlen(s0),l1=strlen(s1); char *riga, *nuova; for (i=0; i<nrighe; i++) riga = testo[i]; while ((riga=strstr(riga,s0))!=null) l = strlen(testo[i])+l1-l0; nuova = malloc((l+1)*sizeof(char)); strncpy(nuova,testo[i],riga-testo[i]); nuova[riga-testo[i]]= \0 ; strcat(nuova,s1); strcat(nuova,riga+l0); free(testo[i]); riga=testo[i]=nuova; Puntatore a nuova stringa (eventualmente di lunghezza diversa) minieditor.c 21

Mini-Editor (6/7) void sostituisci (char *s0, char *s1) int i,l,l0=strlen(s0),l1=strlen(s1); char *riga, *nuova; for (i=0; i<nrighe; i++) riga = testo[i]; while ((riga=strstr(riga,s0))!=null) l = strlen(testo[i])+l1-l0; nuova = malloc((l+1)*sizeof(char)); strncpy(nuova,testo[i],riga-testo[i]); nuova[riga-testo[i]]= \0 ; strcat(nuova,s1); strcat(nuova,riga+l0); free(testo[i]); riga=testo[i]=nuova; minieditor.c 22

Mini-Editor (6/7) void sostituisci (char *s0, char *s1) Concatena 3 pezzi: int -i,l,l0=strlen(s0),l1=strlen(s1); Parte iniziale (prima della sottostringa trovata) char -Stringa *riga, s1*nuova; for -(i=0; parte finale i<nrighe; (dopo la i++) sottostringa trovata) riga = testo[i]; while ((riga=strstr(riga,s0))!=null) l = strlen(testo[i])+l1-l0; nuova = malloc((l+1)*sizeof(char)); strncpy(nuova,testo[i],riga-testo[i]); nuova[riga-testo[i]]= \0 ; strcat(nuova,s1); strcat(nuova,riga+l0); free(testo[i]); riga=testo[i]=nuova; minieditor.c 23

Mini-Editor (7/7) void stampa (char *nomefile, int i, int j) FILE *fp; int k; minieditor.c if (strcmp(nomefile, stdout )==0) fp = stdout; else fp = fopen(nomefile, w ); if (j>=nrighe) j=nrighe-1; for (k=i; k<=j; k++) fprintf(fp, %s\n,testo[k]); if (fp!= stdout) fclose(fp) 24

I puntatori e l allocazione dinamica di memoria

Argomenti trattati Il puntatore come dato e riferimento dato Variabili e operatori sui puntatori Utilizzo avanzato dei puntatori con Vettori e matrici Strutture L allocazione dinamica di memoria e le strutture dati dinamiche Esercizi 2

Tecniche di programmazione Gestione di riferimenti a dati privi di nome Manipolazione dei puntatori e aritmetica Parametri per riferimento Strutture puntate Vettori e matrici dinamiche 3

Suggerimenti I puntatori sono un efficace strumento per Parametri per riferimento Allocazione dinamica (esplicita) di dati Vantaggi Accesso a dati altrimenti non manipolabili (mediante nome) Maggior flessibilità e possibilità di gestire meglio la memoria disponibile Possibilità di adattare la dimensione dei dati all input del programma (in esecuzione) 4

Materiale aggiuntivo Sul CD-ROM Testi e soluzioni degli esercizi trattati nei lucidi Scheda sintetica Esercizi risolti Esercizi proposti Esercizi proposti da altri libri di testo 5