mirror of https://github.com/xfarrow/lasd.git
Initial commit
This commit is contained in:
commit
2e5192afe6
|
@ -0,0 +1,2 @@
|
||||||
|
# Auto detect text files and perform LF normalization
|
||||||
|
* text=auto
|
Binary file not shown.
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
g++ -O3 main.cpp test.cpp -o executable.out
|
Binary file not shown.
|
@ -0,0 +1,8 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include "test.hpp"
|
||||||
|
using namespace std;
|
||||||
|
int main(){
|
||||||
|
cout<<"I'm main"<<endl;
|
||||||
|
test();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include "test.hpp"
|
||||||
|
void test(){
|
||||||
|
std::cout<<"I'm test"<<std::endl;
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
#ifndef TEST_HPP
|
||||||
|
#define TEST_HPP
|
||||||
|
void test();
|
||||||
|
#endif
|
|
@ -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 sè */
|
||||||
|
// *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 sè */
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
|
@ -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 sè.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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;}
|
Loading…
Reference in New Issue