summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/.ninja_depsbin0 -> 16 bytes
-rw-r--r--doc/.ninja_log2
-rw-r--r--doc/build.ninja7
-rw-r--r--doc/quick_cplusplus.md245
-rw-r--r--doc/quick_cplusplus.pdfbin0 -> 212718 bytes
5 files changed, 254 insertions, 0 deletions
diff --git a/doc/.ninja_deps b/doc/.ninja_deps
new file mode 100644
index 0000000..2afb5cc
--- /dev/null
+++ b/doc/.ninja_deps
Binary files differ
diff --git a/doc/.ninja_log b/doc/.ninja_log
new file mode 100644
index 0000000..891c53f
--- /dev/null
+++ b/doc/.ninja_log
@@ -0,0 +1,2 @@
+# ninja log v5
+0 770 1548439603 quick_cplusplus.pdf 5be4e5805f2d04b5
diff --git a/doc/build.ninja b/doc/build.ninja
new file mode 100644
index 0000000..b8b5252
--- /dev/null
+++ b/doc/build.ninja
@@ -0,0 +1,7 @@
+pandocflags = --highlight-style tango
+
+rule pdf
+ command = pandoc $pandocflags -o $out $in
+
+
+build quick_cplusplus.pdf: pdf quick_cplusplus.md
diff --git a/doc/quick_cplusplus.md b/doc/quick_cplusplus.md
new file mode 100644
index 0000000..411e0a3
--- /dev/null
+++ b/doc/quick_cplusplus.md
@@ -0,0 +1,245 @@
+---
+title: Modern C++ per chi conosce un po' di C,
+ spiegato di fretta da qualcuno senza alcuna qualifica per insegnare
+author: Naoki Pross
+---
+
+# Introduzione
+Ultimamente ho così poco da fare che ho deciso di scrivere un corso
+relativamente spedito di C++. È sorprendente a cosa può portare la noia, non
+trovate? Okay, iniziando seriamente prima devo presentarvi nella maniera più
+spiccia possibile un paio di brutte cose.
+
+## Cosa serve per inziare
+Non ho voglia di scrivere un corso di programmazione da *zero*, quindi do per
+assunto che sappiate almeno le fondamenta di programmazione, cosa siano un
+*compiler* o un *linker* e come funzioni il processo di compilazione del C,
+siccome è praticamente lo stesso per il C++. Non vi ricordate? Ecco un corso
+super accelerato:
+```
+source code > compiler > object > linker > eseguibile
+main.cpp > g++ > main.o > ld > my_program
+```
+Ah e il codice è tutto in inglese, buona fortuna.
+
+## Nell'industria il C++ è un casino
+Esistendo da troppo tempo (non quanto il C, ma quasi) ogni idiota sulla faccia
+della terra ha pensato bene di creare una propria variante del C++.
+
+Fortunatamente di recente Bjarne Stroustrup, creatore del C++, ha iniziato
+a cercare di salvare questo casino aggiornato la *C++ standard library*,
+dando un paio di direttive su come scrivere il cosìdetto *Modern C++*, versione
+$\geq$ 11.
+
+Quindi da bravo programmatore io in questo documento seguirò le direttive del
+modern C++, ma sappiate che più o meno la maggior parte della gente non
+rispetta queste regole complicando la vita a tutti, quindi preparatevi per
+quando sarete fuori dalla scuola.
+
+## Documenti del C++
+Quindi è come il C, ma i file del codice sorgente si chiamano `.cpp` invece di
+`.c`, giusto? Sarebbe bello; neanche su questo sono d'accordo le persone.
+Esistono le estensioni `.cpp` e `.cc` per i sorgenti e `.hpp` e `.h` per gli
+headers. Quale usare? `.cpp` e `.hpp` ovviamente.
+
+# Iniziamo con le fondamenta
+Arrivando dal C o da un qualsiasi altro linguaggio di programmazione simile,
+spero sappiate come funzionano le keywords `if`, `while`, `for`, `...` quindi
+le saltiamo per passare alle novità. Prima però vi lascio un programma in C++
+minimo, che non fa assolutamente niente.
+```C++
+int main(int argc, char *argv[]) {
+ return 0;
+}
+```
+Che dovrebbe lasciarsi compilare con un comando come il seguente (o con un
+qualche maledetto bottone nella vostra grafica, se la preferite).
+```sh
+$ g++ -Wall -Werror -std=c++11 -o hello hello.cpp
+```
+Favoloso. Nulla di nuovo, giusto?
+
+## Scope
+Una cosa importantissima in C++ è capire cosa è uno *scope*, traducibile
+dall'inglese come ambito, scopo o raggio.
+```C++
+{
+ int hello_there = 10;
+}
+```
+Lo *scope* della variabile `hello_there` sono quelle parentesi graffe. Perché
+come sapete, una volta fuori dalle parentesi `hello_there` cessa di esistere,
+va *out of scope*. Quindi praticamente ogni elemento come un `if`, un `while` o
+una funzione creano uno *scope*, utilizzando le parentesi graffe.
+
+Uno scopo eredita l'accesso alle variabili del suo scopo parente, mentre non è
+possibile il contrario, ossia:
+```C++
+{
+ int x = 10;
+ {
+ int y = 1;
+ // we can access 'x' from the outer scope
+ x += 10;
+ }
+ // but we CANNOT access this variable 'y'
+ // from the inner scope above
+ // this DOES NOT compile
+ y = 10;
+}
+```
+Tra l'altro, se ve lo steste chiedendo, è assolutamente valido mettere delle
+parentesi `{}` senza alcuna *keyword* come `while` o `if` e si usa per ordinare
+il codice gestendo gli scopi o *lifetime* delle variabili.
+
+## Namespaces
+Un problema del C è che siccome, giustamente, non possono esserci funzioni o
+tipi con lo stesso nome il codice diventa orribile in fretta. Per esempio è
+tipico (e corretto) prependere le funzioni e i tipi di una libreria con il nome
+della libreria. Esempio:
+```C
+GtkWidget* gtk_window_new(GtkWindowType type);
+```
+Ma non essendo una cosa obbligatoria, spesso il codice diventa disordinato
+quando ci si dimentica di applicare questa regola.
+
+
+Si introducono dunque i `namespace`, che non fanno altro che raggruppare varie
+parti di codice sotto un nome comune. Permettendo inoltre funzioni e tipi con
+lo stesso nome! Per esempio:
+```C++
+namespace rs232 {
+ int open(unsigned device_id);
+}
+```
+```C++
+namespace file {
+ const int WRITE = 0;
+ int open(const char *path, int mode);
+}
+```
+Che successivamente si possono utilizzare con la seguente sintassi.
+```C++
+// calls open() from the 'rs232' namespace
+rs232::open(0);
+
+// calls open() from the 'file' namespace
+int fd = file::open("/tmp/log.txt", file::WRITE);
+```
+Esiste dunque un `namespace` che contiene la *standard library* (spesso
+chiamata anche STL) che giustamente è chiamato `std`. `std` contiene molte cose
+molto utili come per esempio la `std::string`.
+
+## Allocazione di memoria dinamica
+Come sapete è spesso utile se non necessario allocare della memoria "dinamica",
+ossia non controllata a tempo di compilazione.
+In C esistono le funzioni `malloc()` e `free()` per richiedere e liberare della
+memoria. In C++ la funzione è stata integrata con delle *keywords* quali `new`
+e `delete`, che si usano come segue.
+```C++
+// C: int *data = malloc(10 * sizeof(int))
+int *data = new int[10];
+```
+```C++
+// C: free(data);
+// data = NULL;
+delete data;
+```
+
+## References
+I puntatori del C sono molto utili, non possiamo negarlo, ma come tutti sanno
+non sono esattamente comodi. Per essi e i loro problemi abbiamo un intero
+documento dedicato (Pointers, the best worst feature of C).
+
+Dunque malgrado in C++ i puntatori esistono e funzionano esattamente come in C,
+esiste un nuovo concetto di *referenza*. Vediamo da dove originano con il
+solito esempio stupido in C.
+```C
+void increment(int *v)
+{
+ if (v == NULL)
+ return;
+
+ (*v)++;
+}
+```
+Che si utilizzerebbe come segue.
+```C
+int x = 10;
+increment(&x);
+// 'x' is now 11
+```
+Questa funzione è sorprendentemente complicata rispetto alla semplicità di ciò
+che deve fare. Insomma non sarebbe più comodo se non si dovesse controllare che
+non è `NULL` e se non si dovesse dereferenziare il puntatore? Qualcosa come:
+```C++
+void increment(int& v) {
+ v++;
+}
+```
+Ecco, questa è una referenza in C++, come un puntatore ma sempre valido e che
+non si deve dereferenziare. E non necessita nemmeno della `&` per convertire
+una variabile in puntatore quando si chiama la funzione.
+```C++
+int x = 10;
+increment(x); // no need to take the address
+// 'x' is now 11
+```
+Questo ovviamente era il caso di un argomento (parametro) di una funzione, ma
+le referenze possono esistere anche come i puntatori. Ma non mi pare di averle
+mai viste utilizzate in questo modo.
+```C++
+int x = 10;
+int& y = x;
+
+y *= 2;
+// 'x' (and 'y' referencing it) is now 20
+```
+
+## Overloading
+La parola *overloading*, tradotta dall'inglese potrebbe essere qualcosa come
+"sovraccaricare" ed è un concetto estremamente utile. Esso serve a risolvere
+un problema facile da riscontrare. Mettiamo per esempio che stiamo creando
+una libreria integrante delle funzioni matematiche.
+```C++
+namespace math {
+ int pow(int base, int exponent);
+ double pow(double base, double exponent);
+}
+```
+Volendo avere le funzioni che funzionano sia per numeri interi che per numeri
+a virgola mobile a doppia precisione, abbiamo due funzioni con lo stesso nome!
+
+In C si creerebbero degli abomini come `powi()` e `powdf()` per differenziare
+i due. Ma in C++ non è necessario! Il codice sopra è assolutamente valido
+e il compiler è abbastanza intelligente da capire quale dei due si vuole
+utilizzare quando la funzione è chiamata.
+```C++
+// uses function with signature
+// int math::pow(int, int)
+int a = math::pow(2, 3); // 8
+
+// uses function with signature
+// double math::pow(double, double)
+double v = math::pow(4.0, 0.5); // 2
+```
+Cosa succede se mischiamo le due cose?
+```C++
+double mixed = math::pow(2, 0.5) // ??
+```
+Esempio con `g++ (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0`
+```sh
+ex.cpp:22:37: error: call of overloaded ‘pow(int, double)’ is ambiguous
+ double mixed = math::pow(4, 0.5);
+ ^
+ex.cpp:4:9: note: candidate: int math::pow(int, int)
+ int pow(int base, int exponent) {
+ ^~~
+ex.cpp:13:9: note: candidate: int math::pow(double, double)
+ int pow(double base, double exponent) {
+ ^~~
+```
+Giustamente non compila, perché il compiler non sa quale delle due funzioni si
+vuole utilizzare. Ci propone però le varianti che ha trovato "`note:
+candidate`" che potrebbero essere valide.
+
diff --git a/doc/quick_cplusplus.pdf b/doc/quick_cplusplus.pdf
new file mode 100644
index 0000000..ac74aa3
--- /dev/null
+++ b/doc/quick_cplusplus.pdf
Binary files differ