Introduzione alla programmazione ricorsiva
|
|
|
- Marianna Venturi
- 9 anni fa
- Visualizzazioni
Transcript
1 Introduzione alla programmazione ricorsiva chiamata ricorsiva di sottoprogrammi un sottoprogramma P chiama lo stesso P direttamente o indirettamente (e.g., P chiama Q che chiama P) sembra circolo vizioso per molti problemi soluzione per un caso generico ricavata della soluzione di altro caso, più semplice, dello stesso problema Esempi di problemi con formulazione e soluzione ricorsiva Funzione fattoriale f(n) = n! = n * (n-1) * (n-2) * 3 * 2 * 1 può essere definito RICORSIVAMENTE come segue: Se n=0 allora f(n) = 1 (base della ricorsione) Se n>0 allora f(n) = n * f(n-1) (passo ricorsivo) numeri di Fibonacci (modello di crescita di animali in parecchie generazioni) F = f 0,, f n, f 0 = 0 (caso base) f 1 = 1 (caso base) Per n > 1, f n = f n 1 + f n 2 (caso risorsivo) da cui per esempio f 0 = 0 f 1 = 1 f 2 = f 1 + f 0 = = 0 f 3 = f 2 + f 1 = = 2 f 4 = f 3 + f 2 = = 3 quinto fascicolo - 1 -
2 massimo comune divisore, MCD(m, n) di due numeri m ed n in base all algoritmo di Euclide se m = n, MCD(m, n) = m (caso base) se m > n, MCD(m, n) = MCD(m-n, n) (caso risorsivo) se m < n MCD(m, n) = MCD(m, n-m) (caso risorsivo) ciò perchè se m > n divisori comuni a m e n coincidono con divisori comuni a m n e n ragionamento può essere ripetuto ripetendo prima o poi si arriva a una coppia di numeri uguali
3 programmazione di funzioni ricorsive funzione non ricorsiva per il calcolo del fattoriale int fatt (int n) int i, ris; ris = 1; for (i = 1; i <=n; i= i+1) ris = ris * i; return ris; basandosi su definizione ricorsiva n! = n (n 1)!, con 0! = 1 per convenzione int FattRic (int n) if (n == 0) return 1; else return n * FattRic(n 1); simulazione del calcolo di FattRic(3) 1. 3 = 0? No. calcola fattoriale di 2 e moltiplica per = 0? No. calcola fattoriale di 1 e moltiplica per = 0? No. calcola fattoriale di 0 e moltiplica per = 0? Sì. fattoriale di 0 è fattoriale di 1 è 1 per fattoriale di 0, cioè 1 1 = fattoriale di 2 è 2 per fattoriale di 1, cioè 2 1 = fattoriale di 3 è 3 per fattoriale di 2, cioè 3 2 =
4 Calcolo numero di Fibonacci di indice n int fibonacci (int n) if (n == 0) return 0; else if (n == 1) return 1; else return fibonacci(n 1) + fibonacci(n 2); Calcolo MCD con algoritmo Euclide Versione iterativa int EuclideIter (int m, n) while( m!= n ) if ( m > n ) m = m n; else n = n m; return m; varsione ricorsiva int EuclideRic (int m, n) if ( m == n ) return m; else if ( m > n ) return EuclideRic(m-n, n); else return EuclideRic(m, n - m);
5 esecuzione dei sottoprogrammi ricorsivi NB: possono essere in corso diverse attivazioni del sottoprogramma ricorsivo a ogni sua esecuzione si associa un area dati distinta contiene copie distinte di parametri e variabili locali Esecuzione di FattRic(3) rischio di catene infinite di chiamate condizione NECESSARIA (non sufficiente) per evitarlo le chiamate ricorsive siano condizionate ( una chiamata può NON generarne un altra) le chiamate ricorsive abbiano argomenti RIDOTTI (contro) esempi catena infinita, argomento decrescente int FattRic(int n) return n * FattRic(n 1); catena infinita di chiamate identiche int FattRic(int n) FattRic(n); - 5 -
6 Attenzione ai parametri passati per indirizzo nelle chiamate ricorsive Esempio void incrementa(int *n, int m) /* incrementa il primo parametro del valore del secondo */ if (m!= 0) *n = *n + 1; incrementa(n, m 1); /* NB: n, non &n, passa per valore indirizzo ricevuto per valore */ int x, y; x = 2, y = 3. incrementa(&x, y); /* NB la chiamata iniziale ha forma diversa dalla chiamata ricorsiva */ - 6 -
7 Esempio: riconoscimento delle stringhe palindrome stringa palindroma uguale se letta nei due versi anna, radar, asorrosa, abbbcbbba programma RicPalindr riconosce stringhe palindrome, anche vuote usa procedura ricorsiva, Palindrome basata su constatazione stringa palindrome è vuota, o un solo carattere, o palindrome racchiusa tra due caratteri, primo e ultimo, uguali RicPalindr legge stringa (termina con \0) calcola la lunghezza con strlen da <string.h> se stringa vuota o di un carattere palindroma se caratteri agli estremi diversi NON palindroma altrimenti applica funzione Palindrome a stringa privata di estremi elegante uso puntatori a inizio e fine stringa ( indirizzi prima e ultima componente esaminata dell array) spostati avanti e indietro da una chiamata ricorsiva alla successiva - 7 -
8 /* Programma RicPalindr*/ #include <stdio.h> #include <string.h> #define LunghMaxStringa 100 typedef enum false, true boolean; main() char Stringa1[LunghMaxStringa]; boolean OK; unsigned LunghStringa; boolean Palindrome(char *PC, char *UC); scanf("%s", Stringa1); /* NB assume caratteri componenti stringa non siano spazi */ LunghStringa = strlen(stringa1); /* attenzione strlung sul libro è scorretta */ if (LunghStringa == 0) printf("la stringa è palindroma"); else OK = Palindrome(&Stringa1[0], &Stringa1[LunghStringa 1] ); if (OK == true) pritnf("la stringa è palindroma ); else printf("la stringa non è palindroma"); boolean Palindrome(char, *PC, char *UC) if (PC >= UC) /* stringa vuota o di un solo carattere */ return true; else if (*PC!= *UC) /* primo e ultimo carattere diversi */ return false; else /* chiamata ricorsiva escludendo primo e ultimo carattere */ return Palindrome(PC+1, UC 1); - 8 -
9 Strutture dati dinamiche allocazione statica di memoria dimensioni fisiche dati note prima di esecuzione programma memoria per esecuzione calcolata dal compilatore prima di esecuzione risponde a esigenza di minimizzare tempo esecuzione anticipando elaborazioni (compilazione) eccezione: programmazione ricorsiva ma ambiente dei sottoprogrammi ha dimensioni note e allocato sistematicamente (pila) rimane problema dei dati in quantità sconosciuta o variabile durante esecuzione array inadeguati: pericolo di spazio insufficiente overflow oppure spreco di memoria inserzioni/cancellazioni in array (soprattutto ordinati) sono onerose variabili dinamiche (ad allocazione dinamica) allocate (e deallocate) durante l esecuzione del programma in numero variabile sono anonime: non esiste corrispondenza fissa con identificatori per accedere a variabili dinamiche usati PUNTATORI puntatori variabili che memorizzano indirizzi di variabili (dinamiche) allocazione e rilascio dinamico di memoria mediante funzioni della standard library (<stdlib.h>) malloc per allocazione free per rilascio - 9 -
10 seguente codice TipoDato *P; P = malloc(sizeof(tipodato)); crea in memoria variabile di tipo TipoDato restituisce l indirizzo della variabile creata (primo byte) assegna l indirizzo restituito a P P perde eventuale valore precedente, punta alla variabile dinamica Simmetricamente, istruzione free(p); rilascia spazio di memoria puntato da P in quantità pari alla dimensione di TipoDato, il tipo puntato da P memoria diventa nuovamente disponibile NB (ovviamente) free deve ricevere solo puntatore a variabile dinamica in testa al file del codice dev essere messo #include <stdlib.h> stdlib.h contiene prototipi delle funzioni di allocazione dinamica dichiarazione della costante NULL (puntatore nullo) durante esecuzione memoria usata da programma partizionata in due pila (stack) per variabili statiche mucchio (heap) per variabili dinamiche int int *Punt1; **Punt2;
11 Rischi della gestione dinamica della memoria effetti collaterali (già visti) produzione di spazzatura (garbage) memoria allocata dinamicamente risulta inaccessibile ( sprecata) perché nessun puntatore punta a essa Esempio banale (esempi realistici più involuti) TipoDato *P, *Q; P = malloc(sizeof(tipodato));. Q = malloc(sizeof(tipodato)); P = Q; /* la variabile puntata da P diventa garbage */ problema simmetrico: riferimenti fluttuanti (dangling references) puntatore punta a zona di memoria deallocata ( a variabile dinamica inesistente) P = Q; free(q); /* ora *P causa un errore */ dangling references più gravi della produzione di garbage: porta a veri e propri errori alcuni linguaggi (e.g., Java) non hanno operazione free hanno garbage collector (parte di macchina astratta che trova e riutilizza memoria scollegata) deteriora l efficienza di esecuzione dei programmi puntatori e variabili dinamiche portano a programmazione di basso livello e pericolosa usare solo quando strettamente necessario, cioè per passaggio parametri per indirizzo costruzione strutture dati complesse (liste, alberi, grafi, )
12 Liste esigenza: memorizzare insiemi di elementi con cardinalità non nota a priori molto variabile lista composta da elementi allocati dinamicamente si accede agli elementi tramite puntatori numero elementi cambia durante esecuzione puntatori agli elementi devono essere variabili dinamiche soluzione: ogni elemento contiene un puntatore a prossimo elemento della lista puntatore nell ultimo elemento vale NULL NULL assume significato di fine lista o lista vuota inizio della lista, chiamata testa della lista una variabile del tipo puntatore a elemento della lista dichiarazione dei tipi per costruzione in tre passi struct EL TipoElemento Info; struct EL *Prox; ; typedef struct EL ElemLista; typedef ElemLista *ListaDiElem; 1. dichiarazione tipo struttura in forma diversa da quella usuale struct EL è una struttura autoreferenziante (con definizione ricorsiva) struct EL è il nome del tipo in corso di definizione utilizzato nella definizione stessa NB: la struttura non contiene una struttura, ma un puntatore a struttura 2. typedef rinomina il tipo struct EL come ElemLista 3. tipo ListaDiElem definito come puntatore a ElemLista
13 poi usuale dichiarazione di variabili ListaDiElem Lista1, Lista2, Lista3; possibili dichiarazioni abbreviate senza evidenziare tipo della lista (puntatore a elemento) ElemLista *Lista1; ulteriore abbreviazione se si omettono entrambe le typedef non si esplicita né tipo della lista né tipo degli elementi struct EL *Lista1 realizziamo operazioni su liste mediante sottoprogrammi lista vuota puntatore con valore NULL Inizializzazione a lista vuota procedura che riceve per indirizzo la variabile testa della lista la testa della lista è un puntatore il parametro formale è un doppio puntatore #include <stdlib.h> void Inizializza (ListaDiElem *Lista) *Lista = NULL; dichiarazione della variabile testa della lista ListaDiElem Lista1; chiamata di Inizializza: passato indirizzo di Lista1 Inizializza(&Lista1); effetto dell istruzione *Lista = NULL;
14 NB testata di funzione equivalente void Inizializza(ElemLista **Lista) per semplificare a volte lista dichiarata variabile globale #include <stdlib.h> ElemLista *Lista1; void Inizializza(void) Lista1 = NULL; sconsigliato: procedura non è più parametrica lista è accessibile senza restrizioni #include <stdlib.h> Controllo di lista vuota boolean ListaVuota(ListaDiElem Lista) /* true sse la lista parametro è vuota */ if (Lista == NULL) return true; else return false; chiamata boolean vuota; vuota = ListaVuota(Lista1);
15 Controllo dell esistenza di un elemento in una lista boolean Ricerca (ListaDiElem Lista, TipoElemento ElemCercato) ElemLista *Cursore; if (Lista!= NULL) Cursore = Lista; /* La lista non è vuota */ while (Cursore!= NULL) if (Cursore >Info == ElemCercato) return true; Cursore = Cursore >Prox; /* Cursore punta a elemento successivo */ return false; NB: lista non viene modificata può essere passata per valore parametro formale può essere modificato (usato come cursore ) boolean Ricerca (ListaDiElem Lista, TipoElemento ElemCercato) while (Lista!= NULL) if (Lista > Info == ElemCercato) return true; Lista = Lista > Prox; return false; versione ricorsiva boolean Ricerca (ListaDiElem Lista, TipoElemento ElemCercato) if (Lista == NULL) return false; else if (Lista >Info == ElemCercato) return true; else return Ricerca(Lista >Prox, ElemCercato); Esercizi: Estrazione della testa o della coda da una lista codificare le seguenti /* applicata a liste non vuote (altrimenti segnala errore); restituisce campo Info del primo elemento della lista */ TipoElemento TestaLista(ListaDiElem Lista) /* restituisce (puntatore al) la lista uguale a Lista priva del primo elemento (NB gli elementi sono gli stessi). non modifica il parametro. Assume parametro lista non vuota */ ListaDiElem CodaLista(ListaDiElem Lista)
16 Inserimento di un nuovo elemento in una lista inserimento in prima posizione #include <stdlib.h> void InsercisciInTesta(ListaDiElem *Lista, TipoElemento Elem) ElemLista *Punt; Punt = malloc(sizeof(elemlista)); Punt >Info = Elem; Punt >Prox = *Lista; *Lista = Punt;
17 inserimento in ultima posizione void InserisciInCoda(ListaDiElem *Lista, TipoElemento Elem); ElemLista *Punt; if (ListaVuota(*Lista)) Punt = malloc(sizeof(elemlista)); Punt >Prox = NULL; Punt >Info = Elem; *Lista = Punt; else InserisciIncoda(&((*Lista) >Prox), Elem); NB: nella chiamata ricorsiva passato indirizzo del puntatore che sta nel primo elemento della lista parametro attuale *Lista (*Lista) >Prox &((*Lista) >Prox) indirizzo primo elemento della lista componente puntatore del primo elemento della lista indirizzo di questo puntatore area dati chiamante Lista1.. Lista area dati chiamato
18 inserimento in lista ordinata ( definita relazione d ordine < per TipoElemento) nuovo elemento inserito mantenendo lista ordinata posizione, tra quelli già presenti subito dopo il massimo tra i minori subito prima del minimo tra i maggiori ipotesi relazione d ordine denotata con > : corretto per tipi semplici, per tipi strutturati servirebbe funzione ad hoc non si verifica se elemento già presente nella lista #include <stdlib.h> void InserisciInOrdine(ListaDiElem *Lista, TipoElemento Elem) ElemLista *Punt, *PuntCorrente, *PuntPrecedente; PuntPrecedente = NULL; PuntCorrente = *Lista; while (PuntCorrente!= NULL && Elem > PuntCorrente >Info) PuntPrecedente = PuntCorrente; PuntCorrente = PuntCorrente->Prox; Punt = malloc(sizeof(elemlista)); Punt >Info = Elem; Punt >Prox = PuntCorrente; if (PuntPrecedente!= NULL ) /* Inserimento internamente alla lista */ PuntPrecedente >Prox = Punt; else /* Inserimento in testa alla lista */ *Lista = Punt; PuntPrecedente indica l elemento che dovrà precedere immediatamente il nuovo elemento PuntCorrente indica l elemento che dovrà seguire immediatamente il nuovo elemento se inserzione avviene in testa PuntPrecedente == NULL se inserzione avviene in coda PuntCorrente == NULL se inserzione avviene in testa e in coda (la lista era vuota) PuntPrecedente == NULL && PuntCorrente == NULL
19 visualizzazione inserimento internamente alla lista (né in testa né in coda) esercizio: disegnare tutti i casi possibili di inserzione domanda: cosa succede se l elemento da inserire è già presente? Cancellazione di un elemento da una lista ipotesi: la lista non contiene elementi ripetuti #include <stdlib.h> void Cancella(ListaDiElem *Lista, TipoElemento Elem) /* Cancella dalla lista passata "per indirizzo" l'elemento Elem, se esiste, assumendo che nella lista non vi siano ripetizioni */ ElemLista *PuntTemp; if (ListaVuota (*Lista) == false) if ((*Lista) >Info == Elem) PuntTemp = *Lista; *Lista = CodaLista(*Lista); free(punttemp); else Cancella(&((*Lista) >Prox), Elem); domanda: cosa succede se elemento da cancellare non è presente?
20 vantaggio di definire sottoprogrammi per operazioni su liste struttura lista vista come nuovo tipo, con operazioni predefinite implementate da sottoprogrammi verso tipo di dato astratto uso delle liste risulta molto semplice (non la programmazione loro operazioni) esempio, leggere n interi e metterli in una lista nell ordine di lettura ListaDiElem Lista1; int i, n, x; Inizializza(&Lista1); for (i = 1; i <= n; i++) scanf( %d, &x); InserisciInCoda(&Lista1, x); confronto tra liste collegate a puntatori e array array semplici nella definizione e costruzione efficienti nell accesso (accesso diretto) NON flessibili: dimensione fissa inefficiente uso della memoria (pericolo di overflow o spreco) liste collegate a puntatori complesse nella definizione e costruzione inefficienti nell accesso (accesso sequenziale) flessibili: dimensione variabile dinamicamente (durante l esecuzione) uso efficiente della memoria (solo sovraccarico marginale per puntatori)
21 struttura caratteristica SEMPLICITÀ FLESSIBILITÀ EFFICIENZA ACCESSO EFFICIENZA USO MEMORIA array liste tecniche per rimediare a punti deboli delle liste per la semplicità trattare strutture collegate come tipi di dati astratti inaccessibili direttamente le parti interne tutte operazioni codificate mediante sottoprogrammi per l efficienza di accesso definire strutture più complesse, usando più puntatori liste bidirezionali alberi bilanciati grafi, argomento di corsi più avanzati
22 alternativa di codifica: stile funzionale notazione si semplifica un po, ci sono in giro meno * e & inizializzazione ListaDiElem Inizializza (void) return NULL; chiamata ListaDiElem Lista1; TipoElemento ElementoDaInserire, ElementoDaCancellare; Lista1 = Inizializza (); inserimento in prima posizione ListaDiElem InserisciInTesta(ListaDiElem Lista, TipoElemento Elem) ElemLista *Punt; Punt = malloc(sizeof(elemlista)); Punt >Info = Elem; Punt >Prox = Lista; return Punt; chiamata Lista1 = InserisciInTesta(Lista1, ElementoDaInserire); inserimento in ultima posizione ListaDiElem InserisciInCoda(ListaDiElem Lista, TipoElemento Elem); ElemLista *Punt; if (ListaVuota(Lista)) Punt = malloc(sizeof(elemlista)); Punt >Prox = NULL; Punt >Info = Elem; return Punt; else Lista -> Prox = InserisciIncoda(Lista > Prox, Elem); return Lista; chiamata Lista1 = InserisciInCoda (Lista1, ElementoDaInserire);
23 inserimento in lista ordinata ListaDiElem InserisciInOrdine(ListaDiElem Lista, TipoElemento Elem) ElemLista *Punt, *PuntCorrente, *PuntPrecedente; PuntPrecedente = NULL; PuntCorrente = Lista; while ( PuntCorrente!= NULL && Elem > PuntCorrente >Info ) PuntPrecedente = PuntCorrente; PuntCorrente = PuntCorrente->Prox; Punt = malloc(sizeof(elemlista)); Punt >Info = Elem; Punt >Prox = PuntCorrente; if (PuntPrecedente!= NULL ) /* Inserimento internamente alla lista */ PuntPrecedente >Prox = Punt; return Lista; else /* Inserimento in testa alla lista */ return Punt; chiamata Lista1 = InserisciInOrdine (Lista1, ElementoDaInserire); cancellazione di un elemento ListaDiElem Cancella(ListaDiElem Lista, TipoElemento Elem) ListaDiElem PuntTemp; if (ListaVuota (Lista) == false) if (Lista > Info == Elem) PuntTemp = CodaLista(Lista); free(lista); return PuntTemp; else Lista -> Prox = Cancella(Lista > Prox, Elem); return Lista; else return Lista; chiamata Lista1 = Cancella (Lista1, ElementoDaCancellare);
Strutture Dinamiche. Fondamenti di Informatica
Strutture Dinamiche Fondamenti di Informatica 1 Indice Allocazione e de-allocazione di memoria Liste e loro gestione Companies, srl 2 Allocazione e cancellazione di memoria malloc (sizeof (TipoDato));
Strutture dati dinamiche
Strutture dati dinamiche Gestione della memoria La gestione statica della memoria è molto efficiente ma non è priva di inconvenienti È rigida rispetto a informazioni la cui dimensione non è nota a priori
Il linguaggio C. Puntatori e dintorni
Il linguaggio C Puntatori e dintorni 1 Puntatori : idea di base In C è possibile conoscere e denotare l indirizzo della cella di memoria in cui è memorizzata una variabile (il puntatore) es : int a = 50;
Esercizio 1: funzione con valore di ritorno di tipo puntatore
Esercitazione Fondamenti di Informatica B Corso di Laurea in Ingegneria Meccanica 7 Esercitazione: 14 dicembre 2005 Esercizi su ricorsione, manipolazione stringhe, strutture dinamiche Problema: Esercizio
Strutture dati dinamiche
Strutture dati dinamiche - Liste concatenate - Pile -> LIFO (last in first out) - Code -> FIFO (first in first out) - Alberi binari: gestione dati in algoritmi complessi Liste Concatenate Formata da elementi
Liste concatenate e allocazione dinamica
Liste concatenate e allocazione dinamica Laboratorio di Programmazione I Corso di Laurea in Informatica A.A. 2018/2019 Argomenti del Corso Ogni lezione consta di una spiegazione assistita da slide, e seguita
Laboratorio di Programmazione
Laboratorio di Programmazione (Laurea triennale in matematica) Lezione 21 Strutture dinamiche Gli array ci permettono di memorizzare un insieme di dati dello stesso tipo Deve essere noto staticamente il
Laboratorio di Calcolatori 1 Corso di Laurea in Fisica A.A. 2006/2007
Laboratorio di Calcolatori 1 Corso di Laurea in Fisica A.A. 2006/2007 Dott.Davide Di Ruscio Dipartimento di Informatica Università degli Studi di L Aquila Lezione del 08/03/07 Nota Questi lucidi sono tratti
Strutture Dati Dinamiche
Strutture Dati Dinamiche Motivazioni Le variabili considerate fino a questo punto devono essere dichiarate staticamente, ossia la loro esistenza, il loro nome e la loro dimensione devono essere previsti
Ogni variabile in C è una astrazione di una cella di memoria a cui corrisponde un nome, un contenuto e un indirizzo.
Ogni variabile in C è una astrazione di una cella di memoria a cui corrisponde un nome, un contenuto e un indirizzo. int a = 5; a 5 α=&a Esistono in C particolari variabili dette puntatori che possono
L'Allocazione Dinamica della Memoria nel linguaggio C
L'Allocazione Dinamica della Memoria nel linguaggio C Prof. Rio Chierego [email protected] http://www.riochierego.it/informatica.htm Sommario Questo documento tratta l'allocazione dinamica della memoria
4 Le liste collegate 4.0. Le liste collegate. 4 Le liste collegate Rappresentazione di liste 4.1 Rappresentazione di liste
4 Le liste collegate 4.0 Le liste collegate c Diego Calvanese Fondamenti di Informatica Corso di Laurea in Ingegneria Elettronica A.A. 2001/2002 4.0 0 4 Le liste collegate Rappresentazione di liste 4.1
Esercitazione 11. Liste semplici
Esercitazione 11 Liste semplici Liste semplici (o lineari) Una lista semplice (o lineare) è una successione di elementi omogenei che occupano in memoria una posizione qualsiasi. Ciascun elemento contiene
Gestione dinamica della memoria
Programmazione M-Z Ingegneria e Scienze Informatiche - Cesena A.A. 2016-2017 Gestione dinamica della memoria Pietro Di Lena - [email protected] A pessimistic programmer sees the array as half empty.
Strutture dati dinamiche in C (II)
Strutture dati dinamiche in C (II) Laboratorio di Linguaggi di Programmazione a.a. 2001/2002 dott.ssa Francesca A. Lisi [email protected] Sommario Le liste concatenate (ancora ma in modo più formale) L
Fondamenti di Informatica T. Linguaggio C: i puntatori
Linguaggio C: i puntatori Il puntatore E` un tipo di dato, che consente di rappresentare gli indirizzi delle variabili allocate in memoria. Dominio: Il dominio di una variabile di tipo puntatore è un insieme
Elementi lessicali. Lezione 4. La parole chiave. Elementi lessicali. Elementi lessicali e espressioni logiche. Linguaggi di Programmazione I
Lezione 4 Elementi lessicali e espressioni logiche Matricole 2-3 Elementi lessicali il linguaggio C ha un suo vocabolario di base i cui elementi sono detti token esistono 6 tipi di token: parole chiave
Implementazione di Liste puntate
Laboratorio di Algoritmi e Strutture Dati Aniello Murano http://people.na.infn.it people.na.infn.it/~murano/ 1 Implementazione di Liste puntate 2 1 Indice Liste puntate semplici: Gli elementi sono logicamente
Esercizio 1 Liste: calcolo del numero di elementi ripetuti in una lista
Esercitazione Fondamenti di Informatica B Corso di Laurea in Ingegneria Meccanica 11 Esercitazione: 27 gennaio 2005 Esercizi su liste, ricorsione, file. Scaletta Esercizio 1 Liste: calcolo del numero di
Unità Didattica 4 Linguaggio C. Vettori. Puntatori. Funzioni: passaggio di parametri per indirizzo.
Unità Didattica 4 Linguaggio C Vettori. Puntatori. Funzioni: passaggio di parametri per indirizzo. 1 Vettori Struttura astratta: Insieme di elementi dello stesso tipo, ciascuno individuato da un indice;
Programmazione I - Laboratorio
Programmazione I - Laboratorio Esercitazione 6 - Liste Gianluca Mezzetti 1 Paolo Milazzo 2 1. Dipartimento di Informatica, Università di Pisa http://www.di.unipi.it/ mezzetti mezzetti di.unipi.it 2. Dipartimento
Introduzione al linguaggio C Funzioni
Introduzione al linguaggio C Funzioni Violetta Lonati Università degli studi di Milano Dipartimento di Informatica Laboratorio di algoritmi e strutture dati Corso di laurea in Informatica Violetta Lonati
La gestione della memoria dinamica Heap
Laboratorio di Algoritmi e Strutture Dati La gestione della memoria dinamica Heap Prof. Luigi Lamberti 2005 Cenni sui Processi Un Programma è un insieme di Istruzioni memorizzato in un file con le costanti
Programmazione Orientata agli Oggetti in Linguaggio Java
Programmazione Orientata agli Oggetti in Linguaggio Java Classi e Oggetti: Metafora Parte a versione 2.2 Questo lavoro è concesso in uso secondo i termini di una licenza Creative Commons (vedi ultima pagina)
Linguaggio C: PUNTATORI
Linguaggio C: PUNTATORI I puntatori sono una delle più importanti caratteristiche del linguaggio C. Permettono di lavorare a basso livello, mantenendo flessibilità e praticità. Il C utilizza molto i puntatori
