This repository has been archived by the owner on Jun 16, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a8a40a7
commit ba7b616
Showing
13 changed files
with
401 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Array circolari e code | ||
|
||
## Code | ||
=> oggetti astratti molto utilizzati | ||
|
||
Code: vettore di elementi in cui gli ele si possono estrarre e inserire sia in testa che in fondo | ||
|
||
ele - ele - ele - ... - ele | ||
^ ^ | ||
testa coda | ||
|
||
Array lineare = array statico o dinamico | ||
|
||
Costo inserimento e rimozione in testa: N+1, con N uguale al numero di elementi presenti -> O(N) | ||
|
||
## Array o buffer circolare | ||
L'elemento successivo all'ultimo corrisponde al primo. "Array nel mondo di PacMan" | ||
|
||
Strutura dati composta da: | ||
- array lineare che contiene gli elementi di un array circolare | ||
- un puntatore al primo ele | ||
- un puntatore all'ultimo ele | ||
|
||
Utilizzo l'aritmetica modulare per implementare la circolarità dell'array | ||
|
||
### Inserimento in coda | ||
`ultimo = (ultimo+1) % N | ||
|
||
### Inserimento in testa | ||
Il modulo non è definito per numeri negativi, quindi non si può fare `(primo-1)%N` | ||
|
||
Possibili soluzioni: | ||
- controllo con if | ||
- sommo N e faccio il modulo: `(primo-1+N)%N` | ||
=> questa operazione la posso applicare sempre, perchè sommare un numero e fare il modulo corrisponde a non sommare niente. Il vantaggio è quello di non doversi preoccupare di valori negativi (oppure di uscire dal range) | ||
|
||
### Controlli aggiuntivi | ||
I puntatori di testa e di coda hanno lo stesso valore (differenza di 1 con coda davanti a testa) sia quando l'array è vuoto, sia quando l'array è pieno. | ||
|
||
Soluzioni: | ||
- aggiungo una var alla struttura dati e mantengo il numero di elementi contenuti nell'array | ||
- mantengo il puntatore alla testa e il numero di elementi presenti nell'array. Il puntatore alla coda rimange ricavabile con `(puntatore_testa+numero_elementi)%N` | ||
|
||
Abbiamo così raggiunto un doppio livello di astrazione: a partire da una struttura dati nota (l'array) siamo riusciti a creare un array circolare e da questo una coda. | ||
|
||
TODO: implementa una coda utilizzando un array circolare + relative funzioni (4 in totale) | ||
|
||
La differenza tra coda e array circolare è il livello di astrazione tra i due |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# Formattazione output | ||
W: no argomento esame | ||
|
||
## Manipolatori con argomenti | ||
`cout << ... << setw(int n) << ...` Setta il numero minimo di cartteri a n per ogni cout | ||
Per specificare il carattere con cui riempire il caratteri necessari a raggiungere la dimensione n bisogna usare `setfill(char c)` | ||
|
||
Necessario includere `<iomanip>` | ||
|
||
## Stampa a dx e sx | ||
`cout << ... << right << ...` | ||
`cout << ... << left << ...` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# Range based for | ||
|
||
Dato un array di tipo `T` e nome `A` | ||
|
||
``` | ||
for ([const] T &<identificatore>: A) | ||
<istruzioni> | ||
``` | ||
|
||
<identificatore> scorre tutti gli elementi di A. È un identificatore, per cui resta possibile modificare l'i-esimo elemento di A (se non si usa const). Questo identificatore resta visibile solamente all'interno del blocco di istruzioni eseguite dal for. | ||
|
||
Utilizzo solo per array statici (no terminatori, no oversized) | ||
|
||
Vantaggi: | ||
- no inizializzazione | ||
- no var ausiliria | ||
|
||
Svantaggi: | ||
- non è supportato da tutti i compilatori |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
# Stream | ||
|
||
## Input stream | ||
|
||
Definizioni: | ||
- stream: sequenza di caratteri | ||
- istream: meccanismo per convertire sequenze di caratteri in valori di vari tipi (input stream) | ||
- cin -> standard istream. Appartiene al namespace std | ||
|
||
|
||
L'istream viene riempito dal SO con una sequenza di caratteri. Il suo contenuto viene passato al programma dal SO (bash) quando riceve in ingresso un linefeed (se in modalità standard) | ||
|
||
### Input formattato | ||
=> quando i caratteri inseriti vengono interpretati in modo contestuale alla variabile che ospiterà il suddetto dato | ||
|
||
I whitespaces vengono scartati. Utilizzati solo come separatori tra i vari token (a meno che non venga utilizzato il manipolatore no-skip-whitespaces) | ||
|
||
### Stream state | ||
Ciascun I/O stream ha un proprio stato: insieme di flag (valori booleani) che indicano lo stato delllo stream. Ogni operazione che fallisce porta lo stream ad uno stato di errore. | ||
|
||
### EOF | ||
La condizione che causa il fallimento in lettura e porta lo stream in uno stato di errore è la lettura del marcatore EOF - End Of File - | ||
=> Questo segnale può essere passato premendo Ctrl-D su una riga vuota (mondo UNIX) | ||
|
||
Utilizzato per chiudere terminale | ||
|
||
### Wrong format | ||
Quando l'istream non riesce a convertire i dati passati in modo da salvarli nella variabile passata. | ||
|
||
### Gestione errori | ||
Una operazione di input che fallisce è un'operazione nulla: | ||
- Negli standard precedenti a C++11 lo stream di input non viene toccato. Il valore della variabile a cui doveva essere assegnato il dato resta invariato. | ||
- Negi standard successivi a C++11 viene assegnato il valore 0, declinato al tipo di dato passato (0, 0.0, carattere nullo...) | ||
|
||
Lo stato dello stream può essere verificato con un if. cin ritorna true (valore diverso da zero) se lo stream non entra in stato di errore. false (zero) altrimenti (formato input errato o fine lettura a causa EOF) | ||
|
||
### Esempi controllo stato cin | ||
``` | ||
if (!(cin >> i)) | ||
cout << "stato errore" | ||
``` | ||
|
||
``` | ||
while (!(cin >> i)) {...} // attende valore valido | ||
``` | ||
|
||
### Funzioni membro cin | ||
|
||
Se f è un io stream posso invocare funzioni membro con l'operatore punto. | ||
Esempi: | ||
- `cin.clear()` -> riporta lo stream in condizione "buona". Pulisco contenuto stream e flag. cin può essere riutilizzato. | ||
- accesso ai flag. Vedi [reference](https://en.cppreference.com/w/cpp/io/basic_istream) | ||
|
||
// TODO link to leggi_numeri.cpp | ||
|
||
|
||
Posso verificare se è stato raggiunto l'EOF con `cin.eof()` -> funzione membro che ritorna true se è stato consumato il carattere EOF. | ||
|
||
Una volta che cin entra in uno stato di errore non può più essere riutilizzato a meno che non venga "ripulito" | ||
|
||
## Output stream | ||
=> sono sempre stream (sequenze di caratteri) che convertono tali sequenze in valori human readable in base al tipo di variabile passata | ||
|
||
Standard output stream: cout | ||
Standard error stream: cerr | ||
=> entrambi appartengono al namespace std | ||
|
||
Es: `cout << 'a'` -> a basso livello viene mandato il byte 97, che rappresenta la lettere 'a' secondo la codifica ASCII | ||
|
||
La shell, prima di far partire il programma, aggancia lo stdout del processo ad un oggetto speciale del sistema operativo. Attraverso questo oggetto la shell legge i caratteri da stampare (passati dal programma) | ||
|
||
Gli stream di I/O entrano in uno stato bloccato finchè o non si preme un tasto da passare su cin o non si invia endl/\r/si fa un flush | ||
|
||
Tutto va bene quando editor, compilatore e terminale utilizzano tuti la stessa codifica (solitamente ASCII a 7 bit), in altri casi potrebbe essere usata una codifica differente (per esempio, potrebbero non essere rappresentate le lettere accentate). | ||
|
||
### Esempio | ||
`cout << 12` passa il carattere '1' e il carattere '2' alla shell | ||
|
||
### Note | ||
Ogni volta eseguo un cin consumo un carattere dalla coda interna allo stream. | ||
|
||
Se il terminale si trova il modalità canonica i caratteri inseriti nella coda vengono passati solamente quando viene inserito un linefeed | ||
|
||
La cin si blocca solamente in attesa dell'inserimento di un carattere | ||
|
||
Eg: `char a; cin >> a;` con inserimento di "Ciao\n" su stdin -> consumo solo il carattere 'C'. Tutto il resto, compreso '\n' resta nel buffer di cin | ||
|
||
### Rimuovere caratteri da stdin | ||
`cin.ignore()` -> getta via i caratteri presenti sul buffer di stdin | ||
|
||
``` | ||
while (!(cin >> n)) { // ATTENZIONE: non esco neanche con EOF | ||
cin.clear(); | ||
cin.ignore(); | ||
cout << "Immetti un numero valido: "; | ||
} | ||
``` | ||
|
||
Eliminazione riga: svuotare l'istream fino al prossimo newline -> `cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');` | ||
|
||
Utilizza controllo su eof per ritornare dal programma se necessario. | ||
|
||
## Bufferizzazione in uscita | ||
Abbiamo già utilizzato `fflush(stdout)` | ||
|
||
L'operatore `<<` su stdout non spedisce immediatamente lo stream di caratteri su stdout. Dato che l'operazione di scrittura è costosa, cout aspetta di riempire il buffer prima di scrivere su stdout. Solitamente cout è configurato per inviare sullo stdout una riga alla volta; quando incontra '\n' il buffer viene svuotato sul terminale. | ||
|
||
L'operazione di scrittura di un'intera stringa costa quanto la scrittura di un solo carattere. | ||
|
||
### Operazione di bufferizzazione | ||
=> la memoria RAM (memoria tampone) viene utilizzata per rendere più efficienti le operazioni di I/O | ||
|
||
Eg: durante il download di un file i dati vengono memorizzati temporanemente sulla RAM e scritti a blocchi (se il file è di grandi dimensioni) oppure il fiele viene scritto direttamente una volta completato il download in RAM. Questo avviene perchè la velocità di download è maggiore di quella di scrittura (vedi connessioni 50kb) | ||
|
||
TODO: link buffer_stdout.cpp -> 'ciao' non viene stampato perchè il buffer di output non viene svuotato. Terminando il programma in modo naturale il buffer di output viene svuotato. Se il processo è killato dal SO no. | ||
|
||
Il buffer di output è statico (implementato con buffer circolare): possono essere memorizzati solo x caratteri. Quando si raggiunge la dimensione del buffer il buffer viene svuotato. | ||
|
||
TODO: link buffer_stdout_full.cpp | ||
|
||
## Sincornizzazione cin/cout | ||
Prima di ogni `cin` il buffer di output viene svuotato (no necessità di endl o simili). L'utente deve visualizzare il messaggio in out prima di inserire un input | ||
|
||
TODO: allega buffer_out_sinc.cpp | ||
|
||
## flush | ||
Comando che forza il buffer di output ad essere svuotato sul terminale: `std::flush(ostream& os)` | ||
|
||
## Creazione di stream | ||
=> per scrivere su file | ||
I seguenti stream sono definiti in `<fstream>` e possono essere utilizzati per scrivere e leggere su file: | ||
- ifstream | ||
- ofstream | ||
|
||
Un file è visto come sequenza di byte. | ||
|
||
Un io stream viene associato ad un file mediante un'operazione chiamata apertura del file. Gli stessi operatori utilizzati per cin e cout possono essere usati per scrivere e leggere su file. | ||
|
||
Per aprire un file è necessario indicare il percorso del file: | ||
- relativo (alla cartella di lavoro) | ||
- assoluto (rispetto alla radice) | ||
- solo nome file -> cartella di lavoro | ||
|
||
Spesso può accadere che l'apertura di un file non vada a buon fine (apertura in lettura di un file con soli permessi di lettura, file già aperto ecc.) | ||
|
||
``` | ||
ifstream f("percorso_file"); // oppure ofstream f("...") per scrittura | ||
if (!f) cerr << "apertura fallita" << endl; | ||
``` | ||
|
||
Come per gli operatori cin e cout è possibile controllare lo stato dello stream associato ad un file | ||
|
||
WARNING: l'apertura di un file in lettura comporta il troncamento se il file esiste già o la creazione di un nuovo file se non esiste. | ||
|
||
Oppure `fstream("nome_file", ios_base::in)` e `fstream("nome_file", ios_base::out)` | ||
|
||
I file possono essere aperti anche il "lettoscrittura". | ||
|
||
Lo stato di un fstream può essere controllato con i soliti flag. È utile verificare, per esempio, se una scrittura sia andata a buon fine o meno. Anche la scrittura formattata è consentita (di default). | ||
|
||
Altra possibilità: lettura e scrittura non formattata -> dati grezzi in binario | ||
|
||
### Accesso a file | ||
L'accesso ai file è sequenziale, posso leggere e scrivere solamente agendo sul byte successivo a quello puntato dal puntatore. | ||
|
||
Un file può essere aperto anche con la funzione `open()` | ||
|
||
TODO: link in_out_redirect.cpp in_outfile.cpp | ||
|
||
WARNING: ricorda di chiudere il file per essere sicuro che tutto venga scritto (buffer svuotato): `f.close()` | ||
Al momento del return avverrebbe la chiusura implicita del file, ma se il programma viene terminato in modo forzato dal SO non è detto che il buffer venga svuotato. | ||
|
||
TODO: link write_read_file.cpp | ||
|
||
TODO: esercizio. Copia di un file con programma C | ||
|
||
### Modalità append | ||
È possibile aprire un file in scrittura evitando il troncamento. Uso modalità append. Quello che scrivo viene messo in coda al file, senza sovrascrivere i byte già presenti. | ||
|
||
``` | ||
ofstream f("nome_file", ios_base::app); | ||
``` | ||
|
||
TODO: scrivi_leggi_array_fomattato.cpp (vedi cartella FTP) | ||
TODO: leggi da file una sequenza di interi di al più 100 ele finchè non se ne trova uno uguale a 0... | ||
TODO: fai esercizi da questo punto in poi | ||
|
||
### Passaggio stream come argomenti | ||
`void fun(istream &cin, ostream &cout);` | ||
-> posso passsare sia cin e cout che due filestream di input/output | ||
|
||
Questo mi permette di creare funzioni che scrivono/leggono su stream |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#include <iostream> | ||
#include <cstdlib> | ||
|
||
using namespace std; | ||
|
||
int main() { | ||
cout << "ciao"; | ||
system("sleep 2"); | ||
while (true) cout << "ciao"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#include <iostream> | ||
#include <cstdlib> | ||
|
||
using namespace std; | ||
|
||
int main() { | ||
cout << "ciao"; | ||
while (true); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#include <iostream> | ||
#include <cstdlib> | ||
|
||
using namespace std; | ||
|
||
int main() { | ||
cout << "ciao"; | ||
system("sleep 2"); | ||
while (true) cout << "ciao"; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#include <iostream> | ||
#include <cstdlib> | ||
|
||
using namespace std; | ||
|
||
int main() { | ||
cout << "ciao"; | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#include <iostream> | ||
#include <iomanip> | ||
#include <fstream> | ||
|
||
|
||
using namespace std; | ||
|
||
int main() { | ||
ofstream f("testo.txt"); | ||
if (!f) { // ricordati di controllare eventuali errori | ||
cerr << "Errore in apertura" << endl; | ||
return 1; | ||
} | ||
|
||
char c; | ||
cin >> noskipws; | ||
while (cin >> c) f << c; | ||
|
||
f.close(); // ricordati di chiudere | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
#include <iostream> | ||
#include <iomanip> | ||
|
||
using namespace std; | ||
|
||
int main() { | ||
char c; | ||
cin >> noskipws; | ||
while (cin >> c) cout << c; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* | ||
* WARNING: il seguente programma non funziona per standard inferiori a C++11 | ||
* | ||
*/ | ||
|
||
#include <iostream> | ||
|
||
using namespace std; | ||
|
||
|
||
int main() { | ||
int tmp, s = 0; // s -> s | ||
// continuo a prendere in input degli interi finchè | ||
// non viene inserito un valore non valido oppure EO | ||
while (cin) { // una soluzione funzionante per tutti gli standard è while(cin >> tmp) {...} | ||
cin >> tmp; | ||
s += tmp; | ||
} | ||
// l'oggetto cin non è più utilizzabile | ||
cout << "Somma: " << s << endl; | ||
cout << "Si è terminato con EOF? " << cin.eof() << endl; | ||
return 0; | ||
} | ||
|
||
// HINT: prova a compilare con -std=c++98 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
a | ||
b | ||
c | ||
d |
Oops, something went wrong.