Informatica di base
A.A. 2003/2004
Algoritmi e programmi
Algoritmi
Algoritmo: procedura per risolvere una classe di
problemi
Da algoritmo a programma
Caratteristiche di un algoritmo efficace:
Generale: deve funzionare per tutti i problemi
Non ambiguo: unica interpretazione dei passi
Eseguibile: i passi devono poter essere fatti in tempo
finito
2
Programmazione
Disciplina che dice come definire gli algoritmi in
modo che possano essere eseguiti da un
calcolatore
Programma: definizione di un algoritmo, scritto
secondo certe regole sintattiche
Fasi di sviluppo di un programma:
Definizione: specifica del problema + algoritmo
Realizzazione: scrittura del programma che
corrisponde all’algoritmo
Manutenzione: modifiche del programma e/o
dell’algoritmo
3
Caratteristiche di un programma
Efficienza: risolvere un problema nel minimo
tempo e con le risorse (memoria) a
disposizione
Leggibilita’: scritto in modo chiaro e
documentato, per agevolare la manutenzione
Modificabilita’: Facilita’ di modificarlo
4
Efficienza – esempio:
somma dei primi n numeri 1, ..., n
1. Leggi n
2. Inizializza S a 0
3. Inizializza I a 1
4. Esegui S = S+I
5. Incrementa I (I=I+1)
6. Se I<n torna a 4, altrimenti se I=n esegui 7
7. Stampa S
Richiede n somme
5
Secondo algoritmo
Uso la proprieta’ S = n x (n+1) /2
1. Leggi n
2. Calcola S = n x (n+1)/2
3. Stampa S
Una sola somma, 1 prodotto, 1 divisione: solo 3
operazioni aritmetiche piu’ efficiente
6
Sviluppo di un algoritmo
Diagrammi di flusso: rappresentazione
grafica per mostrare l’ordine logico delle
operazioni
Rettangolo: operazione da svolgere
Rombo: scelta fra due rami dell’algoritmo
(salto condizionato)
7
Strategia top-down
Suddividere il problema in sottoproblemi
indipendenti pezzi con un punto di ingresso e
uno di uscita
Comporre i pezzi dei sottoproblemi per ottenere
l‘intero algoritmo
Vantaggi:
Scrivere i vari pezzi separatamente
Programmi leggibili
Errori localizzati e semplice trovarli
Piu’ programmatori
Pochi salti intrecciati
Programmazione strutturata
8
Linguaggi di programmazione
Linguaggi ad alto livello (rispetto all’Assembler)
Linguaggi imperativi: rispecchiano le operazioni
reali nell’architettura di Von Neumann
Scrivere un valore in una cella di memoria o in un
registro
Es.: Fortran (Formula Translator), 1954
Algol, Cobol, APL, LISP (’60), Pascal, Prolog (’71),
C (’74), Ada (’79), C++ (’85), Java (’94)
9
Elementi dei linguaggi di
programmazione
Alfabeto: alfabeto inglese, cifre decimali
(0,1,...,9), punteggiatura (;), simboli di operazioni
(+,-,*,...)
Parole chiave: es. IF, THEN, WHILE, ...
Operatori: aritmetici, logici (and, not, or, ...),
relazionali (<, >, =, ...)
Tipi di dati: interi, reali, caratteri, ...
Sintassi: regole per scrivere un programma
Semantica: significato dell’esecuzione di un
programma
10
Variabili e assegnamenti
Variabile: nome associato ad una cella di memoria
Puo’ assumere un valore (quello contenuto nella
cella)
Istruzione di assegnamento per dare un valore
ad una variabile
Valore ottenuto calcolando un’espressione (es:
A+3)
Es. (Pascal): X := Y+3
Es. (C): X = Y+3
Es. (C): X=X+1 (X da entrambe le parti!)
11
Costrutti di programmazione
Sequenza
Selezione
Iterazione
Salto incondizionato
Procedura rientrante
Funzione ricorsiva
12
Sequenza
Istruzioni eseguite in sequenza
Es: S1;S2;S3; ...; Sk;
Es. (Pascal):
S1
Begin
X:=Y+3;
Z:=X+4
End
S2
{
X=Y+3;
Z=X+4;
}
Sk
Es. (C):
13
Selezione (uno o due rami)
Se E e’ vera, esegui S1 (altrimenti esegui S2)
E espressione Booleana (vera o falsa)
Es.: A < B
E
Costrutto IF THEN ELSE
Es.: (Pascal)
S1
If a > 0 then a: a-1 else b:=a
V
If (a >0) a=a-1 else b=a
S1
Es. (C):
E
F
V
F
S2
14
Selezione (piu’ di due rami)
Condizione non Booleana piu’ valori piu’ rami
Costrutto CASE
Es. (Pascal):
Case veicolo of
Bicicletta: tassa:=0;
Motociclo: tassa:=30;
Auto: tassa:=100
End;
15
Iterazione - while
Per ripetere un gruppo di comandi finche’ non si verifica
una certa condizione
Costrutto WHILE: finche’ E e’ vera ripeti S
Test prima del ciclo (loop) se E e’ falsa all’inizio, S non
viene mai eseguito
Es. (Pascal):
i:=1;
While i <= 100 do
Begin ... i:=i+1 end;
E
S1
F
V
Es. (C):
I=1;
While (i<=100) { ... I++;}
16
Iterazione -repeat
Costrutto REPEAT: ripeti S fino a che E
e’ falsa
Test dopo il loop S viene sempre
seguito almeno una volta
Es. (Pascal):
I:=1;
Repeat
...
I:=i+1
Until i> 100;
Es. (C):
I=1;
Do
{...
I++;
} while (i<=100);
S1
F
E
V
17
Iterazione -for
Costrutto FOR: ripeti S n volte
Non c’e bisogno di una condizione, so gia’
quante volte eseguire S
Es. (Pascal):
For i:=1 to 100 do
Begin ... End
Es. (C):
For (i=1;i<=100,i++)
{ ... }
18
Salto incondizionato
Per saltare ad una qualunque istruzione
che non sia la seguente
Costrutto GOTO
Contrasta con la programmazione
strutturata (effetto spaghetti)
Usare solo se assolutamente necessario!
19
Gruppi di aula informatica
Gruppo 1 (matematici):
Martedi’ 4 Novembre 14:00
Mercoledi’ 12 Novembre 14:00
Venerdi’ 21 Novembre 11:20
Venerdi’ 28 Novembre 11:20
20
Gruppi di aula informatica
Gruppo 2:
Mercoledi’ 5 Novembre 14:00
Givedi’ 13 Novembre 11:20
Giovedi’ 20 Novembre 11:20
Martedi’ 25 Novembre 14:00
21
Gruppi di aula informatica
Gruppo 3:
Giovedi’ 6 Novembre 11:20
Venerdi’ 14 Novembre 11:20
Martedi’ 18 Novembre 14:00
Mercoledi’ 26 Novembre 14:00
22
Gruppi di aula informatica
Gruppo 4:
Venerdi’ 7 Novembre 11:20
Martedi’ 11 Novembre 14:00
Mercoledi’ 19 Novembre 14:00
Giovedi’ 27 Novembre 11:20
23
Esercizio: programma per somma
(C++)
Main()
Nome funzione principale
{
Int X=10, Y=25, Zero=0;
Dichiarazioni
X=X+Y;
If (X > Zero) Y=X);
Sequenza
}
Dichiarazioni: utili per sapere quanto spazio allocare per
questi nomi
24
Esercizio: minimo esponente e tale
che 2 alla e superi X (C++)
Main()
{
Int X=10, p=1, e=0;
While (X>p)
{
p=p*2;
esponente++;
}
}
Nome funzione principale
Dichiarazioni
Sequenza
25
Struttura di un programma (C)
Intestazione
Dichiarazione variabili
Comandi (corpo) programma principale
Funzione 1
Funzione 2
...
Funzione n
26
Esempio: stampa dei numeri da 1 a 10
main()
{
Int i;
For (i=0;i<10;i++)
Printf(“%d\n,i+1);
}
27
Procedura rientrante (o sottoprogramma)
Pezzo di programma con un nome e una lista di variabili
(argomenti o parametri)
Scritto una volta solo, ma posso ‘’chiamarlo’’ piu’ volte e
con dati diversi
Anche risultati dal sottoprogramma al programma
chiamante (funzione)
Quando lo chiamo (call), salto alla prima istruzione del
sottoprogramma e salvo l’indirizzo della prossima
istruzione
Quando finisce, ritorno al punto in cui ero (quello salvato)
28
Esempio: funzione per xy (in Pascal)
Function potenza (base: real, esponente: integer): real;
Var risultato: real;
begin
risultato := 1;
While (esponente >0)
begin
Risultato := risultato * base;
Esponente := esponente –1;
End;
Potenza : = risultato
End;
29
Esempio: funzione per xy (in C)
Float potenza (float base, int esponente)
{
Float risultato = 1.0;
While (esponente >0)
{
Risultato = risultato * base;
Esponente = esponente –1;
}
Return risultato;
}
Es. di chiamata: z = potenza(x,3);
30
Struttura delle chiamate –1
Programma
Call A
Call B
Call C
Funzione A
Fine A
Funzione B
Fine B
Funzione C
Call B
Fine C
31
Struttura delle chiamate - 2
Programma
Call A
Call A
Funzione A
Call B
Fine A
Funzione B
Call C
Fine B
Funzione C
Fine C
32
Funzioni ricorsive
Definizione ricorsiva: in termini di se’ stesso
Funzione ricorsiva: chiama se’ stessa al suo
interno
Esempio: funzione fattoriale (fatt)
0! = 1
N! = 1*2*3*4*...*n
Definizione iterativa:
If (n=0 or n=1) then fatt = 1
else {fatt = 1; for i=2 to n fatt = fatt*i}
return fatt
33
Funzioni ricorsive
Definizione ricorsiva: in termini di se’ stesso
Funzione ricorsiva: Chiama se’ stessa al suo
interno
Esempio: funzione fattoriale (fatt)
0! = 1
N! = 1*2*3*4*...*n
Definizione ricorsiva:
0! = 1
N! = n*(n-1)!
Funzione ricorsiva:
If (n=1 or n=0) then fatt = 1
Else {fatt = 1; fatt = n*fatt(n-1)}
Return fatt
34
Da linguaggio X a linguaggio macchina
Se X= Assembler assemblatore
Se X piu’ ad alto livello compilatore o
interprete
Fasi di un compilatore:
Analisi lessicale: da caratteri a nomi,
operatori, parole chiave, ... (tokens)
Analisi sintattica/semantica: da tokens a
costrutti (if then else, while, ...)
Generazione codice oggetto in linguaggio
macchina
Linker/loader: collegamento tra vari
Programmi e scelta degli indirizzi di RAM
Programma
compilatore
Codice oggetto
linker
eseguibile
loader
Programma in ling. macchina in RAM
35
Esempio
p := p + r * 60
sequenza di caratteri
Analisi lessicale:
id1 := id2 + id3 * 60
sequenza di tokens
Analisi sintattica/semantica
Generazione codice intermedio:
Temp1 := 60
Temp2 := id3*temp1
Temp3 := id2 + temp2
Id1 := temp3
Ottimizzazione codice:
Temp1 := id3 * 60
Id1 := id2 + temp1
:=
+
id1
id2
*
id3
60
Generazione codice oggetto:
MOVE id3 R2
MULT R2 60
MOVE id2 R1
ADD R1 R2
MOVE R1 id1
36
Tipi di dati
I programmi possono gestire dati di
diverso tipo:
Numerici: interi e reali
Non numerici: booleani e caratteri
Inoltre, i dati possono essere:
semplici (es. Un numero singolo o un
carattere)
strutturati (es. Ora: ore, minuti, secondi)
37
Tipi di dato strutturati
Array
Record
Coda
Pila
Lista
38
Array
V
B
V[1]
B+ixL
V[i]
L
Sequenza finite di dati omogenei
Per indicare un elemento: nome dell’intero array +
indice(i)
Indice: posizione rispetto al primo elemento
Un indice vettore (array monodimensionale). Es.:
V[3]
Due o piu’ indici matrice. Es.: V[3,2]
Dichiarazione di un array: nome + numero dimensioni +
tipo elementi + numero elementi in ogni dimensione.
Es.: int V[100];
In memoria: celle contigue a partire da B, N elementi,
ognuno lungo L indirizzo elemento i: B+ixL
Limiti: dimensione fissa e dati omogenei
Vantaggio: accesso diretto con tempo fisso
39
Esempio (C)
Inizializzazione a 0 degli elementi di una matrice 20x20
Macro: ogni occorrenza di Max e zero viene
#define Max 20
sostituita con 20 e 0.0 prima di iniziare a
#define zero 0.0;
compilare (pre-processore)
main()
{
int i,j;
float A[Max][Max];
for (i=0;i<Max;i++)
for j=0; j<Max; J++)
A[i][j] = zero
}
40
Esempio (C++): determinare la posizione del
massimo in un array di interi (while)
#include <iostream>
il pre-processore include la libreria di funzioni iostream
main()
{
int a[]={10,0,5,-12,45,-9,23};
int i=1, max=A[0], pos_max=0;
while (i<7)
{
Output standard (video)
if (A[i]>max)
{
max=A[i];
pos_max=i;
Funzione << di scrittura
}
i++;
}
cout<<‘’Il massimo e’:’’<<max<<‘’ in posizione:’’ <<pos_max<<endI;
}
41
Esempio (C++): determinare la posizione del
massimo in un array di interi (for)
#include <iostream>
main()
{
int a[]={10,0,5,-12,45,-9,23};
int max=A[0], pos_max=0;
for (int i=1;i<7;i++)
if (A[i]>max)
{
max=A[i];
pos_max=i;
}
cout<<‘’Il massimo e’:’’<<max<<‘’ in posizione:’’ <<pos_max<< endI;
}
42
Esempio (C): prodotto degli elementi di un
vettore di interi
main()
{
int num[100]={10,0,5,-12,45,-9,23, ...};
float prod = 1.0;
for (i=0;i<100;i++)
prod= prod*num[i];
printf(“il Prodotto e’”,prod);
}
43
Esempio (C): minimo e massimo di un vettore
main()
{
int V[10]={10,0,5,-12,45,-9,23,8,10,9};
int min=max=V[0];
for (i=1;i<10;i++)
{
if (V[i]<min) min=V[i];
if (V[i]>max) max=V[i];
}
}
44
Esempio (C): trovare la posizione di un
elemento in un vettore
main()
{
int val = 45, pos, i, T[10]={10,0,5,-12,45,-9,23,8,10,9};
pos=-1; i=0;
do
{
if (val ==T[i]) pos=i;
i++;
}
}
Numero di confronti O(n): 1 nel caso migliore, n nel caso pessimo (val
non e’ contenuto in T)
45
Esempio (C): trovare la posizione di un
elemento in un vettore ordinato – metodo
dicotomico
main()
{
int sn, dx, ct, N=10, val = 45, pos, i, T[10]={10,0,5,-12,45, 9,23,8,10,9};
pos=-1; sn = 0; dx = N-1;
do
{
ct = (sn+dx+1)/2;
if (val ==T[ct]) pos = ct;
if (val < T[ct]) dx = ct-1
else sn=ct+1;
}
while (sn<=dx);
}
Numero di confronti O(log2(n))
46
Esempio (C++): numero di elementi <0 in un
array
main()
{
int num=0,T[10]={10,0,5,-12,45, 9,23,8,10,9};
for (i=0;i<10;i++)
if (T[i] < 0) num=num+1;
}
47
Record
Composto da campi contenenti dati possibilmente di tipo
diverso
Es.: elenco del telefono, ogni riga e’ un record con
Cognome: sequenza di caratteri
Nome: sequenza di caratteri
Numero telefono: intero
Struttura dati statica
Accesso diretto
Come un array, ma con elementi di tipo diverso e indicati
con nome invece che indice. Es.: riga.cognome = Rossi
Es. (C):
struct riga
{
char cognome[20];
char nome[20];
int numero_telefono;
}
48
E1
E2
En
Lista
Struttura dinamica: oltre a leggere e scrivere elementi,
anche inserimento e cancellazione
Ogni elemento ha due parti: dato + indirizzo (puntatore)
elemento successivo elemento successivi possono
essere in posizioni lontane di memoria
Per accedere all’elemento i-esimo: scansione sequenziale
dall’indirizzo del primo elemento tempo variabile
Inserzione di E tra Ei e Ei+1:
Scansione fino a Ei
Link(E) = link(Ei)
Link(Ei)= ind(E)
Eliminazione di Ei:
Scansione fino a Ei-1
Link(Ei-1) = link(Ei)
49
Coda e pila
coda
pila
Dati ordinati in sequenza
Strutture dinamiche
Coda: meccanismo FIFO (first in, first out)
Inserzione in fondo
Eliminazione in cima
Pila: estrazione e inserzione dalla stessa parte (LIFO:
last in, first out)
Celle contigue di memoria
Per una coda, basta un array (se si conosce la dimensione
max.) e il puntatore al primo elemento
Per la pila, lista con inizio pila = inizio lista no
scansione
Pila usata per gestione memoria dei sottoprogrammi 50
Domande – algoritmi e programmi
Cos’e’ un algoritmo?
Che differenza c’e’ tra un algoritmo e un programma?
Come si misura l’efficienza di un algoritmo?
Un algoritmo che ha complessita’ O(n) e’ piu’ o meno
efficiente di uno che ha complessita’ O(logn)? E di uno che
e’ O(n2) o O(2n)?
Cosa sono le parole chiave di un linguaggio di
programmazione?
51
Domande – linguaggi
Cos’e’ la sintassi di un linguaggio di programmazione? E la
semantica?
Cosa si intende per linguaggi imperativi?
Cos’e’ una variabile?
Cos’e’ un’espressione Booleana?
Cos’e’ un assegnamento?
52
Domande – costrutti e
sottoprogrammi
Descrivere il costrutto di selezione a uno, due o piu’ rami
Descrivere i tre costrutti per l’iterazione, specificando
le loro differenze
A cosa servono le dichiarazioni in un programma?
Cos’e’ un sottoprogramma?
Che differenza c’e’ tra una procedura e una funzione?
Cosa succede quando viene chiamato un sottoprogramma?
Cosa si intende per sottoprogramma ricorsivo?
53
Domande – compilatori e tipi di
dato
Qual e’ la funzione di un compilatore?
Cosa succede durante la fase di analisi lessicale?
E quella di analisi sintattica?
Fare degli esempi di tipi di dati semplici
Cosa sono i tipi di dati strutturati? Fare degli esempi
Quali sono le principali caratteristiche di un array?
Cosa contiene la dichiarazione di un array?
Quali sono le principali differenze tra array e record?
54
Domande - liste
Quali sono le principali caratteristiche delle liste, e le
differenze con gli array?
A parita’ di dati memorizzati, occupa piu’ spazio un array
o una lista?
Quali sono le operazioni necessarie per inserire un nuovo
elemento in una lista?
E per cancellare un elemento?
55
Esercizio
Cosa contengono le variabili d, n, e i alla fine
dell’esecuzione del seguente programma? d=5.0, n=5, i=4
Dato un qualunque array a, cosa calcola il programma nella
variabile d?
d calcola la media degli elementi dell’array a
main();
{
int n=0, a[] = {11, 3, 2, 4, 5};
float d = 0.0;
for (i=0;i<5;i++)
{
d = d+a[i];
n=n+1;
}
d=d/n;
}
56
Esercizio: trovare il minimo e il massimo di
una matrice
main()
{
int V[10][20]={10,0,5, ...};
int min=max=V[0][0];
for (i=0;i<10;i++)
for (j=0;j<20;j++)
{
if (V[i][j]<min) min=V[i][j];
if (V[i][j]>max) max=V[i][j];
}
}
57
Esercizio: inizializzare una matrice a righe
crescenti
main()
{
int V[4][4];
for (i=0;i<4;i++)
for (j=0;j<4;j++)
{
V[i][j] = j +1 + i*4;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
58