Initial commit

This commit is contained in:
Alessandro Ferro 2021-03-18 21:54:45 +01:00
commit 2e5192afe6
12 changed files with 301 additions and 0 deletions

2
.gitattributes vendored Normal file
View File

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

BIN
teoria/a.out Executable file

Binary file not shown.

View File

@ -0,0 +1,44 @@
#include<iostream>
using namespace std;
void array();
void arrayInizializzato();
void noArray();
int main(){
return 0;
}
void array(){
int* ptr = nullptr;
try{
ptr = new int[5];
}catch(bad_alloc ex){ // Se non riesce a creare abbastanza memoria viene sollevata un'eccezione
cout<<"Errore allocazione memoria";
}
for(int i=0;i<5;i++){
cout<<"Valore "<<i<<": ";
cin>>ptr[i];
}
for(int i=0;i<5;i++){
cout<<ptr[i];
}
cout<<endl;
delete[] ptr;
}
void arrayInizializzato(){
try{
int* ptr = new int[3]{1,2,3};
for(int i=0;i<3;i++){
cout<<ptr[i];
}
delete[] ptr;
}catch(bad_alloc ex){
cout<<"Errore allocazione memoria";
}
}
void noArray(){
int* ptr = new int(5);
cout<<*ptr<<endl;
delete ptr;
}

17
teoria/domande.cpp Executable file
View File

@ -0,0 +1,17 @@
#include<iostream>
using namespace std;
int main(){
string s1 = "hello";
string s2 = "world";
cout<<"Stringa 1: "<<s1<<endl<<"Stringa 2: "<<s2<<endl;
cout<<"PTR Stringa 1: "<<&s1<<endl<<"PTR Stringa 2: "<<&s2<<endl<<endl;
s1 = move(s2);
cout<<"Stringa 1: "<<s1<<endl<<"Stringa 2: "<<s2<<endl;
cout<<"PTR Stringa 1: "<<&s1<<endl<<"PTR Stringa 2: "<<&s2<<endl<<endl;
s2 = "cacca";
cout<<"Stringa 1: "<<s1<<endl<<"Stringa 2: "<<s2<<endl;
return 0;
}

51
teoria/lezione2.cpp Executable file
View File

@ -0,0 +1,51 @@
#include<iostream>
#include "header.hpp"
using namespace std;
int main(){
/* Puntatori */
const int x = 5;
const int y = 3;
const int* p = &x;
//*p = 3; // errore
p = &y; //OK
const int* const p2 = &x;
//*p2 = 3; //errore
//p2 = &y; //errore
/* Casting */
char c = 'a';
void* p3 = &c;
//cout<<*p3; //errore (non conosce il tipo)
//cout<<*((char*)p3)<<endl; //OK
//cout<<*(static_cast<char*>(p3))<<endl; //miglior modo
/* Riferimenti */
int d = 7;
int& e = d;
e++;
//cout<<d<<endl;
// int a = function(); //OK
//int& b = function(); //errore cannot bind non-const lvalue reference of type int& to an rvalue of type int
const int& b = function(); // perché funziona?
//cout<<b<<endl;
string s1 = "hello";
string s2 = "world";
cout<<"Address of s2 is"<<&s2<<endl;
s1 = std::move(s2);
cout<<"Address of s1 is"<<&s1<<endl;
int r = move(function()); //ok
cout<<r<<endl;
int&& r2 = move(function()); //ok
return 0;
}

1
teoria/multiple_files/build.sh Executable file
View File

@ -0,0 +1 @@
g++ -O3 main.cpp test.cpp -o executable.out

Binary file not shown.

8
teoria/multiple_files/main.cpp Executable file
View File

@ -0,0 +1,8 @@
#include <iostream>
#include "test.hpp"
using namespace std;
int main(){
cout<<"I'm main"<<endl;
test();
return 0;
}

5
teoria/multiple_files/test.cpp Executable file
View File

@ -0,0 +1,5 @@
#include <iostream>
#include "test.hpp"
void test(){
std::cout<<"I'm test"<<std::endl;
}

4
teoria/multiple_files/test.hpp Executable file
View File

@ -0,0 +1,4 @@
#ifndef TEST_HPP
#define TEST_HPP
void test();
#endif

85
teoria/puntatori.cpp Normal file
View File

