Grammatica di base: esempio -...

26
F.S. Cafagna, Linguaggi di programmazione avanzati: C++ , XXIII ciclo 117 Grammatica di base: esempio Esempio 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.cpp 2. g++ -c main.cpp 3. g++ -o my_prog main.o fac.o 4. ./my_prog 5. echo $? Compilazione Link Esecuzione Risultato

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,&copy,&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