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