@ -0,0 +1,85 @@
/**** puntatori ****/
#include <iostream>
using namespace std;
// prototipi di funzione
void assegnazione();
void dimensione_puntatore();
void puntatori_const();
void casting();
int main(){
casting();
return 0;
}
void casting(){
int i = -1;
int* ptr_int = &i;
/* trasformo il puntatore da puntatore a intero a puntatore a unsigned intero
quindi stamperà 4294967295 perchè interpreta il valore puntato come unsigned */
cout<<*((unsigned int*)ptr_int)<<endl;
void* ptr_void = &i;
// cout<<*ptr_void<<endl; //errore. non sa come interpretare il valore puntato da ptr_void
cout<<*((int*)ptr_void)<<endl; //ok
/* Il C++ offre lo static_cast ed è più restrittivo rispetto al cast normale */
cout<<*(static_cast<int*>(ptr_void)); // Il tipo void* può sempre essere castato
//cout<<*(static_cast<unsigned int*>(ptr_int)); // errore. Non avrebbe dato errore con il cast normale
}
void puntatori_const(){
const char carattere_const = 'a';
char carattere = 'b';
/* ----- CONST TYPE* PTR ----- */
// Se una variabile è const anche il suo puntatore deve esserlo
// char* ptr = carattere_const; // errore
const char* ptr = &carattere_const; // OK
/* Se un puntatore è const char*, non posso modificare il valore della
variabile, ma posso modificare il valore del puntatore in */
// *ptr = 'z'; //errore
ptr = &carattere; //ok
/* ----- CONST TYPE* CONST PTR ----- */
/* const char* const vuol dire che è un puntatore const che non
può neanche modificare il valore del puntatore in */
const char* const ptr2 = &carattere_const;
// *ptr2 = 'z'; //errore
// ptr2 = &carattere; //errore
/* ----- TYPE* CONST PTR ----- */
/* Punta a tipi non-const ma il suo valore non può essere cambiato,
ovvero non può puntare a locazioni diverse rispetto alla dimensione_puntatore
inizializzazione */
char* const ptr3 = &carattere;
*ptr3 = 'k'; // OK
char carattere2 = 's';
//ptr3 = &carattere2; // errore
}
void dimensione_puntatore(){
/* la dimensione di un puntatore non dipende dal tipo a cui punta
dato che deve semplicemente essere abbastanza grande per individuare
una cella di memoria */
long double* ptr1 = nullptr;
char* ptr2 = nullptr;
cout<<sizeof(ptr1)<<endl<<sizeof(ptr2)<<endl;
}
void assegnazione(){
char carattere = 'a';
char* ptr = nullptr; // equivalente al NULL di C
ptr = &carattere; // assegno a ptr l'indirizzo di carattere
cout<<"carattere: "<<carattere<<endl;
cout<<"deferenziazione di ptr: "<<*ptr<<endl;
}

84
teoria/riferimenti.cpp Normal file
View File

@ -0,0 +1,84 @@
/* Il riferimento è un concetto non presente in C */
#include <iostream>
using namespace std;
void lvalue();
void rvalue();
void move();
int f();
int main(){
//lvalue();
//rvalue();
move();
return 0;
}
void lvalue(){
/* Il riferimento è come se fosse un puntatore, ma non devo usare la deferenziazione
per accedere al contenuto. è utile quando vogliamo passare dei parametri a puntatore
funzione per riferimento (risparmiando sulla copia) ma senza usare la sintassi
dei puntatori */
int var = 7;
int& riferimento = var;
riferimento++;
cout<<var<<endl; // stampa 8
// il che è esattamente equivalente a fare questo
int var2 = 7;
int* riferimento2 = &var2;
(*riferimento2)++;
cout<<*riferimento2;
}
void rvalue(){
/*
fare una cosa del genere
int k = f();
richiede una copia dal valore di ritorno di f() che sta sullo stack in k
*/
// Per ottenere valori da una funione seza dover fare copie posso usare due metodi:
int&& x = f(); // questo è un riferimento, come se fosse un lvalue
int y = std::move(f());
cout<<x<<" "<<y<<endl;
/*
è consigliabile utilizzare std::move() al posto di && in quanto
x è un riferimento a un indirizzo sullo stack, e proprio per natura dello
stack, quella stessa porzione di memoria può essere riutilizzata e dunque
contenere risultati inattesi
*/
}
void move(){
//La move può essere utilizzata per altri scopi
string s1 = "hello";
string s2 = "world";
cout<<s1<<" "<<s2<<endl; //hello world
s1 = move(s2);
cout<<s1<<" "<<s2<<endl; //world
/*
Quello che succede è che s1 ha LO STESSO oggetto di s2 senza fare copie.
Praticamente a s1 viene puntato il vecchio indirizzo di s2.
Lo standard non dice cosa avviene per s2. In questo caso il valore
di s2 viene impostato a "" (stringa vuota).
In realtà, se si analizzano i puntatori, si vede che non avviene nulla di
particolare. Il prof Mogavero ha detto che questo è normale perché
quello che faccio è stampare i puntatori della classe (string) e non
delle stringhe in .
*/
int i1 = 100;
int i2 = 50;
i1 = move(i2);
cout<<i1<<" "<<i2<<endl; // Qui a differenza delle stinghe, il valore di i2 viene mantenuto
/*
N.B. move() viene creato dai programmatori e non è un qualcosa fatto dal compilatore.
Il move di interi e stringhe è fatto dalla libreria standard.
*/
}
int f(){return 3;}