Grammatica di base: esempio -...
Transcript of Grammatica di base: esempio -...
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 117
Grammatica di base: esempioEsempio di funzione con assegnazione condizionata: Calcoliamo il fattoriale
int fac( int b){return (n<2) ? 1 : n* fac(n-1);
} fac.cpp
int fac(int );
int main(){int bb=3;return fac(3);
} main.cpp
1. g++ -c fac.cpp2. g++ -c main.cpp3. g++ -o my_prog main.o fac.o4. ./my_prog5. echo $?
Compilazione
LinkEsecuzione
Risultato
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 118
Grammatica di base: esempioDi solito si riuniscono le dichiarazioni in files separati, detti header .(Vengono messi all’inizio, ma noi sappiamo che una dichiarazione in C++ può essere messa dappertutto… ) Di solito si distinguono con l’estensione: .h
int fac( int b){return (n<2) ? 1 : n* fac(n-1);
} fac.cpp
#include “my_decl.h”
int main(){int bb=3;return fac(3);
} main.cpp
int fac( int ); my_decl.h
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 119
Grammatica di base: esempio#include è una macro di preprocessoreRichiede al preprocessore di includere, a partire dalla linea della macro, il contenuto del file: my_decl.h, nel codice di main.cpp.In una macro #include, il nome del file da includere può esseredelimitato da < … > , o “ ...“
< … > , il file viene cercato nelle cartelle “standard” di sistema, i.e. quelle dichiarate all’atto della configurazione“...“ , il file viene cercato nella cartella dove viene invocato ilcompilatore o in quelle indicate dall’opzione -I
g++ -I/home/cafagna/includes –I../inc –I/my_header_dir …
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 120
Grammatica di baseLe funzioni
Quando una funzione viene chiamata, viene creata un aria di memoria per ogniargomento ed ogni argomento è inizializzato al suo valore reale.
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 121
Grammatica di baseUtilizziamo la funzione:
#include <iostream>#include "my_first_f.h"using std::cout;using std::endl;typedef int Fscaf;int do_nothing(int a){return a++;}int main(){
int a,c;a=c=2; Fscaf d;d=a;a+=c; {int d=12;c+=d;
}c=do_nothing(a);cout << " a: " << a << endl << " c: " << c << endl <<" d: " <<d << endl;
cout << " Adesso uso la mia my_first_f " << std::endl << std::endl;cout << " Risultato : " << my_first_f(a,c) << std::endl;return 0;}
Includo dichiarazione funzione
Dichiaro cosa usare del namespace
Scope con variabili locali: d != d del main, c == c del main
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 122
Funzionalità avanzate: function overloading
Spesso diamo alle funzioni nomi differenti ma effettuano le stesse operazioni su tipi diversi. Dare lo stesso nome ad operazioni effettuate su tipi diversi è detto: overloading. Secondo voi come fa l’operatore “+” ad operare sudiversi tipi chiamandosi nello stesso modo ?
void Voglio_la_millefoglie(fragole *f);void Voglio_la_millefoglie(frutti_di_bosco *f);void Voglio_la_millefoglie(cigliege *f);void Voglio_la_millefoglie(pesche *f, bool no_chantilly);
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 123
Grammatica di base: Pointers
Esistono I puntatori a funzioni. Bisognaesplicitare esattamente il tipo di ritorno e il tipodi argomento. Per evitare ambiguità con ilprefisso * nel declarator, il nome e l’operatoreva incluso tra parentesi tonde:
int *dn (int); // Funzione che ritorna un puntatore ad un intero ed ha come argomento un interoint (*dn)(int); // Puntatore ad una funzione cheritorna un intero ed ha come argomento un intero
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 124
Grammatica di base: PointersSi può applicare & al nome o usare il nomedirettamente: int do_nothing(int a);int (*dn) (int);int main() {
int a=2;dn=&do_nothing;dn=do_nothing;return dn(a);
}Molto utili per definire menù usando array di funzioni:typedef void (*FILE ) ();FILE edit_ops[]={&cut,&paste,©,&search};FILE file_ops[]={&open,&append,&close,&write};FILE *button2=edit_ops;FILE *button3=file_ops; button2[2]();
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 125
Grammatica di base: References
ReferenceUna reference è un nome alternativo per un oggetto. La notazione: T& vuol dire: reference a T
int i=2: int &ref=i: int a=ref; ref=2;Per assicurarsi che la reference punti a qualche cosa è obbligatorio inizializzarla:
int i=0; int & ref=I; //Permessoint & ref: // Non è permesso, non punta a niente, non è inizializzataextern int &ref2; // Permesso, deve essere inizializzata da qualchealtra parte.
Non ci sono operatori che operino direttamente sulla reference: ref++; // Somma +1 all’oggetto puntato dalla reference
Viene utilizzata per passare parametri che possono esseremodificati, a funzioni o per tipi di ritorno di operatori.
Per migliorare la leggibilita’ dei programma e’ preferibile usarepuntatori piuttosto che reference, negli argomenti delle funzioni.
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 126
Grammatica di base: References
void modify_it(int &a){a++;}void f(){
int x=1;modify_it(x); // Non si capisce che x viene modificata
}
int incr(int a) {return a+1;}void sum_it(int *a){ (*a)++;}void f(){
int x=1;x=incr(x); // x=2sum_it(&x); // x=3, si capisce che viene modificata perchè si passa
il puntatore}
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 127
Funzionalità avanzate: Tipi aggregati
Le strutture.Un array è un aggregato di tipi tutti uguali. Unastruttura: struct, è un aggregato di tipi diversi.
struct studente {char * name;int anno_dott;bool buoni_e_cattivi;bool corso_cpp;};
Si dichiara come gli altri tipi, usando il nome delladefinizione:
studente f_cafagna;
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 128
Si inizializza come i vettori:studente f_cafagna={“Francesco Cafagna”,1,TRUE,TRUE};
Come posso accedere ai membri individuali di una struttura?
Si usa l’operatore :“.” (punto)std::cout << f_cafagna.name << std::endl;
E se usassi un puntatore ad una struttura ?Al punto va sostituito l’operatore: -> (structure pointer dereference)
void Print_student_name( studente *s){std::cout << s->name << std::endl;
}
Attenzione al ‘;’
Funzionalità avanzate: Tipi aggregati
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 129
Funzionalità avanzate:Tipi aggregatiÈ possibile assegnare strutture , passarle come argomenti e ritornarle come risultati di una funzioneNon sono definite a priori le operazioni, vanno definiteIl nome di un tipo si può usare appena diventadisponibile:
struct test {test* prova;test* riprova;
};Perchè non è possibile scrivere:
struct test {test prova;test riprova;
};
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 130
Funzionalità avanzate:Tipi aggregati
E questo :struct prova2;struct test{prova2 sbagliato;test *corretto;};
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 131
Funzionalità avanzate: Tipi aggregati
Unions.Sono struct i cui membri hanno tutti lo stessoindirizzo di memoria. Le dimensioni saranno quelle del membro più grande:
union test {char* t;int s;
};test prova;prova.t=‘y’;std::cout << prova.s << std::endl;
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 132
Funzionalità avanzate:Tipi aggregati
In C++ si possono usare unions anonime:struct esempio{char *name;My_type t;union {char *s;int t;};
};
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 133
Funzionalità avanzate: TemplatesIl C++ supporta il generic programming, ovveropermette che un tipo sia usato come parametrodi una classe o una funzione:template<class T> struct Pere{T variabile_generica;T* puntatore_generico;
};template<class C> C do_nothing(C a){ return a++;}
Si possono definire funzioni template overloaded:
template<class T> T sqrt(T);template<class T> complex<T> sqrt(complex<T>);
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 134
Funzionalità avanzate: Templates
Come si instanziano ?Pere <int> kaiser;int a; do_nothing(a);
Un template può usare parametri:template <class S, int n> struct Pere{
S v[n];}; Pere<int,5> Williams;
Parametri possono essere: costanti, address di oggetti o funzioni esterne, o puntatori a membrinon-overloaded.
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 135
Funzionalità avanzate: S(T)L
Il C++ viene fornito con una Standard Library. la Standard Library viene definita nel namespace std, e contiene strumenti per:
Run-time language support (typeid, memory operation, etc.)La C standard library (printf, scanf, etc. )Stringhe e I/O streams (string, cout, cin, etc.)Supporto per calcolo numerico (complex, etc.)Contenitori (Containers) ed algoritmi che li utilizzano(vector, list, map, iterator, for_each, etc.)
Utilizza pesantemente I templates
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 136
Abbiamo già usato la libreria per I/O: iostreamcout: definisce un output per ogni tipo;cin: definisce un input per ogni tipo;
Si specializza per I/O su file usando: fstream,ofstream, ifstreamSu stringhe: sstream, istringstream, ostringstream
Contenitori:vector : array dinamico. Non ha dimensione fissa. Templates.
vector <int> caf;for(int a=0;a<10;++a){
caf.push_back(a);}std::cout << “ Dim. : “ << caf.size() << std::endl;
Funzionalità avanzate: S(T)L
Templates
Dinamico. Cresce alla bisogna
Chiedo al vector le dimensioni
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 137
Funzionalità avanzate: S(T)L
È possibile navigare in un vettore usandol’operatore: []vector<Pere> kayser; for(int i=0; i< kayser.size; ++i)
do_nothing(kayser[i]);
È possibile navigare in un vettore usando degli:iteratori . Oggetti che “sanno” come spostarsi in un vettore:vector<Pere> kayser; for(vector<Pere>::const_iterator
i=kayser.begins(); i!= kayser.end(); ++i) do_nothing(*i);
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 138
Funzionalità avanzate: S(T)L
Facciamo un pò di esempi: test_union
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 139
Funzionalità avanzate: S(T)L
Che succede se faccio ritornare una reference ad unafunzione ?
Posso usarla come lvalue !Provare per credere: provaref2.cppLVALUE ?!?!?!?!?!?
“something that can be on the left side of an assignment”
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 140
Funzionalità avanzate: S(T)L#include <iostream>#include <vector>#include <string>
using namespace std;
struct Pair {string name;double val;
};
vector<Pair> pairs;
double& value(const string& s){
for (int i=0; i< pairs.size(); i++)if( s== pairs[i].name) return pairs[i].val;
Pair p={s, 0};pairs.push_back(p);
return pairs[pairs.size()-1].val;
}
Includo gli header dellefacilities STL, namespaces,
classi etc. etc. che mi servono
Dichiaro namespaces da usare
Creo un vettore di Pair. Globale
Navigo nel vettore usando []
Creo un Pair locale e lo inizializzo
Lo aggiungo al vettore
Ritorno la parte val della struct
Creo un tipo aggregato, struct, di nome Pair
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 141
Funzionalità avanzate: S(T)L#include <iostream>#include <vector>#include <string>
using namespace std;
struct Pair {string name;double val;
};
vector<Pair> pairs;
double& value(const string& s){
for (int i=0; i< pairs.size(); i++)if( s== pairs[i].name) return pairs[i].val;
Pair p={s, 0};pairs.push_back(p);
return pairs[pairs.size()-1].val;
}
Domande ?
È locale ? Che fine fa ?
Ma non dovevo ritornare unareference ?
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 142
Funzionalità avanzate: S(T)L
int main(){string buf;while(std::cin>>buf) value(buf)++;// value(buf)++ == {value(buf) = value(buf) + 1;}for(vector<Pair>::const_iterator p=pairs.begin(); p!=pairs.end(); ++p)std::cout << p->name << ": "<<p->val << '\n';return 0;
}while ( expression ){ … }: esegui il codice nello scope fino a che expression è vera.
Navigo nel vettore usandol’iteratore