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