Esplora E-book
Categorie
Esplora Audiolibri
Categorie
Esplora Riviste
Categorie
Esplora Documenti
Categorie
Ingegneria Elettronica,
delle Telecomunicazioni,
Biomedica, dell’Automazione, Informatica
1
Materiale didattico
• Libri di testo:
– A. Chianese, V. Moscato, A. Picariello, C. Sansone
Le radici dell'informatica.
Dai bit alla programmazione strutturata. Apogeo. 2017
– E.Burattini, A. Chianese, V. Moscato, A. Picariello, C.
Sansone
Che C serve. Per iniziare a programmare
Apogeo Editore, II edizione 2016
2
Programma del corso e libri di testo
• Le radici dell'informatica
• Capitolo 1 tranne 1.15
• Capitolo 2 escluso 2.7 e approfondimenti
• Capitolo 3 da 3.1 fino a 3.7
• Capitoli 4 ,5, 6,7 (più dettagliati su Che Ci Serve)
• Le dispense del Prof. Iannello rappresentano un utile libro alternativo che copre
una parte degli argomenti trattati dagli altri libri, In particolare, sono da
consultare:
• Capitolo 1, 2, 3
• Capitolo 5
• Alcuni algoritmo del capitolo 6
• Capitoli 7, 8, 9 e 10
3
Programma del corso e libri di testo
• A Che C Serve?
• Capitolo 1 tranne 1.2.1, 1.4.1
• Capitolo 2 tranne 2.8.5 e 2.11.7
• Capitolo 3 tranne 3.4.1 e 3.4.3
• Capitolo 4
• Capitolo 5 tranne 5.2, 5.5 e 5.8
• Capitolo 6 tranne 6.8 e 6.12
• Capitolo 7, solo paragrafi 7.1, 7.2, 7.5
• Capitoli 8,9
• Gli esempi presentati nei diversi capitoli (in particolare nei capitoli 10,11) fungono
da ulteriori esempi svolti, in aggiunta a quelli visti a lezione
• Tutti i paragrafi saltati e il capitolo 12 rappresentano utili approfondimenti sul
linguaggio C++ non espressamente inseriti nel programma di questo corso,
4
Algoritmi: fonti
5
Concetti fondamentali
• Informatica:
– Scienza della risoluzione dei problemi con l’aiuto degli
elaboratori
– Scienza per la elaborazione automatica delle informazioni
• Problema
– Specifica
• Elaborazione
• Algoritmo
• Sequenza finita di passi che porta alla risoluzione di un problema
• Esecutore
• Entità che deve realizzare il compito
– Linguaggio di programmazione
• Azioni elaborative
6
Concetti fondamentali
• Programma
– Specifica
– Dati di ingresso e di uscita
– Sequenza statica e sequenza dinamica
– Casi di test
7
Concetti Fondamentali
8
Logica: fonti
• Capitolo 2 da (Iannello)
• Capitolo 1 da (Chianese, Picariello, Moscato) (parte
centrale)
9
Logica delle proposizioni
• Proposizioni
• Valori logici
• Operatori di relazione
• Proposizioni semplici e composte
• Connettivi logici e tabelle di verità
– AND
– OR
– NOT
– XOR
• Precedenze: NOT →AND →OR XOR
10
• Esercizi:
• Riconoscere se un numero x è compreso tra 5 e
10 (escluso il 5)
• Riconoscere se si è entrati nell’aula giusta
• Riconoscere se un triangolo è equilatero, isoscele
o scaleno
11
Algebra di Boole
• Dalla logica delle proposizioni all'aritmetica binaria
-
• Algebra di Boole < D={0,1}, +, *, , min=0, max=1 >
• Proprietà:
– Commutativa
– Associativa
– Distributiva
– Idempotenza
– Dell'esistenza dell'elemento neutro
– Del complemento
– Del minimo e del massimo
– Dell'assorbimento
• Principio di Dualità
• Legge di De Morgan
Esercizi
A AND C OR NOT C = A OR C
13
Esercizi
14
Informazione
• http://www.federica.eu/l/linformatica_e_la_codifica_de
lle_informazioni
15
Informazione
• Tipo
– Cardinalità
• Valore
• Attributo
• Valori logici
• Numeri naturali
– Sistema posizionale
– Trasformazione di numeri decimali in bit e viceversa
– Operazioni aritmetiche, overflow e underflow
• Numeri esadecimali
• Caratteri
– Codice ASCII
– American Standard Code for Information Interchange
– ASCII esteso
– Unicode
17
Codice ASCII (0-127)
18
Rappresentazione dei numeri relativi
– Rappresentazione in segno e modulo
• Problema del doppio zero
• Numeri relativi
– Rappresentazione in complemento
• Proprietà della somma
• Calcolo del complemento
• Complementa i bit e somma 1
• Trasformazione inversa
• Riconoscimento del segno
• Problema della proprietà associativa
• Problema dell’overflow
19
Rappresentazione in complementi alla base
• Dal numero alla rappresentazione
• Se è positivo, converti in binario
• Se è negativo:
• Cambia segno (cioè calcola il valore assoluto)
• Converti in binario
• Nega tutti i bit
• Somma uno
• Dalla rappresentazione al numero:
• Se il primo bit è zero (è positivo), converti in decimale
• Se il primo bit è uno (è negativo)
• Nega tutti i bit
• Somma uno
• Converti il numero in decimale
• Cambia segno (trasforma il valore assoluto nel valore)
20
Esercizio 1
21
Esercizio 1
00010000
22
Esercizio 2
23
Esercizio 2
Prova:
10100 (nega) 01011 (+1) 01100 (conv) +12 (-) -12
24
Esercizio 3
25
Esercizio 3
26
Esercizio 4
27
Esercizio 4
Prova:
-8 (abs) +8 (conv) 001000 (nega) 110111 (+1) 111000
28
Rappresentazione dei numeri reali
29
Convergenza digitale
• Conversione analogico-digitale
• Campionamento e quantizzazione
• Compressione
• Codifica delle immagini
– Pixel e colori
• Codifica del video
• Codifica del suono
30
Macchina di Von Neumann: fonti
31
Modello di Von Neumann
32
Algoritmo di Von Neumann
1. Boot
2. Fetch
• Preleva l’istruzione puntata da PI, la copia in IR e
incrementa PI
3. Operand Assembly
• Esamina l’istruzione IR, e preleva dalla posizione di
memoria puntata da PI (che poi incrementa) gli eventuali
altri operandi
4. Execute
• A seconda del comando da eseguire, manda comandi
alle altre unità, legge/scrive sulla memoria, avvia
operazioni di input/output, setta valori dei registri e dei
codici di controllo
33
Processore
Estensioni del Modello di Von Neumann
• Bus
• Bus dati
• Bus indirizzi
• Bus di controllo
• Parallelismo del bus
• Clock
• Sincronizzazione delle operazioni
• Frequenza di clock
• Buffer
• Buffer di input e di output
• Memoria di massa
• Sistema delle Interruzioni
• Segnali di interruzione
• Interrupt Service Routine (ISR)
• Uso delle interruzioni per la sincronizzazione con le periferiche
di input e output
• Algoritmo di Von Neumann con interruzioni
35
Estensioni del Modello di Von Neumann
Gerarchia delle memorie
37
Traduzione dei programmi
38
Linguaggi di programmazione
• Lessico
• Sintassi
• Semantica
• Linguaggio macchina
• Linguaggi ad alto livello
• Metalinguaggi
39
Realizzazione di un programma
40
Compilatore
• Fase di precompilazione
– Sostituzione automatica di parti di codice sorgente
• Esempio
#define PIGRECA 3.1415
• Il precompilatore sostituisce automaticamente a tutte le
occorrenza nel testo della parola PIGRECA il valore 3.1415
• Fase di analisi
– Analisi lessicale → Riconoscimento dei simboli (token)
– Analisi sintattica → Riconoscimento delle istruzioni
– Analisi semantica → Riconoscimento del significato delle
istruzioni
• Fase di sintesi
– Trasformazione della semantica individuata in codice oggetto
41
Introduzione alla Programmazione
• Iannello, capitolo 5
• Chianese, Picariello, Moscato, Alla scoperta dei
fondamenti dell’informatica, capitoli 4 e 6
• A che C serve, capitolo 1 paragrafo 5
42
Il primo programma in C++
#include <iostream>
// Il primo programma in C++
int main()
{
std::cout<<"Hello, world!"<<std::endl;
return 0;
}
43
Il primo programma in C++
#include <iostream>
// Il primo programma in C++
int main()
{
cout<<"Hello, world!"<<endl;
return 0;
}
44
Il programma equivalente in C
#include <stdio.h>
/* Il primo programma in C */
int main()
{
printf("Hello, world!\n");
return 0;
}
45
• Direttive per il precompilatore
– #include <iostream>
• Simboli speciali
– Operatori e delimitatori
• { } ; <<
• Parole chiave
– using namespace return
• Commenti
– // /* */
• Identificatori
– main cout
• Stringhe Costanti
– “Hello, World!”
46
Dev CPP
47
Dev CPP
48
Tipi semplici
• Tipi semplici
– bool
– int
– char
– float
– double
– Modificatori:
– short
– unsigned
– long
49
Tipi semplici
50
Variabili e costanti
• Costanti
– Definizione tramite precompilatore: #define
– Definizione per compilatore: const
• Variabili
– Dichiarazione
– Definizione
– Assegnazione
– Scope
• Variabili Globali e variabili locali
51
Esempi
• Esempio:
– Calcolo della lunghezza di una circonferenza
• L=2 r
– Controesempio
• Calcolo di 6 * 9
– Con e senza l’utilizzo di define
– Swap
• Date due variabili x, y scrivere un programma che inverta
il valore di x con quello di y
– Esempio: se x=3, y=4 il programma deve restituire x=4,
y=3
52
Casting dei tipi
53
Operatori sovraccaricati
• Divisione reale
int x=13;
int y=4;
float z=(float)x/(float)y
• Z=3.25
• Divisione intera
int x=13;
int y=4;
float z=(int)x/(int)y;
• Z=3
54
Input dei dati
• cin e cout
• Esempio:
– Modifica degli esempi visti con l’introduzione dei valori
in ingresso
55
Costrutti di selezione if-then e if-then-else
if (condizione) if (condizione)
{
{
Blocco di
Blocco di istruzioni
istruzioni }
} else
{
Blocco di istruzioni
alternativo
}
57
Operatori logici
== (uguaglianza)
!= (disuguaglianza)
<
>
&& (and logico)
|| (or logico)
! (not logico)
Attenzione: = (diventa uguale a) non è la stessa cosa di == (è uguale a), ma per il
compilatore scrivere = in un’espressione logica non è un errore (in realtà
potrebbe essere una scorciatoia)
58
Esempi
Circonferenza
Aggiungere il controllo che verifica che il raggio sia
positivo e maggiore di zero
Multipli
– Valutare se dati due numeri naturali in ingresso, essi
sono multipli l’uno dell’altro
59
Selezione tra più scelte
60
Esempi
61
Altri esempi
while (condizione)
{
Blocco di istruzioni
}
63
Iterazione: do-while
do
{
Blocco di istruzioni
}
while (condizione);
64
Il problema della validazione dei dati in
input
• Ogni dato in input deve essere validato
66
Esempio DoWhile: Media voti
Equivalente a:
{
prologo;
while (condizione)
{
Blocco di istruzioni
continuazione;
}
}
68
Esempi
69
Esempio For: Fattoriale
• Modifica
– Imporre che il numero debba essere indovinato al massimo
in 7 tentativi
– Per fare le prove è opportuno fissare un numero costante da indovinare
– Successivamente possiamo generare numeri casuali con la funzione rand()
72
Schema della soluzione
#include <time.h>
#include <cstdlib
#include <iostream>
using namespace std;
int main(){
int x; //x e' il numero da indovinare
x=42; //soluzione con valore costante
//SOLUZIONE CASUALE
//srand(time(NULL));
//x=1+rand()%100;
//DA COMPLETARE
return 0;}
73
Esempi di output
Dimmi un numero : 90
Dimmi un numero : 50 Di meno
Di meno Dimmi un numero : 80
Dimmi un numero : 15 Di meno
Di piu' Dimmi un numero : 70
Dimmi un numero : 38 Di meno
Di piu' Dimmi un numero : -5
Dimmi un numero : 42 Deve essere tra 1 e 100
Indovinato in 4 tentativi Dimmi un numero : 60
Premere un tasto per continuare . . . Di meno
Dimmi un numero : 50
Di meno
Dimmi un numero : 40
Di piu'
Dimmi un numero : 45
Di meno
Troppi tentativi
Premere un tasto per continuare . . .
74
Dati strutturati
76
Array
77
Esempi
78
Dimensione di un array
79
Operazioni sui vettori
80
Visualizzazione di un vettore
#define MAXV 7
int v[MAXV]={1,32,5,32,12,65,20};
int riemp=7;
cout<<"Vettore :";
for (int i=0;i<riemp;i++)
cout<<v[i]<<", ";
cout<<endl;
81
Ricerca di un elemento in un vettore
int v[MAXV]={1,32,5,32,12,65,20};
int riemp=MAXV;
cout<<"Valore da cercare? ";cin>>num;
bool trovato=false;
int i=0;
while (!trovato && i<riemp)
{
if (v[i]==num)
trovato=true;
else
i++;
}
if (trovato)
cout<<"Trovato in posizione "<<i<<endl;
else
cout<<"Non trovato"<<endl;
82
Ricerca di un elemento in un vettore
ordinato
int v[MAXV]={1,2,5,8,12,15,20};
int riemp=MAXV;
cout<<"Valore da cercare? ";cin>>num;
83
Ricerca di tutte le occorrenze di un
elemento in un vettore ordinato
int v[7]={1,32,5,32,12,65,20};
int riemp=7;
int elemento;
cout<<"Valore dell'elemento da cercare :";
cin>>elemento;
bool trovato=false;
for(int i=0;i<riemp;i++)
if (v[i]==elemento){
cout<<"Trovato in posizione "<<i<<endl;
trovato=true;
}
if (!trovato)
cout<<"Non l'ho trovato"<<endl;
84
Ricerca di tutte le occorrenze di un
elemento in un vettore ordinato
Soluzione con while
int v[7]={1,32,5,32,12,65,20};
int riemp=7;
int elemento;
cout<<"Valore dell'elemento da cercare :";
cin>>elemento;
bool trovato=false;
int i=0;
while (i<riemp){
if (v[i]==elemento){
cout<<"Trovato in posizione "<<i<<endl;
trovato=true;
}
i++;
}
if (!trovato)
cout<<"Non l'ho trovato"<<endl;
85
Eliminazione di un elemento da un vettore
cout<<"Numero da eliminare? ";cin>>num;
bool trovato=false;
//utilizziamo l’algoritmo di ricerca per trovare la posizione i
86
Eliminazione di un elemento da un vettore
(altra soluzione equivalente)
cout<<"Numero da eliminare? ";cin>>num;
bool trovato=false;
//utilizziamo l’algoritmo di ricerca per trovare la posizione i
if (trovato)
{
for (int j=i+1;j<riemp;j++)
v[j-1]=v[j]; Sposta verso sinistra
riemp--; tutti i successivi
}
else Aggiorna il riempimento
cout<<"Non trovato"<<endl;
87
Inserimento di un elemento in un vettore
if (riemp<MAXV){
int num, pos;
cout<<"Numero da inserire? "; cin>>num;
cout<<“Posizione ? “; cin>>pos;
//Aggiorna il riempimento
riemp++;
}
88
Inserimento di un elemento in un vettore ordinato
if (riemp<MAXV){
int num,pos=0;
cout<<"Numero da inserire? "; cin>>num;
//trova pos, indice del primo elemento uguale o superiore
//a quello da inserire
while (!trovato && pos<riemp && !superato){
if (v[pos]==num)
trovato=true;
else if (v[pos]>num)
superato=true;
else
pos++;
}
//Inserisci
for (j=riemp;j>pos;j--)
v[j]=v[j-1];
v[pos]=num;
riemp++;
}
89
Tipo char
90
Tipo char
91
Stringhe
92
Operazioni su stringhe
93
Esempio stringhe
#include <iostream>
#include <cstring>
int main()
{
char s[50]="parola1";
char t[50]="parola2";
cout<<strlen(s)<<endl;
cout<<strcat(s,t)<<endl;
cout<<strcmp(s,t)<<endl;
system("pause");
return 0;
}
94
Algoritmi con le stringhe
95
strlen
char s[]=“parola1”;
int i=0;
Nota:
while (s[i]!=0) 0 (inteso come codice ASCII numero 0)
i++; è equivalente a ‘\0’
ma non è equivalente a ‘0’ (carattere 0
della tastiera, che ha codice ASCII 48)
cout<<i<<endl;
int i=0;
while (t[i]!=0){
s[i]=t[i];
i++;
}
s[i]=0;
cout<<s<<endl;
97
strcat
int i,j;
char s[]="parola1";
char t[]="parola2";
char u[100]; // oppure char u[strlen(s)+strlen(t)-1]
cout<<u<<endl;
98
Strcat
(soluzione alternativa con 3 contatori)
int i,j,k;
char s[]="parola1";
char t[]="parola2";
char u[100]; // oppure char u[strlen(s)+strlen(t)-1]
cout<<u<<endl;
99
strcmp
char s[50];
char t[50];
int res;
cout<<"Prima parola : ";cin>>s;
cout<<"Seconda parola : ";cin>>t;
int cont=0;
while (s[cont]==t[cont] && s[cont]!=0)
cont++;
100
Stringhe in C++ (cenno)
101
Esercizi
102
Matrici
103
Esercizi
104
Esercizio: Insiemi
105
Esercizio: Insiemi
Primo insieme
Secondo insieme
Inserisci il numero di elementi dell’insieme
Inserisci il numero di elementi dell’insieme
-1
3
Inserisci il numero di elementi dell’insieme
Inserisci il valore dell'elemento in posizione 0 : 4
15
Inserisci il valore dell'elemento in posizione 1 : 6
Inserisci il numero di elementi dell’insieme
Inserisci il valore dell'elemento in posizione 2 : 3
5
Insieme 1: 2, 3, 1, 5, 4,
Inserisci il valore dell'elemento in posizione 0 : 2
Insieme 2: 4, 6, 3,
Inserisci il valore dell'elemento in posizione 1 : 3
Unione : 2, 3, 1, 5, 4, 6,
Inserisci il valore dell'elemento in posizione 2 : 1
Intersezione : 3, 4,
Inserisci il valore dell'elemento in posizione 3 : 3
Differenza primo insieme - secondo insieme : 2, 1, 5,
L'elemento gia' esiste: non va bene
Differenza secondo insieme - primo insieme : 6,
Inserisci il valore dell'elemento in posizione 3 : 5
Premere un tasto per continuare . . .
Inserisci il valore dell'elemento in posizione 4 : 4
106
Struct
107
Struct
108
Struct
• Assegnazione
• Ad un campo alla volta
• Ad eccezione della definizione con = e parentesi graffe
• L’utilizzo di = per l’assegnazione potrebbe dare risultati inattesi
• Input, output
• Ad un campo alla volta
• Confronto
• Ad un campo alla volta
• L’operatore == Ha lo stesso comportamento del caso array
• Non esistono operatori come < o >
Esempi
//dichiaro il tipo struct data e una
//dichiaro il tipo struct persona ma non
//variabile oggi e assegno un valore ad oggi //la variabile struct persona
struct data struct persona
{ {
char nome [20];
int anno; char cognome [20];
int giorno; int peso;
char mese[20]; };
} oggi = {2012,7,”novembre”};
//dichiaro la variabile p
struct persona p;
//dichiaro la variabile domani e assegno un strcpy(p.nome,”Pinco”);
// valore strcpy(p.cognome,”Pallino”);
struct data domani = {2016, p.peso=75;
16,”novembre”}; cout<<p.nome<<p.cognome<<p.p
oggi.giorno=21; eso;
strcpy(oggi.mese,”dicembre”);
oggi.anno=2012;
110
Altro esempio
struct persona p;
strcpy(p.nome,”Pinco”);
strcpy(p.cognome,”Pallino”);
p.peso=75
p.nascita.giorno=10;
strcpy(p.nascita.mese,”novembre”);
p.nascita.anno=2009;
111
Typedef
• Un modo più generale per creare nuovi tipi è dato dalla parola
typedef
• Ad esempio:
typedef float reale;
reale x=3.5;
typedef struct persona individuo;
individuo x; x.peso=90;
typedef char[35] parola;
parola p=“parola”;
112
Puntatori
113
Dichiarazione di un puntatore
int y;
int* x = &y;
114
Puntatori a struct
115
Puntatori ad array
• Esempio:
int v[3]={25,28,34};
int* pzero=&v[0];
int* puno=&v[1];
cout<<v<<endl<<pzero<<endl<<puno<<endl<<&v<<endl;
116
Esercitazione: gioco dell’impiccato
117
Esempio di output
Inserisci la stringa : Che lettera devo cercare? q
FraseConMaiuscole quara--a-u-
Contiene simboli non ammessi Che lettera devo cercare? s
Inserisci la stringa : quara--a-u-
unafrasedecisamentetroppolunga Che lettera devo cercare? t
Troppo lunga quara-ta-u-
Inserisci la stringa : Che lettera devo cercare? d
quarantadue quara-tadu-
Inizia il gioco: Che lettera devo cercare? e
----------- quara-tadue
Che lettera devo cercare? a Che lettera devo cercare? n
--a-a--a--- quarantadue
Che lettera devo cercare? r Bravo: hai indovinato in 9 tentativi!
--ara--a---
Che lettera devo cercare? u
-uara--a-u-
118
Esercizio: confronti tra date
Si realizzi un programma che legge una data scritta sotto forma di stringa,
nel formato gg-mm-aaaa.
Il programma dovrà:
• Leggere in input la data, controllando che sia esattamente nel formato
gg-mm-aaaa, ovvero con due cifre per il giorno seguite da un trattino,
seguito da due cifre per il mese seguite da un altro trattino e da quattro
cifre per l’anno;
• Effettuare alcuni controlli di validità, e precisamente che il giorno sia
compreso tra 1 e 31 e il mese tra 1 e 12. Inoltre si controlli che i valori in
ingresso non corrispondono a giorni inesistenti come il 31 aprile, 31
giugno, 31 settembre o 31 novembre o il 29, 30, 31 febbraio (per
semplicità si ignorino gli anni bisestili);
• Scrivere in output se la data è precedente o successiva al 17-12-2019 o
se coincida con quella data.
120
Esempio di output
121
Esercizio: istogramma
Si realizzi un programma che riceve in input un vettore di 5 numeri interi
compresi tra 0 e 9 ciascuno, che rappresentano i valori di una
grandezza, misurata ogni secondo.
122
Esempio di output
123
Sottoprogrammi e Funzioni
124
Dichiarazione e definizione di una funzione
125
Chiamata di funzione
126
Passaggio dei parametri
• Concettualmente, si può distinguere tra
– Parametri di ingresso (in)
– Che possono essere letti ma non modificati
– Parametri di uscita (out)
– Che possono essere definiti e modificati
– Parametri di ingresso e uscita (inout)
– Che possono essere letti, definiti e modificati
• Tecnicamente, esistono tre modalità di passaggio dei
parametri, in C++
– Per valore
– Per puntatore
– Per riferimento
127
Passaggio per valore
• Dichiarazione
int somma (int addendo1, int addendo2)
• Definizione
int somma (int addendo1, int addendo2)
{ return addendo1+addendo2;}
• Chiamata
int z=somma(3,5);
int z=somma(x,y);
128
Passaggio per valore
129
Passaggio per puntatore
• Soluzione:
Trasmettiamo per valore il puntatore alla variabile
130
Passaggio per puntatore
• Dichiarazione e definizione
void dimezza (float* x)
{
*x = *x / 2.0;
return;
}
• Chiamata:
float a=3.14;
dimezza(&a);
float* p=&a;
dimezza(p);
131
Passaggio per puntatore
132
Passaggio di una struct
• Chiamata:
struct elemento s;
…
visualizza (&s);
133
Passaggio di un array
• Un array può essere passato solo per puntatore
– Ma il nome dell’array è anche un puntatore ad esso
• Chiamata:
int a[3];
…
visualizza (a);
134
Passaggio per RiferimentoRi
Dichiarazione
– tipo nomefunzione (tipo &nomevariabile)
Definizione
– { … nomevariabile = … }
Chiamata
– nomefunzione (variabile)
135
Passaggio per Riferimento
Dichiarazione e definizione
void dimezza (float &x)
{
x = x / 2.0;
return;
}
Chiamata:
float a=3.14;
dimezza(a);
cout<<a;
136
Esempi
– Circonferenza
– strcpy
– Ricerca in un vettore
- Insiemi
a
137
Confronti
138
Allocazione statica, automatica e
dinamica
• Per allocazione statica si intende una allocazione in posizione
costante, per tutta la durata dell’esecuzione del programma (ad
es. allocazione di costanti o variabili globali)
• Per allocazione automatica si intende l’allocazione di variabili
locali ad un blocco
• E’ detta automatica perchè l’esecutore decide
automaticamente la posizione (nella memoria stack) dove
allocare le variabili e le distrugge automaticamente alla fine
dell’esecuzione del blocco (termine dello scope della
variabile)
– L’allocazione statica e quella automatica non ci consentono
di risolvere problemi come quello di gestire una lista di
elementi di lunghezza variabile, allocando, istante per
istante, solo lo spazio di memoria minimo indispensabile
139
Allocazione dinamica
• Per allocare una variabile da una istruzione
int* p = new int;
– p è un puntatore, ed è allocato automaticamente nella memoria
stack (è dichiarato come ogni altra variabile locale vista finora)
– *p, valore puntato da p è un int allocato dinamicamente nella
memoria heap all’atto dell’esecuzione dell’istruzione new
• Per distruggere la variabile dinamica puntata da p
delete p;
– Con questa istruzione viene distrutta *p, non il puntatore p, che
viceversa scompare quando termina naturalmente il proprio scope
– Le variabili allocate dinamicamente devono essere distrutte
esplicitamente perchè non vengono distrutte automaticamente
• Per allocare un array di n elementi
int* p=new int[n];
• Per distruggere un array
– delete [] p;
140
Esercizio
141
Soluzione
//per invertire
for (int i=0;i<cont/2;i++){
char temp=b[i];
b[i]=b[cont-1-i];
b[cont-1-i]=temp;
}
return;
}
142
Soluzione
int main()
{
char bin[17];
int dec;
do{
cout<<"Inserisci il numero decimale :";
cin>>dec;
if (dec<0 || dec>65535)
cout<<"Deve essere un numero positivo compreso tra 0 e
65535"<<endl;
} while (dec<0 || dec>65535);
dec2bin(dec,bin);
143
Esercitazione
144
Esempio
3 4 9 2
Valore dell'elemento in riga 1 e colonna 0 :5
Valore dell'elemento in riga 1 e colonna 1 :8
Valore dell'elemento in riga 1 e colonna 2 :11
Valore dell'elemento in riga 1 e colonna 3 :6
5 8 11 6
Valore dell'elemento in riga 2 e colonna 0 :7
Valore dell'elemento in riga 2 e colonna 1 :1
Valore dell'elemento in riga 2 e colonna 2 :12
Valore dell'elemento in riga 2 e colonna 3 :10
Prodotto dei numeri della prima riga = 216
Massimo di seconda e terza colonna = 12
L'ultimo numero pari della seconda riga e' 6
7 1 12 10
Il minimo sulla diagonale principale vale 3
Premere un tasto per continuare . . .
145
Soluzione proposta 1/3
# include <iostream>
int main()
{
int m[3][4];
int i,j;
for (i=0;i<3;i++)
for (j=0;j<4;j++)
{
do
{
cout<<"Valore dell'elemento in riga "<<i<<" e colonna "<<j<<" :";
cin>>m[i][j];
}while (!(m[i][j]>=0));
}
int prodotto=1;
for (i=0;i<4;i++)
prodotto*=m[0][i];
cout<<"Prodotto dei numeri della prima riga = "<<prodotto<<endl;
146
Soluzione proposta 2/3
int massimo=0;
for (i=0;i<3;i++)
{
if (m[i][1]>massimo)
massimo=m[i][1];
if (m[i][2]>massimo)
massimo=m[i][2];
}
cout<<"Massimo di seconda riga e terza colonna = "<<massimo<<endl;
i=3;
int pari=1;
do
{
if (m[1][i]%2==0)
pari=m[1][i];
else
i--;
} while ((pari==1)&&(i>=0));
if (pari==1)
cout<<"Non ci sono numeri pari"<<endl;
else
cout<<"L'ultimo numero pari della seconda riga e' "<<pari<<endl;
147
Soluzione proposta 3/3
int minimo=m[0][0];
for (i=1;i<3;i++)
if (m[i][i]<minimo)
minimo=m[i][i];
cout<<"Il minimo sulla diagonale
principale vale "<<minimo<<endl;
system("pause");
return 0;
}
148
Lista
struct Elemento {
int valore;
struct Elemento* prossimo;
};
typedef struct Elemento* Lista;
149
Esempio: riempimento (con i valori 4,5,7)
struct Elemento {
int valore;
struct Elemento* prossimo
};
typedef struct Elemento* Lista;
150
Riempimento di una lista con i valori di un
vettore
//trasforma un array in una lista
151
Esempio: visualizzazione della lista
153
Soluzione errata
while (l!=NULL)
{
cout<<l->valore<<endl;
l=l->prossimo;
}
Questa soluzione non va bene perchè durante il ciclo viene modificato il
puntatore l alla lista, che alla fine vale NULL.
Quindi, dopo questo ciclo, non abbiamo più modo di ricordare dove
cominciasse la nostra lista.
Bisogna sempre operare su di una copia (alias) del puntatore!
154
Esempio: cerca un elemento in una lista
155
Esempio: inserimento in testa
156
Eliminazione del primo elemento della
lista
//elimina il primo elemento della lista (se c'è)
void eliminaPrimo(Lista &l){
Lista p=l;
if (l!=NULL){
l=l->prossimo;
delete p;
}
return;
}
160
Eliminazione: caso generale (1)
161
Eliminazione: caso generale (2)
if (trovato){
//l'elemento trovato è p, preceduto da precedente
if (precedente==NULL){
//E' il primo elemento
l=p->prossimo;
} else {
precedente->prossimo=p->prossimo;
}
delete p;
}
return;
}
162
Esempio: Deallocazione di tutta la lista
167
Esempio di Progetto
168
Compilazione separata
169
Definizione ed uso di funzioni di libreria
170
Esercizio Insiemi.h
171
Esercitazione: Tombola
• Si realizzi un programma che simuli le estrazioni dei numeri nel gioco della
“tombola”.
• Il sistema deve estrarre un numero casuale tra 1 e 90 e lo scrive a video.
Bisogna controllare che il numero estratto non sia stato già estratto in
precedenza. Dopo ogni estrazione, vengono visualizzati tutti i numeri estratti, in
ordine a partire dal più recente. Le estrazioni continuano fino a quando non
siano stati estratti tutti e 90 i numeri.
• Vincoli di progetto:
• - Si realizzi il programma organizzandolo su più file, uno con tutte le funzioni,
uno con tutte le dichiarazioni e uno con il main;
• - Per memorizzare i numeri estratti si utilizzi una lista;
• - Si realizzino, in particolare, le funzioni visualizza (che visualizza tutti i
numeri estratti), estrai (che estrae un numero a caso, controllando che non sia
già uscito, e lo aggiunge all’inizio della lista) e cerca (che cerca un numero tra
quelli già estratti), scegliendo opportunamente i parametri.
• Per generare numeri casuali, si può utilizzare la funzione rand() contenuta in
<cstdlib>
173
Tombola: Output
Gioco della tombola
Ho estratto il numero 42
Numeri usciti fino ad ora: 42 –
Ho estratto il numero 18
Numeri usciti fino ad ora: 18 - 42 –
Ho estratto il numero 35
Numeri usciti fino ad ora: 35 - 18 - 42 –
Ho estratto il numero 41
Numeri usciti fino ad ora: 41 - 35 - 18 - 42 –
Ho estratto il numero 90
Numeri usciti fino ad ora: 90 - 41 - 35 - 18 - 42 –
Ho estratto il numero 45
Numeri usciti fino ad ora: 45 - 21 - 86 - 73 - 27 - 16 - 89 - 69 - 14 - 30 – 44 - 38 - 54 - 2 - 79 - 32 -
56 - 60 - 1 - 68 - 8 - 11 - 81 - 76 - 7 - 61 - 28 - 31 - 50 - 13 - 74 - 57 - 40 - 72 - 17 - 55 - 24 - 10 -
39 - 67 - 71 - 46 - 5 – 47 - 43 - 51 - 77 - 59 - 80 - 83 - 15 - 78 - 29 - 22 - 34 - 4 - 3 - 84 - 85 - 20 -
70 - 12 - 48 - 6 - 9 - 87 - 52 - 23 - 64 - 33 - 25 - 82 - 37 - 58 - 63 - 26 – 88 - 62 - 66 - 36 - 75 - 53 -
19 - 49 - 65 - 90 - 41 - 35 - 18 - 42 –
Premere un tasto per continuare . . .
174
Tombola: FunzioniTombola.h
struct Elemento{
int valore;
struct Elemento* successivo;
};
typedef struct Elemento* Lista;
175
Tombola: FunzioniTombola.cpp
int estrai(Lista &primo){
int estratto;
#include <iostream>
do {
#include <cstdlib>
estratto=1+rand()%90;
#include ".\FunzioniTombola.h"
} while (cerca(primo,estratto));
using namespace std;
Elemento *e=new Elemento;
e->valore=estratto;
e->successivo=primo;
bool cerca(Lista primo,int estratto){
primo=e;
Lista p=primo;
return estratto;
while (p!=NULL){
}
if (p->valore==estratto)
return true;
void visualizza(Lista primo){
p=p->successivo;
Lista p=primo;
}
while (p!=NULL)
return false;
{
} cout<<p->valore<<" - ";
p=p->successivo;
}
return;
}
176
Tombola: Main.cpp
#include <iostream>
#include ".\FunzioniTombola.h"
int main()
{
Lista l=NULL;
cout<<"Gioco della tombola";
int estratti=0;
do{
cout<<endl<<"Ho estratto il numero "<<estrai(l)<<endl;
cout<<"Numeri usciti fino ad ora: ";
visualizza(l);
estratti++;
} while (estratti<90);
177
Esercizio
• Avvertenze:
– Controllare se il numero di cifre è un intero compreso
tra 1 e 16
– Controllare se l’input è un numero binario valido
178
Esempio di esecuzione
• Suggerimenti;
– Per calcolare il valore si ricordi che:
– Ma é anche possibile scrivere:
Esempio di esecuzione
179
Soluzione proposta
# include <iostream> if (!ok)
cout<<"NUmero binario non valido"<<endl;
using namespace std; else if (i>16)
//conversione da binario a decimale cout<<"Troppo lungo"<<endl;
180
File
• Un file può essere letto o scritto come uno stream (come cin e cout),
tramite gli operatori << e >>
181
Operazioni sui file
182
Esercizio con i file
183
Ricorsione
184
Ricorsione
• Esempio
• Calcolo della potenza con base e esponenti interi
• be = b * be-1
• b0 = 1
185
Esempi di problemi risolvibili con la
ricorsione
• Calcolo del fattoriale
• Caso base: 1!=1
• Caso generale: n! = n* (n-1)!
186
Esempi di problemi risolvibili con la
ricorsione
bool ricercaBin(int x, int v[], int start, int end, int &dove)
{
if (start > end) //non possiamo trovarlo
return false;
else {
int mid = (start + end) / 2; //punto centrale
if (x==v[mid]){
dove=mid; //trovato nel punto centrale
return true;
}
else if (x < v[mid])
//cerca nella prima meta’
return ricercaBin(x,v,start,mid-1,dove);
else
// cerca nella seconda meta’
return ricercaBin(x,v,mid+1,end,dove);
}
}
187
Break, return, exit
• break ;
• causa l’uscita da un blocco di codice (parentesi graffe)
• Non ci sono parametri associati a break;
• E’ sconsigliata (tranne che nello switch) poiché una piccola modifica del
programma (introduzione di un altro blocco) potrebbe cambiarne l’esito;
• return valore ;
• Causa l’uscita immediata da una funzione
• Può essere seguita da un parametro (scalare) del tipo specificato nella
dichiarazione della funzione (a meno che non sia specificato il tipo void, vuoto)
• exit(valore);
• Causa l’uscita immediata da tutto il programma
• Ha un parametro tra parentesi del tipo corrispondente a quello restituito dalla
funzione main (di solito int). Il valore di questo parametro sarà restituito al sistema
operativo
188
Debugging
• Due soluzioni:
• Inserire all’interno del programma una o più sonde (probe), ovvero
istruzioni cout che ci scrivono a video qualcosa riguardo l’attuale stato
del programma
• Sfruttare le funzioni messe a disposizione dal programma gdb integrato
in Dev-Cpp
189
Strumenti per il Debugging
• Breakpoint
• Un breakpoint può essere inserito nel codice semplicemente
con un click sul numero di linea di codice. Un cerchio rosso
verrà disegnato
• Esecuzione in modalità debug
• Scegliendo di eseguire in modalità debug, l’applicazione verrà
eseguita normalmente fino a quando non si incontra un
breakpoint: a quel punto è possibile:
• Eseguire una sola istruzione (Step Succ.)
• Eseguire solo fino al termine di quella funzione (Step Est.)
• Eseguire una istruzione alla volta la funzione che si sta per chiamare
(Step Interno)
• Osservare il valore di una qualsiasi variabile in quel momento oppure
chiedere il risultato di una qualsiasi operazione (Nuova Osservazione)
• I valori delle variabili e delle espressioni controllate sono visibili
nella scheda Debug (accanto a quella Progetto)
190
Esempio Debugging
Algoritmi di ordinamento
192
Selection Sort
193
Selection Sort
void SelectSort(int a[], int n){
int i,j,posmin;
for (i=0;i<n-1;i++){ //dal primo al penultimo
// trova il minimo tra i e l’ultimo
posmin=i;
for (j=i+1;j<n;j++)
if (a[j] < a[posmin])
posmin = j;
// se non e’ già al posto giusto mettilo in posizione i
if (posmin!=i){
int temp = a[i];
a[i]=a[posmin];
a[posmin]=temp;
}
}
}
194
Bubble Sort
195
Bubble Sort
196
Bubble Sort
197
Calcolabilità e Trattabilità
198
Macchina di Turing
199
Macchina di Turing
Formalmente:
200
Macchina di Turing e Calcolabilità
• Tesi di Church-Turing
• Non esiste alcun formalismo in grado di risolvere problemi che
non siano risolvibili tramite una macchina di Turing
201
Trattabilità
• Complessità computazionale
• Spaziale
• Temporale
• Ordini di grandezza
• Complessità asintotica
• Confronto con algoritmi di complessità nota
202
Complessità computazionale
203
Esempi di complessità computazionale
204