ALGORITMI Risoluzione di problemi Algoritmi Strutture dati Strumenti del linguaggio di programmazione La risoluzione di un problema è il processo che dato un problema e individuato un opportuno metodo risolutivo, trasforma i dati iniziali nei corrispondenti risultati finali. Affinché la risoluzione di un problema possa essere realizzata attraverso l’uso del calcolatore, tale processo deve poter essere definito come sequenza di azioni elementari. Algoritmo Un algoritmo (matematico arabo Al Khuwarizmi, vissuto nel IX secolo d.C.) è una sequenza finita di mosse che risolve in un tempo finito una classe di problemi L’esecuzione delle azioni nell’ordine specificato dall’algoritmo consente di ottenere, a partire dai dati di ingresso, i risultati che risolvono il problema. METODO RISOLUTIVO (ALGORITMO) DATI Esecutore RISULTATI ESECUTORE: una macchina astratta capace di eseguire le azioni specificate dell’algoritmo Algoritmi: proprieta’ • Eseguibilità: ogni azione deve dall’esecutore in un tempo finito essere eseguibile • Non-ambiguità: ogni azione deve essere univocamente interpretabile dall’esecutore • Finitezza: il numero totale di azioni da eseguire per ogni insieme di dati di ingresso deve essere finito Algoritmi: proprieta’ Quindi, un algoritmo deve: • Essere applicabile a qualsiasi insieme di dati in ingresso appartenenti al dominio di definizione dell’algoritmo • Essere costituito di operazioni appartenenti determinato insieme di operazioni fondamentali ad un • Essere costituito di regole non ambigue, cioè interpretabili in modo univoco qualunque sia l’esecutore (persona o «macchina») che le legge Algoritmi: proprieta’ Un algoritmo deve poter essere eseguito da chiunque, senza che l'esecutore sia stato necessariamente coinvolto nella formulazione del problema o nella descrizione dell’algoritmo Gli algoritmi devono essere formalizzati per mezzo di appositi linguaggi, dotati di strutture linguistiche che garantiscano precisione e sintesi I linguaggi naturali non soddisfano questi requisiti, infatti... …sono ambigui: la stessa parola può assumere significati diversi in contesti differenti (pesca è un frutto o un’attività sportiva) …sono ridondanti: lo stesso concetto può essere espresso in molti modi diversi, ad esempio “somma 2 a 3”, “calcola 2+3”, “esegui l’addizione tra 2 e 3” Algoritmi e programmi Ogni elaboratore è una macchina in grado di eseguire azioni elementari su oggetti detti DATI L’esecuzione delle azioni è richiesta all’elaboratore tramite comandi elementari chiamati ISTRUZIONI espresse attraverso un opportuno formalismo: il LINGUAGGIO DI PROGRAMMAZIONE Il linguaggio di programmazione è un linguaggio utilizzato per descrivere l’insieme delle azioni consecutive che un calcolatore deve eseguire La formulazione testuale di un algoritmo in un linguaggio comprensibile a un elaboratore è detta PROGRAMMA Il programmatore è colui che, attraverso la fase di programmazione, traduce (o implementa o codifica) un algoritmo in codice sorgente, utilizzando un linguaggio di programmazione Programma Un PROGRAMMA è un testo scritto in accordo alla sintassi e alla semantica di un linguaggio di programmazione Un programma è la formulazione testuale, in un certo linguaggio di programmazione, di un algoritmo che risolve un dato problema Problema Relazioni tra problema, analisi, algoritmo, programmazione, programma, dati ed elaborazione ANALISI Algoritmo PROGRAMMAZIONE Programma ELABORAZIONE Risultati Dati Algoritmo e programma Per risolvere un problema: • • • Individuazione di un procedimento risolutivo Scomposizione del procedimento in un insieme ordinato di azioni ALGORITMO Rappresentazione dei dati e dell’algoritmo attraverso un formalismo comprensibile dal calcolatore LINGUAGGIO DI PROGRAMMAZIONE Problema Algortimo Metodo risolutivo Programma Linguaggio di programmazione Esempio Come piegare un foglio quadrato per ottenere una figura: Primitive Esempio: Ordinamento di un mazzo di carte Problema: Sia dato un mazzo da 40 carte da ordinare in modo che quelle di cuori precedano quelle quadri, che a loro volta precedono quelle di fiori e quelle di picche; le carte di uno stesso seme sono ordinate dall’asso al re. Algoritmo: • Si suddivida il mazzo in 4 mazzetti, ciascuno costituito da tutte le carte dello stesso seme • Si ordinino le carte di ciascun mazzetto dall’asso al re • Si prendano nell’ordine i mazzetti di cuori, quadri, fiori e picche Esempio: Calcolo delle radici di eq. di 2° grado Problema: Calcolo delle radici reali dell’equazione ax2+bx+c=0 Algoritmo: • Acquisire i coefficienti a,b,c • Calcolare = b24ac • Se <0 non esistono radici reali, eseguire l'istruzione 7) • Se =0, x1=x2=b/2a, poi eseguire l'istruzione 6) • Se >0, x1=(b+)/2a, x2=(b)/2a • Comunicare i valori x1, x2 • Fine Si utilizzano VARIABILI, ossia nomi simbolici usati nell’algoritmo per denotare dati Esempio: Calcolo del M.C.D. • Problema: Calcolare il M.C.D. di due interi a,b, con a>b • Algoritmo: Formalizzato da Euclide nel 300 a.C., si basa sul fatto che ogni divisore comune ad a e b è anche divisore del resto r della divisione intera di a per b, quando a>b e r0; se r=0, b è il M.C.D. MCD(a,b) = MCD(b,r), se r0 MCD(a,b)=b, se r=0 • L’algoritmo garantisce la determinazione del M.C.D. senza il calcolo di tutti i divisori di a e b Esempio: Calcolo del M.C.D. • • • • • • Acquisire i valori di a e b Se b>a, scambiare i valori di a e b Calcolare il resto r della divisione intera di a per b Se r=0, MCD(a,b)=b; comunicare il risultato all’esterno; eseguire l’istruzione 6) Se r0, sostituire il valore di a con il valore di b ed il valore di b con il valore di r; tornare al passo 3) Fine Algoritmi equivalenti • • • • Due algoritmi si dicono equivalenti quando: Hanno lo stesso dominio di ingresso Hanno lo stesso dominio di uscita In corrispondenza degli stessi valori del dominio di ingresso producono gli stessi valori nel dominio di uscita Algoritmi equivalenti • • • • Due algoritmi equivalenti: Forniscono lo stesso risultato Ma possono avere diversa efficienza e possono essere profondamente diversi … ad esempio, i vari algoritmi visti a lezione per risolvere il problema dei numeri di Fibonacci Costanti e variabili I dati su cui opera un algoritmo sono costanti e variabili • Un dato è costante quando il suo valore non può essere aggiornato durante l'esecuzione dell’algoritmo • Una variabile è una coppia <nome, valore>: può essere immaginata come una unità di memorizzazione identificata da un nome e che può contenere un valore VALORE NOME Rappresentazione di una variabile Costanti e variabili Celle di memoria ordinate per indirizzo Costanti e variabili Il valore di una variabile deve appartenere all’insieme di definizione, su cui si opera mediante regole opportune, specifiche dell'insieme Data una variabile <x,v>, x è il nome della variabile e v è il suo valore attuale; le variabili sono indeterminate in fase di definizione dell’algoritmo, ma devono corrispondere a valori ben precisi durante ogni esecuzione Esempio: Nell’algoritmo di risoluzione delle equazioni di 2° grado, a, b, c non corrispondono a nessun valore finché non si esegue l’algoritmo per trovare le soluzioni di una specifica equazione, ad esempio x29x4=0. In fase di esecuzione, a=1, b=9, c=4. Nell'istruzione =b24ac, è la variabile che contiene il valore del risultato del calcolo del discriminante Assegnamento L’istruzione di assegnamento definisce il valore attuale di una variabile, che resta inalterato fino all’assegnamento successiva. In C l’operatore di assegnamento è = nome_di_variabile = espressione; che si legge assegna alla variabile “nome_di_variabile” il valore di “espressione”. L’espressione a destra di = è costituita da variabili, costanti e operatori L’assegnamento viene così eseguito: si valuta l’espressione a destra di =, sostituendo ai nomi di variabile i loro valori attuali; il risultato della valutazione deve appartenere all’insieme di definizione della variabile a sinistra di = il valore calcolato diventa il nuovo valore della variabile il cui nome appare a sinistra di = Assegnamento 6 4 b c 10 6 4 a b c a = b+c; x = x+3; Prima dell’assegnamento Dopo l’assegnamento 14 x Prima dell’assegnamento 17 x Dopo l’assegnamento Le istruzioni Istruzioni operative, che producono risultati Istruzioni di controllo, che controllano il verificarsi di condizioni specificate e, in base al risultato del controllo, determinano il flusso di istruzioni da eseguire Istruzioni di salto, che alterano il normale flusso di esecuzione delle istruzioni di un algoritmo, specificando quale sia la successiva istruzione da eseguire • nelle istruzioni di salto condizionato, l’effettiva esecuzione del salto è condizionata al verificarsi di una condizione specificata • l’istruzione di salto incondizionato produce sempre un salto Istruzioni di ingresso/uscita, che specificano come debba essere effettuata una trasmissione di dati o messaggi fra l’algoritmo e l’ambiente esterno Istruzioni di inizio/fine esecuzione, che indicano l’inizio/la fine dell’algoritmo Le istruzioni Esempio: Calcolo delle radici di equazioni di 2° grado a) “acquisire i coefficienti a,b,c” è un’istruzione di lettura (ingresso) b) “calcolare =b24ac” è un’istruzione operativa c) “se =0, x1=x2=b/2a” è un’istruzione di controllo, infatti l'assegnazione x1=x2=b/2a viene eseguita solo se =0 d) “comunicare i valori x1, x2” è un’istruzione di scrittura (uscita) e) “eseguire l'istruzione 6)” è un’istruzione di salto incondizionato f) “se <0 eseguire l'istruzione 7)” è un’istruzione di salto condizionato, perché l'istruzione 7) è la prossima istruzione da eseguire solo se <0 LINGUAGGI Cos’è un linguaggio • Un linguaggio è un insieme di parole e di metodi di combinazione delle parole usati e compresi da una comunità di persone. È una definizione poco precisa perché… • …non evita le ambiguità dei linguaggi naturali • …non si presta a descrivere processi computazionali automatici • …non aiuta a stabilire proprietà • Il linguaggio (formale) è un sistema matematico che consente di ispondere a domande come: • quali sono le frasi lecite? • si può stabilire se una frase appartiene al linguaggio? • come si stabilisce il significato di una frase? • quali sono gli elementi linguistici primitivi? • In informatica, un linguaggio di programmazione è un linguaggio formale, dotato di un lessico, una sintassi e una semantica ben definite, utilizzabile per il controllo del comportamento di una macchina formale, o di una implementazione di essa (tipicamente, un computer). Linguaggio di programmazione Per usare un linguaggio di programmazione serve conoscere i suoi elementi linguistici: • Alfabeto: insieme non vuoto di simboli tramite i quali è possibile costruire gli elementi base del linguaggio. • Lessico: insieme di regole formali (grammatica) per la scrittura di parole nel linguaggio, cioè per decidere quali sequenze sono simboli del linguaggio e quali no (fanno parte del lessico C le 32+5 keywords, gli identificatori, le costanti letterali, le stringhe letterali e gli operatori) • Sintassi: insieme di regole formali per la scrittura di frasi grammaticalmente corrette nel linguaggio. • Semantica: insieme di significati da attribuire alle frasi sintatticamente corrette del linguaggio. Conoscere la sintassi di un linguaggio di programmazione non implica saper codificare programmi semanticamente sensati (così come accade per i linguaggi naturali). Esempio: la sintassi di un numero naturale <cifra-non-nulla> : 1|2|3|4|5|6|7|8|9 <cifra> : 0 | <cifra-non-nulla> <naturale> : 0 | <cifra-non-nulla>{<cifra>} Diagramma sintattico I linguaggi di programmazione A livello hardware, i calcolatori riconoscono solo comandi semplici, del tipo copia un numero, addiziona due numeri, confronta due numeri I comandi realizzati in hardware definiscono il set di istruzioni macchina (Instruction Set) e i programmi che li utilizzano direttamente sono i programmi in linguaggio macchina In linguaggio macchina… • …ogni “operazione” richiede l’attivazione di numerose istruzioni base • …qualunque entità, istruzione, variabile, dato, è rappresentata da numeri binari: i programmi sono difficili da scrivere, leggere e mantenere Il linguaggio macchina riflette l’organizzazione della macchina più che la natura del problema da risolvere. Dalla nascita dei primi calcolatori, si è cercato di diminuire lo sforzo ed aumentare la produttività dell’utente, anche a costo di caricare la macchina di maggiori compiti I linguaggi di programmazione Negli anni ‘50, tutti i programmi erano scritti in linguaggio macchina o in assembly. Per la prima volta, con la nascita degli assembler, fu applicato il principio che è meglio risparmiare il tempo dell’uomo anche a costo di utilizzare più tempo macchina (una parte del tempo è dedicata alla traduzione di programmi, non alla loro esecuzione). Oggi si utilizza l’assembly solo se esistono vincoli stringenti sui tempi di esecuzione; viceversa, si usano linguaggi più vicini al linguaggio naturale, i linguaggi di alto livello. I linguaggi di alto livello sono elementi intermedi di una varietà di linguaggi ai cui estremi si trovano il linguaggio macchina, da un lato, ed i linguaggi naturali, come l’italiano e l’inglese, dall’altro. I linguaggi di programmazione differiscono comunque dai linguaggi naturali: • sono infatti meno espressivi (poche parole chiave, poche regole) • ma più precisi, perché privi di qualsiasi ambiguità Astrazione In informatica si parla di programmazione a basso livello quando si utilizza un linguaggio molto vicino alla macchina Si parla invece di programmazione ad alto livello quando si utilizzano linguaggi più sofisticati ed astratti, slegati dal funzionamento fisico della macchina Si viene così a creare una gerarchia di linguaggi; in questa gerarchia il linguaggio C si pone ad un livello intermedio Usando un linguaggio di alto livello il programmatore tratta oggetti complessi senza doversi preoccupare dei dettagli della particolare macchina sulla quale il programma viene eseguito Ogni singola istruzione di un linguaggio di alto livello corrisponde a molte istruzioni in linguaggio macchina: quanto più il linguaggio si discosta dal linguaggio macchina, tanto più il lavoro di traduzione del compilatore è difficile Linguaggi di programmazione di alto livello I linguaggi che non dipendono dall’architettura della macchina offrono due vantaggi fondamentali: • i programmatori non devono cimentarsi con i dettagli architetturali di ogni calcolatore • i programmi risultano più semplici da leggere e da modificare portabilità (previa compilazione), leggibilità, mantenibilità Alcune stime considerano che le attività di manutenzione assorbono il 70% del budget investito nel software e occupano il 75% del personale. Consideriamo che la manutenzione può essere: • manutenzione correttiva, per la risoluzione di errori riscontrati nel codice • manutenzione adattiva, per adeguarlo a modifiche non sostanziali nell’ambiente di elaborazione o nei dati, • manutenzione evolutiva, per estenderne le funzionalità a seguito di nuove richieste dell’utente, o per migliorarne l’efficienza o la documentazione The 2015 Top Ten Programming Languages The ranking system is driven by weighting and combining 12 metrics from 10 data sources. The weighting of these sources can be adjusted using the interactive Web app to give, say, more importance to languages that have turned up in job ads. http://spectrum.ieee.org/computing/software/the-2015-top-ten-programming-languages Evoluzione dei paradigmi di programmazione http://www.levenez.com/lang/