Approfondimento 1.1
Elaborazione dell’informazione
•
Elaborazione dell’Informazione (EI): richiede di risolvere problemi connessi
con la ricerca e/o manipolazione di informazione.
•
Agente risolutore per problemi di EI:
esecutore.
•
Informazione trattata in problemi di EI:
dati.
•
Metodo risolutivo per problemi di EI:
algoritmo1.
Dati
•
Esecutore
Algoritmo
EI è parte della nostra vita quotidiana: es. ricerca di un numero di telefono.
Algoritmo
Nome
Abbonato
Esecutore
Numero
Abbonato
Elenco
Telefonico
•
Proprietà che definiscono un algoritmo:
1. Non ambiguità: le istruzioni devono essere univocamente interpretabili
dall’esecutore.
2. Eseguibilità: l’esecutore deve essere in grado di eseguire ogni istruzione
dell’algoritmo in tempo finito con le risorse a disposizione.
3. Finitezza: l’esecuzione dell’intero algoritmo deve terminare in tempo
finito per qualunque insieme finito di dati trattati.
•
Ulteriore proprietà desiderabile:
4. Efficienza: l’algoritmo deve eseguire il minor numero possibile di
istruzioni (⇒ deve terminare nel più breve tempo possibile).
•
1
Possibili procedure per il problema della ricerca del numero di telefono:
Algoritmo: deriva dal nome del matematico persiano al-Khowarismi (IX secolo DC)
tradotto in latino come Algorismus.
1. Ricerca casuale: si aprono ripetutamente pagine a caso finchè non si
trova quella che contiene il nome dell’abbonato.
2. Ricerca sequenziale: si sfoglia tutto l’elenco fino a trovare il numero
dell’abbonato.
3. Ricerca binaria: assumendo che i nomi degli abbonati siano in ordine
alfabetico, si apre l’elenco a metà e si vede se il nome cercato è nella
prima o nella seconda metà ci si concentra su quella, ripetendo il
ragionamento fino a trovare il punto in cui dovrebbe esserci il nome
dell’abbonato.
•
•
•
Rispettano le proprietà?
•
Ambiguità: che fare se ci sono omonimi nell’elenco?
•
Eseguibilità: sì.
•
Terminazione: 1 no. 2 e 3 sì (ogni passo ci porta più vicino alla
soluzione).
•
Efficienza: crescente per 1, 2, 3
Dati organizzati in strutture dati: es. elenco ordinato di nomi permette
ricerca binaria. Es.:
•
Struttura dati: struttura di elenco telefonico ordinato
•
Dati: nomi e numeri dell’elenco
Modellazione di un problema di EI: rappresentazione dei dati in strutture
dati e dei procedimenti risolutivi mediante algoritmi.
Es. un algoritmo risolutore funzionerà su qualunque insieme di dati presenti
nell’elenco.
•
Livelli di astrazione: progettazione mediante raffinamenti successivi
•
Quanto è facile trovare un algoritmo efficiente per un problema?
Esempi in ordine di difficoltà:
1. Dati due numeri, trovare il maggiore: facile…
2. Ordinare una sequenza di numeri: sono noti algoritmi ottimi.
3. Cercare i cammini più corti tra tutte le coppie di città in una rete
stradale: esistono algoritmi efficienti, ma non si sa se sono ottimi.
4. Cercare il cammino più corto che passa per tutte le città di una regione:
sono noti solo algoritmi estremamente lenti o algoritmi efficienti che
formiscono soluzioni approssimate.
5. Scrivere tutti gli n per cui l’equazione Xn+Yn=Zn ha soluzioni X,Y,Z
intere: non è noto nessun algoritmo (problema di Fermat).
6. Decidere se una funzione f(x)=cost per ogni x: è dimostrato che non è
possibile progettare un algoritmo risolutore.
Approfondimento 1.2
Elaborazione automatica dell’informazione
•
Elaborazione automatica dell’informazione: esecutore = elaboratore
elettronico.
•
Esecutore umano: algoritmi e dati espressi in linguaggio naturale.
•
Esecutore meccanico: algoritmi e dati espressi in linguaggio di
programmazione comprensibile alla macchina.
•
Un programma è (tipicamente) un testo scritto in un linguaggio di
programmazione e contiene:
• la codifica (o implementazione) di un algoritmo
• la rappresentazione delle strutture dati da esso utilizzate.
•
Software: programmi e dati.
•
Hardware: componenti fisiche di un sistema di elaborazione automatica.
•
Cenni storici: http://mangrove.umd.edu/~alfredo/lectures/2.html.
•
Architettura di Von Neumann (anni ‘40):
Hardware
Periferiche
Unità centrale di
elaborazione
Memoria principale
E’ tutt’ora alla base dei moderni elaboratori elettronici.
•
Unità centrale di elaborazione = esecutore (CPU = Central Processing
Unit)
Esegue programmi scritti in Linguaggio Macchina.
•
Memoria principale = contenitore per dati e programmi (RAM = Random
Access Memory).
•
Periferiche = dispositivi per l’ingresso e l’uscita di dati (schermo, tastiera,
mouse, stampante ecc.) e memoria secondaria - o di massa - (dischi).
•
Gerarchie di linguaggi di programmazione:
•
Linguaggi di alto livello: Fortran, Prolog, Lisp, Cobol, Ada, Basic, Pascal,
C, C++, JAVA ecc.
•
Hanno costrutti linguistici sofisticati che permettono di esprimere algoritmi e
strutture dati in modo naturale.
•
Sono indipendenti dalla CPU dell’elaboratore usato: programmi
potenzialmente portabili.
•
Linguaggi di basso livello: Assembly, Linguaggio Macchina
•
Istruzioni molto elementari che permettono solo di operare su numeri:
difficissimo da usare.
•
Dipendono dalla CPU dell’elaboratore usato: programmi non portabili.
•
Permette di scrivere programmi estremamente veloci
Linguaggi di alto livello
Linguaggio macchina
CPU (esecutore)
1. Due possibili approcci per l’uso di linguaggi di alto livello:
2. Compilatore: programma che traduce un programma in linguaggio di alto
livello in programma in linguaggio macchina.
Programma in
Linguaggio di
alto livello
Compilatore
Programma in
Linguaggio macchina
(programma eseguibile)
CPU
Programmi eseguibili in codice macchina sono veloci, ma non portabili.
3. Interprete: programma che esegue direttamente programmi scritti in
linguaggio di alto livello, senza bisogno di traduzione in linguaggio
macchina.
Programma in
Linguaggio di
alto livello
Interprete
CPU
Esecuzione programmi interpretati molto più lenta di quelli compilati, ma
potenziale portabilità.
1. Linguaggi di programmazione: tipicamente compilati, programmi complessi.
2. Linguaggi di comandi e di script: tipicamente interpretati, programmi
semplici e per uso interattivo del calcolatore.
1. Esistono più linguaggi di programmazione che linguaggi naturali. Per lo più
fortemente specializzati (pochi general-purpose):
Linguaggi per il WEB (HTML), linguaggi per la composizione dei documenti
(LaTeX), per basi di dati (SQL), per programmazione di Robot (Lego
MindStorm), per grafica 3D (VRML) ecc. ecc.
2. Esempi in 97 linguaggi di programmazione:
http://www.uni-karlsruhe.de/~uu9r/lang/html/lang-all.en.html.
1. Il linguaggio Java sviluppato da Sun Microsystems negli anni ’90, astro
nascente nel panorama dei linguaggi di programmazione. Linguaggio
moderno: fa tesoro dell’esperienza maturata nel passato.
1. Approccio misto in JAVA: sia compilazione che interpretazione.
Programma in
Java
Compilatore
Java
Programma in
Java bytecode
Java Virtual Machine
Java Virtual Machine
Java Virtual Machine
Macintosh
(CPU PowerPC)
PC
(CPU Intel Pentium)
Sun
(CPU SPARC)
Garantisce portabilità su diverse piattaforme.
2. Tempo di compilazione: il tempo in cui un programma viene compilato.
3. Tempo di esecuzione: il tempo in cui un programma viene eseguito.
•
Sintassi dei linguaggi di programmazione: stabilisce le regole che
definiscono in modo non ambiguo tutte le frasi esprimibili nel linguaggio. Gli
errori di sintassi in un programma sono facili da scoprire poiché vengono
individuati automaticamente dal compilatore al tempo di compilazione o
dall’interprete a tempo di esecuzione.
•
Semantica dei linguaggi di programmazione: stabilisce il significato delle
frasi corrette nel linguaggio. Gli errori di semantica sono più difficili da
scoprire perché sono discrepanze accidentali rispetto alle intenzioni del
programmatore. Essi inoltre si manifestano a tempo di esecuzione.
Es. Un programma sintatticamente corretto che calcola la somma di due
numeri è semanticamente scorretto se le intenzioni del programmatore
erano di calcolare il prodotto di due numeri.
•
Esempi di programmi in differenti linguaggi di programmazione per
stampare sullo schermo la scritta: “Hello World”.
Assembly Intel 80X86
section .text
_start:
push dword len
push dword msg
push dword 1
mov
eax, 0x4
call _syscall
add
esp, 12
push dword 0
mov
eax, 0x1
call _syscall
_syscall:
int
0x80
ret
msg db
len equ
"Hello World",0xa
$ - msg
C
#include <stdio.h>
main() {
printf("Hello World\n");
}
Java
import java.io.*
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
Pascal
PROGRAM HelloWorld;
BEGIN
WRITELN('Hello World');
END.
Approfondimento 1.3
Modellazione mediante oggetti
•
I programmi sono basati su modelli di problemi.
•
Modello = rappresentazione semplificata, basata su elementi astratti.
Es. Un programma che scrive “Hello World” modella i caratteri che vengono
visualizzati sullo schermo, ma trascura eventualmente dettagli come colore,
font, dimensione, posizione ecc.
Es.: Modello di Gestione di un servizio di pronto intervento.
•
Oggetti ( 20 Riparatori, 1000 Clienti, 1 Smistatore)
•
Comportamento basato su scambio di messaggi:
4. Il Cliente richiede l'intervento allo Smistatore.
5. Lo Smistatore registra la chiamata, sceglie un Riparatore e gli comunica di
eseguire il lavoro.
6. Il Riparatore comunica la conclusione dell'intervento.
1. Classi (Riparatori/Clienti/Smistatore)
1. Il nostro modello può omettere molti dettagli.
Es. dettagli sulla natura del lavoro eseguito dal riparatore.
1. Oggetto = Istanza di una classe
Cliente 1
Cliente 2
Cliente 3
Smistatore
Riparatore 1
Cliente 1
Riparatore 2
Cliente 2
Cliente 3
Classe degli
Smistatori
Smistatore
Riparatore 1
Classe dei
Clienti
Riparatore 2
Classe dei
Riparatori
1. Proprietà di un modello:
1. Gli elementi di un modello rappresentano cose più complesse.
Es. Pensiamo ai riparatori, clienti e smistatore come “oggetti”.
2. Gli elementi di un modello sono caratterizzati da un comportamento
consistente.
Es. I clienti chiamano lo smistatore, questi chiama i riparatori, che
effettuano il lavoro.
3. Gli elementi di un modello possono essere raggruppati in differenti categorie
basate sul loro comportamento comune.
Es. Pensiamo a tutti gli oggetti che modellano clienti come appartenenti alla
stessa classe.
4. Le azioni degli elementi di un modello avvengono su sollecitazione di azioni
provocate da altri elementi del modello.
Es. Un oggetto smistatore agisce solo quando riceve un messaggio da un
oggetto cliente. Un oggetto riparatore agisce solo quando riceve un
messaggio dall’oggetto smistatore.
Programmazione orientata agli oggetti in Java
2. Scrivere un programma in Java consiste nello scrivere frasi che definiscono
classi di oggetti. Ogni programma deve contenere almeno una classe.
2. Per ogni classe si possono prevedere più comportamenti possibili per i suoi
oggetti: gli oggetti di una classe “sanno” fare più cose.
3. I comportamenti degli oggetti di una classe vengono programmati in Java
scrivendo frasi chiamate metodi. Ogni metodo ha un nome per identificarlo
e può contenere istruzioni per:
3. creare nuovi oggetti;
4. inviare messaggi ad oggetti, in modo da farli agire;
5. risolvere problemi algoritmici.
Quindi a tempo di esecuzione un oggetto Java può creare altri oggetti,
mandare loro messaggi, e risolvere problemi algoritmici.
2. Gli oggetti Java non sono entità astratte, ma hanno una evidenza fisica
poiché occupano spazio nella memoria del computer quando un programma
viene eseguito.
4. In Java gli oggetti creati vengono automaticamente distrutti quando non
servono più: tecnologia software estremamente sofisticata! Questo rende
Java molto diverso da altri linguaggi come Pascal, C, C++. Ecco perché Java
non fornisce istruzioni per distruggere oggetti predecentemente creati.
3. Fortunatamente, Java mette a disposizione librerie con molte classi ed
oggetti predefiniti che possiamo utilizzare nei nostri programmi per gli scopi
più vari.
4. Analisi del programma HelloWorld.java.
•
“scrivere almeno una classe”:
class HelloWorld {
…
Definizione
della classe
Corpo della classe HelloWorld
HelloWorld
}
•
“i metodi definiscono i comportamenti delle classi”:
class HelloWorld {
public static void main(String[] args) {
…
Definizione
del metodo
Corpo del metodo main
main
}
}
•
“i metodi contengono istruzioni che definiscono un comportamento”:
class HelloWorld {
public static void main(String[] args) {
Istruzione
del metodo
System.out.println("Hello World");
main
}
}
•
“inviare messaggi ad altri oggetti”:
System.out
.
Riferimento oggetto destinatario
println("Hello World")
;
messaggio
dove System.out è un oggetto predefinito della classe PrintStream. Un
messaggio in Java è costituito dal nome del metodo invocato (es. println) e
da dettagli tra parentesi (argomenti) che specificano ulteriori informazioni
del messaggio (es. “Hello World”).
•
“Java mette a disposizione librerie”:
import java.io.*
System.out è un riferimento ad un oggetto predefinito della classe
PrintStream definita nelle librerie java.io.*.
•
import, class, public, static, void sono alcune delle parole chiave
(keywords) del linguaggio Java e sono parole prefissate definite dalla
sintassi.
•
HelloWorld, main, String, args, System, out, println sono invece
identificatori, parole definite dal programmatore per identificare
univocamente di un programma classi, oggetti ecc. Gli indentificatori non
sono parole prefissate definite dal linguaggio.
•
In Java gli identificatori validi sono qualunque sequenza di lettere e cifre
inizianti per una lettera, purchè non sia una parola chiave.
Es. Program1 è un identificatore valido, mentre 1Program e static non
losono.
•
Diversamente dal Pascal, Java è “case sensitive” come il C e il C++. Cioè le
lettere minuscole e maiuscole sono diverse.
Es. System è un identificatore diverso da system e da sYsTeM. Allo stesso
modo static è una parola chiave, mentre Static non lo è. Quindi Static è un
identificatore valido.
•
Modello di esecuzione del programma HelloWorld:
Oggetti predefiniti
Messaggio
println(“Hello World”)
Classe
HelloWorld
System.out
Classe
PrintStream
Messaggio
main()
java HelloWorld
•
Al momento dell’esecuzione del programma HelloWorld, ad esempio
invocando il comando java HelloWorld, viene inviato il messaggio main()
all’oggetto predefinito della classe HelloWorld che rappresenta il nostro
programma.
•
L’esecuzione del metodo main consiste nell’invio del messaggio
println(“Hello World”) all’oggetto predefinito System.out della classe
PrintStream fornita dalle librerie Java.
•
L’esecuzione del metodo println provoca la stampa a video della scritta
“Hello World”.
2. Nota Bene: ogni programma Java deve avere una classe “principale” (es.
HelloWorld) che modella l’intero programma e che ha un metodo chiamato
main che viene attivato automaticamente all’avvio del programma.
3. Il significato delle parole chiave public, static, void ed import usate nel
programma HelloWorld verrà discussa più avanti nel corso. Lo stesso vale
per la frase: String[] arg.