elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente...

206
Elementi di C++ con UML, HTML, Java Corso di Informatica per la Fisica per studenti del primo anno del Corso Triennale di FISICA

Transcript of elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente...

Page 1: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

Elementi di C++ con UML, HTML, Java

Corso di Informatica per la Fisica per studenti del primo anno del Corso Triennale di FISICA

Adele Rimoldi - Dipartimento di Fisica Nucleare e Teorica Università di Pavia, I

Page 2: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

3

Riepilogo del linguaggio C........................................................................14

Struttura di un programma in C..........................................................14

Il Preprocessore................................................................................15

Il main program.................................................................................17

Commenti.........................................................................................17

Input/Output......................................................................................17

I/O: lettura e scrittura..........................................................................18

I/O: principali funzioni I/O da tastiera..................................................18

I/O: scanf()........................................................................................19

I/O: lettura e scrittura da file................................................................19

Tipi predefiniti in C.............................................................................20

Identificatori.......................................................................................21

Dichiarazione....................................................................................21

typedef..............................................................................................22

Enumeratori......................................................................................23

Operatori...........................................................................................24

Espressioni di assegnazione..............................................................25

Statements........................................................................................26

Statement composti...........................................................................26

if.......................................................................................................26

while e do-while.................................................................................27

break e continue................................................................................27

switch...............................................................................................28

L’operatore ?....................................................................................28

Array.................................................................................................29

Puntatori...........................................................................................30

&.......................................................................................................30

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 3

Page 3: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

4

*........................................................................................................31

Puntatore nullo..................................................................................32

Puntatori e array................................................................................32

Puntatori: allocazione dinamica..........................................................33

Regole di conversione e cast.............................................................34

Funzioni............................................................................................34

Prototipi delle funzioni........................................................................35

Call-by-Value.....................................................................................35

Call-by-Reference..............................................................................36

Funzioni esterne................................................................................37

struct.............................................................................................37

Accesso ai membri delle strutture.......................................................39

Passaggio dei membri di una struct a una funzione.............................39

Passaggio di una intera struttura ad una funzione...............................40

Puntatori a strutture...........................................................................40

Dichiarazione di un puntatore ad una struttura....................................40

Uso dei puntatori a struttura...............................................................40

L’operatore ->....................................................................................40

C++ come C “migliorato”..........................................................................42

main program....................................................................................42

Parametri del programma..................................................................43

Organizzazione dei files.....................................................................44

Stringhe............................................................................................44

Size e capacity..................................................................................45

Accesso agli elementi di una stringa...................................................45

iostream............................................................................................46

Manipolatori......................................................................................47

fstream..............................................................................................48

Page 4: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

5

stringstream......................................................................................48

commenti..........................................................................................49

const.................................................................................................49

Riferimenti.........................................................................................50

Riferiementi e Puntatori......................................................................50

Scope...............................................................................................50

namespace.......................................................................................51

new e delete......................................................................................52

Regole di conversione e cast.............................................................53

Casting in ANSI C++..........................................................................53

Funzioni............................................................................................54

Funzioni inline...................................................................................54

Argomenti di default...........................................................................54

Call by reference...............................................................................55

Overloading.......................................................................................55

Function signature.............................................................................55

C++ vs. C: le differenze......................................................................56

Classi......................................................................................................57

Linguaggio C e struct.....................................................................57

Problema: il tipo complesso................................................................57

Metodi...............................................................................................58

Metodi const......................................................................................59

Modificatori........................................................................................59

L’ esempio: il tipo complesso..............................................................60

Classi................................................................................................61

struct e class: riepilogo................................................................62

L’ esempio: il tipo complesso..............................................................62

Costruttori e distruttori........................................................................63

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 5

Page 5: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

6

L’ esempio: il tipo complesso..............................................................64

Inizializzazione..................................................................................65

Costruttore di default..........................................................................65

Costruttore di copia............................................................................65

Costruttori ad un parametro................................................................67

Distruttore.........................................................................................67

L’ esempio: il tipo complesso..............................................................68

Operatori...........................................................................................68

Regole per la ridefinizione degli operatori............................................69

Un esempio: l’operatore <<................................................................69

L’esempio: il tipo complesso...............................................................70

this....................................................................................................70

L’operatore di assegnazione (=).........................................................71

Overloading di operatori.....................................................................71

Che cos’è una classe?.......................................................................72

Un esempio: come costruirla ed usarla...............................................72

Incapsulamento.................................................................................75

friend................................................................................................75

static.................................................................................................75

Un contatore.....................................................................................76

Singleton...........................................................................................77

Templates...............................................................................................79

Template di template.........................................................................79

Funzioni template e parametri............................................................80

Membri statici....................................................................................81

Un esempio:lo stack di interi...............................................................81

typename........................................................................................83

Un altro esempio: la classe Queue.....................................................84

CORSO DI INFORMATICA PER LA FISICA6

Page 6: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

7

Potenza dei templates.......................................................................86

STL (Standard Template Library).............................................................87

Template (ripasso).............................................................................87

Container..........................................................................................87

Container sequenziali........................................................................88

Operazioni comuni a tutti i container...................................................88

Sequenze.........................................................................................88

vector................................................................................................88

list.....................................................................................................90

deque...............................................................................................91

Stringhe............................................................................................91

Accesso agli elementi di una stringa...................................................93

Stringhe e vectors..........................................................................93

Funzioni numeriche globali.................................................................93

Contenitori associativi........................................................................94

map..................................................................................................94

multimap...........................................................................................95

Contenitori speciali............................................................................96

stack.................................................................................................96

queue...............................................................................................96

Iteratori..............................................................................................97

Iterator adapters................................................................................98

Funzioni base....................................................................................99

Algoritmi............................................................................................99

Algoritmi di manipolazione................................................................100

Nonmodifying algorithms..................................................................101

Algoritmi di modificazione.................................................................101

Algoritmi di removing e mutating......................................................102

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 7

Page 7: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

8

Polimorfismo ed ereditarietà...................................................................104

Classi base e classi derivate............................................................104

“Is a”...............................................................................................105

Ereditarietà (Inheritance)..................................................................105

Classi base.....................................................................................105

Metodi virtuali..................................................................................106

Metodi virtuali e classi astratte..........................................................107

Ereditarietà ed interfaccia.................................................................108

Costruttori ed ereditarietà.................................................................108

Distruttori ed inheritance...................................................................108

Inheritance privata...........................................................................109

Un esempio:l’elenco telefonico.........................................................109

Ereditarietà multipla.........................................................................110

dynamic_cast..................................................................................111

Un altro esempio di polimorfismo......................................................111

Un altro esempio: shape..................................................................112

Esempio di ereditarietà multipla........................................................118

UML (Unified Modeling Language).........................................................120

Processi..........................................................................................120

Scopo (Inception phase) ed elaborazione.........................................120

Rischi..............................................................................................120

Use cases.......................................................................................121

Scheletro di un modello concettuale.................................................121

Planning..........................................................................................121

Costruzione.....................................................................................121

Transizione.....................................................................................122

Strategie nello sviluppo di un progetto...............................................122

L’esempio: il sistema solare..............................................................122

CORSO DI INFORMATICA PER LA FISICA8

Page 8: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

9

Confronto tra i modelli di sviluppo.....................................................123

Requisiti..........................................................................................123

Analisi.............................................................................................123

Disegno..........................................................................................124

Codifica...........................................................................................124

Test................................................................................................125

Metodi di sviluppo del software.........................................................125

Diagrammi......................................................................................125

Class diagrams................................................................................125

Rappresentazione delle classi..........................................................126

Attributi e metodi..............................................................................126

Principali relazioni tra classi..............................................................127

Associazioni....................................................................................127

Aggregazione(contenimento)...........................................................128

Composizione.................................................................................128

Dipendenza.....................................................................................128

Generalizzazione (ereditarietà).........................................................129

Esempi di Class Diagram.................................................................129

Interaction Diagrams........................................................................130

Collaboration Diagrams....................................................................131

Altri diagrammi................................................................................131

CRC (Classi, Responsabilità, Collaborazioni)....................................132

CRC Workshop...............................................................................132

Design patterns.....................................................................................134

Composite.......................................................................................135

Gruppo di Shapes............................................................................135

Strategy..........................................................................................136

Observer.........................................................................................136

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 9

Page 9: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

10

Open/Closed principle......................................................................137

HTML....................................................................................................138

DTML, XML HTML browsers............................................................138

Utilizzatori e Programmatori.............................................................138

Le basi di HTML..............................................................................139

tags.................................................................................................139

attributes.........................................................................................139

values.............................................................................................139

Simboli speciali................................................................................140

URL(Uniform Resource Locator)......................................................140

Il design del proprio sito web............................................................141

Creare una pagina web....................................................................141

Formattazione del testo....................................................................141

Creare immagini..............................................................................142

Formato..........................................................................................142

Colore.............................................................................................142

Trasparenza....................................................................................142

Velocità...........................................................................................142

Animazione.....................................................................................142

Utilizzare le immagini.......................................................................142

Testo attorno alle immagini..............................................................143

Layout.............................................................................................143

Links...............................................................................................144

Liste................................................................................................144

Tabelle............................................................................................144

Frames...........................................................................................145

Forms.............................................................................................145

Java......................................................................................................146

CORSO DI INFORMATICA PER LA FISICA10

Page 10: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

11

Che cosa c’è di nuovo in Java?........................................................146

Java ed Internet...............................................................................147

Linguaggi compilati ed interpretati.....................................................147

Bytecode.........................................................................................147

Applicazioni ed applets....................................................................147

Un esempio di applicazione..............................................................147

Java vs. C++...................................................................................148

Creazione degli oggetti....................................................................148

Ereditarietà......................................................................................148

Interfacce........................................................................................148

Un esempio.....................................................................................149

Uso delle interfacce.........................................................................149

Pacchetti.........................................................................................149

Un Applet........................................................................................150

L’esecuzione dell’applet...................................................................150

Un esempio di applet.......................................................................150

La programmazione multithread.......................................................151

La gestione delle eccezioni..............................................................151

Un ulteriore esempio........................................................................152

Python...................................................................................................159

Usare l’interpreter di Python.............................................................160

Usare python come una calcolatrice.................................................160

altre caratteristiche generali del linguaggio........................................160

stringhe...........................................................................................161

docstrings........................................................................................162

Tipi numerici....................................................................................162

moduli.............................................................................................163

importare moduli..............................................................................163

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 11

Page 11: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

12

sequences......................................................................................163

lists.................................................................................................163

tuples..............................................................................................163

strings.............................................................................................163

unpacking tuples..............................................................................163

indexing and slicing..........................................................................163

sequence operations.......................................................................163

binding – call by value......................................................................163

Bibliografia.............................................................................................164

CORSO DI INFORMATICA PER LA FISICA12

Page 12: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

13

Introduzione

Lo scopo di questo corso risiede nell’ insegnare i concetti della programmazione Object Oriented attraverso l’introduzione del linguaggio C++. Esso e’ rivolto a studenti del primo anno del Corso di Laurea in Fisica triennale (Laurea Specialistica in Scienze Fisiche) che hanno già seguito il corso propedeutico di Informatica per la Fisica I nel primo semestre e che quindi posseggono conoscenze basilari del linguaggio C nonché familiarità con Unix. La generalità dell’approccio rende questo corso altresi’ adatto anche a studenti di altri indirizzi di Laurea affini che abbiano un corso similare nel loro piano di studi.

Nella progettazione di questo corso e nella stesura di questo testo si è quindi scelta la strada del riepilogo dei concetti già noti riguardo il linguaggio C per poi passare all’ introduzione delle caratteristiche principali ed innovative del linguaggio C++ rispetto al C.

In realtà quasi tutti i manuali di C++ esistenti sono divisi in due parti, la prima che introduce il linguaggio C, la seconda che consiste in una sorta di estensione del linguaggio C per la programmazione Object Oriented, ovvero il C++. Alcuni manuali recenti propongono un approccio diretto alla programmazione in C++ e alla metodologia UML ,dedicato quindi a studenti privi di conoscenze del tipo di quelle previste qui, che si affacciano alla programmazione OO da zero. In questo corso si omette qualunque riferimento al FORTRAN dato che non e’ oggetto di studio nel corso del primo semestre e che, anche se ancora largamente usato in molti campi della fisica, nel corso del tempo verrà sostituito da linguaggi più evoluti basati sulla programmazione OO.

Perché si insegna la programmazione Object Oriented ? In genere perché essa semplifica di molto la gestione di medi e grandi pacchetti di software tipici di grandi strutture (banche, industrie, enti pubblici) e inoltre poichè nella vita di un fisico, sia che la sua attività rimanga chiusa in ambito Universitario, sia che spazi nell’Industria, sia che si rivolga alla Scuola, esisterà un momento di approccio al software (anche attraverso il web) che porrà in relazione le proprie conoscenze software con la continua “softwarizzazione” della vita reale e lavorativa.

Questo Corso, nell’ambito della Laurea Triennale in Fisica, e’ un corso fondamentale del primo anno e queste dispense nascono dal desiderio di fornire agli studenti un supporto di studio adeguato ai contenuti esposti durante le lezioni in aula.

Questo testo, nella sua stesura odierna, e’ ancora ricco di imprecisioni ed incompleto e non vuole avere nessuno scopo se non quello di annotare gli argomenti trattati. Il testo riporta il contenuto di ciascun argomento presentato a lezione e un seguente commento , talvolta ampliato o circostanziato.

Gli studenti che ritengono di avere interessi che vanno oltre quanto presentato qui sono rimandati, attraverso una ampia bibliografia, a testi ‘classici’ o meno noti che sembrano meglio spaziare sugli argomenti trattati durante le lezioni.

Esiste una versione del corso (in formato powerpoint) rintracciabile su web all’indirizzo:

http://www.pv.infn.it/~rimoldi/corsoinformatica.html

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 13

Page 13: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

14

Riepilogo del linguaggio C

In questo capitolo vengono riepilogati i concetti fondamentali della programmazione in linguaggio C. Una versione powerpoint delle trasparenze relative al seguente capitolo del corso si trova all’ indirizzo riportato nell’ introduzione.

Struttura di un programma in C

Un programma in C è composto da:file sorgente:

essi contengono istruzioni eseguibili, essi vengono compilati ed includono i file header e sono normalmente caratterizzati da un’estensione “.c”.

main.c#include <stdio.h>main(){printf(“Ciao \n”);}

file header:essi contengono dichiarazioni di funzioni e variabili, definizioni di “macro”,… essi vengono inclusi in un file sorgente prima della compilazione per mezzo del pre-processore C ed hanno normalmente un’estensione “.h”.

max.hextern int max(int,int);

Nel linguaggio C lettere maiuscole e minuscole sono distinte. E’ inessenziale il punto di partenza per la scrittura del codice lungo una linea (diversamente da altri linguaggi, come ad esempio il FORTRAN e il COBOL). Naturalmente un certo ordine non può che aiutare nella lettura e viene fortemente consigliato.

A differenza di altri linguaggi ad alto livello il C non esegue verifiche di errore a run-time, dunque nulla vieta per esempio al programmatore di scrivere fuori dalle dai limiti di un’array. Il controllo è quindi lasciato al programmatore. In C un argomento può essere di qualsiasi tipo che possa essere ragionevolmente convertito nel tipo del parametro.La conversione di tipo viene eseguita quindi automaticamente dal C.La peculiarità del linguaggio consiste nella possibilità di manipolazione diretta dei bit, byte, word e puntatori. Quindi è adatto a programmazione di software di sistema in cui questo genere di operazioni è molto comune.

Il C è un linguaggio strutturato, cioè il codice è isolabile dai dati. Esso è capace di suddividere e nascondere dal resto del programma tutte le informazioni e le istruzioni necessarie per eseguire una determinata operazione. Un modo per ottenere ciò consiste nel impiego di subroutine che impiegano variabili locali (temporanee), quindi ciò che accade in esse non è potenzialmente deleterio per altri parti di programma. Ciò semplifica la condivisione di parti di codice da parte di più programmi.

Tutte le linee di programmazione devono essere concluse da un carattere di “;”.

CORSO DI INFORMATICA PER LA FISICA14

Page 14: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

15

Un blocco di codice è formato da un gruppo di istruzioni connesse logicamente, considerato come una unità singola e posto tra due parentesi graffe.La forma generale di un programma C è la seguente:

Dichiarazioni globalitipo restituito main(elenco parametri){

sequenza istruzioni}tipo restituito f1(elenco parametri){

sequenza istruzioni}tipo restituito f2(elenco parametri){

sequenza istruzioni}…tipo restituito fN(elenco parametri){

sequenza istruzioni}

Molti programmi contengono chiamate alle varie funzioni contenute nella libreria standard.Tutti i compilatori sono dotati di una libreria di funzioni standard che eseguono le operazioni più comuni.►►Il linguaggio C++ supporta l’intera libreria di funzioni definita dallo standard C, quindi nei programmi C++ sono disponibili tutte le funzioni standard C.Quando una funzione che non fa parte del programma viene richiamata, il compilatore C prende nota del nome e in seguito il linker riunisce al codice scritto dal programmatore il codice oggetto che si trova nella libreria standard (linking).

Il Preprocessore

Il preprocessore C fornisce al programmatore la possibilità di sviluppare programmi più facili da leggere, da modificare, da trasportare su computer diversi. Il programmatore può anche usare il preprocessore per adattare il linguaggio C a seguire una particolare applicazione o a seguire il proprio stile di programmazione.In un file sorgente, qualsiasi istruzione che cominci con il simbolo # in colonna 1 viene interpretata dal preprocessore.L’uso del preprocessore permette di “personalizzare” il codice eseguibile a seconda dei “flag” definiti per il compilatore, del tipo di sistema operativo, della versione del compilatore etcIl preprocessore è parte del processo di compilazione in C che riconosce speciali istruzioni che possono essere inframmezzate all’interno di un programma. Come implica il suo nome il preprocessore analizza questi statements speciali prima che l’analisi del programma vero e proprio abbia luogo.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 15

Page 15: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

16

#include <stdio.h> /*inclusione di uno header di sistema*/

#include “mydefs.h” /*inclusione di uno header “personale”*/

#define MAX 100 /*definizione di una costante*/#define MAX(a,b) a<b?b:a; /*definizione di una macro*/#if - #else - #endif /*direttiva di compilazione condizionale*/#ifdef - #else - #endif /*utilizza definizioni precedenti*/

Lo statement:

#define TRUE 1

definisce il nome TRUE e lo rende equivalente a 1. Il nome TRUE può essere usato nel programma tutte le volte che la costante 1 può essere usata.Ovunque il nome appaia il suo valore definito di 1 sarà automaticamente sostituito nel programma dal preprocessore.La compilazione condizionale è un’altra delle caratteristiche del proprocessore.Essa è spesso utilizzata per avere lo stesso programma che funziona su diversi sistemi. Essa è anche usata per mettere switch on o off a statements del programma per debug o per printing.

#if MACHINE== 1 /* VAX-11 */…#elif MACHINE ==2 /* IBM PC */...#else...#endif

Altre istruzioni di preprocessore aiutano a personalizzare il codice eseguibile o per scopi particolari; se per esempio si vuole rendere indefinito un nome particolare si può utilizzare la seguente istruzione:

#undef nome

Un seguente #ifdef nome o #ifdefined nome sarà valutato falso.Se invece verrà utilizzata la seguente sequenza di operazioni di preprocessore

#define AND &&#define OR ||

Si potrà poi eseguire la seguente operazione:

if(y==0 OR y==value)…

CORSO DI INFORMATICA PER LA FISICA16

Page 16: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

17

Il main program

Ogni programma in C, per essere eseguibile, deve contenere una funzione main() da cui l’esecuzione cominceràmain() può avere un tipo (decidere quale è compito del programmatore). Regola generale è che main() ritorni un intero, a significare il return code dell’applicazione

main(){/* il più semplice programma in C */}

La linea di programma main() informa il sistema che il nome del programma è main. Main è un nome speciale che indica precisamente dove il programma deve iniziare la sua esecuzione. Le parentesi aperta e chiusa dopo il nome main specificano che main() è il nome di una funzione. Dopo la specificazione di main occorre indicare che cosa la routine è supposta fare nell’area sottostante entro il campo delle parentesi graffe, in questo caso nulla, anche se all’interno e’ specificata una linea di commento.

Commenti

In C Esiste la possibilità di inserire linee di commento nel codice (buona pratica per documentare la funzionalità di un programma)Si utilizza una coppia /* */. Tutto quanto è compreso fra questi caratteri non verrà considerato dal compilatore

int Ntries; /* questo e‘ un commento multiline:tutto viene trattato come un commentofino a quando il commento stesso non viene chiuso con uno */

L’aggiunta di ulteriori /*o */ in un commento comporterà un messaggio d’erroreUn commento inzia con i caratteri /* e termina non appena sono incontrati i caratteri */. Un commento può essere inserito ovunque in un programma, in tutti i luoghi in cui un carattere “ “ può esistere.

►►Il linguaggio C++ supporta lo stesso tipo di commenti, ma ne aggiunge un altro tipo che vale per la lunghezza di una linea di codice senza necessità di delimitarne il fondo

// questo è un commento in C++

Input/Output

Le principali funzioni di I/O si possono eseguire da file o da tastiera.Tecnicamente non esiste una grande diversità tra le funzioni da tastiera o da file benché si tratti concettualmente di situazioni diverse.

I/O: lettura e scrittura

Per leggere e scrivere dati formattati si usa printf() (scrive dati sullo schermo) e scanf() (legge dati dalla tastiera) accettando qualsiasi tipo di dati interno del C compresi

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 17

Page 17: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

18

caratteri, stringhe e numeri. Queste funzioni sono contenute nella standard library del C che viene richiamata usando il comando di preprocessore:

#include <stdio.h>

Questo file include tutte le dichiarazioni e definizioni di macro contenute nella standard C library

#include <stdio.h>main(){ printf( “Hello, world !\n” );/* \n caratteri di newline*/}

I/O: principali funzioni I/O da tastiera

getchar()getchar() legge un carattere dalla tastiera, attende la pressione di “enter”putchar()putchar() scrive un carattere sullo schermogets()gets() legge una stringa dalla tastieraputs()puts() scrive una stringa sullo schermo

La funzione getchar() risulta di particolare interesse quando si vogliono leggere dati dal terminale ad un carattere alla volta.Si può inoltre pensare di sviluppare facilmente una funzione read_line per leggere una intera linea di testo da un terminale. Questa funzione chiama ripetutamente getchar() finchè un carattere di newline viene riconosciuto.Una funzione analoga alla precedente, ma per scrivere dati sul terminale è putchar(). La chiamata a putchar() e’ la seguente:

putchar (c) ;putchar (‘\n’); /* porta il cursore a muoversi all’inizio della riga successiva */

Il solo argomento richiesto e’ il carattere da essere inviato. c è definito di tipo char.I prototipi delle funzioni getchar e putchar sono i seguenti

int getchar(void);int putchar(int c):

gets() e puts() leggono e scrivono rispettivamente una stringa dalla/sulla tastiera. Anch’esse fanno parte della standard library.La funzione printf() scrive gli argomenti specificati sullo stdout in accordo con il formato specificato

int printf(format,arg1,arg2,argN);

Essa restituisce il numero di caratteri scritti o un valore negativo in caso di errore.Nell’esempio seguente è illustrato un semplice programma che, definiti v1 e v2 stampa il valore della somma (sum) con una appropriata funzione printf().

CORSO DI INFORMATICA PER LA FISICA18

Page 18: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

19

#include <stdio.h>main(){ int v1, v2,sum;

v1=50;v2=25;sum=v1+v2;printf( “Sum of %i and %i is %i\n”,v1,v2,sum);

}

I campi e le convenzioni sono indicate nel prospetto seguente:

%c legge un singolo carattere%d(i) un intero decimale%e(f)(g) un numero in virgola mobile%o un numero ottale%s una stringa%x un numero esadecimale%p un puntatore%n riceve un numero intero= al numero di caratteri letti%u legge un intero senza segno%[ ] attende l’immissione di un determinato gruppo di caratteri%% legge un segno percentuale

I/O: scanf()

Questa funzione della libreria standard del C viene utilizzata per leggere da console secondo il formato specificato dalla stringa format

int scanf(format,arg1,arg2,…);

Gli argomenti che seguono format devono essere tutti puntatori. Essa restituisce il numero di dati a cui e’ stato assegnato un valoreIn caso di errore (cioe’ quando viene incontrato un EOF prima che tutti gli elementi siano stati convertiti) resituisce EOF.

#include <stdio.h>main(){ int i,j;

scanf( “%o%x”,&i ,&j);printf(“%o,%x,i,j);return 0;

}

Un numero ottale e un numero esadecimale sono letti dalla console e poi scritti dal semplice programma precedente.

I/O: lettura e scrittura da file

Molto spesso occorre leggere dati da un file o scriverli su un file, quando la tastiera o il display sono insufficienti o scomodi. Entrambe queste operazioni possono essere eseguite facilmente in Unix , se ad esempio volessimo scrivere tutti i risultati di un programma in un file di nome data potremmo redirigere il programma al file con la seguente istruzione:

a.out > data

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 19

Page 19: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

20

Questo comando istruisce il sistema ad eseguire il programma a.out e a mandare tutto l’output che normalmente viene visualizzato sul terminale nel file data.Naturalmente se si volesse redirigere anche l’input facendolo leggere da un file basterebbe usare la sintassi:

a.out < number > data

dove number è un file di input che contiene l’informazione che dovrebbe essere digitata sulla tastiera. Naturalmente occorre ricordarsi di aggiungere alla fine del file number un carattere in più a significare la raggiunta fine del file.La redirezione dell’ I/O non è parte dello standard ANSI C, questo significa che si possono trovare sistemi operativi che non la supportano, anche se nella maggior parte dei casi questo non succede.►►Il linguaggio C++ supporta l’intero sistema di I/O su file del C. Quindi le trasformazioni di codice da C a C++ non richiedono alcuna variazione per quanto riguarda le routine di I/O del programma.

Tipi predefiniti in C

In C sono definiti una serie di tipi numerici che permettono di rappresentare numeri interi, reali e caratteri.char (un solo byte) viene normalmente usato per rappresentare interi inferiori a 256. Stringhe e numeri complessi sono implementati come tipi derivati. Non esiste un tipo “logico” a significare “vero” o “falso”. Si utilizza generalmente una macro

#define TRUE 1#define FALSE 0

int intero in singola precisionelong intero in doppia precisionefloat reale in singola precisionedouble reale in doppia precisionelong double reale in precisione estesaunsigned int intero senza segnounsigned double reale senza segno in doppia precisionechar carattere singolo

esempi di costanti:

123 123 0x123 interi costanti, decimale, ottale, esadecimale

123l 123u interi, long, unsigned‘A’ ‘1’ ‘\t’ caratteri, tab3.14f 3.1415 3.1415L float, double, long double300°-2 .03°2 30°-1 double, notazione

esponenziale“Nome” stringa costante

costanti carattere:

CORSO DI INFORMATICA PER LA FISICA20

Page 20: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

21

‘\a’ alert‘\\’ backslash‘\b’ backspace‘\r’ carriage return‘\”’ double quote‘\f’ form feed‘\t’ tab‘\n’ newline‘\0’ carattere nullo‘\’’ single quote‘\v’ vertical tab‘\101’ 101 ottale, ‘A’‘\x041’ esadecimale, ‘A’

stringhe costanti:

“” stringa nulla (‘\0’)“nome” ‘n’ ‘o’ ‘m’ ‘e’ ‘\0’“una \”stringa\”” stampa: una “stringa”“una stringa \ un \ alla fine della lineasu piu‘ linee” per continuare la stringa

Il numero di bit riservati ad ogni tipo dipende dal microprocessore e dal compilatore impiegati. Come si vede anche dalla tabella un carattere è ad esempio contenuto in un byte nella maggior parte dei casi. Le dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli ambienti a 16 bit, come DOS o Windows 3 un intero è di 16 bit, mentre in ambienti come Windows o NT in genere un intero occupa 32 bit. ►►Il linguaggio C++ aggiunge ai tipi definiti bool e wchar che non hanno uguale in C

Identificatori

I nomi delle variabili, delle funzioni, delle etichette e degli altri oggetti definiti dall’utente sono chiamati genericamente identificatori.Un identificatore è composto da uno o più caratteri. Il primo carattere deve essere una lettera o un underscore (carattere di sottolineatura). I caratteri successivi possono essere lettere, numeri o underscore. Non esiste un limite in lunghezza, anche se alcuni sistemi si limitano a considerare i primi 31 caratteri ►►Il linguaggio C++ supporta qualsiasi lunghezza per un identificatore, fino a 1024 caratteri; quindi se si deve trasformare un programma dal C al C++ occorre controllare questo aspettoGli identificatori che iniziano con un doppio underscore o con un underscore e una lettera maiuscola sono riservati ad usi di sistema. Il C e‘ case sensitive!

int Ntries; double _attempts;double 2A; /* errore! */

Dichiarazione

Le dichiarazioni associano un significato ad un identificatore. In C ogni variabile deve essere dichiarata per poter essere usata. La forma generale di una dichiarazione è:

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 21

Page 21: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

22

tipo elenco_variabili;

tipo deve essere un tipo di dati valido in C mentre elenco variabili può essere formato da uno o più nomi di identificatori separati da virgole. Inoltre in C il nome della variabile non ha nulla a che fare con il suo tipo.

int i; /* la variabile i */

double max(double r1,double r2); /* la funzione max */

Una dichiarazione è spesso anche una definizione. Per variabili semplici questo consiste nell’associare un valore alla variabile al momento della dichiarazione */

double pi=3.1415926; /* definizione */double max(double r1, double r2) { /* dichiarazione*/

return (r1>r2) ? r1: r2; /*definizione di max*/ }

Le variabili possono essere definite in tre luoghi diversi: all’ interno delle funzioni (variabili locali) nella definizione dei parametri delle funzioni all’esterno delle funzioni

Le variabili locali possono essere usate solo dalle istruzioni che si trovano all’interno del blocco in cui sono dichiarate. Esse quindi NON sono note all’esterno del proprio blocco di codice che inizia e chiude con una coppia di parentesi graffe. La vita delle variabili locali è legata all’esecuzione del blocco di codice in cui sono dichiarate.Normalmente si dichiarano le variabili locali all’inizio del blocco di codice, cioè subito dopo la parentesi graffa di apertura della funzione e prima di ogni altra istruzione. Si possono tuttavia dichiarare variabili locali in qualunque altro punto del blocco di codice, per esempio dentro un if. Se una variabile è dichiarata al di fuori di qualsiasi funzione (variabile globale) o localmente ad una funzione.Le variabili globali essendo note all’intero programma possono essere usate quindi ovunque. Esse conservano inoltre il proprio valore per l’intera esecuzione del programma.

double r; /* r è globale, può essere usata da tutte le funzioni definite in questo file */main(){

int i=4; /* dichiarazione e definizione */double h;r=3;h=i*r;

}

typedef

L’istruzione typedef viene utilizzata per creare un alias per tipi esistenti, cioè non si crea un nuovo tipo di dati ma si definisce un nuovo nome ad un tipo di dati preesistente.Questo processo può essere utile per rendere più trasportabili i programmi dipendenti da una macchina.La forma generale è la seguente:typedef tipo nuovonome;

CORSO DI INFORMATICA PER LA FISICA22

Page 22: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

23

questo nuovo nome si aggiunge a quello preesistente senza sostituirlo.►►Il linguaggio C++ supporta lo stesso tipo di definizione

typedef int INTEGER; /* per i nostalgici del fortran */typedef int BOOLEAN; /* un tipo logico */typedef void (*ptr_f)(); /* ptr_f e` un puntatore ad una procedura

(subroutine) */ essa NON può essere usato per implementare nuovi tipi, ma solo per definire un alias.

typedef mela frutto; /* compila soltanto se mela e` gia` stata definita */

Enumeratori

enum è il caso più semplice di un tipo definito dall’utente (è assimilabile ad un tipo intero).Essa è formata da un gruppo di costanti intere dotate di un nome che specificano tutti i valori consentiti per una variabile di tale tipo.La forma generale delle enumerazioni è la seguente:

enum nome_tipo_enumerativo {elenco enumerazioni} elenco_variabili;

gli esempi sono riportati nei due riquadri sottostanti.

enum Color{ red, green=10, blue};

Color screenColor = blue;Color windorColor = red;

int n = blue; /* valido */Color c = 1; /* errore */

enum Seme{ cuori, picche, quadri, fiori};

Il nome del tipo enumerativo può essere utilizzato per dichiarare variabili di tale tipo. In C la seguente riga

enum coin money;

Dichiara money come una variabile di tipo coin.►►Il linguaggio C++ semplifica invece la definizione per cui la stessa variabile può essere dichiarata con la seguente forma abbreviata: coin money;Il fattore chiave per capire una enumerazione è che ad ognuno dei simboli corrisponde un valore intero.Questi valori possono quindi essere utilizzati in qualunque punto si potrebbe utilizzare un intero. Ad ogni simbolo viene assegnato un valore maggiore di una unità rispetto al simbolo precedente. Il valore del primo simbolo dell’enumerazione è 0.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 23

Page 23: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

24

Quindi:

printf(“%d %d”, cuori, quadri);

visualizza i valori 0 e 2.I valori di uno o più simboli possono essere esplicitati tramite un inizializzatore. Nell’esempio precedente green è posto a 10. inoltre va ricordato che cuori è il nome di un intero, non di una stringa.

Operatori

Esistono quattro classi principali di operatori in C►►Il linguaggio C++ si comporta in ugual modo per quanto riguarda gli operatori.

Espressioni aritmetiche -i +w piu` e meno unaria*b a/b i%2 moltiplicazione,

divisione, moduloa+b a-b addizione e

sottrazione binariea=3; assegnazione

auto-incremento esperessionee decrementok = ++j; j=j+1; k=j;k = j++; k=j; j=j+1;k = --j; j=j-1; k=j;k = j--; k=j; j=j-1;

Gli operatori di incremento e di decremento si comportano diversamente a seconda che l’operatore preceda o segua l’operando. Se l’operatore precede l’ operando il C esegue l’incremento o il decremento prima di fornire il valore dell’operando all’espressione.Se invece l’operatore segue il C fornisce il valore dell’operando e poi lo incrementa o decrementa.

x=10;y= ++x;

assegna ad y il valore 11

x=10;y= x++;

a y viene assegnato il valore 10.

CORSO DI INFORMATICA PER LA FISICA24

Page 24: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

25

operatori relazionali

< minore di .LT.> maggiore di .GT.<= minore o uguale .LE.>= maggiore o uguale .GE.== uguale .EQ.!= diverso .NE.! Negazione unaria .NOT.&& and logico .AND.|| or logico .OR.

bit-wise

~i; Complemento bit a biti&j; AND bit a biti|j OR bit a biti^j XOR bit a biti<<n shift a sinistra di n pos.i>>n shift a destra di n pos.

Espressioni di assegnazione

Le espressioni di assegnazione sono valutate da destra a sinistra

a = j++;j viene assegnato ad a ed in seguito incrementato

Le assegnazioni multiple sono permesse

a = b = c = d = 100;

alcuni operatori di assegnazione combinano assegnazione ed altri operatori.

a *= b; /* equivale ad a = a*b; */a -= b; /* equivale ad a = a-b; */

Assegnazioni possono essere fatte all’interno di espressioni aritmetiche

a = b + ( c = 3 ); /* equivale a c=3; a=b+c; */

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 25

Page 25: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

26

Statements

Le tabelle seguenti indicano una sintesi di statement comuni a partire dal più semplice (quello vuoto costituito solo dal carattere finale di linea (;) agli altri più articolati.

vuoto ;espressione j=j+k;composto { . . . . } usato in funzioni, if..

Costituisce un blocco goto goto label; da non usarsiif if (p==0)

cerr<<“error”; un solo branchif-else if (x==y)

printf(“the same\n”);else printf(“different\n”); due branch

for for (j=0;j<n;j++) usato normalmente pera[j]=0; definire un loop

while while (i != j) 0 o piu` iterazioni i++;

do-while do y=y-1; 1 o piu` iterazioniwhile (y>0);

break break; esce dal bloccocontinue continue; prossima iterazione

switch switch (s) {case 1: si deve usare break per

++i; evitare di cadere nei case 2: casi successivi e

--i; aggiungere un caso didefault: default alla fine della

++j; lista};

dichiarazione int i=7;globale o in una funzione label error:

cerr<<“Error!”; usato con gotoreturn return x*x*x;valore di ritorno di una funzione

Statement composti

Uno statement composto in C è costituito da una serie di statement contenuti fra parentesi graffeUsato normalmente per raggruppare istruzioni in un blocco (if, for, while, do-while, etc.). Il corpo di una funzione è sempre uno statement composto.Ovunque si possa usare uno statement singolo si può definire un blocco.

if

Attenzione all’uso di = e ==

CORSO DI INFORMATICA PER LA FISICA26

Page 26: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

27

if (i=1) /* questo e` sempre vero!!! */{. . . .}

Nel dubbio, usare sempre un blocco…

if (i != 0) /* possibile divisione per 0 */ a++; /* mancano delle {}? */a/=i;

Attenzione agli else!

if (i == 0) /* possibile divisione per 0 */if (a<0)

{printf(“a e` negativo!\n”);

}else b=a/i;

while e do-while

La forma generale di un while è :

while (condizione)statement;

Lo statement verrà eseguito fino a quando la condizione verrà verificata (true). A seconda del valore della condizione, lo statement verrà eseguito zero o più voltela sintassi di un do-while è invece:

dostatement;

while (condizione);

Lo statement verrà quindi eseguito almeno una volta

break e continue

break e continue sono utilizzati nei loop per saltare alla fine del loop o fuori dal loop stesso

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 27

Page 27: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

28

int i,n=0;int a[100];scanf(“%i”,&i); /* leggo il valore di i */while (1) /* loop infinito */{

if (i<0) break;if (n>=100) continue;a[n]=i;n++;/* continue salta qui */

}/* break salta qui */

break e continue possono solamente essere utilizzati nel corpo di un for, while o do-while. break e‘ anche usato negli switch

switch

Lo switch è uno statement condizionale che generalizza lo if-else

switch (condizione)(statement);

lo statement è generalmente composito e consiste di diversi case e, opzionalmente, di un default

switch (n) {case 0:

printf(“ n e` nullo\n”); break;case 1: case 3: case 5: case 7: case 9:

printf(“ n e` dispari\n”); break;case 2: case 4: case 6: case 8: case 10:

printf(“ n e` pari\n”); break;default:

printf“ n non e` compreso tra 0 e 10\n”);}

L’operatore ?

L’operatore ? e‘ l’unico esempio di operatore ternario in C.

expr1 ? expr2 : expr3;

Equivale a:

if(expr1) expr2;else expr3;

Viene cioè valutata l’espressione 1 se è vera viene valutata l’espressione 2 che diverrà il valore dell’espressione. Se invece l’espressione 1 è falsa viene valutata l’espressione 3 ed il suo valore diviene il valore dell’espressione.Consideriamo l’esempio seguente:

CORSO DI INFORMATICA PER LA FISICA28

Page 28: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

29

double max(double a, double b){

return max = (a>b) ? a : b;}

La funzione max ritorna a come massimo se a>b, altrimenti b.

Array

Un array (monodimensionale)è un elenco di informazioni dello stesso tipo conservate in locazioni di memoria contigue, secondo un ordine preciso.Esso è formato da una serie di variabili dello stesso tipo cui si fa riferimento utilizzando un nome comune. Per accedere ad un determinato elemento si utilizza un indice. In C tutti gli array sono memorizzati in locazioni di memoria contigue. L’indirizzo più basso corrisponde al primo elemento, quello più alto all’ultimo. Gli array non sono necessariamente monodimensionali. Il tipo più comune è la stringa che termina con il carattere nullo. In C sono supportati gli array di dimensione fissa.La forma generale di una dichiarazione di un array monodimensionale è la seguente:

tipo nome_var[dim];

Come ogni altra variabile un array deve essere dichiarato esplicitamente in modo che il compilatore possa allocare lo spazio di memoria richiesto da tale array. Qui ‘tipo’ dichiara il tipo base dell’array, cioè di ogni elemento , ‘dim’ indica il numero degli elementi che l’array deve contenere. Per dichiarare un array di 100 elementi di tipo double chiamato bilance occorre scrivere :

double balance[100];

Per accedere ad un elemento si associa un indice al nome dell’array:

balance[3]=121.121;

In C tutti gli array iniziano dall’indice 0. Quindi quando si scrive

char p[10];

si sta dichiarando un array di caratteri formato da 10 elementi da p[0] a p[9].In C non esiste nessuna verifica di superamento dei limiti degli array. Quindi significa che, se non si pone abbastanza attenzione si può finire per scrivere in un’ altra variabile o nel codice del programma stesso senza che venga segnalato!

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 29

Page 29: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

30

int main(){ int x[10]; int i,j; double m[5][5]; for ( i = 0; i < 10, i++ ) x[i] = 0;

for ( i = 0; i < 5; i++ ) for ( j = 0; j < 5; j++ ) m[i][j] = i * j; return 0;}

Inizializzazione:

int x[] = { 1, 2, 3, 4 };

char[] t = { ‘C’, ‘i’, ‘a’, ‘o’, ‘\0’ };

char[] s = “Ciao”;

int m[2][3] = { {11, 12, 13}, {21, 22, 23} };

L’indice va da 0 a n-1. Usare un indice maggiore di n-1 può causare un crash.La moltiplicazione fra matrici è indicata nell’esempio sottostante:

main() { int DIM=3; int i,j,k; float sum=0; float m[DIM][DIM], m1[DIM][DIM], m2[DIM][DIM]; // Assumiamo che m1 ed m2 vengano riempiti qui... // Moltiplicazione: for (i=0; i<DIM; i++) { for (j=0; j<DIM; j++) { for (k=0; k<DIM; k++) sum += m1[i][k] * m2[k][j]; m[i][j] = sum; } }}

Puntatori

Un puntatore è l’indirizzo di memoria di un oggetto. Una variabile puntatore è una variabile dichiarata in modo specifico per contenere un puntatore ad un oggetto di un determinato tipo.

CORSO DI INFORMATICA PER LA FISICA30

Page 30: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

31

In C i puntatori possono essere un metodo pratico e rapido per far riferimento agli elementi di un array. Essi consentono alle funzioni C di modificare i parametri di chiamata e la creazione di liste concatenate e di altre strutture di dati dinamiche.I due operatori usati per manipolare i puntatori sono ‘&’ e ‘ *’.

&

è un operatore unario che restituisce l’indirizzo di memoria del proprio operando. Un operatore unario ha un solo operando :

m= &count;

inserisce nella variabile m l’indirizzo di memoria in cui si trova la variabile count.Questo indirizzo corrisponde alla posizione fisica della variabile nella memoria. Quindi quando si vede l’operatore & si può pensare di leggerlo come “indirizzo di “.Se ad esempio la variabile count si trova all’indirizzo di memoria 200 e contiene il valore 100 dopo l’applicazione di questo operatore in m si trova il valore 200.

*

questo operatore, dato l’esempio precedente,

q= *m;

inserisce il valore di count in q. Quindi all’indirizzo di memoria 200 si trova il valore 100.Si può pensare di leggerlo come “ il contenuto all’indirizzo”.Quindi nell’istruzione precedente q riceve il valore che si trova all’indirizzo di m.Le variabili che devono contenere indirizzi di memoria (ad esempio i puntatori) devono essere dichiarate inserendo un * davanti al nome della variabile. Ad esempio per dichiarare ch come puntatore ad un carattere si usa:

char *ch;

In questo caso ch non è un carattere ma un puntatore ad un carattere. Il tipo di dati puntati dal puntatore (in questo caso char) è detto tipo base del puntatore. Ma anche un puntatore è una variabile che contiene l’indirizzo del proprio tipo base, per cui ha le dimensioni sufficienti a contenere un indirizzo, che variano a seconda dell’architettura del computer utilizzato. Un puntatore può puntare solo a dati corrispondenti al proprio tipo base, con riferimento ad una locazione di memoria.Quindi un codice come il seguente:

#include <stdio.h>int main(){

int j = 12;int *ptr = &j;

printf(“ %i\n “, *ptr) ;j = 24;printf(“ %i\n “, *ptr) ;printf(“ %p\n “, ptr) ;return 0;

}

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 31

Page 31: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

32

produce sul terminale il seguente risultato:

12240x7b03a928 /* indirizzo di memoria */

Puntatore nullo

include <stdio.h>int main(){ int j = 12; int *ptr = NULL;

printf(“%i\n”,*ptr); /* crash ! */ /* non punta a niente: il suo contenuto non c’e’ */ return 0;}

Provoca segmentation violation (core dumped)

Puntatori e array

In C gli array sono trattati come puntatori

main(){ float x[5]; int j; for (j = 0; j < 5; j++) x[j] = 0; /* inizializzazione a 0 */ /* il nome del vettore e’ il puntatore al suo primo elemento */ float *ptr = x; *ptr = 1.5; /* x[0] = 1.5 */ *(ptr+1) = 2.5; /* x[1] = 2.5 */ *(ptr+3) = 3.5; /* x[3] = 3.5 */}

Quindi in questo esempio scrivere x+1 significa puntare all’elemento x[1] che contiene 2.5 mentre scrivere x+3 significa indicare il valore 3.5.

x[0] x[1] x[2] x[3] x[4]

1.5 2.5 0.0 3.5 0.0

x x+1 x+3

Quando si definisce un’ array yy[10] so che posso usare yy per puntare a yy[0].

CORSO DI INFORMATICA PER LA FISICA32

Page 32: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

33

Puntatori: allocazione dinamica

#include <stdio.h>int main(){ int *ptr=(int *)malloc(sizeof(int)); *ptr = 12; printf(“%i\n”,*ptr);

free(ptr); return 0;}

Si tratta di un riferimento ad una locazione di memoria. Q.uando si vuole rilasciare dello spazio in memoria si usa il comando free.Non usare free fa accumulare locazioni di memoria inutilizzate (memory leak)Utilizzare puntatori prima del malloc o dopo il free che puntano a zone di memoria allocalte da malloc o liberate da freecausa il crash del programmaL’allocazione dinamica è il modo con cui un programma può ottenere memoria durante l’esecuzione. Lo spazio di memoria delle variabili globali viene infatti assegnato in fase di compilazione.Le variabili locali utilizzano invece un’area di memoria denominata stack. Durante l’esecuzione del programma non è più possibile aggiungere variabili locali o globali. Esistono casi in cui la memoria di un programma non può essere determinata prima della sua esecuzione: ad esempio un word processor o un database dovranno poter utilizzare tutta la RAM disponibile nel sistema ( che varia da computer a computer). Quindi questi ed altri programmi dovranno poter allocare memoria su richiesta.

►►Il linguaggio C++ conserva il modo di allocare memoria del C e ne aggiunge un altro proprio più esteso.

La memoria allocata dinamicamente nel C è ottenuta dallo heap, che è la regione di memoria libera tra cui si trova il programma ( e la sua area di memoria permanente) e lo stack. Anche se le dimensioni dello heap non sono note si può pensare che esso contenga una grande area disponibile. Quindi il prototipo della funzione malloc() è il seguente:

void *malloc(size_t numero_di_byte);

La funzione restituisce un puntatore di tipo void, size_t è definito nello stdlib.h come un intero unsigned e numero_di_byte è il numero di bytes da allocare alla memoria.Se la memoria non è in grado di soddisfare le richieste di allocazione essa ritorna un puntatore nullo.L’esempio seguente mostra l’uso dei puntatori in riferimento a più locazioni di memoria:

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 33

Page 33: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

34

#include <stdio.h>int main(){ int *ptr = (int *)malloc(3*sizeof(int)); ptr[0] = 10; ptr[1] = 11; ptr[2] = 12

free(ptr); return 0;}

ptr punta alla locazione di memoria che contiene il numero 10 a cui sono contigue quella che contiene l’11 e il 12.

Regole di conversione e cast

In C esistono conversioni esplicite ed implicite di tipo. Le conversioni implicite (e.g. intfloat) nelle espressioni aritmetiche, nel passare i parametri ad una funzione o nel ritornare un valore da una funzione rendono il meccanismo di conversione molto conveniente ma anche potenzialmente pericoloso (errori a run time)

Conversioni implicite

•Char e short vengono promossi ad int•Tipi interi che non possono essere rappresentati con un int vengono promossi a unsigned•In una espressione di tipo misto, gli operandi di ordine inferiore vengono promossi all’ordine superiore secondo la gerarchia:int<unsigned<long<unsigned long<float<double<long double

Le conversioni esplicite sono lasciate all’utente (e sono spesso necessarie)

int *ptr= (int *) malloc(sizeof(int));

malloc ritorna void *.

Funzioni

In C le funzioni sono caratterizzate da un nome, dal tipo della variabile ritornata e da una lista di parametri (opzionali)

double max( double a, double b) {

return (a>b) ? a : b;}

CORSO DI INFORMATICA PER LA FISICA34

Page 34: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

35

La lista dei parametri (anche se vuota) deve essere esplicitata (quindi si indica con una parentesi aperta e chiusa).Il valore ritornato deve essere compatibile, a meno di conversione esplicita, con il tipo della funzione.Se non si specifica il tipo ritornato, la funzione ritornerà int.Nell’esempio citato il tipo ritornato dalla funzione è “double”, i parametri della funzione sono a e b, il corpo della funzione sta entro le due parentesi graffe e il valore di ritorno è indicato nell’espressione di return. Si ritorna il cubo di x.

double cube(double x) { return x*x*x; } procedura “by value”void pr_square(int i) subroutine, non si {printf(“%i”,i*i);} usa return senza argomentivoid hello () { printf(“Hello”); } void hello(void) int scanf(const char, …)

scanf e’ una variabile chiamata con un qualsiasi numero di argomenti.

Prototipi delle funzioni

Prima di essere usata, una funzione deve essere dichiarata (nel file che la usa)

main.cc

#include <stdio.h>double max(double, double); /* !!! il ; e’ un prototipo */int main(){

double m = max(1, 3);printf(“Il massimo e` %i\n“,m);return 0;

}

La linea nel main:

double max(double, double); è il prototipo della funzione, normalmente in max.h.

double max (double a, double b){

return (a>b) ? a : b;}

I prototipi rendono le funzioni in C “type safe”, nel senso che i valori reali degli argomenti vengono all’occorrenza convertiti nei tipi formali specificati dal prototipo

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 35

Page 35: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

36

Call-by-Value

Gli argomenti di una funzione vengono normalmente passati “by value” (ne viene creata una copia locale alla funzione). Una funzione con argomenti “by value” non può modificare i suoi argomenti.

main.c

#include <stdio.h>void swap(int a, int b){

int temp;temp=a; a=b; b=temp;

}main(){

int i=10,j=20;swap(i,j); /* i e j conservano

i loro valori iniziali */

}

swap non puo’ uscire dalla sua “localita’” . Occorrera’ usare i puntatori con cui si punta a variabili “fuori”.

#include <stdio.h>int sqr(int x);int main (void){

int t=10;printf(“%d %d”, sqr(t),t);

return 0;}int sqr(int x){

x=x*x;return(x);}

Qui il valore dell’argomento di sqr(), 10, viene copiato nel parametro x. Quando viene eseguito l’assegnamento x=x*x solo la variabile locale x viene modificata. La variabile t usata per richiamare sqrt() continuerà a contenere il valore 10. L’output sarà 100 10. Alla funzione viene passata solo una copia del valore dell’argomento.Ciò che avviene all’interno della funzione non ha alcun effetto sulla variabile utilizzata nella chiamata.

Call-by-Reference

L’uso di puntatori permette ad una funzione di modificare il valore dei suoi argomentiPer ragioni di efficienza, oggetti di grandi dimensioni (in termini di memoria) vengono normalmente passati “by reference”. Gli arrays sono sempre passati “by reference” e possono quindi sempre essere modificati.In C/C++ è possibile una chiamata per indirizzo passando quindi alla funzione un puntatore ad un argomento al posto dell’argomento stesso. Poiché alla funzione viene

CORSO DI INFORMATICA PER LA FISICA36

Page 36: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

37

passato l’indirizzo dell’argomento il codice che si trova all’interno della funzione può modificare il valore dell’argomento che si trova all’esterno della funzione stessa.La funzione swap() scambia i valori delle due variabili intere puntate dai suoi argomenti. Il relativo programma di test si può presentare così:

main.c void swap(int *x,int *y){

int temp;temp=*x; /* salva il valore all’ indirizzo x */

*x=*y; /* copia y in x */*y=temp; /* copia x in y */}int main(void){

int i=10,j=20;swap(&i,&j); /* passa gli indirizzi di i e j */printf(“%d %d”,i,j);

}

swap scambia i valori delle due variabili puntate da x e da y perché le vengono passati gli indirizzi delle variabili e non i valori. Quindi all’interno della funzione è possibile accedere al contenuto delle variabili utilizzando le operazioni sui puntatori. Questo è il motivo per cui è possibile scambiare il contenuto delle variabili utilizzate per chiamare la funzione. Nell’esempio alla variabile i viene assegnato il valore 10 e a j il valore 20. Quindi viene chiamata swap con gli indirizzi di i e j (con l’operatore unario &). Allora alla funzione swap vengono passati gli indirizzi di i e j e non i rispettivi valori. Avviene lo scambio di indirizzi. Quindi la stampa equivalente sarà 20 10. (nell’esempio precedente relativo alla chiamata “by value” la stessa stampa porterà a 10 20).

Funzioni esterne

Si possono chiamare funzioni FORTRAN da C:

SUBROUTINE HBOOK1(ID, TITLE, NBIN, MIN, MAX, OPT)SUBROUTINE HFILL(ID,X, Y, WEIGHT)

extern “C” void hbook1_(int&, char*, int&, float&, float&, float&, int); extern “C” void hfill_(int&, float&, float&, float&);... hbook1_(100, title, ……) // BUS ERROR!!! (il FORTRAN passa // sempre “by-reference”int id=100;hbook1_(id, title, ……) // OK!

struct

Il linguaggio C offre una (limitata) possibilità di definire nuovi “tipi” (tipi derivati) per mezzo del concetto di struct. Una struttura è un raggruppamento di variabili sotto un unico nome che è chiamato tipo di dati aggregato o conglomerato. L’utilizzo di struct consente l’implemen- tazione di strutture dati abbastanza complesse ed uno stile di programmazione più “generico”.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 37

Page 37: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

38

persona.h

struct persona {char nome[20];char cognome[20];int eta;char professione[20];struct persona *coniuge; /*uso una struct di tipo

persona*/struct persona *figli[5];

};

persona è l’identificatore del tipo,all’interno delle parentesi graffe c’e’ la struttura del tipo e il tutto si chiude sul “;” finale. Il nome identifica la struttura e diventa quindi lo specificatore di tipo. Si ricorda che nell’esempio precedente si usa struct all’interno di una struct.

main.c

#include “persona.h”#include <stdio.h>main() {

struct persona john={ {“John”},{“Doe”},40,{“Medico”} };struct persona mary={ {“Mary”},{“Doe”},37,{“Giornalista”} };john.coniuge=&mary;mary.coniuge=&john;printf(“La moglie di John e’ %s\n”,john.coniuge->nome);

}

L’inizializzazione della struct avviene attraverso l’uso delle parentesi graffe come indicato nell’esempio soprastante. Nota: il puntatore john.coniuge e’ proprio l’indirizzo della struttura mary.In C per dichiarare una variabile di tipo addr, ad esempio occorre utilizzare la seguente istruzione:

struct addr addr_info;

Qui viene dichiarata una variabile di tipo struct addr e chiamata addr_info.

►►Il linguaggio C++ supporta una definizione abbreviata: addr addr_info;

Infatti in C il solo nome della struttura non identifica un tipo: il nome di una struttura è un tag.

struct addrchar name30;char street40;char city20;char state3;unsigned long int zip;

addr_info,b_info,c_info;

Qui si definisce un tipo di struttura chiamata addr e si dichiarano le variabili addr_info, b_info,c_info.

CORSO DI INFORMATICA PER LA FISICA38

Page 38: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

39

►►In C++ il nome della struttura è già un nome di tipo completo e quindi può essere utilizzato per definire variabili, anche se la dichiarazione del C può essere utilizzata anche per un programma C++. Una volta dichiarata una variabile del tipo della struttura il compilatore alloca automaticamente una quantità di memoria sufficiente per contenere tutti i membri della struttura.

Accesso ai membri delle strutture

Per accedere ai membri si utilizza l’operatore “.”, l’ operatore punto.Ad esempio:

addr_info.zip=12345;

assegna il valore 12345 al campo zip della variabile addr_info. Per accedere ai singoli membri di una struttura si utilizza quindi il nome della variabile definita del tipo della struttura seguito da un punto e dal nome del membro.Quindi per stampare il nome del membro sullo schermo si userà la seguente linea:

printf(“%d”, addr_info.zip);

L’array di caratteri addr_info.name può essere utilizzato nel modo seguente:

gets(addr_info.name);

Qui si passa un puntatore al carattere iniziale di name. Dato che name è un’array di caratteri si può accedere direttamente ai singoli caratteri di addr_info.name indicizzando name.

Passaggio dei membri di una struct a una funzione

La funzione riceve il valore del membro. Esempi: data la struttura:

struct fred

char x;int y;float z ;char s 50;

mike;

Ecco alcuni esempi di passaggio a una funzione dei membri di una struttura:

func(mike.x); /*passa il valore del carattere di x*/func(mike.y); /*passa il valore dell’ intero di y*/func(mike.z); /*passa il valore del float di z*/func(mike.s); /*passa l’indirizzo della stringa s*/func(mike.s2)); /*passa il valore del carattere s2*/

Se invece si desidera passare l’ indirizzo basta inserire l’operatore & prima del nome della struttura:

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 39

Page 39: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

40

func(&mike.x); /*passa l’indirizzo del carattere di x*/func(&mike.x); /*passa l’indirizzo dell’ intero di y*/func(&mike.x); /*passa l’indirizzo del float di z */func(mike.x); /*passa l’indirizzo della stringa s */func(&mike.x); /*passa l’indirizzo del carattere s2*/

Passaggio di una intera struttura ad una funzione

Se una struttura è usata come argomento di una funzione essa viene passata utilizzando il metodo standard della chiamata per valore. Quindi ogni modifica che la funzione apporta al contenuto della struttura non modifica la struttura utilizzata come argomento.

Puntatori a strutture

In C è possibile utilizzare un puntatore ad una struttura come si usa un puntatore normale.

Dichiarazione di un puntatore ad una struttura

La dichiarazione di un puntatore ad una struttura è del tipo seguente:

struct addr *addr_pointer;

►►In C++ il nome della struttura è pleonastico, quindi viene normalmente omesso.

Uso dei puntatori a struttura

E’ possibile il passaggio di una struttura ad una funzione tramite una chiamata per indirizzo. Dato l’esempio precedente ed iniziale main.c, scrivere:

john.coniuge =&mary;

significa inserire nel puntatore john.coniuge l’indirizzo della struttura mary.

L’operatore ->

Per accedere ai membri di una struttura utilizzando un puntatore a tale struttura si usa l’operatore -> (operatore freccia). Esso viene utilizzato al posto dell’operatore punto (.) quando si accede ad un membro di una struttura tramite un puntatore alla struttura stessa.Nell’esempio iniziale:

struct persona john={ {“John”},{“Doe”},40,{“Medico”} };struct persona mary={ {“Mary”},{“Doe”},37,{“Giornalista”} };john.coniuge=&mary;mary.coniuge=&john;printf(“La moglie di John e’ %s\n”,john.coniuge->nome);

Si accede al nome, membro della struttura, tramite il puntatore alla struttura stessa.In generale i tipi derivati non si comportano come i tipi predefiniti.

CORSO DI INFORMATICA PER LA FISICA40

Page 40: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

41

struct complesso { double reale; double immaginario; };main() {

int i=3,j=4;int k = i+j;

struct complesso x=(3.5,6.) , y=(1.3,4.8);struct complesso r = x*y;double modulo= sqrt(x.reale*x.reale+

x.immaginario*x.immaginario);}

Le caratteristiche “derivate” del tipo “complesso” sono implementate nel programma che lo utilizza. Nell’esempio precedente è da notare che l’aritmetica dei tipi derivati non viene riconosciuta.Le caratteristiche “derivate” del tipo “complesso” sono implementate nel programma che lo utilizza. Nel linguaggio C struct fornisce uno strumento per l’implementazione di strutture dati complesse (liste, alberi, vettori) per la manipolazione e lo stoccaggio dei dati e la possibilità (embrionale) di definire nuovi tipi (tipi derivati).I tipi derivati in C non si comportano come i tipi predefiniti e mancano di funzionalità. In particolare non e’ definita un’algebra dei tipi derivati (operatori)La manipolazione di una struct (accesso ai dati, struttura dei dati) e’ lasciata al programma che la utilizza.

►►Il C++ ripartira’ dal concetto di struct per l’introduzione di una nuova entità, la classe (class), con funzionalità e capacità ben più estese.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 41

Page 41: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

42

C++ come C “migliorato”

L’evoluzione del linguaggio C è il linguaggio C++: una prova che esso lo sia sta persino nel fatto che il C++ alla sua nascita fu chiamato “C con classi”.Perché la nascita di un nuovo linguaggio? Essenzialmente per superare i limiti del C nella trattazione di programmi estesi e complessi (~100000 linee). La terza standardizzazione (fine degli anni 90) lo ha portato alla versione attuale. Ulteriore miglioramento essenziale si è avuto dopo l’ introduzione della STL (Standard Template Library, di cui si parlerà più avanti estesamente) che è costituita da una serie di routine generiche per la manipolazione dei dati che offre soluzioni brillanti ed evolute al programmatore per la soluzione di numerosi problemi.In generale è stata la programmazione ad oggetti (OO da Object Oriented) che ha portato alla nascita del C++. Essa rappresenta un nuovo e potente metodo di programmazione. Infatti a partire dai linguaggi strutturati (tipici degli anni 70) come il C e il Pascal la richiesta di programmi sempre più complessi ha portato alla coscienza della incontrollabilità degli stessi al di sopra di una soglia di dimensioni fisiche. Creare la programmazione a oggetti ha significato capovolgere le tecniche di programmazione precedenti, tipiche di linguaggi strutturati (come il C) in cui un programma è definito dalle sue funzioni che operano sui dati. Nella programmazione OO i programmi sono organizzati attorno a i dati e si basano sul fatto che sono i dati a controllare l’accesso al codice. In un linguaggio ad oggetti si definiscono i dati e le routine che sono autorizzate ad agire su tali dati: quindi sono i dati a stabilire quali operazioni possono essere eseguite. I linguaggi che consentono di applicare i principi della programmazione ad oggetti posseggono tre fattori in comune: l’incapsulamento, il polimorfismo e l’ereditarietà. Ma di questo si tratterà più avanti.Per ora , dopo aver introdotto il C come sottoinsieme del C++, passiamo ad un’ analisi delle differenze o delle migliorie del linguaggio C++ rispetto al C.Prima di trattare l’argomento dei costrutti ad oggetti del linguaggio C++ si passano in rassegna i tratti che caratterizzano il C++ rispetto al C: i principali risiedono nel modo di eseguire operazioni di I/O, nel modo di inclusione dei file header.(le trasparenze relative al seguente capitolo del corso sono state scritte in powerpoint e si trovano all’ indirizzo riportato nell’ introduzione con click da: dal C al C++.)

main program

Il più semplice programma in C++ha la seguente struttura:

#include <iostream>using namespace std;int main()

int I;cout<<”Stringa di output.\n”; //commento su una sola riga/*si puo’ utilizzare anche il commento in stile C*/

//input di un numero con l’operatore <<cout<<”Immettere un numero:”;cin>>i;//output di un numero con l’operatore <<cout<<i<<”al quadrato = “<<i*i<<”\n”;return 0;

Page 42: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

43

Ogni programma in C++, per essere eseguibile, deve contenere una funzione main() da cui l’esecuzione comincerà.main() deve avere un tipo (decidere quale è compito del programmatore). Regola generale è che main() ritorni un intero, a significare il return code dell’applicazione.In questo programma sono sintetizzate le caratteristiche principali: lo header <iostream> è incluso come direttiva al preprocessore per consentire di eseguire operazioni di I/O (come stdio.h in C).

using namespace std; indica al compilatore di utilizzare il namespace std. Il namespace, come si vedrà in seguito, crea una regione di dichiarazione nel programma in cui possono essere inseriti vari elementi. Questo è il namespace in cui è dichiarata tutta la libreria standard C++. Allora utilizzando questo namespace si semplifica l’accesso alla libreria standard.

int main()

main è una funzione senza parametri. Diversamente dal C dove l’assenza di parametri si dichiara con void, qui si può omettere.

Parametri del programma

Talvolta può essere utile passare informazioni a un programma al momento dell’esecuzione.Dotando main() di una lista di argomenti, è possibile avere accesso ai parametri passati dalla command line.

#include <iostream.h>int main(int argc, char *argv[]){

cout<<“ argc e`: “<<argc<<endl;cout<<“ il nome dell’eseguibile e` “<<*argv<<endl;for (int i=1; i<argc; i++)

cout<<“Argomento #”<<i<<“ = “<<*(argv+i)<<endl;return 0;

}

argc è il numero di parametri passati dalla command line (sempre almeno =1, cioè il primo parametro è il nome del programma), esso è un intero che contiene il numero degli argomenti passati dalla riga di comando, mentre il vettore di stringhe argv contiene ogni singolo parametro cioè è un puntatore ad un array di puntatori a caratteri. Tutti gli argomenti della riga di comando sono quindi stringhe e i numeri dovranno essere convertiti nel formato interno corretto.Lanciato con il comando:

prompt> mytest questo e un test

il programma produrrà il seguente output:

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 43

Page 43: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

44

argc e‘ : 5il nome dell’eseguibile e‘/user/andrea/myprogramArgomento #1 = questo Argomento #2 = eArgomento #3 = unArgomento #4 = test

Organizzazione dei files

Normalmente, le dichiarazioni delle interfacce e le specifiche sono separate dall’implementazione (files separati). Esistono dei files speciali chiamati header files (con estenzione .h oppure .hh) che vengono inclusi nei file sorgente utilizzando direttive del precompilatore, la sintassi e’ riportata nell’esempio sottostante:.

#include <iostream.h>

essi non contengono codice eseguibile (con l’eccezione delle definizioni delle funzioni inline) e non devono essere inclusi più di una volta, per evitare problemi con il linker.

#ifndef MyHeader_H#define MyHeader_H// dichiarazioni…..#endif

I files sorgente ( che hanno normalmente estensione .c,.cxx,.cpp,.cc) contengono invece l’implementazione di funzioni e metodi , codice eseguibile ed includono gli header files utilizzando le direttive del preprocessore. Essi vengono compilati. Le funzioni inline (con estensione .icc) sono tali per cui devono essere visibili là dove vengono usate. Normalmente implementate negli header files o in files separati (con estensione .icc) che devono essere inclusi nel files sorgente che ne facciano uso.

Stringhe

Lo ANSI/C++ introduce un nuovo tipo di stringhe che rimpiazzano effettivamente le “vecchie” stringhe C (chiamate stringhe di tipo char* o const char*).Le stringhe della libreria standard sono viste come tipi e quindi si possono copiare, assegnare, paragonare senza preoccuparsi della memoria allocataLe operazioni concesse con le stringhe sono riassunte nella seguente tabella:

=,assignswap+=, append(),push_back()insert()erase()clear()resize()replace()+==,!=,<,<=,>,>=,compare()size(), length()

Assegna un nuovo valoreSwap dei valori tra due stringheAppende caratteriInserisce caratteriCancella caratteriRimuove i caratteri (la svuota)Cambia il # di caratteri (cancella o appende)Sostituisce caratteriConcatena stringheParagona stringheRitorna il numero dei caratteriRitorna il massimo num di caratteriRitorna se la stringa e’ vuotaRitorna il numero di caratteri possibili da

CORSO DI INFORMATICA PER LA FISICA 44

Page 44: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

45

max_size()empty()capacity()reserve()[],at()>>,getline()<<copy()c_str()data()substr()begin(), end()rbegin(), rend()find functions

all.Riserva memoria per un certo num. di caratt.Accede ad un carattereLegge il valore da uno streamScrive il valore su uno streamCopia o scrive I valori in una c_stringRitorna il valore come c_stringRitorna il valore come array di caratteriRitorna una certa sottostringaProvide normal iterator supportProvide reverse iterator supportCerca per una sottostringa o carattere

Anche se da questa lista sembrerebbe che tutte le operazioni siano possibili con le stringhe rimangono impossibili da eseguire le seguenti operazioni che non hanno soluzione diretta: espressioni regolari, text processing, oppure ad esempio un paragone tra stringhe del tipo “case insensitive”.

Size e capacity

Per usare correttamente le stringhe occorre conoscerne il comportamento in modo corretto; ad esempio analizziamo le funzioni size() e length(). Esse sono equivalenti: ritornano il numero di caratteri di una stringa.Il metodo empty()rappresenta un modo per verificare se il numero di caratteri è = 0 ed è più veloce dei precedenti due metodi.max_size() ritorna il massimo numero di caratteri che una stringa può contenere. riserve() riserva in memoria un numero di caratteri uguale a n:

std::string s; // crea una stringa vuotas.reserve(80); // riserva memoria per 80 caratteri

Accesso agli elementi di una stringa

Una stringa consente di avere accesso read-write agli elementi (caratteri) che la compongono. Il singolo carattere può essere acceduto in due modi diversi:

tramite l’operatore [ ] in questo modo non viene fatto il controllo se l’indice passato come argomento è valido o meno. Si possono quindi voler accedere elementi che sono furi dall’area in cui risiede l’informazione voluta.

tramite il metodo at()in questo caso il controllo viene effettuato. Entrambi ritornano il carattere alla posizione indicata dall’indice passato. Il primo carattere ha indice 0, mentre l’ultimo ha indice length()-1 . Nell’esempio seguente si può controllare l’ esito dell’uso dei due diversi approcci:

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 45

Page 45: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

46

const std::string cs (“nico”); // cs contiene ‘n’ ‘i’ ‘c’ ‘o’ std::string s(“abcde”); // s contiene ‘a’ ‘b’ ‘c’ ‘d’ ’e’ s[2] //vale ‘c’s.at(2) //vale ‘c’s[100] //ERRORE comportamento indefinitos.at(100) //ERRORE comportamento indefinitos[s.length()] //indica out_of_range[s.length()] //ERRORE comportamento indefinitocs[cs.length()] //indica ‘\0’s.at(s.length()) //indica out_of_rangecs.at(cs.length()) //indica out_of_rangechar &r=s[2]; //referenza al terzo caratterechar *p=s[3]; //puntatore al quartor= ‘X’; //OK! Contiene ‘a’ ‘b’ ‘X’ ‘d’ ‘e’

iostream

Gli operatori “<<” e “>>” sono usati per definire la direzione del flusso cin, cout e cerr rappresentano lo standard input, output e error del programma.In C per includere il file di header per le funzioni di I/O si usa

#include <stdio.h> stdio.h è il nome del file utilizzato dalle funzioni di I/O e l’istruzione precedente provoca l’inclusione fisica di tale file nel programma.

#include <iostream> // direttiva al preprocessoreint main(){ std::cout << “Hello, world !” << std::endl; // end-of-line

return 0;}

#include <iostream> è la direttiva al preprocessore, endl fa parte del namespace std (che viene trattato in seguito nel sottocapitolo namespace).La linea precedente di stampa indica che in C++ è possibile utilizzare di seguito più operazioni di output “<<”.L’ultima riga return 0; fa in modo che al processo chiamante sia restituito 0. La restituzione di 0 indica che l’operazione ha avuto successo. Il valore ritornato deve avere il tipo appropriato per quello che si vuole che la funzione ritorni.

std::cout<<”A\tB\tC”;

Produce sullo schermo la scrittura dei caratteri A B e C separati da spazi di tabulazione. Il carattere % davanti al tipo scompare in C++ e l’operatore “<<” e “>> “si prestano ad essere implementati.Analizziamo adesso il significato della seguente linea:

std::cout<<“Hello World!”<<std::endl;

Essa è una espressione. In generale una espressione chiede all’implementazione di calcolare qualcosa:

CORSO DI INFORMATICA PER LA FISICA 46

Page 46: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

47

3+4=7

non ha effetti collaterali particolari.Invece la riga di programmazione precedente scrive Hello World! sullo schermo e termina la linea corrente. L’ operatore “<<” ha due operandi. Ogni operando ha un tipo. Un tipo denota una struttura dati e i significati delle operazioni che hanno senso su di essi.L’operando di sinistra e’ del tipo std::ostream. Invece std::endl;E’ un manipolatore.Scrivere un manipolatore fa compiere qualcosa di diverso che scrivere caratteri in una stream, In questo caso l’azione e’ quella di terminare la linea corrente di output.“: :” e’ detto scope operator.

Manipolatori

Per cambiare i parametri di formattazione di uno stream si usano particolari funzioni, alcune delle quali sono riassunte nella tabella seguente:

manipolatore scopo input/output

boolalpha //attiva il flag boolalpha input/outputdec //attiva il flag dec “endl //output del carattere di fine riga

//svuotamento dello stream outputends //output di un carattere nullo outputfixed //attiva il flag fixed outputflush //svuotamento di uno stream outputhex //attiva il flag hex input/outputinternalleftsetw //imposta l’ampiezza di campo outputsetfill(int ch)//setta il carattere di riempimento output

Per accedere ai manipolatori che fa uso di parametri (come setw) si deve includere nel programma lo header <iomanip>.Quindi l’esempio seguente:

#include <iostream>#include <iomanip>std::cout<<hex<<100<<std::endl;std::cout<<setfill(‘?’)<<setw(10)<<2343.0;return o;

produce il seguente output:

64??????2343

Il vantaggio nell’uso dei manipolatori risiede nel fatto che spesso il codice si fa più compatto.Il manipolatore setioflags() consente di impostare direttamente i vari flag di formattazione relativi ad uno stream.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 47

Page 47: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

48

Uno dei più interessanti manipolatori è boolalpha che consente di introdurre i valori logici come true e false invece che come valori numerici, come nel caso in cui non è settato (cioè il default) . Il valore 0 è quindi sempre usato per false e il valore 1 per true. Quindi quando si legge un valore booleano ed il suo valore è diverso da 0 o da 1 viene emesso un messaggio d’errore.Il manipolatore boolalpha forza la rappresentazione testuale (setta il flag ios::boolalpha, il manipolatore noboolalpha forza la rappresentazione numerica (elimina il flag ios::boolalpha)

fstream

Per leggere/scrivere da/su file si utilizzano le fstream.Se le funzioni fstream(), ifstream(),ofstream() non richiedono parametri esse creano uno stream che non e’ associato ad un fileQuesto stream può essere poi associato ad un file con open().Normalmente le istruzioni più utilizzate sono quelle con il nome del file associato come parametro.

#include <fstream>#include <string>#include <iostream>void main(){

std::ifstream infile;if ( infile.open(“persone.txt”) ){

std::string nome, cognome;int eta;infile>>nome>>cognome>>eta;

}else

std::cout<<“ errore nell’aprire il file!<<std::endl;std::ofstream outfile(“persone.out”) ;outfile<<eta<<“ – “<<nome<<“ – “<<cognome<<std::endl,outfile.close();

}

Se il file di input è persone.txt, del tipo seguente:

John Smith 34Joe Doe 28

Il file di output sarà persone.out:

34 – John - Smith

stringstream

Per leggere/scrivere da/in una stringa si usano le stringstream.L’uso più interessante riguarda il fatto di poter formattare del testo di output in una stringa per poi mandarlo ad un canale di output anche con ritardo. Un altro uso interessante è quello legato alla possibilità di leggere riga per riga e poi processare ogni linea usando stringstreams.

Per leggere da stringhe si usa istringstream Per leggere da o per scrivere su stringhe si usa ostringstream Per leggere/scrivere una stringa si usa stringstream Per leggere/scrivere caratteri di una stringa si usa stringbuf

CORSO DI INFORMATICA PER LA FISICA 48

Page 48: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

49

Una specializzazione di questa parte sarà ritrattata nella parte dedicata alla Standard Template Library. Un esempio ne illustra l’uso:

#include <sstream>#include <string>#include <iostream>using namespace std;int main(){

stringstream s(“Questa è la stringa iniziale”);//legge la stringastring str =s.str();std::cout<<str<<std::endl;//output sulla stringas<<“Numeri: “<<“ “<<10<<“ “<<123.2;int i;double d;s>>str>>I>>d;std::cout<<str<<“ “<<i<<d<<std::endl;return 0;

}

L’output di questo programma è:

Questa è la stringa inizialeNumeri: 10 123.2

commenti

Esistono due tipi di commento in C++, inline e multiline.

const int Ntries; // questo e` un commento inline// il resto della linea e’ trattato come un commentoconst int Ntries; /* questo e` un commento multiline: tutto viene trattato come un commento fino a quando il commento stesso non viene chiuso con uno */

I due tipi possono essere usati indifferentemente, ma si raccomanda di usare l’inline (più semplice e meno ambiguo).

const

La keyword const viene utilizzata per dichiarare un oggetto costante.Alcuni esempi:

const int N=100; N non puo` essere cambiatodouble w[N]; N usato come per dimensionare

un vettoreconst int vect[5]= le componenti di vect non {10,20,30,40,50}; possono essere cambiate

In C le costanti vengono normalmente dichiarate usando il preprocessore.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 49

Page 49: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

50

#define N 100

In questo caso N e` una costante senza tipo ed il preprocessore sostituisce N ovunque lo trovi nel programma, senza rispettare le regole di scope , quindi è da evitare.

Riferimenti

Il C++ fornisce un nuovo sistema (oltre al puntatore) per accedere all’indirizzo di una variabile, il riferimento (reference)

int i=10,j=3; int& a = i;// a è inizializzato all’indirizzo di i// a e’ un indirizzo, int& e’ l’indirizzo di un intero// a può essere utilizzato in luogo di istd::cout<<“ i = “<<a<<std::endl; a=j; // errore! a non è una variabile!

I riferimenti vengono utilizzati come alias alla variabile a cui sono associati.Al momento della dichiarazione, un riferimento deve essere associato alla variabile a cui “riferirà”. Al contrario dei puntatori, i riferimenti non possono essere riassegnati ad altre variabili.a e’ un indirizzo che può essere utilizzato esattamente come si utilizzerebbe una variabile.Lo scopo della referenza e’ proprio quello di riunire le caratteristiche dei puntatori(che, essendo indirizzi, sono parole a 32 bit che danno accesso in maniera complicata all’informazione contenuta in un oggetto) con quelle degli oggetti stessi che hanno accesso immediato alle loro caratteristiche, ma che sono in generale troppo grossi per venire passati, per esempio, come argomenti di una funzione.

const vect <double>& hw //referenza ad un vettore di const doublevector<double> homework;vector<double>& hw = homework; //hw è un sinonimo per homework

Dire che un nome e’ a referenza ad un oggetto significa che il nome è un altro nome per lo stesso oggetto.

Riferiementi e Puntatori

Il puntatore porta sempre l’indicazione del tipo di informazione a cui punta, il compilatore quindi conosce il tipo di informazione puntata e ne controlla le modalità di impiego.Esiste anche il puntatore void (senza tipo) ma prima di utilizzarlo occorre definirne il tipo attraverso una operazione di casting.

p e’ una variabile di tipo puntatorep=&x al puntatore p viene assegnato come valore l’indirizzo della variabile x*p denota la variabile puntata da p, cioè il contenuto di x

Scope

Le variabili possono essere dichiarate e definite quasi ovunque in un programma in C++. La visibilità (scope) di una variabile dipende da dove la variabile è stata dichiarata.

CORSO DI INFORMATICA PER LA FISICA 50

Page 50: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

51

int func(){

…const int n=50; // function scopefor (int i=0;i<100;i++) // i e` locale{

double r; // r e` locale...

}cout<<“n “<< n <<endl; // OKcout<<“i “<< i <<endl; // errore! Ma...cout<<“r “<< r <<endl; // errore!…

}

Attenzione! La stessa variabile può essere ridichiarata (con visibilità diversa). Questo è da evitare (se possibile) per non rendere il programma oscuro e a rischio di errore.

int i; // file (global) scopeint func(){

int i=50; // function scope, nasconde // la i a file scope

for (int i=0;i<100;i++) // block scope. Nasconde // la i a function scope

{int i; // questo e` un errore......

}std::cout<<“i “<< i <<“ “<< ::i <<std::endl;...

}

namespace

Un namespace è una regione di dichiarazioni per un programma nella quale risiedono nomi di variabili, funzioni, ecc.. Lo scopo di un namespace è quello di localizzare i nomi degli identificatori per evitare conflitti.Gli elementi dichiarati in un namespace sono distinti da quelli dichiarati in un altro namespace.Funzioni e variabili definite a global scope sono visibili dappertutto in un programma in C++.Per evitare che funzioni diverse (definite in librerie diverse) con lo stesso nome possano interferire (name clash), il linguaggio C++ implementa il concetto di namespace, che introduce un ulteriore, più alto livello di scope.

namespace mynames{ int i; // la mia dichiarazione di i float max(float, float); // la mia dichiarazione di max}

float mynames::max(float a, float b) // implementazione della{ // funzione max appartenente

return (a>b) ? a : b; // al namespace mynames}

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 51

Page 51: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

52

Per utilizzare variabili e funzioni racchiuse in un namespace si può: accedere all’intero namespace:

using namespace mynames;...float r = max (2.1f, 5.3f);

accedere alla singola variabile o funzione

float r = mynames::max (2.1f, 5.3f);

oppure dichiarare la singola funzione using mynames::max;...float r = max (2.1f, 5.3f);

new e delete

Gli operatori new and delete vengono utilizzati per allocazione/deallocazione di memoria dinamica.

int *i=new int; alloca un intero, ritorna il puntatorechar *c=new char[100]; alloca un array (stringa) di 100

caratteriint *i=new int(99); alloca un intero e lo inizializza a 99char *c=new char(‘c’); alloca un carattere inizializzato a cint *j=new int[n][4]; alloca un array di puntatori ad intero

La memoria dinamica (heap), è un’area di memoria libera provvista dal sistema per quegli oggetti la cui durata di vita è sotto il controllo del programmatore.new riserva la quantità necessaria di memoria richiesta e ritorna l’indirizzo di quest’area.L’operatore delete è usato per restituire una certa area di memoria (allocata con new) allo heap.Ogni oggetto allocato con new deve essere distrutto con delete se non viene piu` utilizzato, altrimenti l’area di memoria che esso occupata non potra` piu` essere ri-allocata (memory leak).L’argomento di delete è tipicamente un puntatore inizializzato preventivamente con new:

delete ptr; distrugge un puntatore ad un oggettodelete p[i]; distrugge l’oggetto p[i]delete [] p; distrugge ogni oggetto di tipo p

la dimensione dello heap non e` infinitaL’ allocazione con new può fallire, nel qual caso new restituisce un puntatore nullo o suscita un’eccezione. Nel caso di allocazione di memoria importante bisogna verificare che l’operazione abbia avuto successo prima di usare il puntatore.Ogni oggetto creato con new deve essere distrutto con delete, ogni oggetto creato con new [] deve essere distrutto con delete []: queste forme NON sono intercambiabili.

CORSO DI INFORMATICA PER LA FISICA 52

Page 52: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

53

Regole di conversione e cast

In C++ esistono conversioni esplicite ed implicite. Le conversioni implicite (e.g. int -> float) nelle espressioni aritmetiche, nel passare i parametri ad una funzione o nel ritornare un valore da una funzione rendono il meccanismo di conversione molto conveniente, ma anche potenzialmente pericoloso (errori a run time).Valgono le seguenti regole di conversione:

char, short e bool vengono promossi ad int Tipi interi che non possono essere rappresentati con un int vengono promossi a unsigned In una espressione di tipo misto, gli operandi di ordine inferiore vengono promossi all’ordine

superiore secondo la gerarchia:

int<unsigned<long<unsigned long<float<double<long double

bool e` un tipo intero, con true che viene promosso a 1 e false a 0Ogni genere di puntatore può essere convertito in un puntatore generico a void.Al contrario di quanto avviene in C, un puntatore generico non è compatibile con un puntatore di tipo arbitrario, ma richiede un cast esplicito:

static_cast <T*> (p);

char *ch;void *generic_p;. . .generic_p=ch; // OK, char* va in void*ch=generic_p; // OK in C, illegale in C++ch=(char *)generic_p; // OK, C e C++ arcaico

Ogni puntatore puo` essere inizializzato a 0 senza bisogno di un cast esplicito. In C++ occorre usare 0 e non NULL per i puntatori.

Casting in ANSI C++

Data la complessità delle operazioni di casting in C++ nuovi operatori di casting sono stati aggiunti a quelli già esistenti in C.

x=(float) i; cast in C++ - notazione Cx=float(i); cast in C++, notazione funzionalex=static_cast<float>(i); ANSI C++ - raccomandatoi=reinterpret_cast<int>(&x) ANSI C++, non portabile e system

dependentfunc(const_cast<int>(c_var))dove C_var e` una variabile dichiarata const.

Usato per eliminare la “const-ness” per chiamare func

Esiste anche un dynamic_cast, utilizzato per riconoscere il tipo di un oggetto a run-time (RTTI).

Funzioni

La forma generale di una funzione è la seguente:

tipo_restituito nome_funzione (elenco parametri)

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 53

Page 53: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

54

Il tipo_restituito specifica il tipo di dati restituito dalla funzione. Una funzione può restituire un qualsiasi tipo di dati tranne un array. L’ elenco_parametri è un elenco di nomi di variabili separati da virgole e seguiti dai rispettivi tipi che ricevono i valori degli argomenti quando la funzione viene chiamata. Una funzione può anche non aver parametri, in questo caso il campo dei parametri rimane (anche se vuoto) e le parentesi sono necessarie. Nella dichiarazione delle variabili si può dichiarare più variabili dello stesso tipo utilizzando un elenco di nomi di variabili separati da virgole, ma nella dichiarazione dei parametri di una funzione occorre dichiarare esplicitamente il tipo di ogni parametro insieme al nome.

Funzioni inline

La keyword inline suggerisce al compilatore che ogni chiamata alla funzione deve essere convertita in codice eseguibile (la definizione della funzione viene sostituita alla chiamata dovunque nel codice). Le funzioni inline vengono usate per ragioni di efficienza e (per non sovraccaricare il compilatore) devono essere semplici.Il compilatore può decidere autonomamente (per esempio se la funzione è troppo lunga) di ignorare la direttiva inline.

Argomenti di default

Ad ogni parametro di una funzione può essere assegnato un valore di default. Questo permette di chiamare la funzione tralasciando quei parametri il cui valore di default risulta appropriato:

main.cc

int pow(int , int);int main(){

int r=3;int a1=pow(3,3); // a1=27int a2=pow(3); // a2=9return 0;

}

pow.cc

int pow (int a, int k=2){

if (k==2) return a*a;else return a*pow(a, k-1);

}

Solo ai parametri più a destra nella calling sequence può essere dato un default. Nell’esempio precedente l’argomento di default è int k=2;

Call by reference

L’uso di riferimenti permette ad una funzione di modificare il valore dei suoi argomenti senza usare dei puntatori

CORSO DI INFORMATICA PER LA FISICA 54

Page 54: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

55

void swap(int& a, int& b){

int temp;temp=a; a=b; b=temp;

}main(){

int i=10,j=20;swap(i,j); // la funzione lavora sugli

// indirizzi di i e j}

I riferimenti sono normalmente utilizzati per passare l’indirizzo di una variabile ad una funzione.Se la funzione non deve potere modificare un argomento passato per riferimento, si deve dichiarare l’argomento stesso const..

Overloading

Funzioni diverse possono avere lo stesso nome. La funzione che viene chiamata è scelta dal compilatore in base al tipo di ritorno ed al numero e tipo degli argomenti.

average_array.cc

double average_array(const int a[], int size){

int sum=0;for (int i=0;i<size;i++) sum+=a[i];return double(sum)/size;

} double average_array(const double a[], int size){

double sum=0;for (int i=0;i<size;i++) sum+=a[i];return sum/size;

}

Function signature

La lista dei tipi degli argomenti di una funzione è chiamata signature.Il tipo ritornato dalla funzione non fa parte della signature, mentre il numero e l’ordine degli argomenti è cruciale

void print(int i=0) {. . .} // (1)void print(int i, double x) {. . .} // (2)void print(double y, int i) {. . .} // (3). . .print(‘A’); // ‘A’ e` convertito a int, chiama (1)print(str[]); // errore! Non e` possibile una conversioneprint(15,9); // errore! Ambiguita` fra (2) e (3)print(15,9.); // OK, chiama (2)print(); // OK, chiama (1) con il default

Il compliatore quando e’ presente una ambiguita’ sceglie a seconda della signature.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 55

Page 55: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

56

C++ vs. C: le differenze

Lo standard C++ è una estensione dello standard C, quindi ogni programma C è anche un programma C++. Esistono però delle differenze tra i due linguaggi. Le più importanti sono le seguenti:

In C++ le variabili locali possono essere dichiarate in qualsiasi punto di un blocco. In C devono essere dichiarate all’inizio di un blocco prima di ogni dichiarazione “attiva”.

In C una funzione dichiarata int f(); non dice nulla sui parametri della funzione. Se in C non viene specificato nulla significa che non viene stabilito nulla rispetto ai parametri della funzione In C++ una dichiarazione simile significa che la funzione non ha parametri, quindi in C++ scrivere int f(); o int f(void); è la stessa cosa

In C++ tutte le funzioni devono avere un prototipo, diversamente dal C in cui la prototipatura è opzionale.

In C una costante carattere viene automaticamente trasformata in un intero. In C++ no. In C non è un errore dichiarare più volte una variabile globale, in C++ si. In ANSI C un identificatore può avere al massimo 31 caratteri significativi, in C++ questa

restrizione non esiste In C quando viene richiesto uno specificatore di tipo nelle estensioni di dichiarazione viene

utilizzato per default il tipo int, in C++ no.

CORSO DI INFORMATICA PER LA FISICA 56

Page 56: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

57

Classi

Il concetto di classe in C++ è l’ estensione di quello di struct in C ed è l’ elemento centrale della programmazione ad oggetti. In generale si può dire che:

un programma è una rappresentazione (piu’ o meno fedele) di una situazione reale Una situazione reale non e’ fatta di int e di char ma di oggetti (tracce, finestre grafiche,

satelliti, volumi) che interagiscono fra di loro a seconda delle loro caratteristiche e peculiarità.

Per riprodurre una situazione reale, un buon linguaggio di programmazione deve permettere la descrizione di qualsiasi oggetto (tipi derivati), delle sue caratteristiche (rappresentazione interna) e delle sue interazioni con qualsiasi altro oggetto coinvolto nella simulazione (interfaccia verso l’esterno).

Le trasparenze del corso relative all’argomento di questo capitolo (in formato powerpoint) si trovano all’indirizzo della pagina web indicata nell’introduzione e sono disponibili tramite click su: classi.

Linguaggio C e struct

Tipi derivati e oggetti sono implementati per mezzo di struct nel linguaggio C.Viene effettuata una rappresentazione interna poi esportata pubblicamente al programma utente che deve implementare una rappresentazione alternativa se necessario.Ad esempio il tipo complesso esporta una rappresentazione cartesiana (reale-immaginario): se una rappresentazione polare (rho-phi) e’ richiesta, questa deve essere implementata dal programma utente.Non esiste nessuna interfaccia verso l’esterno, se non ancora la rappresentazione interna.La moltiplicazione di due numeri complessi (o di un numero complesso e uno scalare) fa parte dell’interfaccia che il complesso dovrebbe “fornire”. In C l’implementazione di questo “comportamento” e’ lasciata al programma utente. Supponiamo di voler implementare un nuovo tipo, il tipo complesso.

Problema: il tipo complesso

Vogliamo generalizzare la definizione di complesso data in C in maniera che: qualsiasi rappresentazione (cartesiana, polare) sia disponibile all’utente,

indipendentemente da quale effettivamente sia la rappresentazione interna il tipo complesso si comporti come qualsiasi altro tipo predefinito (inizializzazione,

definizione delle operazioni algebriche, interazione con altri tipi funzionalita’ addizionale (ad esempio il modulo) possa essere associata al tipo e non al

programma utenteIn C++ una struct puo’ contenere, oltre che variabili (data members), anche funzioni (metodi) che normalmente operano sui data members ed estendono la funzionalita’ del tipo

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 57

Page 57: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

58

//complesso.hstruct complesso {

double reale;double immaginario;double Modulo(){

return reale*reale+immaginario*immaginario;}

};L’accesso ai metodi avviene con la stessa modalità usata per l’accesso ai data members.Modulo() diventa così una caratteristica del tipo complesso e ne estende la definizione.

//main.cc#include “complesso.h”#include <iostream>void main() {

complesso a;a.reale=3.2; // inizializzazione parte realea.immaginario=5.6; // inizializzazione parte imm.std::cout<<“Modulo di a “<< a.Modulo() <<std::endl;

}

La definizione di Modulo appartiene ora al tipo complesso e non piu’ a main() (ne’ a nessun altro codice utente).La funzione Modulo() appartiene al tipo complesso e non puo’ essere esserne separata. Per sottolineare questo possesso, il compilatore associa il nome del metodo al tipo per mezzo dell’operatore di scope ( :: )

double complesso::Modulo()

La definizione di Modulo() puo’ quindi, univocamente avvenire in qualsiasi file source (prassi normale).

//complesso.hstruct complesso {

double reale;double immaginario;double Modulo();

};

//complesso.cc#include “complesso.h”double complesso::Modulo(){

return reale*reale+immaginario*immaginario;

}

Metodi

L’uso di metodi permette di accedere alla rappresentazione interna di un oggetto e di implementarne rappresentazioni alternative.

CORSO DI INFORMATICA PER LA FISICA 58

Page 58: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

59

struct complesso {double reale;double immaginario;double Modulo();// accesso alla parte reale double Reale() {return reale;}// accesso alla parte immaginadouble Immaginario() {return immaginario;}// accesso al modulo (rappresentazione polare)double Rho() {return Modulo();}// accesso all’angolo polaredouble Phi() {return atan(immaginario/reale);}

};

Metodi const

Metodi che non modificano lo stato (il valore dei data members) di un oggetto dovrebbero essere definiti const (non obbligatorio ma consigliabile). L’uso di qualificatori come const ha una duplice valenza:

documentazione: l’uso di un metodo dichiarato const non modifichera’ l’oggetto su cui il metodo stesso opera (interfaccia “read-only” )

evoluzione del codice: per “contratto” modifiche al codice dovranno rispettare il carattere read-only dell’interfaccia (a meno di modificare l’interfaccia stessa).//complesso.hstruct complesso {

double reale;double immaginario;double Modulo();// accesso alla parte reale double Reale() const {return reale;}// accesso alla parte immaginariadouble Immaginario() const {return immaginario;}// accesso al modulo (rappresentazione polare)double Rho() const {return Modulo;}// accesso all’angolo polaredouble Phi() const {return atan(immaginario/reale);}

};

Modificatori

La tecnica dell’overloading permette di definire metodi che possano modificare lo stato dell’oggetto su cui operano (modificatori) unificando le interfacce Read-only e Read/Write:

//complesso.hstruct complesso {

double reale;double immaginario;double Modulo();

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 59

Page 59: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

60

// accesso (Read-only)double Reale() const {return reale;}double Immaginario() const {return immaginario;}double Rho() const {return Modulo;}double Phi() const {return atan(immaginario/reale);}// modifiche (accesso Read-Write)void Reale(double r) {reale=r;}void Immaginario(double r) {immaginario=r;}void Rho(double r);void Phi(double r);

};

//complesso.cc#include “complesso.h”double complesso::Modulo(){

return reale*reale+immaginario*immaginario;

}void complesso::Rho(double r){

reale=r*cos( Phi() );immaginario=r*sin( Phi() );

}void complesso::Phi(double r){

reale=Rho() * cos(r);immaginario=Rho() * sin(r);

}

L’ esempio: il tipo complesso

L’uso di accessori e modificatori permette di operare direttamente sulla rappresentazione interna di un oggetto. Il tipo “complesso” si comporta ora come se sia la rappresentazione cartesiana che quella polare fossero state implementate.La rappresentazione interna (cartesiana) e’ tuttavia ancora accessibile direttamente: se volessimo cambiare la rappresentazione interna (a polare per esempio) qualsiasi codice che acceda direttamente alla rappresentazione cartesiana non funzionerebbe più.

#include “complesso.h”#include <iostream>void main() {

complesso a;a.Reale(3.2); // inizializzazione parte realea.Immaginario(5.6); // inizializzazione parte imm.complesso b;b.Rho(6.); // inizializzazione modulob.Phi(1.23); // inizializzazione angolostd::cout<<“Phi di a “<< a.Phi() <<std::endl;std::cout<<“Reale di b “<< b.Reale() <<std::endl;std::cout<<“Reale di b “<< b.reale <<std::endl;

}

CORSO DI INFORMATICA PER LA FISICA 60

Page 60: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

61

Classi

La classe (class) in C++ e’ una generalizzazione del concetto di struct, a cui aggiunge la possibilità di controllo dell’accesso alla struttura interna del tipo.

class identificatore {public:

// parte “pubblica” dell’interfaccia. Qualsiasi // altro pezzo di codice puo’ accedere liberamente // ai data members ed ai metodi dichiarati in questa// sezione

private:// soltanto i metodi che appartengono alla classe// stessa (indipendentemente se pubblici o privati)// possono accedere a questa sezione

};

Una struct e’ una classe i cui dati e metodi sono pubblici. In generale una classe NON e’ una struct.La rappresentazione interna diventa “privata”, la rappresentazione “visibile” e’ ora soltanto quella fornita dall’interfaccia “pubblica”.Il codice utente non ha più modo di sapere se la rappresentazione interna sia cartesiana o polare.La rappresentazione interna può ora essere modificata o cambiata completamente senza che il codice utente debba essere toccato.

complesso.hclass complesso {private:

double reale;double immaginario;

public:double Modulo();// accesso (Read-only)double Reale() const {return reale;}double Immaginario() const {return immaginario;}double Rho() const {return Modulo;}double Phi() const {return atan(immaginario/reale);}// modifiche (accesso Read-Write)void Reale(double r) {reale=r;}void Immaginario(double r) {immaginario=r;}void Rho(double r);void Phi(double r);

};

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 61

Page 61: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

62

main.cc#include “complesso.h”#include <iostream>void main() {

complesso a;a.Reale(3.2); // inizializzazione parte realea.Immaginario(5.6); // inizializzazione parte imm.complesso b;b.Rho(6.); // inizializzazione modulob.Phi(1.23); // inizializzazione angolostd::cout<<“Phi di a “<< a.Phi() <<std::endl;std::cout<<“Reale di b “<< b.Reale() <<std::endl;

// la linea seguente e’ ora ILLEGALE! (e’ private!)std::cout<<“Reale di b “<< b.reale <<std::endl;

}

struct e class: riepilogo

In C++ il concetto di struct viene generalizzato, da semplice raggruppamento di variabili utile per costruire una struttura dati a strumento per definire nuovi tipi.La possibilità di aggiungere ad una struct metodi che operano sulla rappresentazione interna permette di dotare la struct stessa di un comportamento proprio e di ampliarne la funzionalità.La classe e’ un’ulteriore generalizzazione della struct . L’aggiunta di un sistema di controllo dell’accesso ai dati in una classe consente di nasconderne l’implementazione: il codice utente dipende così soltanto dall’interfaccia pubblica della classe che ne specifica la funzionalità.

L’ esempio: il tipo complesso

La definizione di una classe “complesso” permette l’introduzione di un tipo derivato in un linguaggio di programmazione che non lo supporta a priori. La rappresentazione interna del tipo è nascosta al codice utente. L’interfaccia “pubblica” specifica il comportamento del tipo (per esempio la possibilità di accedere alla sua parte “reale”).Vogliamo ora risolvere il problema dell’ inizializzazione di un oggetto (quali valori vengono assegnati alla rappresentazione interna quando un oggetto viene creato) ed aggiungere un’algebra al nostro tipo “complesso”.

main.cc#include “complesso.h”#include <iostream>void main() {

complesso a;a.Reale(3.2); // inizializzazione parte realea.Immaginario(5.6); // inizializzazione parte imm.complesso b;b.Reale(6.); // inizializzazione parte b.Immaginario(1.23); // inizializzazione angolocomplesso c=a+b;complesso d=c*a;

}

In questo codice la parte di inizializzazione funziona, mentre queste operazioni non sono definite perché il compilatore non conosce nulla dell’algebra complessa. Cio’ che si vorrebbe è quindi un codice che si presenta così:

CORSO DI INFORMATICA PER LA FISICA 62

Page 62: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

63

main.cc#include “complesso.h”#include <iostream>void main() {

complesso a(3,2); // inizializzazione direttacomplesso b(6.,1.23); // inizializzazione direttacomplesso c=a+b;complesso d=c*a;

}

Queste operazioni non sono definite, perché il compilatore non conosce nulla dell’algebra complessa.

Costruttori e distruttori

Un costruttore è un metodo il cui nome è quello della classe a cui appartiene. Un costruttore non ritorna un tipo. Lo scopo di un costruttore è quello di costruire oggetti del tipo della classe e quello di inizializzare oggetti del tipo della classe, al momento della loro creazione. Questo implica l’inizializzazione degli attributi e, frequentemente, allocazione di memoria dallo heap.La lista degli argomenti assegnati ad un costruttore è liberamente scelta da chi implementa la classe. Una classe può avere più di un costruttore (overloading).Alcuni costruttori sono necessari perchè il compilatore possa fare il suo lavoro: se non vengono definiti il compilatore li genererà automaticamente.

L’ esempio: il tipo complesso

class complesso {private:

double reale;double immaginario;

public:complesso(); //default constructorcomplesso(double r); //inizializzata la parte realecomplesso(double r, double i);//inizializzate entrambedouble Modulo();// accesso (Read-only)double Reale() const {return reale;}double Immaginario() const {return immaginario;}double Rho() const {return Modulo;}double Phi() const {return atan(immaginario/reale);}// modifiche (accesso Read-Write)void Reale(double r) {reale=r;}void Immaginario(double r) {immaginario=r;}void Rho(double r);void Phi(double r);

};

Nel codice precedente appare il costruttore di default

complesso();

il costruttore in cui e’ inizializzata la parte reale

complesso(double r);

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 63

Page 63: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

64

e quello in cui e’ inizializzata anche la parte immaginaria:

complesso(double r, double i);

#include “complesso.h”complesso::complesso() // costruttore di default. Non ha tipo{

reale = 1; // per default, l’unitàimmaginario = 0;

}

complesso::complesso(double r) // non ha tipo !{

reale=r; // inizializza solo parte realeimmaginario=0;

}

complesso::complesso(double r,double i) //non ha tipo{

reale=r;immaginario=i;

}

I costruttori ubbidiscono alle stesse regole di overloading dei metodi normali Il costruttore “appropriato” viene invocato ogni volta che un oggetto viene creato

#include “complesso.h”#include <iostream>void main() {

complesso a; // default, a è 1

complesso b(6.,1.23) ; // costruttore a due parametricomplesso c(3) ; // costruttore a un parametrocomplesso d (“hello!”) ; // errore di compilazione!!

}

Quando uno degli attributi è esso stesso una classe, il costruttore appropriato viene scelto sulla base dei parametri forniti nell’inizializzazione.

Inizializzazione

Una sintassi alternativa permette di attribuire valori ai membri di una classe per mezzo di una lista di inizializzatori, che precede il corpo della funzione

CORSO DI INFORMATICA PER LA FISICA 64

Page 64: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

65

complesso.cc#include “complesso.h”complesso::complesso() : reale(1), immaginario(0){ // vuoto}complesso::complesso(double r): reale(r),immaginario(0) {}complesso::complesso(double r,double i): reale(r),immaginario(i){}

E` obbligatorio inizializzare così gli attributi (non statici) che siano o riferimenti o const.

Costruttore di default

Un costruttore senza una lista di argomenti viene chiamato costruttore di default.

complesso.cc#include “complesso.h”complesso::complesso() : reale(1), immaginario(0){ // vuoto}

La funzionalità del compilatore dipende in modo cruciale dall’esistenza di un costruttore di default per ogni classe definita, per cui, in assenza di un costruttore di default, il compilatore ne genererà uno automaticamente (il più banale).Se si desidera avere un costruttore di default non banale, questo deve essere esplicitamente dichiarato e definito (nel caso di “complesso”, il costruttore di default autogenerato inizializzerebbe reale ed immaginario a 0 invece avendolo implementato esso setta reale =1 e immaginario =0).

Costruttore di copia

La forma più generale di un costruttore di copia è la seguente:

classname (const classname& O) //corpo del costruttore

O è un riferimento all’oggetto che si trova nel corpo del costruttore. Un costruttore di copia (copy constructor) permette di copiare oggetti in oggetti. Un costruttore di copia viene utilizzato ogni qualvolta che si passi un oggetto “by value” ad una funzione o un metodo (una copia locale dell’oggetto viene creata) nonché in diversi altri casi.Un costruttore di copia per classe è necessario al compilatore che ne genererà uno (il più banale) nel caso che esso non sia stato esplicitamente dichiarato.La copia di oggetti in oggetti rappresenta un problema complesso nel caso di allocazione dinamica di memoria (“deep copy”, “shallow copy”) ed è quindi buona regola esplicitare sempre un costruttore di copia (a meno di casi assolutamente banali).

complesso.h...complesso(const complesso& c); //prototipo...

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 65

Page 65: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

66

complesso.cc#include “complesso.h”complesso::complesso(const complesso& c):

reale(c.reale), immaginario(c.immaginario){}

main.cc#include “complesso.h”#include <iostream>void main() {

complesso a; // default, a è 1complesso b(6.,1.23) ; // costruttore a due parametricomplesso c(b) ; // costruttore di copia!

//”fa una copia di b”}

Se invece:

myclass x=y;

L’operazione sarebbe stata quella di eseguire una copia bit a bit; x sarebbe stato una copia esatta di y , cioè y avrebbe usato la stessa memoria allocata per x., non una propria area distinta. Se ad esempio myclass avesse contenuto un distruttore che libera memoria la distruzione di x e y sarebbe risultata in una doppia cancellazione di memoria. Questo richiamo ricorda chein C++ ci sono due situazioni per cui a un oggetto viene assegnato il valore di un altro oggetto.

L’assegnamento L’inizializzazione che si può verificare in tre modi diversi:

Quando un oggetto inizializza esplicitamente un altro oggetto,come nelle dichiarazioni

Quando viene eseguita una copia di un oggetto che deve essere passato ad una funzione

Quando viene creato un oggetto temporaneo (normalmente come valore restituito da una funzione)

Il costruttore di copie viene usato solo nelle inizializzazioni.L’ inizializzazione viene utilizzata da ciascuna delle seguenti istruzioni:

myclass x=y; //y inizializza esplicitamente xfunc(y) ; // y passata come parametroy=funx(); //y riceve da func() un oggetto temporaneo

Costruttori ad un parametro

Un costruttore ad un solo parametro viene considerato dal compilatore come regola di conversione implicita.Un costruttore di questo tipo è utilizzato infatti per convertire il parametro (o il suo tipo) il un oggetto. Questo può portare ad errori o effetti indesiderati nel caso di espressioni complicate.Nel caso NON si desideri che un costruttore funga da operazione di conversione, lo si deve dichiarare explicit.

CORSO DI INFORMATICA PER LA FISICA 66

Page 66: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

67

complesso.hclass complesso {...public:

explicit complesso(double r);...};

Distruttore

Così come è possibile intervenire sul modo in cui un oggetto viene creato (tramite la definizione di uno o più costruttori), è anche possibile agire su un oggetto appena prima che questo venga eliminato (sia perché si è invocato esplicitamente delete sia perché esso è giunto alla fine della sua vita naturale).Un distruttore è un metodo che porta lo stesso nome della classe a cui è associato preceduto da una ~.

complesso.hclass complesso {...public:

~complesso(); // distruttore...};

Il distruttore viene automaticamente invocato ogni qualvolta che un oggetto sta per venire distrutto. Se non è esplicitato, il compilatore ne genererà uno automaticamente.

Il distruttore non ha tipo. Il distruttore NON ubbidisce alle normali regole di overloading.

Esiste soltanto un distruttore per classe. Il distruttore NON accetta argomenti: la lista dei parametri deve rimanere vuota (si

comporta in modo contrario al costruttore, anche nelle caratteristiche).

L’ esempio: il tipo complesso

complesso.cc#include “complesso.h”complesso::~complesso(){

std::cout<<“un altro complesso se ne va!”<<std::endl;}

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 67

Page 67: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

68

main.cc#include “complesso.h”#include <iostream>void main() {

complesso a;complesso b= new complesso(6.,1.23) ;std::cout<<“ b viene distrutto qui!”<<std::endl;delete b; // distruttore di b invocatofor (int i=0; i<10; i++) {

complesso c(3.);std::cout<<“ c è creato e distrutto “<<std::endl;

} // distruttore di c invocato (10 volte)// perche’?

std::cout<<“ fine del programma, a viene distrutto”<<std::endl;// distruttore di a invocato

}

Per molte classi il distruttore è triviale e può essere tralasciato. Il compilatore genererà automaticamente un distruttore altrettanto triviale.Se la classe ha invece una funzionalità complessa (per es. allocazione dinamica di memoria), il distruttore ha il compito cruciale di riportare la situazione allo stato originale quando un oggetto viene distrutto (per es. invocando delete per restituire memoria allo heap ) .Un distruttore è caratterizzato dalla ~ e dal fatto di non avere argomenti e dal fatto di non ritornare un tipo.Qualsiasi altra combinazione verrà interpretata come “normale” metodo di una classe (e mai utilizzata).Dal punto di vista del computer, un programma è un insieme di operazioni predefinite su certe aree di memoria.Il compilatore prestabilisce come le aree di memoria corrispondenti ai tipi predefiniti debbano essere configurate e come interagiscano.Costruttori e distruttori sono operazioni che un programmatore può definire per stabilire la configurazione dei tipi derivati.Resta ancora da stabilire come questi tipi interagiscano fra di loro. Per questo, il C++ permette di ridefinire tutte le principali operazioni fra tipi derivati.

Operatori

In C++, la somma fra due interi è predefinita (operazioni binarie su due aree di memoria).

int a=3,b=4;int c=a+b;

Una semplice addizione può essere vista come un operatore (una funzione) che, prendendo come argomenti due interi (a e b) restituisce un intero (che viene poi associato a c).

int a=3,b=4;int c=operator+(a,b);

Oppure come metodo della classe intero che, preso un argomento intero, lo associa all’oggetto su cui opera per restituire un intero.

int a=3,b=4;int c=a.operator+(b);

CORSO DI INFORMATICA PER LA FISICA 68

Page 68: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

69

Qualsiasi operatore che sia definito per i tipi fondamentali (+ - * /, operatori di assegnazione, operatori di shift a sinistra e a destra etc.) può essere ridefinito per i tipi derivati in termini di funzioni globali o metodi appartenenti alle classi stesse.La cardinalità (operatori unari o binari) e l’associatività (la “precedenza” di un operatore rispetto ad un altro) non possono essere modificate.Non si possono definire operatori che non siano già stati definiti per i tipi fondamentali (non si può definire un nuovo operatore ** come in Fortran per significare l’elevamento a potenza).

Regole per la ridefinizione degli operatori

Tutti gli operatori previsti dal C++ possono essere ridefiniti tranne: Operatore di risoluzione di visibilità Operatore punto per la selezione di un membro di una struttura Operatore di selezione di un membro a mezzo di puntatore

Gli operatori della seguente tabella possono essere ridefiniti:

+ - * / % &| ! = < > +=-= *= /= %= = |=<< >> >>= <<= == != <=>= && || ++ -- ->* ->[] () new new[] delete delete []

Un esempio: l’operatore <<

L’operatore di shift a sinistra (<<) viene utilizzato per le operazioni di output su una strema.

int i,k;std::cout<<i<<k;

Utilizzando una notazione “espansa”, l’operatore << può essere visto come una funzione globale che opera su una ostream e su un intero per restituire una ostream

int i,k;operator<<(operator<<(std::cout,i),k);

L’operatore << deve ritornare una ostream perché si possano concatenare due o più operazioni di output.

L’esempio: il tipo complesso

Nello stesso modo, possiamo definire un operatore << che operi sul tipo complesso e che ci permetta di stampare un complesso nella stessa maniera in cui stampiamo un intero.

ostream& operator<<(ostream& out, const complesso& c){

out<<“ “<<c.Reale()<<“+i*”<<c.Immaginario();return out;

}

L’operatore prende come input una ostream ed un complesso (che non viene modificato e quindi dichiarato const )

L’operatore ritorna una ostream

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 69

Page 69: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

70

L’operatore “modifica” il suo argomento e lo ritorna per una successiva operazione

complesso a(3,2),b(1,4);std::cout<<a<<“ “<<b<<std::endl;

Sappiamo ora come definire un operator+, un operator*, un operator/ per il tipo complesso:

complesso operator+(const complesso& a, const complesso& b) {complesso c( a.Reale()+b.Reale(),

a.Immaginario()+b.Immaginario() ); return c

//uso della notazione cartesiana}

complesso operator*(const complesso& a, const complesso& b) {complesso c;c.Rho( a.Rho() * b.Rho() );c.Phi( a.Phi() + b.Phi() ); return c;

//notazione polare}

complesso operator/(const complesso& a, const complesso& b) {complesso c;c.Rho( a.Rho() / b.Rho() );c.Phi( a.Phi() - b.Phi() ); return c;

}

this

Per ogni oggetto creato, un puntatore predefinito chiamato this permette di riferirsi all’oggetto stesso.

complesso.cc#include “complesso.h”// sintassi alternativa per Modulo()double complesso::Modulo(){

return this->reale*this->reale+this->immaginario*this->immaginario;

}

this viene normalmente utilizzato da quei metodi che devono ritornare un puntatore all’oggetto su cui operano.

L’operatore di assegnazione (=)

Gli operatori unari (assegnazione, + e – unari, ++, +=, etc.) devono essere definiti come metodi della classe su cui operano.

CORSO DI INFORMATICA PER LA FISICA 70

Page 70: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

71

complesso.hclass complesso {...public:

complesso& operator=(const complesso& c); ...};

complesso.cc#include “complesso.h”complesso& complesso::operator=(const complesso& c){

reale=c.reale;immaginario=c.immaginario;return *this;

}

complesso a(3,2);complesso b;b=a;std::cout<<a<<“ “<<b<<std::endl;

Overloading di operatori

Come qualsiasi altro metodo o funzione, definizioni di operatori diverse per tipi di argomenti possono coesistere.Somma di un complesso e di uno scalare.

complesso operator+(const complesso& a, const double d){

complesso temp(d);return a+temp; // somma fra complessi

}// proprietà commutativacomplesso operator+(const double d,const complesso& a){

return a+d; // operator+ definito sopra}

complesso a(3,2);double r=5.3; complesso b = a+r;complesso c = r+a;

Ma allora in sintesi:

Che cos’è una classe?

La dichiarazione di una classe e’ la dichiarazione di un nuovo tipo che racchiude sia il codice che i dati. Il nuovo tipo sarà utilizzato per definire oggetti di tale classe.Una classe e’ un’astrazione logica mentre un oggetto ha esistenza fisica.Un oggetto e’ una istanza di una classe.La dichiarazione di una classe e’ sintatticamente uguale a quella di una struttura.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 71

Page 71: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

72

Il concetto di classe si basa sui seguenti cardini : I dati privati (o attributi) di una classe definiscono lo stato dell’oggetto Le funzioni (o metodi) di una classe implementano la risposta ai messaggi dell’oggetto

Un esempio: come costruirla ed usarla

Attraverso questo esempio (la costruzione e la manipolazione della classe del vettore bidimensionale) si vogliono ripercorrere le definizioni e le osservazioni precedenti per quanto riguarda il concetto di classe e la sua trattazione.

Vector2d.hclass Vector2D{public:

Vector2D(double x, double y);

double x(); // \double y(); // \double r(); // funzioni o metodidouble phi(); // /

private:double x_; // \double y_

}; // dati o attributi; // punto e virgola!

Gli attributi privati :

double x ; double y_;

non sono accessibili al di fuori della classe. I metodi pubblici :

double x();double y ; double r();double phi();

sono gli unici visibili.

Vector2D(double x, double y);

E’ il costruttore della classe. La definizione della classe termina con un “;” e l’implementazione dei metodi avviene in Vector2D.cc

CORSO DI INFORMATICA PER LA FISICA 72

Page 72: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

73

Vector2D.cc#include “Vector.h”Vector2D::Vector2D(double x, double y) : x_(x), y_(y){} double Vector2D::x(){ return x_; }double Vector2D::r(){ return sqrt(x_*x_ + y_*y_); }

Come usare la classe Vector2D:

#include <iostream.h>#include “Vector2D.h”int main(){ Vector2D v(1, 1); //invoca il constructor cout << “ v = (“ << v.x() << “,” << v.y() << “)” << endl; cout << “ r = “ << v.r(); cout << “ phi = “ << v.phi() << endl; return 0;}

L’output è il seguente:

v = (1, 1)r = 1.4141 phi = 0.7854

Oppure attraverso un puntatore :

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 73

Page 73: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

74

main.cc#include <iostream.h>#include “Vector2D.h”int main(){ Vector2D *v = new Vector2D(1, 1); //allocazione sullo heap cout << “ v = (“ << v->x() << “,” << v->y() << “)” << endl; cout << “ r = “ << v->r(); cout << “ phi = “ << v->phi() << endl; delete v; //attenzione! return 0;}

e l’output relativo:

v = (1, 1)r = 1.4141 phi = 0.7854

new alloca memoria sullo heap; dopo aver invocato new occorre cancellare l’area prenotata con delete. Esiste una protezione dell’accesso ai dati . Il codice seguente, che cerca di accedere a dati privati fallisce, non compilando l’applicazione. Solo i metodi hanno libero accesso ai dati privati (e protected) della classe.

#include <iostream>#include “Vector2D.h”int main(){ Vector2D v(1, 1); cout << “ V = (“ << v.x_ << “,” // << v.y_ << “,” << endl; // non compila ! cout << “ r = “ << v.r(); cout << “ phi = “ << v.phi() << endl;

Selettori e modificatori (chiamati anche setters e getters rispettivamente)sono metodi che agiscono in modo diverso sui data members di una classe. I selettori non modificano lo stato di una classe e sono caratterizzati dalla parola chiave const. I modificatori invece sono in grado di modificarne i contenuti.

CORSO DI INFORMATICA PER LA FISICA 74

Page 74: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

75

class Vector2D{public: Vector2D(double x, double y); double x() const; //selettore double y() const; //selettore double r() const; //selettore double phi() const; //selettore void scale(double s); //modificatoreprivate: double x_, y_;};

Incapsulamento

Possibilità di nascondere gli attributi di un oggetto ad altri oggetti. L’accesso all’oggetto è possibile solo attraverso i metodi. In questo modo si impedisce una errata manipolazione di un dato da parte di un programma garantendo quindi l’ integrità e correttezza dei dati in ogni momento.Si nasconde quindi all’utilizzatore della classe il dettaglio implementativo dello stato dell’oggetto.La programmazione ad oggetti attraverso l’incapsulamento consente di

ridurre la dipendenza del codice di alto livello dalla rappresentazione dei dati riutilizzare del codice di alto livello (codice di analisi), mentre il codice di basso livello

dipende dai dettagli della struttura dei dati sviluppare moduli indipendenti uno dall’altro avere codice utente che dipende dalle interfacce e non dall’implementazione nascondere i dettagli di implementazione supportare tipi di dati astratti

friend

La keyword friend può essere usata perché una funzione (o una classe) abbia libero accesso ai dati privati di un’altra classe oppure per definire metodi che operano su più oggetti di una stessa classe o di classi distinte.Quando una classe è friend di un’altra classe la classe friend e tutte le sue funzioni membro hanno accesso ai membri privati definiti all’interno dell’altra classe. Cio’ equivale a dire che tutto va come se fossero metodi della classe anche quelli appartenenti alla classe friend.

class A {. . .

friend int aFunc();friend void C::f(int);

}; class B {…

friend class C;};class C {. . .};

friend (nonostante il nome) è nemico dell’incapsulamento e quindi dell’Object Orientation.Un uso eccessivo di friend è quasi sempre sintomo di un cattivo design.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 75

Page 75: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

76

static

Se la dichiarazione di una variabile membro è preceduta dalla keyword static si chiede al compilatore di creare una sola copia di tale variabile e di utilizzare tale copia per tutti gli oggetti della classe: quindi esisterà una sola copia di dati membri static.Tutti gli oggetti di una classe utilizzano quindi la stessa variabile.Tutte le variabili static sono inizializzate a 0 nel momento in cui viene creato il primo oggetto. Non si sta allocando spazio di memoria per tali dati e si dovrà fornire una definizione globale per i dati membro static in un altro punto del programma all’esterno della classe.Una variabile static esiste prima che venga creato un qualsiasi oggetto della sua classe.In sintesi:

attributi dichiarati static in una classe sono condivisi da tutti gli oggetti di quella classe. Metodi dichiarati static non possono accedere ad attributi non statici della classe . Attributi statici possono essere usati e modificati soltanto da metodi statici.

Un esempio:

#include <iostream.h>class shared {

static int a;int b;

public:void set(int i,int j) {a=i; b=j;}void show();

};

int shared::a; //definisce avoid shared::show(){

cout << “Variabile statica a: ”<<a;cout << “\nVariabile non statica b: ”<<b;cout << “\n”;

}int MyClass::counter=0;int main() {

shared x,y;x.set(1,1); //assegna 1 alla variabile ax.show();y.set(2,2); //ora le assegna 2

y.show();x.show();return 0;

}

Nell’esempio precedente a e’ stata modificata sia per x che per y perchè a e’ condivisa da entrambi gli oggetti. Quindi l’output del programma sarà il seguente:

CORSO DI INFORMATICA PER LA FISICA 76

Page 76: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

77

Variabile statica a: 1Variabile non statica b: 1Variabile statica a: 2Variabile non statica b: 2Variabile statica a: 2Variabile non statica b: 1

Nonostante l’utilizzo di static sembri imporre condizioni troppo restrittive, esso risulta utile nell’implementazione di:

contatori singleton (vedi oltre)

Un contatore

Si vuole contare il numero di oggetti di una determinata classe correntemente istanziati.Per il conteggio si usa una variabile membro statica che e’ incrementata (decrementata) da ciascun costruttore(distruttore).Una funzione membro statica stampa il valore corrente del contatore.

Class MyClass {private:

static int counter;static void increment_counter() { counter++; }static void decrement_counter() { counter--; }

public:MyClass() { increment_counter(); }~MyClass() { decrement_counter(); }static int HowMany() { return counter; }

};

#include <iostream.h>#include “MyClass.h”int MyClass::counter=0;int main() {

MyClass a,b,c;MyClass *p=new MyClass;cout<<“ How many? “<< MyClass::HowMany() <<endl;delete p;cout<<“ and now? “<< a.HowMany() <<endl;return 0;

}

Un membro statico deve essere inizializzato una e una sola volta nel codice eseguibile

int MyClass::counter=0;

Un metodo statico puo` essere invocato nei due modi seguenti:

cout<<“ How many? “<< MyClass::HowMany() <<endl;cout<<“ and now? “<< a.HowMany() <<endl;

Singleton

Un singleton è una classe di cui, ad ogni momento nel corso del programma, non può esistere più di una copia (istanza)

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 77

Page 77: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

78

class aSingleton {private:

static aSingleton *ptr;aSingleton () {}

public:static aSingleton *GetPointer(){

if (ptr==0) ptr=new aSingleton;

return ptr; }

};

Pattern utile per l’implementazione di classi “manager” di cui deve esistere una sola istanza.

#include “aSingleton.h”aSingleton *aSingleton::ptr=0;int main() {

aSingleton *mySing=aSingleton::GetPointer();

. . . return 0;

}

Occorre fare attenzione a non farlo diventare l’equivalente di un common block! (sempre per i nostalgici del FORTRAN).

CORSO DI INFORMATICA PER LA FISICA 78

Page 78: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

79

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 79

Page 79: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

80

Templates

Template e’ sinonimo di modello. Con i templates in C++ è possibile creare funzioni e classi generiche e il tipo dei dati su cui esse operano è specificato come parametro.L’utilizzo della funzione o della classe avviene con vari tipi di dati senza dover ricodificare esplicitamente.Ad esempio un algoritmo che ordina un’array di int è lo stesso che per un’array di float, non e’ necessario codificarne due diversi.I template sono quindi funzioni o classi scritte per uno o più tipi non specificati. Quando si usano i template si passano i tipi, implicitamente o esplicitamente.Il C++ fornisce un metodo per creare un polimorfismo parametrico. E’ possibile utilizzare lo stesso codice per tipi differenti: il tipo della variabile diventa un parametro.

template<class T> T max( T p1, T p2 ) { if ( p1 < p2 ) return p2; else return p1;}

Per il tipo T deve essere definito l’operatore < .

main.ccint main() { Vector v1,v2; cout << max<int>(10,20) << endl; cout << max<float>(2.6,1.0) << endl; cout << max<Vector>(v1,v2) << endl;}

Sintassi dei template:

template < function identifier > function definition template < class identifier > class definition

Ogni volta che nella definizione della funzione o della classe appare identifier questo viene sostituito dal compilatore con il tipo fornito nella chiamata.La dichiarazione e l’implementazione del template devono essere nello stesso file dove il template viene utilizzato.I parametri di interi possono essere inclusi nella dichiarazione del template.

template <typename T=int , int n=10>class array_n {...private:

T items[n]; // n istanziato esplicitamente}; array_n<complex, 1000> w; // w array di complessi

I parametri di default possono essere invece tralasciati.

Template di template

L’argomento di un template puo` essere esso stesso un template.

CORSO DI INFORMATICA PER LA FISICA 80

Page 80: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

81

template <class T1, template <class T2> class T3 >

questo permette la creazione e l’utilizzo di meta-template (template istanziati con template) molto sofisticati. La Standard Template Library fa uso di questa possibilità.

Funzioni template e parametri

Una buona parte dei compilatori accetta una sintassi ristretta per quel che riguarda le funzioni template. ANSI/C++ prevede invece che anche parametri numerici possano essere inclusi nella definizione del template.

template <class T> //OK per ogni compilatorevoid swap(T& x, T& y){

T temp;temp=x;x=y;y=temp;

}

template <class T, int n=10>T aFunc(){

T temp[n];. . .

}

Questa notazione è ANSI/C++, ma la maggior parte dei compilatori la rifiuta.Un esempio:

int main() {int i=10,j=20;float x=10.1, y=23.1;char a=‘x’, b=‘z’;

swap(i,j);swap(x,y);swap(a,b);cout<<“i e j scambiati: “<<i<<“ “<<j<<endl;cout<<“x e y scambiati: “<<x<<“ “<<y<<endl;cout<<“a e b scambiati: “<<a<<“ “<<b<<endl;

return 0;}

La funzione swap viene qui richiamata con tre diversi tipi di dati: int, double e char. Dato che essa è una funzione generica (cioè la definizione di una funzione preceduta dalla dicitura template, il compilatore crea automaticamente tre definizioni di swap: una di esse scambia valori interi, un’altra scambia valori reali, una terza valori char.Con l’istruzione template si può definire anche più di un tipo di dati generico, basta utilizzare un elenco separato da virgole. Il programma seguente, ad esempio, utilizza due tipi generici per creare una funzione template:

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 81

Page 81: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

82

#include <iostream>using namespace std;template <class type1,class type2>

void myfunc (type1 x,type2 y)cout <<x<<’  ‘<<y<<endl ;int main()myfunc(10, ‘Programmare in C++ ‘) ;myfunc(.23,19L);return 0;

I tipi type1 e type2 vengono sostituiti dal compilatore rispettivamente con i tipi int e char* e double e long nel momento in cui il compilatore genera le specifiche istanze di myfunc() all’interno di main().Quando si crea una funzione template si chiede al compilatore di generare tutte le versioni di tale funzione necessarie per gestire tutte le situazioni nelle quali il programma deve impiegare tale funzione.

Membri statici

Per le classi template, gli attributi statici non sono universali ma specifici di ogni istanza.

template <class MyClass>class MyClass {public:

static int counter;...

};MyClass<int> a,b;MyClass<double> c;

Le variabili statiche MyClass<int>::counter e MyClass<double>::counter sono diverse (sono statiche).

Un esempio:lo stack di interi

Si vuol ora creare una classe generica per lo stack. Iniziamo dallo stack di interi. La schematizzazione della classe e’ la seguente:

La classe “Contenuto” contiene come data member un puntatore next all’elemento successivo e la variabile intera val che ne descrive il valore, mentre la classe “Stack” contiene il puntatore top di tipo “Contenuto”.

CORSO DI INFORMATICA PER LA FISICA 82

val

Contenuto

next

val

Contenuto

next

..

..

..val

Contenuto

next

Stack

top

Stack

top

Page 82: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

83

class Contenuto {...private: Contenuto* next; int val; };class Stack {...private: Contenuto* top;};

Se quindi si vuole implementare la classe stack per gli interi e la classe contenuto un codice possibile alla sua implementazione è il seguente:

class Contenuto {public: Contenuto ( int i, Contenuto* ptn ) { val=i; next=ptn; } int getVal (){ return val; } Contenuto* getNext() {return next;}private: Contenuto* next; int val; };

class Stack {public: Stack() {top = 0;} ~Stack() {} void push ( int i ) { Contenuto* tmp = new Contenuto(i,top ); top = tmp; } int pop () { int ret = top->getVal(); Contenuto* tmp = top; top = top->getNext(); delete tmp; return ret; }private: Contenuto* top;};

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 83

Page 83: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

84

int main() {Stack s;s.push ( 10 );s.push ( 20 );cout << s.pop() << “ - “ << s.pop;return 0;};

con il seguente output:

10 - 20

L’ implementazione della classe relativa allo stack templato diventa:

template <class T>class Stack {public: Stack() {top = NULL;} ~Stack() {;} void push ( T i ) { Contenuto<T>* tmp = new Contenuto<T> (i,top ); top = tmp; } T pop () { T ret = top->getVal(); Contenuto<T>* tmp = top; top = top->getNext(); delete tmp; return ret; }private: Contenuto<T>* top;};

template <class T>class Contenuto {public: Contenuto ( T i, Contenuto* ptn ) { val = i; next = ptn; } T getVal (){ return val; } Contenuto* getNext() {return next;}private: Contenuto* next; T val; };

con il relativo user code:int main() {Stack<int> s;s.push ( 10 );s.push ( 20 );Stack<double> s1;Stack<Shape *> s2;cout << s.pop() << “ “ << s.pop;return 0;};

Quando viene dichiarata una istanza specifica di stack il compilatore genera automaticamente tutte le funzioni e le variabili necessarie per gestire i dati

CORSO DI INFORMATICA PER LA FISICA 84

Page 84: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

85

effettivamente impiegati. Nell’esempio vengono usati un tipo di stack per double e per un tipo Shape *.

typename

È una parola chiave (insieme ad export) riservate in modo specifico ai template. Il primo utilizzo è quello relativo alla sostituzione della parola class nella dichiarazione di un template. Oppure, come nell’esempio seguente, essa indica il tipo generico:

template <class T>class MyClass {typename T::SubType *ptr;//ptr è un puntatore al tipo T::SubType…};template <class T>class MyClass {T::SubType *ptr;//significherebbe membro statico//si farebbe una moltiplicazione del valore //SubType con ptr…};

Con typename si informa il compilatore che un nome utilizzato nella dichiarazione di un template fa riferimento ad un tipo e non al nome di un oggetto. Ogni identificatore di un template è considerato essere un valore a meno che sia qualificato da typename.

Un altro esempio: la classe Queue

Si voglia ad esempio definire una classe che supporti il meccanismo di una coda.Struttura di dati che si vuol costruire riguarda una collezione di oggetti aggiunti al fondo e rimossi in alto (LIFO, last in first out).Le operazioni da introdurre sono quindi:

Aggiungere un elemento al fondo Rimuovere un elemento all’inizio Determinare se la coda è vuota Determinare se la coda è piena

Esse vengono espletate da opportuni metodi:

void add(item);item remove();bool_is empty();bool is_full();

La definizione della classe sarà:

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 85

Page 85: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

86

class Queue{public: Queue(); ~Queue(); Type& remove(); void add(const Type& ); bool is_empty(); bool is_full();private:// …};

Quale tipo per Type? intIn questo caso se è assegnato un valore diverso esso viene automaticamente convertito in int, se la conversione esiste, altrimenti a compile-time appare un errore.

Queue qObj; string str(“adele”); qObj.add(3.141549); //ok item aggiunto come == 3 qObj.add (str);//errore di conversione da str a int

Il C++ assicura che solo oggetti di tipo int o trasformabili in int possano essere aggiunti alla Queue. E per tipi diversi come ci si comporta? Si può ad esempio copiare la classe e adattarla per lavorare con int, double,complessi, string creando classi diverse:

IntQueue DoubleQueue ComplexQueue StringQueueLa generalizzazione ovvia avviene attraverso i templates.

template <class Type>Class Queue { public: Queue (); ~Queue(); Type& remove(); void add (const Type &); bool is_empty(); bool is_full(); private: //…};

Queue<int> qi;Queue<complex<double>> qc;Queue<string> qs;

CORSO DI INFORMATICA PER LA FISICA 86

Page 86: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

87

template <class Type>Class QueueItem { public: //… private: typedef double Type; Type item; QueueItem *next;};

Errore ! Typedef non può avere lo stesso nome del parametro templato Type.Il nome di un parametro templato può essere riusato nelle definizioni o dichiarazioni di una classe templata.

template <class Type>Class QueueItem; template <class Type>Class Queue;

#ifndef Queue_h#define Queue_h//dichiarazione di QueueItemtemplate <class T> class QueueItem; template <class Type>class Queue{ public: Queue():front (0),back(0){}; ~Queue(); Type & remove(); void add (const Type &); bool is_empty() const {return front ==0;} private: QueueItem<Type> *front; QueueItem<Type> *back;};#endifQueue<int> qi;Queue<string> qs;Queue qs;//errore

Potenza dei templates

Uno degli obiettivi più difficili della programmazione è creare codice riutilizzabile.La classe stack nella sua prima versione era utilizzabile solo per maneggiare interi. Anche se l’algoritmo poteva essere utilizzato per ogni tipo di dati, l’indicazione del tipo di dati ne limitava l’applicazione. Se si trasforma, come nell’esempio precedente,la classe stack in una classe generica diventa possibile creare uno stack per qualsiasi tipo di dati.La Standard Template Library è costruita sui template.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 87

Page 87: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

88

STL (Standard Template Library)

La STL (Standard Template Library) é una raccolta di funzioni generiche (algoritmi) e di classi di uso molto generale.La libreria di algoritmi contiene l’implementazione di numerose funzioni di carattere generale: copia, scambio, ordinamento di oggetti e così via. Tra le classi più utilizzate della libreria di classi standard vi sono quelle che vanno sotto il generico nome di containers: si tratta di classi in grado di rappresentare oggetti generici costituiti, in generale, da collezioni di oggetti più semplici. Stringhe, vettori, iteratori, contenitori associativi (come mappe o multimappe) ne sono gli esempi più noti.La STL è progettata in modo che operazioni simili su diversi contenitori abbiano la stessa interfaccia e la stessa semantica.Essa e’ una libreria generica: tutti i suoi componenti sono parametrizzati mediante l’utilizzo dei template.E’ consigliato un uso intensivo della STL dato che essa, pur possedendo una sintassi complessa, ha un uso semplice. Il concetto base si basa sulla separazione tra dati e operazioni. I dati sono maneggiati da classi container, le operazioni sono definite da algoritmi configurabili, mentre gli iteratori sono una sorta di collante tra algoritmi e dati.

Qui viene presentata una panoramica della libreria, partendo dalla sua organizzazione, dagli elementi di base e continuando con una panoramica sulle tecniche di programmazione con alcuni esempi. Le trasparenze presentate a lezione, scritte in formato powerpoint, sono raggiungibili all’indirizzo web indicato nell’introduzione alla voce: Standard Template Library.

Template (ripasso)

Tutte le parti (o quasi) della STL sono scritte come template trattate nel capitolo precedente. Le funzioni o le classi sono scritte per uno o più tipi non specificati; quando si usano i template si passano i tipi, implicitamente o esplicitamente.Un esempio:

template <class T>inline const T& max(const T& a, const T& b){

//if a<b usa b altrimenti areturn a < b ? b : a;

}

T quindi è un tipo di dati arbitrario: il tipo è specificato da chi chiama la funzione.

Container

I container sono oggetti che contengono altri oggetti. La STL offre container di vario tipo. Definiamo i contenitori sequenziali:

vector definisce un array dinamico deque crea una coda a doppio concatenamento list fornisce una lista lineare

Questi container sono chiamati container sequenziali perché in STL una sequenza è una lista lineare. Oltre ai container di base vengono definiti dei container associativi che consentono di ricercare in modo efficiente un valore sulla base di una chiave.I contenitori associativi sono invece:

set/multiset con map e multimap che forniscono l’accesso ai valori tramite chiavi univoche

CORSO DI INFORMATICA PER LA FISICA 88

Page 88: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

89

Una mappa memorizza coppie chiave/valore e consente di trovare un valore sulla base della sua chiave.

Container sequenziali

vector deque list string array sono tutti container sequenziali che vengono di seguito trattati singolarmente con esempi.

Operazioni comuni a tutti i container

Le operazioni comuni a tutti i container sono elencate nella tabella sottostante con un breve commento che ne esplicita la funzionalità:

ContType cContType c1(c2)ContType c(beg,end)c.˜ContTypec.size()c.empty()c.max_size()c1==c2c1 !=c2Idem con gli operatori < >c1.swap(c2) e swap(c1,c2)c.begin() end()rbegin()rend()c.insert(pos,elem)c.clear() c.erase(beg,end)c.get_allocator()

Crea un container vuotoCopia un container dello stesso tipoCopia un container e inizializza con Copie degli elementi da beg a endCancella gli elementi e libera memoriaRitorna il numero di elementiRitorna se il container è vuotoRitorna il max numero di leementi possibileRitorna se c1 è = a c2Se diversoSwap tra c1 e c2Ritorna un iteratore al primo/ultimo Inserisce una copia di elemVuota il containerRimuove gli elementi da beg a endRitorna il modello in memoria del container

Sequenze

Vector e list sono le sequenze più usate, con caratteristiche diverse.Le principali sono elencate qui in sintesi:Vector ha un tempo costante di inserimento e cancellazione di elementi all’inizio e alla fine.Il tempo per inserimento e cancellazione di elementi all’interno del vettore e’ lineare con il numero di elementi . L’ iteratore e’ ad accesso casuale.List ha un tempo costante di inserimento e cancellazione di elementi in ogni punto della lista eil suo iteratore e’ bidirezionale.

vector

Un vettore manipola i propri elementi in un array dinamico; si può accedere ad ogni elemento direttamente con l’indice corrispondente, operazione chiamata random access.Appendere/rimuovere elementi alla fine di un vettore è molto veloce. Inserire elementi all’inizio o in mezzo è invece time consuming, dato che gli elementi che seguono devono essere mossi per far posto al nuovo elemento entrato.Quindi il tempo di inserimento e di cancellazione di elementi all’inizio e alla fine del vettore è costante, mentre il tempo varia linearmente con il numero di elementi per inserimento e cancellazione di elementi all’interno del vettore.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 89

Page 89: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

90

vector è un iteratore ad accesso casuale. Le locazioni di memoria sono contigue. L’accesso agli elementi è veloce, mentre è lento l’inserimento e l’eliminazione di elementi.

//stl/vector.cpp#include <iostream>#include <vector> int main(){

vector<int> coll;for (int i=1; i<=6; ++i) {coll.push_back(i);}

for (int i=0; i<coll.size(); ++i) {

cout<<coll[i]<<‘ ‘;}

cout << endl;}

In questa porzione di codice è stato definito un vettore di interi di nome coll ed è stato utilizzato per introdurre come elementi degli interi e per stamparli poi su standard output.

1 2 3 4 5 6

Esistono meccanismi per preallocare elementi ed una operazione per dire al vettore di riservare della memoria addizionale per non trovarsi con ripetute allocazioni di memoria.

v.reserve(n)

L’istruzione precedente riserva spazio per n elementi , ma non li inizializza. Questa operazione non cambia la dimensione del container; ha solo a che fare con le volte che ad un vettore viene chiesto di riservare memoria in risposte a ripetute chiamate di insert o push_back.

v.resize(n)

da al vettore v una nuova size pari ad n; se n è inferiore alla size corrente il vettore viene troncato dei suoi elementi eccedenti. Se n è superiore allora al vettore avvengono assegnati nuovi elementi dello stesso tipo in modo da raggiungere la size indicata.

Nella tabella riassuntiva seguente sono invece ricordate alcune operazioni possibili su vettori ed è indicata una caratterizzazione del tipo di oggetto ritornato:

CORSO DI INFORMATICA PER LA FISICA 90

Page 90: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

91

c.at(idx) // l’elemento con indice idxc[idx] // l’elemento con indice idx (no range checking)c.front() // il primo , no check di esistenzac.back() //l’ultimo no checkc.begin() //il random access operator per il primo elemc.end() //il r a o per la posizione dopo l’ultimo elemc.rbegin() //reverse iterator al primo elem di una iter.inv.c.rend() //un reverse iterator per la pos dopo l’ultimo el di

una iterazione rovesciacapacity() //il max num di elementi senza riallocazionec.size() // il numero di elementic.empty() //se il contenitore è vuotoc.max_size() //il max numero di elementi possibile

Con i vettori si possono inserire o eliminare elementi; ecco le operazioni più comuni, alcune di esse commentate:

c.insert(pos,ele) :inserisce alla posizione dell’iteratore pos una copia di ele e ritorna la posizione del nuovo elemento

c.insert(pos,n,ele): inserisce n copie di ele alla posizione di pos e non ritorna nulla c.insert(pos,beg,end) c.push_back(elem) c.pop_back() c.erase(pos) c.erase(begin,end) c.resize(num): cambia il numero di elementi a num; se la dimensione cambia

aumentando si costruiscono nuovi elementi facendo uso del default constructor c.resize(num,ele): cambia il numero di elementi a num; se la dimensione cambia

aumentando si costruiscono nuovi elementi tutti uguali a ele c.clear()

list

Essa è una sequenza di elementi a doppio link.. Ogni elemento ha la sua posizione di memoria e riferisce al suo predecessore e al suo successore.Il random access non è consentito.Quindi per accedere al decimo elemento di una list occorre passare attraverso i nove precedenti. L’accesso lineare all’i-esimo elemento è funzione lineare del tempo.L’immissione o l’ esclusione di un elemento è facile in qualunque posizione della lista.Più veloce rispetto a deque e a vector per rimuovere un elemento dal mezzo.E’ simile allo stack, ma consente di muoversi in due direzioni. La ricerca di elementi è lenta, ma veloce ne è l’inserimento e l’estrazione.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 91

Page 91: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

92

//stl/list.cpp#include <iostream>#include <list> int main(){

list<char> coll;for (cha c=‘a’; c<=‘z’; ++c) {

coll.push_back(c);}

//stampa tutti gli elementi//finchè ci sono elementi//stampa e rimuove il primo elemento while (!coll.empty())

{cout<<coll.front()<<‘ ‘;coll.pop_front();

} cout << endl;}

Ciò che si ottiene è la sequenza seguente:

a b c d e f g h i j k l m n o p q r s t u v x y z

deque

È una abbreviazione per “double endend queue”. Siamo quindi in presenza di un array dinamico che può essere espanso in entrambe le direzioni. L’inserzione di elementi in cima e in fondo è rapida. Essa è invece problematica in mezzo (movimento di elementi).

//stl/deque.cpp#include <iostream>#include <deque> int main(){

deque<float> coll;for (int i=1; i<=6; ++i) {

coll.push_front(i*1.1);}

for (int i=0; i<coll.size(); ++i) {

cout<<coll[i]<<‘ ‘;}

cout << endl;}

Il risultato di questa operazione sarà il seguente:

6.6 5.5 4.4 3.3 2.2 1.1

Stringhe

Esse vengono trattate come collezioni di caratteri. Infatti finora con le stringhe si sono effettuate poche operazioni:

CORSO DI INFORMATICA PER LA FISICA 92

Page 92: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

93

creazione lettura concatenazione scrittura ispezione della loro size

In ognuno di questi usi esse erano viste come una singola entità. Spesso questo tipo di uso astratto è esattamente ciò che si vuole: si vuole ignorare il contenuto interno di una stringa. Ma talvolta si vorrebbe guardare agli specifici caratteri entro una stringa.Allora si può pensare ad una stinga come un particolare container: esso contiene solo caratteri e supporta quasi tutte le operazioni dei containers. Una delle operazioni è ad esempio l’indexing, come per i vettori, per cui si può pensare di trattare una stringa come un vettore.Ad esempio si può pensare di suddividere una stringa in due parti separate da un carattere di blank (space, blank, tab, end-of-line). Oppure si vuol leggere una linea ed analizzarne il contenuto.Ad esempio:

s.substr(i,j)

crea una nuova stringa che mantiene una copia dei caratteri in s con indici nell’ intervallo [i, i+j]

getline(is, s)

legge una linea di input da is e la salva in s

s+= s2

sostituisce il valore di s con s+ s2.

size()e length()

Sono equivalenti: ritornano il numero di caratteri di una stringa.

empty()

rappresenta un modo per verificare se il numero di caratteri è=0.

max_size()

ritorna il massimo numero di caratteri che una stringa può contenere.

reserve()

riserva una zona di memoria corretta per la stringa da contenere (una volta definita) aggiustando il valore di default.

reserve(int)

indica il numero di caratteri che vanno riservati per la stringa. Ad esempio:

std::string s; // crea una stringa vuotas.reserve(80); // riserva memoria per 80 caratteri

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 93

Page 93: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

94

Accesso agli elementi di una stringa

L’operazione è effettuata tramite l’operatore [ ]. Non viene eseguito però il controllo se l’indice passato come argomento è valido. Se invece si utilizza la funzione membro at()il controllo viene effettuato. Sia l’operatore che la funzione membro ritornano il carattere alla posizione indicata dall’indice passato.Il primo carattere ha indice 0 mentre l’ultimo ha indice length()-1

const std::string cs (“nico”);std::string s(“abcde”);s[2]s.at(2)s[100]s.at(100)s[s.length()]cs[cs.length()] s.at(s.length())cs.at(cs.length())char & r=s[2];char* p=s[3];r= ‘X’;

// cs contiene ‘n’ ‘i’ ‘c’ ‘o’// s contiene ‘a’ ‘b’ ‘c’ ‘d’ ’e’//vale ‘c’//vale ‘c’//ERRORE comportamento indefinito//indica out_of_range

//ERROREcomport. indefinito

//indica ‘\0’//indica out_of_range//indica out_of_range//referenza al terzo carattere//puntatore al quarto//OK! Contiene ‘a’ ‘b’ ‘X’ ‘d’ ‘e’

Stringhe e vectors

Stringhe e vectors si comportano in modo similare, dato che sono entrambi container che sono implementati come array dinamici. Quindi una stringa può essere pensata come un particolare tipo di vettore che ha i caratteri come elementi, anche se con talune differenze:

Il goal primario di un vettore è quello di trattare gli elementi del contenitore e non il contenitore come un tutto. Allora le implementazioni di vettori sono ottimizzate per operare su elementi dentro il contenitore.

Una stringa invece deve manipolare il contenitore (la stringa stessa) come un tutto. Le stringhe sono quindi ottimizzate per ridurre i costi di assegnazione e di passaggio dell’intero container.

Funzioni numeriche globali

Gli header files <cmath> e <cstdlib> forniscono le funzioni numeriche globali che sono ereditate dal C. Per ragioni storiche alcune di esse si trovano in <cstdlib> altre in <cmath>.Le funzioni dello header file <cmath> sono riassunte nella seguente tabella:

pow()exp()sqrt()log()log10()sin()cos()tan()sinh()cosh()tah()asin()

PotenzaFunzione esponenzialeRadice quadrataLogaritmo naturaleLogaritmo in base 10SenoCosenoTangenteSeno iperbolicoCoseno iperbolicoTangente iperbolicaArcoseno

CORSO DI INFORMATICA PER LA FISICA 94

Page 94: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

95

acos()atan()atan2()fabs()fmod()

ArcocosenoArcotangenteArcotangente di un quozienteValore assoluto di un valore floating pointResto della divisione di un floating point

Contenitori associativi

In base a un criterio di ordine avviene un sorting automatico degli elementi.Una funzione paragona se il valore o la chiave speciale è quella definita per quel valore.Per default essi paragonano la chiave o gli elementi con l’operatore <.I contenitori associativi sono alberi binari: ogni elemento (ogni nodo) ha un padre e due figli. Esistono diversi tipi di contenitori associativi:set, collezione in cui gli elementi sono ordinati in funzione del loro valore , ogni elemento può apparire una volta sola multiset come il set, ma con la duplicazione di elementi consentitamap contiene elementi che sono coppie chiave/valore; la chiave è la base per il criterio di ordinamento; chiavi duplicate non sono ammessemultimap come una mappa ma con duplicazioni concesseDate queste definizioni ad esempio un set puo’ essere inteso come una mappa in cui il valore coincide con la chiave.Un esempio di set/multiset:

//stl/set1.cpp#include <iostream>#include <set> int main(){typedef std::set<int> IntSet;IntSet coll;//inserisce elemeti in ordine sparso da 1 a 6coll.insert(3); coll.insert(2); coll.insert(1); coll.insert(5); coll.insert(4); coll.insert(6); coll.insert(1);IntSet::const_iterator pos; for (pos=coll.begin(); pos != coll.end(); ++pos){

std::cout<< *pos<<‘ ‘;}

std::cout<<std::endl;}

map

Un esempio di map:

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 95

Page 95: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

96

#include <map> #include <algorithm> #include <iostream> #include <string> int main() { map<string,int> amap; amap["Primo”]=1; amap[“Secondo”]=2; cout << "Size : " << amap.size() << endl; amap["Terzo"]=3; amap["Quarto"]=4; cout << "Size : " << amap.size() << endl; map<string,int>::iterator it; for ( it=amap.begin(); it!=amap.end(); it++) cout << "map : " << it->first << " " << it->second << endl; cout << amap.find("Terzo")->second << endl; return 0; }size: 2size : 4map: Primo 1map: Quarto 4map: Secondo 2map: Terzo 3

l’ordine e’ alfabetico, infatti la key e’ di tipo string.

multimap

Un esempio di multimap:

#include <map> #include <iostream> #include <string> int main() { typedef multimap<int,string> mmap; mmap coll;//insert some elements in arbitrary order coll.insert(make_pair(5,”tagged”)); coll.insert(make_pair(2,”a”)); coll.insert(make_pair(1,”this”)); coll.insert(make_pair(4,”of”)); coll.insert(make_pair(6,”strings”)); coll.insert(make_pair(1,”is”)); coll.insert(make_pair(3,”multimap”));mmap::iterator pos; for ( pos=coll.begin(); pos!=coll.end(); ++pos){ cout << pos->second << ‘ ‘ ;

}cout <<endl;

}

Viene prodotto il seguente output:

CORSO DI INFORMATICA PER LA FISICA 96

Page 96: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

97

This is a multimap of tagged strings.

Contenitori speciali

Due tipi di contenitori speciali sono previsti: i container adapters a cui appartengono stack queue e priority queue e un contenitore speciale chiamato bitset. Passiamo in rassegna i vari tipi:

stack

la classe stack <> implementa uno stack altrimenti noto come LIFO (Last In First Out). Con push() si possono inserire elementi mentre con pop() si eliminano, in ordine inverso a quello di inserzione. Per usare uno stack occorre introdurre lo header <stack> . top() ritorna l’elemento successivo senza rimuoverlo. Per verificare se la classe stack contiene elementi le funzioni membro size() ed empty() sono implementate.Un esempio:

//cont/stack1.cpp#include <iostream>#include <stack>using namespace std;int main()

stack<int> st; //push tre elementi nello stackst.push(1);st.push(2);st.push(3); //pop e stampa di due elementi

cout<<st.top()<<’ ‘;st.pop();cout<<st.top()<<’ ‘;//modifica il top elementst.top()=77; //push due nuovi elementist.push(4);st.push(5);st.pop(); //pop e stampa i rimanentiwhile(!st.empty()

cout<< st.top()<<’ ‘;st.pop();cout<<endl;

L’output del programma è il seguente:

3 2 4 77

queue

La classe queue implementa una coda (di tipo FIFO, First In First Out).Le funzioni membro push() e pop() sono utilizzate per inserire o per rimuovere elementi (in ordine uguale a quello di inserimento).La funzione membro back() ritorna invece l’ultimo elemento nella coda.In realtà si tratta di un buffer in cui l’elemento successivo è sempre l’elemento che ha la più alta priorità nella queue. Se esiste più di un elemento con la uguale priorità, non è definito un ordine.L’ operatore usato è sempre <. Implementazioni proprie dell’operatore sono sempre possibili.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 97

Page 97: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

98

Iteratori

Gli iteratori sono dei puntatori agli elementi di un contenitore e ci permettono di muoverci all’interno di esso:

Iteratori monodirezionali: permettono di accedere all’elemento successivo o al precedente Iteratori bidirezionali : permettono di accedere sia all’elemento successivo che al

precedente Iteratori ad accesso casuale : permettono di accedere ad un qualunque elemento del

contenitoreEssi sono dei puntatori intelligenti: fanno scorrere il contenuto di un container come un puntatore fa scorrere una arrayDopo un’operazione il puntatore è lasciato al prossimo elemento della collezioneOgni classe container fornisce il suo tipo di iteratore che conosce la struttura interna del proprio container ed agisce su essaOperazioni fondamentali che definiscono il comportamento di un iteratore sono le seguenti:

Operator *

Ritorna l’elemento della posizione attualeOperator ++

Lascia che l’operatore proceda di un elementoOperators == e !=

Ritorna sei due operatori sono nella stessa posizioneOperator = assegna un iteratore

(assegna la posizione dell’ elemento a cui riferisce)Un’altra distinzione per operatori è quella che riunisce gli aeratori bidirezionali e quelli arandom access:

Bidirezionali: possono operare in due direzioni

In avanti con l’operatore incremento e all’indietro con l’operatore decremento. list, set, multiset,map,multimap hanno iteratori di questo tipo.

A random access: essi hanno tutte le proprietà dei bidirezionali, ma in più hanno il random access abilitato.Si possono aggiungere o sottrarre offset, processare differenze, paragonare operatori usando gli operatori relazionali < e >. vector deque e string hanno iteratori di questo tipo.

Nell’esempio che segue si vede come nel primo caso l’operatore “!= “può essere sempre utilizzato, con ogni tipo di container, mentre nel secondo caso l’operatore < funziona solo con quelli a random access.

for (pos=coll.begin(); pos != coll.end(); ++pos){…

}//ok con ogni containerInvece:for (pos=coll.begin(); pos < coll.end(); ++pos){

…}//non funziona con tutti i container, ma solo //con quelli a random access

CORSO DI INFORMATICA PER LA FISICA 98

Page 98: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

99

Iterator adapters

Gli iteratori sono pure astrazioni. In realtà quando qualcosa si comporta come un iteratore è ritenuto esso stesso un iteratore e quindi gode delle proprietà degli iteratori. Tre sono le principali categorie di iteratori:insert iterators: chiamati anche inserters. Essi sono usati per consentire agli algoritmi di lavorare in insert mode e non in overwrite mode. Ecco alcune funzionalità da essi possedute:

back_inserter(container)//appende nello stesso ordine con push_backfront_inserter(container)//inserisce in fronte in ordine inverso usando push_frontinserter(container,pos) //inserisce nello stesso ordine alla posizione pos usando insert

stream iteratorsIteratori di questo tipo leggono da e scrivono su una stream, cioè su oggetti che rappresentino canali di I/O. Essi forniscono una astrazione che permette all’input da tastiera di comportarsi come una collezione da cui si può leggere. Si può inoltre redirezionare l’output di un algoritmo direttamente a un file o sullo schermo

vector<string> coll;//legge da standard input fino a eof(o errore)//destinazione:coll(inserting)copy (istream_iterator<string>(cin),

istream_iterator<string>(),back_inserter(coll));

sort (coll.begin(),coll.end());//stampa tutti gli elementi senza duplicazioni//sorgente: coll//destinazione: standard output con newline tra gli elunique_copy (coll.begin(),coll.end(),ostream_iterator<string>(cout,”\n”));}

reverse iterators

Operano in reverse mode, sostituiscono una chiamata di un operatore incrementale con una a un operatore di decremento e viceversa.Tutti i container possono creare operatori di reverse tramite le loro funzioni membro rbegin() e rend().I vantaggi offerti:Tutti gli algoritmi sono capaci di operare in direzione opposta senza codice specialeUno step all’elemento successivo tramite l’operatore ++ è ridefinito come uno step all’elemento precedente con l’operatore - -.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 99

Page 99: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

100

#include <iostream>#include <vector>#include <algorithm>using namespace std;int main(){

vector<int> coll;//inserisce elementi da 1 a 9 for (int i=1; i<=9; ++i){

coll.push_back(i);}//stampa tutti gli elementi in ordine inversocopy (coll.rbegin(),coll.rend(),ostream_iterator<int>(cout,” ”));

cout <<endl;}

Se allora si considera *coll.rbegin()viene ritornato il valore dell’ultimo elemento.*coll.rend() è invece indefinito come pure *coll.end(), dato che entrambi si riferiscono ad una posizione che non è un valido elemento per la collezione.

Funzioni base

begin()

Ritorna un iteratore che rappresenta l’inizio degli elementi di un containerIl beginning è la posizione del primo elemento se esiste.

end()

Ritorna un iteratore che rappresenta la fine degli elementi di un container. La posizione end è la posizione dietro l’ultimo elemento. Iteratore chiamato past-the-end operator.

begin e end definiscono un half-open range. Gli iteratori loopano finche non arrivano a end.Non ci sono problemi se la dimensione è 0: begin() e end() coincidono.

Algoritmi

Sono funzioni globali che operano su container anche di tipo diverso. Gli algoritmi vengono usati per manipolare il contenuto dei container:

Inizializzazione ordinamento ricerca trasformazione del contenuto anche su intervalli di elementi.

Essi usano gli iteratori.Sono incluse le operazioni di ordinamento, come : sort, merge, min, max... e di ricerca come: find, count, equal.. e di trasformazione, come: transform, replace, fill, rotate, shuffle... oltrechè generiche operazioni numeriche come: accumulate, adjacent difference...Un esempio di uso di algoritmi:

CORSO DI INFORMATICA PER LA FISICA 100

Page 100: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

101

#include <algorithm>#include <iostream>#include <vector>int main{

vector<int> coll,vector<int>::iterator pos;coll.push_back(2);coll.push_back(5);coll.push_back(4);coll.push_back(1);coll.push_back(6);coll.push_back(3);

pos = min_element (coll.begin(),coll.end());//l’algoritmo ritorna la posizione del minimo elemento

cout <<“min”<< *pos<<endl; //stampa il minimo elementosort (coll.begin(),coll.end());//sorting in ordine ascendentepos=find(coll.begin(),coll.end(),3);//cerca il primo el. =3reverse pos,coll.end());

//rovescia l’ordine dal terzo elemento fino all’ultimo

qui l’output che si ottiene è il seguente, nei due casi:

1 2 3 4 5 61 2 6 5 4 3

Algoritmi di manipolazione

Nell’esempio seguente:

#include <algorithm>#include <iostream>#include <list>Using namespace std;int main{

list<int> coll;//inserisce elementi da 1 a 6 e da 6 a 1

for (int i=1; i<=6; ++i; { coll.push_front(i);coll.push_back(i);

}cout <<“pre: “;copy (coll.begin(),coll.end(),ostream_iterator<int>(cout,” “));cout<<endl;remove (coll.begin(),coll.end(),3);cout << “post:”; copy (coll.begin(),coll.end(),ostream_iterator<int>(cout,” “));cout<<endl;

Sono rimossi gli elementi con valore 3.size() è la vecchia size della collezione. end() ritorna la vecchia end. Gli elementi hanno cambiato il loro ordine come se i vecchi fossero stati rimossi. Ogni elemento di valore 3 è sovrascritto dai seguenti. Alla fine i vecchi elementi che non sono stati sovrascritti rimangono inalterati e la scrittura su standard output è la seguente:

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 101

Page 101: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

102

pre: 6 5 4 3 2 1 1 2 3 4 5 6post:6 5 4 2 1 1 2 4 5 6 5 6

Una miglioria al codice precedente è fornita dall’esempio seguente:

#include <algorithm>#include <iostream>#include <list>using namespace std;int main{

list<int> coll;//inserisce elementi da 1 a 6 e da 6 a 1

for (int i=1; i<=6; ++i; { coll.push_front(i); coll.push_back(i);

}cout <<“pre: “;copy (coll.begin(),coll.end(),ostream_iterator<int>(cout,” “));cout<<endl;list<int>::iterator end = remove (coll.begin(),coll.end(),3);cout << “post:”;copy (coll.begin(),end,ostream_iterator<int>(cout,” “));cout<<endl;cout<<“num. of removed elements: “<<distance(end,coll.end())<<endl;coll.erase(end,coll.end());copy (coll.begin(),coll.end(),ostream_iterator<int>(cout,” “));cout<<endl;}

come si vede dalla stampa finale l’effetto della modifica fa cancellare la parte finale del container:

pre: 6 5 4 3 2 1 1 2 3 4 5 6post:6 5 4 2 1 1 2 4 5 6num. Of removed elements: 26 5 4 2 1 1 2 4 5 6

Nonmodifying algorithms

Essi non cambiano l’ordine né tantomeno il valore degli elementi che processano. Essi possono essere chiamati da tutti gli standard containers.In sintesi i più usati:

VEDI TABELLA VECCHIA DISPENSA!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!Da inserire

Algoritmi di modificazione

Essi possono modificare il valore degli elementi direttamente o mentre essi vengono copiati da un range ad un altro.La sorgente non cambia, la destinazione si’.I principalisono:

for_each()

Accetta una operazione che modifica l’argomento. L’argomento è passato per reference.

CORSO DI INFORMATICA PER LA FISICA 102

Page 102: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

103

void square (int & elem){elem= elem*elem;

}for_each(coll.begin(), coll.end(), square);

transform()

Può essere usato per assegnare il risultato all’elemento originale.

int square (int elem){return elem*elem;

}transform(coll.begin(), coll.end(), coll.begin(), square);

Algoritmi di removing e mutating

Essi rimuovono, copiano o cambiano elementi.

remove()remove_if()remove_copy()unique()reverse()rotate()rotate_copy()next_permutation()random_shuffle()partition()

Rimuove elementi di un dato valoreRimuove elementi secondo un criterioCopia gli elementi che non soddisfano un criterioRimuove duplicati adiacentiRovescia l’ordine degli elementiRuota l’ordine degli elementiCopia gli elementi mentre ruota l’ordinePermuta l’ordine degli elementiPrende gli elementi in ordine casualeCambia l’ordine degli elementi in modo che quelli che soddisfano un criterio siano davanti

front() e back() ritornano l’elemento successivo senza rimuoverlo. Per verificare se la coda contiene elementi si usa size() ed empty(). In una priority queue invece gli elementi sono letti in rapporto alla loro priorità. L’ interfaccia è simile alle queue. L’elemento successivo non è il primo inserito, ma quello che ha la priorità più alta. Gli elementi sono quindi parzialmente ordinati in rapporto al loro valore. E’ anche possibile fornire un proprio criterio di ordinamento. Un esempio:

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 103

Page 103: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

104

#include <iostream>#include <queue>using namespace std;

int mainpriority_queue<float> q; //inserimento di 3 elementi q.push(66.6);q.push(22.2);q.push(44.4); //lettura e stampa di 2 elementicout<<q.top()<<’ ‘;q.pop() ;cout<<q.top()<<endl ;q.pop() ; //inserimento di 3 elementi nuoviq.push(11.1);q.push(55.5);q.push(33.3); //salto di un elementoq.pop();//pop e stampa dei rimanentiwhile(!q.empty()) cout<<q.top()<<’ ‘ ; q.pop() ;cout<<endl;

L’output del programma è allora il seguente :

66.6 44.433.3 22.2 11.1

CORSO DI INFORMATICA PER LA FISICA 104

Page 104: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

105

Polimorfismo ed ereditarietà

Il polimorfismo nei linguaggi di programmazione ad oggetti è un concetto cardine. In sintesi si potrebbe anticipare il concetto di polimorfismo dicendo che oggetti simili sono trattati nello stesso modo indipendentemente dal loro tipo. Esso è caratterizzato dalla frase “un’interfaccia, più metodi”. In altre parole il polimorfismo consente ad una interfaccia di controllare l’accesso ad una classe generale di azioni. La specifica azione selezionata è determinata dalla natura della situazione. Oggetti simili possono essere trattati come se fossero dello stesso tipo senza implementare trattamenti specifici per distinguere le tipologie.Un esempio tratto dal mondo reale è quello del termostato: un termostato (interfaccia) è una apparecchiatura che consente un controllo della temperatura indipendentemente dal tipo di combustibile (metodo) utilizzato per l’impianto.In C++ una nuova classe può essere ottenuta per eredità da una preesistente.

Le trasparenze in formato powerpoint relative a questo capitolo si trovano all’indirizzo web indicato nell’introduzione e sono raggiungibili alla voce: Polimorfismo.

Nella programmazione orientata agli oggetti l’introduzione del concetto di classe permette di definire, in qualsiasi programma, oggetti complessi e di modellare le interazioni fra di loro. La programmazione OO estende la programmazione basata sugli oggetti introducendo relazioni fra tipi e sottotipi

Una Fiat Panda e’ un veicoloUn Elenco Telefonico e’ una lista di abbonati

Questa categorizzazione viene ottenuta per mezzo di un meccanismo chiamato ereditarieta’ (inheritance).

Una Fiat Panda ha tutte le caratteristiche di un veicolo

Classi base e classi derivate

L’introduzione di una relazione tipo/sottotipo comporta che molte caratteristiche siano condivise:

Un veicolo si muove, una Fiat Panda si muove

Un tipo derivato puo’ riprodurre lo stesso comportamento pubblico del tipo base (oppure no)

L’ Elenco Telefonico e’ una lista , ma fornisce una serie di servizi diversi da quelli della lista

Un tipo derivato che riproduce il comportamento pubblico di una classe base e’ considerato un sottotipo di quella classe (ereditarieta’ pubblica)

Un tipo derivato che non riproduce il comportamento pubblico di una classe base non e’ un sottotipo di quella classe ma puo’ riutilizzarne le caratteristiche (ereditarieta’ privata)

Tipi derivati dalla stessa classe base hanno caratteristiche individuali che li rendono incompatibili fra di loro :

Una bicicletta e’ un veicolo, una Panda e’ un veicolo, una Panda NON e’ una bicicletta

Classi base possono essere a loro volta tipi derivati:

Page 105: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

106

Una Panda e’ un automezzo, un automezzo e’ un veicolo, una bicicletta NON e’ un automezzo

Nel caso di ereditarieta’ pubblica, un oggetto del tipo derivato puo’ essere usato indifferentemente come oggetto del tipo base.

Una Panda si comporta come un automezzo (astrazione)Un automezzo non e’ necessariamente una Panda!!!

“Is a”

Quando di un tipo si puo’ dire “e’ un…” si stabilisce automaticamente una relazione di ereditarieta’. Questo permette di:

Definire precise gerarchie di classi Generalizzare il comportamento dei tipi (astrazione) Utilizzare tipi diversi in maniera generica (polimorfismo)

Ereditarietà (Inheritance)

In C++ una classe può essere derivata da una classe esistente usando la sintassi:

class newclass: (public|private) oldclass {dichiarazioni...};

public e private specificano il tipo di ereditarieta’ che vogliamo implementare Inheritance pubblica:

La classe derivata avra’ lo stesso comportamento pubblico della classe base Inheritance privata

La classe derivata eredita il comportamento pubblico della classe base ma “esporta” il proprio comportamento.

Classi base

Non esistono prerequisiti che una classe deve soddisfare per essere una classe base.In linea di principio è possibile ereditare da qualsiasi classe. Ogni dato o metodo pubblico della classe base viene “esportato” alla classe derivata.Dati o metodi privati della classe base non possono venire esportati e rimangono caratteristici della classe base.Un ulteriore qualificatore (protected) viene introdotto per garantire accesso (da parte delle classi derivate) a dati e membri altrimenti “privati” della classe base.

CORSO DI INFORMATICA PER LA FISICA

veicoloveicolo

AutotrenoAutotreno AutomezzoAutomezzo

PandaPanda

BiciclettaBicicletta

106

Page 106: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

107

class Base {public:

int i;void f();

private:float r;int g(int k);

protected:double z;void r();

};

Gli attributi pubblici sono esportati alla classe derivata. Gli attributi privati non sono accessibili alla classe derivata, gli attributi protetti sono accessibili alla classe derivata ma non al mondo esterno.

class Derivata: public Base {public:

void ff();private:

double square() {

return z*z;}

};Derivata eredita implicitamente da Base tutti gli attributi pubblici. Dati e metodi caratteristici di Derivata (void ff(); e double square()). zz appartiene a Base ed è protetta.Derivata può accedere direttamente.

#include “Base.h”#include “Derivata.h”void main() {

Base b; // oggetto della classe BaseDerivata d; // oggetto di Derivatab.r(); // Errore! r() protettod.f(); // OK, Derivata eredita f()d.r(); // Errore! r() protettod.ff(); // OK, ff() appartiene a

// Derivatab.ff(); // Errore! ff() appartiene a

// a Derivata ma non a Base!}

Metodi virtuali

Ogni metodo pubblico o protetto della classe base viene ereditato dalle classi derivate (e ne costituiscono parte dell’interfaccia). Se un metodo della classe base è dichiarato virtual, questo può essere ridefinito in ognuna delle classi derivate.L’interfaccia viene definita dalla classe base, il comportamento dalle classi derivate. La Fiat Panda si comporta diversamente da una Ferrari, pur mantenendo le caratteristiche di veicolo.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 107

Page 107: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

108

class Base {public:

virtual void Print() {std::cout<<“questa è la classe Base”<<std::endl;}

};class A: public Base {public:

void Print() {std::cout<<“questa è la classe A”<<std::endl;}

};class B: public Base {public:

. . .// Print() non è ridefinito qui

};

#include “Base.h”void main() {

Base base; // oggetto della classe BaseA a; // oggetto di tipo AB b; // oggetto di tipo B

base.Print(); // questa e’ la classe basea.Print(); // questa e’ la classe Ab.Print(); // questa e’ la classe base

}

Metodi virtuali e classi astratte

Un metodo virtuale in una classe base puo’ venire dichiarato nullo (=0) e non essere definito. Questo trasferisce la responsabilita’ della definizione sulle classi derivate che devono allora definire quel metodo per potere essere usate.Una classe base con almeno un metodo virtuale nullo e’ chiamata classe astratta. Dal punto di vista del compilatore, una classe astratta non e’ un tipo completo e oggetti di questo tipo non possono essere creati. Una classe astratta definisce l’interfaccia per le sue classi derivate.E’ sempre comunque possibile utilizzare puntatori a classi astratte per manipolare oggetti di tipo concreto in maniera polimorfica.Si puo’ sempre guidare una Fiat Panda come se fosse un veicolo, una volta definito quale debba essere il comportamento del veicolo stesso (ed avendo la garanzia che la Fiat Panda si comporti come tale)

CORSO DI INFORMATICA PER LA FISICA 108

Page 108: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

109

class Base {public:

virtual void Print() = 0; // la responsabilita’ e’ deferita alle classi derivate};class A: public Base {public:

void Print() {std::cout<<“questa è la classe A”<<std::endl;}

};class B: public Base {public:

// B deve ora definire Print()void Print() {std::cout<<“questa è la classe B”<<std::endl;}

};#include “Base.h”void main() {

// Base base; // Questo e’ ILLEGALEBase *base; // questo e’ ammessoA a; // oggetto di tipo AB b; // oggetto di tipo B

// base->Print(); // ILLEGALE!base = &a ; // Polimorfismo base->Print();base = &b ; // Poliformismobase->Print()

}

Ereditarietà ed interfaccia

La definizione dell’interfaccia (metodi pubblici) della classe base è estremamente importante perchè determina il comportamento delle classi derivate.Un metodo della classe base può essere:

dichiarato e definito normalmente« la classe derivata eredita questo metodo e NON può ridefinirlo

dichiarato virtual e definito normalmente« la classe derivata eredita questo metodo e può ridefinirlo

dichiarato virtual e non definito (=0)« la classe derivata eredita il metodo e DEVE ridefinirlo (se si vuole che la classe derivata sia utilizzabile per creare oggetti)

Costruttori ed ereditarietà

I costruttori della classe base NON vengono ereditati! La classe derivata e` a tutti gli effetti un nuovo tipo e deve implementare i suoi propri costruttori. D’altra parte, la classe derivata “contiene” la classe base che dovra`, in qualche modo, essere inizializzata.I costruttori della classe derivata NON possono inizializzare direttamente i dati della classe base!Ne consegue che, in qualche modo, i costruttori della classe derivata devono invocare un costruttore della classe base…Il costruttore della classe derivata puo’ (deve) invocare il costruttore della classe base nella propria lista di inizializzazione:

. . .

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 109

Page 109: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

110

Derivata::Derivata(): Base(){

. . .}Derivata::Derivata(int i): Base(){

. . .}

Se il costruttore della classe base richiede degli argomenti, questi andranno ricavati dagli argomenti del costruttore derivato o forniti di default.

Distruttori ed inheritance

Anche se si sta definendo un nuovo tipo, il distruttore della classe base verra` “ereditato” dalla classe derivata.Se il distruttore della classe base non e’ dichiarato virtual, il distruttore della classe derivata NON verra` invocato quando uno dei suoi oggetti verra` distrutto!Solo il distruttore della classe base verra’ invocato in questo casoOgni classe base che si rispetti deve dichiarare il proprio distruttore virtual (anche se vuoto)Se il distruttore di una classe non e` dichiarato virtuale, probabilmente chi ha implementato quella classe non voleva che si potesse ereditare da essa o forse se ne e` dimenticato…

Inheritance privata

L’ereditarieta’ privata viene utilizzata normalmente per ereditare un’implementazione (quella della classe base) senza poi esportarne l’interfaccia privata.Utilizzata per ri-utilizzare codice esistente senza esporre i clienti (classi o programmi che utilizzeranno la classe derivata) ai dettagli dell’implementazione interna.Ri-uso di codice tramite inheritance e’ normalmente considerato sintomo di cattivo disegno ed andrebbe evitato.

Un esempio:l’elenco telefonico

Un (semplice) elenco telefonico puo` essere implementato per mezzo di una multimap di abbonati. In questo caso l’elenco e` una multimap ma, per nascondere i dettagli di implementazione, si utilizzera l’inheritance privata.Per ogni applicazione “cliente”, il comportamento dell’elenco telefonico sara` limitato alla sua sola interfaccia pubblica, l’interfaccia pubblica della multimap essendo “nascosta” dall’ inheritance privata.

CORSO DI INFORMATICA PER LA FISICA 110

Page 110: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

111

#include <string>#include <map>#include <vector>struct Abbonato {

std::string cognome;std::string nome;std::string numero;std::string indirizzo;

};typedef std::multimap<std::string, Abbonato, std::less<std::string> > Elenco; class ElencoTelefonico: private Elenco {public:

ElencoTelefonico();void AggiungiAbbonato(const Abbonato& a);std::string Indirizzo(std::string nome,std::string cognome) const;std::string Numero(std::string nome,std::string cognome) const;std::vector<Abbonato>& Lista(std::string cognome) const;

};Lo stesso risultato puo` essere ottenuto per “composizione”, nascondendo una multimap nella classe ElencoTelefonico ed evitando cosi` di utilizzare l’inheritance e senza complicare eccessivamente l’implementazione…La relazione “Is a” si trasforma cosi` in una relazione di composizione (“has a”).

#include <string>#include <map>#include <vector>struct Abbonato {

std::string cognome;std::string nome;std::string numero;std::string indirizzo;

};typedef std::multimap<std::string, Abbonato, std::less<std::string> > Elenco; class ElencoTelefonico {private:

Elenco elencoTelefonico;public:

ElencoTelefonico();void AggiungiAbbonato(const Abbonato& a);std::string Indirizzo(std::string nome,std::string cognome) const;std::string Numero(std::string nome,std::string cognome) const;std::vector<Abbonato>& Lista(std::string cognome) const;

};Ereditarietà multipla

L’ereditarietà multipla permette di derivare una classe da due o più classi base. La sintassi viene estesa per permettere una lista di classi base

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 111

Page 111: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

112

class A {. . . .};class B {. . . .};class AplusB: public A, private B {. . . .};

L’ ereditarietà multipla viene spesso utilizzata per combinare un’interfaccia ed una implementazione, ma è molte volte sintomo di un cattivo disegno .L’ereditarieta` multipla puo` portare ad effetti indesiderati:

D eredita due volte da A, F addirittura tre volteSi puo` anche verificare il caso di una classe che, attraverso complicate catene, eredita da se stessa.

dynamic_cast

dynamic_cast opera una conversione, se è possibile, fra due tipi. Il puntatore ritornato NON è nullo soltanto se il tipo dell’oggetto su cui si opera è quello che ci si aspetta

class Base {. . . . // base implementation};class Derived: public Base {. . . .

void new_method() ; // non e’ definito in Base!};void func(Base *ptr) // ptr e’ un oggetto dell classe Base{ ptr->new_method(); // Errore!!! (..non c’e’ in base !)

Derived *p = dynamic_cast<Derived *> (ptr)if (p !=0) {

p->new_method();}

}Un altro esempio di polimorfismo

Per capire meglio il polimorfismo si può utilizzare un altro esempio: il soldato.Tutti i soldati devono capire il messaggio attacca. Il messaggio ha conseguenze diverse a seconda del tipo di soldato:

un arcere lancia una freccia

CORSO DI INFORMATICA PER LA FISICA

A A

B B C C

D D

E E

F F

112

Page 112: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

113

un fante usa la spada un cavaliere lancia una lancia

Il gestore della schermata vuole tenere una lista di soldati e vuole poter dire ad ogni soldato di attaccare indipendentemente dal tipo ma basandosi solo sulla posizione.

list<Soldato> lista;riempiLista(lista);Posizione unaPosizione=...;list<Soldato>::iterator iter;for(iter=lista.begin();iter!=lista.end();iter++){ Soldato unSoldato=(*iter); if(unSoldato.posizione()==unaPosizione) unSoldato.attacca();}

class Soldato { void attacca() { // cosa scrivo qui?!? Per quale tipo di // soldato implemento il metodo attacca()? }};

In C++ il polimorfismo viene implementato tramite il concetto di ereditarietà (inheritance).

Una classe astratta definisce i messaggi . Una classe concreta: assegna i metodi ai messaggi. La classe concreta eredita da quella astratta.

class Soldato { virtual void attacca()=0;};class Arcere : public Soldato { virtual void attacca() { // lancia una freccia }};class Fante : public Soldato { virtual void attacca() { // usa la spada }};...

Un altro esempio: shape

Tutti gli oggetti nella finestra hanno comportamenti comuni che possono essere considerati in astratto:

disegna sposta ingrandisci etc...

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 113

Page 113: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

114

Il relativo codice:

Circle.hClass Circlepublic: Circle(Point2d center, double radius); ~Circle(); void moveAt(const Point2d & p); void moveBy(const Point2d & p); void scale(double s); void rotate(double phi); void draw() const; void cancel() const;private: Point2d center ; double radius ;;

Nella classe Circle dopo l’esplicitazione del costruttore e del relativo distruttore Point2d ( classe che rappresenta un punto in due dimensioni). Sono indicati i metodi (interfaccia pubblica) e i “dati” privati (attributi e membri).L’utilizzo della classe Circle e’indicato nell’ esempio seguente:

CORSO DI INFORMATICA PER LA FISICA 114

Page 114: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

115

circle.cc#include “Circle.h”void Circle::draw() const { const int numberOfPoints = 100; float x[numberOfPoints], y[numberOfPoints]; float phi = 0, deltaPhi = 2*M_PI/100; for ( int i = 0; i < numberOfPoints; ++i ) { x[i] = center_.x() + radius_ * cos( phi ); y[i] = center_.y() + radius_ * sin( phi ); phi += dphi; } polyline_draw(x, y, numberOfPoints, color_, FILL);}

void Circle::moveAt( const Point2d& p ){ cancel(); center_ = p; draw(); }void Circle::scale( double s ) { cancel(); radius_ *= s; draw(); }Circle::Circle( Point2d c, double r ) : center_( c ), radius_( r ) { draw(); } Circle::~Circle() { cancel(); }

ed il relativo main :

main.cc#include “Circle.h”int main() { Circle c( Point2d(10, 10), 5 ); c.draw(); c.moveAt(Point2d(20, 30)); return 0;}

L’ implementazione della classe quadrato:

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 115

Page 115: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

116

Square.hclass Square {public: Square(const Point2d&, const Point2d&, Color color = TRASPARENT); ~Square(); void moveAt( const Point2d& p ); void moveBy( const Point2d& p ); void changeColor( Color color ); void scale( double s ); void rotate( double phi ); void draw() const; void cancel() const;private: Point2d center_; Vector2d centerToUpperCorner_; Color color_;};

e la relativa:

square.cc#include “Square.h”void Square::draw() const { float x[4], y[4]; Vector2d delta( centerToUpperCorner_ ); for ( int i = 0; i < 4; i++ ) { Point2d corner = center_ + delta; x[i] = corner.x(); y[i] = corner.y(); delta.rotate( M_PI_2 ); } polyline_draw(x, y, 4, color_, FILL);}

void Square::rotate( double phi ) { cancel(); centerToUpperCorner_.rotate( phi ); draw(); }Square::Square(const Point2d& lowerCorner, const Point2d& upperCorner, Color color) : center_( median(lowerCorner, upperCorner) ), centerToUpperCorner_( upperCorner - center_ ), color_( color ) { draw(); } void Square::scale( double s ) { cancel(); centerToUpperCorner_ *= s; draw(); }

Il codice applicativo(client):

CORSO DI INFORMATICA PER LA FISICA 116

Page 116: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

117

#include “Circle.h”#include “Square.h”int main() { Circle c1( Point2d(2.,3.), 4.23 ); Square r1( Point2d(2.,1.), Point2d(4.,3.) ); Circle * circles[ 10 ]; for ( int i = 0; i < 10; ++i ) { circles[ i ] = new Circle( Point2d(i,i), 2. ); } for ( int i = 0; i < 10; ++i ) circles[ i ]->draw(); return 0;}

In questo esempio l’istruzione:

new Circle( Point2d(i,i), 2. );

Costruisce un vettore di puntatori a cerchi, crea oggetti in memoria e salva i loro puntatori nel vettore.Invece l’istruzione:

circles[ i ]->draw();

Itera sul vettore e invoca draw() per ogni elemento. A questo punto il problema è come gestire cerchi e quadrati insieme?Tutte le shapes hanno la stessa interfaccia: draw, pick, move, fillColor,…. Ma ogni sottotipo diverso può avere la sua personale implementazione.Una interfaccia di metodi puramente virtuali:

class Shape {public: Shape() { } virtual ~Shape() { } virtual void moveAt(const Point2d& where) = 0; virtual void changeColor(Color newColor) = 0; virtual void scale(double s) = 0; virtual void rotate(double phi) = 0; virtual void draw() const = 0; virtual void cancel() const = 0;};#include “Shape.h”class Square : public Shape { // …. Il resto tutto uguale a prima};

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 117

Page 117: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

118

main.cc#include “Circle.h”#include “Square.h”int main() { Shape * shapes[ 20 ]; int index = 0; for ( int i = 0; i < 10; i++ ) { Shape * s; s = new Circle( Point2d(i, i), 2.) ); shapes[ index ++ ] = s; s = new Square( Point2d(i, i), Point2d(i+1, i+2)) ); shapes[ index ++ ] = s; } for ( int i = 0; i < 20; i++ ) shapes[ i ]->draw(); return 0;

Class CenteredShape: public Shape {public: CenteredShape(Point2d c, Color color = TRASPARENT) : center_(c), color_(color) { /*draw();*/ } ~Circle() { /*cancel();*/ } void moveAt( const Point2d& ); void moveBy( const Vector2d& ); void changeColor( Color ); virtual void scale( double ) = 0; virtual void rotate( double ) = 0; virtual void draw() const = 0; virtual void cancel() const = 0;protected: Point2d center_; Color color_;};

CORSO DI INFORMATICA PER LA FISICA 118

Page 118: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

119

#include “CenteredShape.hh”class Square : public CenteredShape {public: Square( Point2d lowerCorner, Point2d upperCorner, Color col = TRASPARENT) : CenteredShape( median(lowerCorner, upperCorner), col), touc_(upperCorner - center_) { draw(); } ~Square() { cancel(); } virtual void scale( double s ) { cancel(); centerToUpperCorner_ *= s; draw(); } virtual void rotate( double phi ); virtual void draw() const; virtual void cancel() const;private: Vector2d touc_;};

occorre anche fare attenzione alle generalizzazioni:

class Rectangle {public: Rectangle(double x0, double y0, double lx, double ly) : lx_(lx), ly_(ly), x0_(x0), y0_(y0) { } void scaleX(double s); void scaleY(double s);protected: double x0_, y0_; double lx_, ly_;};

Attenzione: scegliere le relazioni di ereditarietà può essere non banale.Un quadrato è un rettangolo?

class Square : public Rectangle{public: Square(double x0, double y0, double l) : Rectangle(x0, y0, l, l) { }};

Avere lx_ e ly_ è ridondante per Square.Che cosa succede se si invoca scaleX o scaleY ?

Esempio di ereditarietà multipla

Una classe può ereditare da più classi:

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 119

Page 119: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

120

class DrawableObj{public: virtual void draw() = 0;};

class Shape {public: virtual void scale(double s) = 0; virtual void moveAt( Vector2d& ) = 0;};

class DrawableShape : public DrawableObj, public Shape{public: virtual void draw(); virtual void scale(double s); virtual void moveAt( Vector2d& ); };

CORSO DI INFORMATICA PER LA FISICA 120

Page 120: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

121

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 121

Page 121: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

122

UML (Unified Modeling Language)

Questo acronimo (UML- Unified Modeling Language) indica il linguaggio di modellazione ad oggetti e la sua rappresentazione tramite diagrammi per la visualizzazione di problemi di software engineering. Esso insegna come esprimere un object oriented design.Le trasparenze (in formato powerpoint) relative a questo capitolo sono raggiungibili all’indirizzo indicato nell’introduzione di questo testo sotto la dicitura UML.

Processi

Lo svolgimento di un processo visto come astrazione del concetto legato all’analisi sviluppo e modellizzazione di un problema passa attraverso fasi ben distinte che si possono categorizzare nel modo seguente:

I quattro momenti di sviluppo del processo si susseguono e possono essere ripetuti all’interno di una stessa fase.Un processo è quindi iterativo ed incrementale. Il software è sviluppato ed edito per gradi e a moduli. Ogni iterazione produce un software provato ed integrato che soddisfa un set di requirements del progetto. Esso contiene tutte le fasi di un ciclo sintetizzabili come:

analisi design implementazione test

Alcuni progetti sono classificati come high-ceremony projects: essi richiedono lo svolgimento di meetings, la scrittura di documenti , una fase iniziale (incipit) molto lunga, la presenza di sponsors…Altri progetti sono invece più immediati e vengono chiamati low-ceremony projects. Essi infatti richiedono la chiacchierata di un’ora ad inception phase perché possano essere iniziati.

Scopo (Inception phase) ed elaborazione

Durante l’inception phase si lavora al caso in esame capendone lo scopo, i costi, l’impatto. Se ne fa una analisi iniziale per capire le dimensioni del progetto.Essa può e deve richiedere poco tempo.Durante la fase di elaborazione le domande da porsi riguardano essenzialmente:

Che cosa costruire? Come ? Con quale tecnologia? Valutare i rischi: Quali sono i fattori che potrebbero far ‘deragliare’ il progetto?

Rischi

Sui requirements: Quali sono i requirements per il sistema? Quali sono le priorità d’uso e di implementazione? Qual e’ il pericolo nel costruire un sistema errato?

Tecnologici:

CORSO DI INFORMATICA PER LA FISICA

Scopo

(inception)Elaborazione

Costruzionecon varieiterazioni

TransizioneBeta testing

Performance tuningUser training

122

Page 122: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

123

Quanta esperienza pregressa è necessaria per usare tecniche OO?Di personale:Si ha wo/manpower sufficiente per affrontare il progetto?

Use cases

Interazione tipica che uno user ha con un sistema per raggiungere degli scopi. Quando si costruisce un processo attraverso gli use cases si fonda una base di comunicazione tra sponsor e sviluppatore nella stesura di un progetto. Con un word processor use case tipici:

Trasformare un testo in grassetto Creare un indice ad un documento

Nella fase di elaborazione occorre scoprire tutti i possibili use cases attraverso colloqui con gli users. Non occorre che essi siano dettagliati, occorre conoscerli nella loro individualità e diversità per valutarne l’impatto.

Scheletro di un modello concettuale

È il fondamento di un modello.Non occorre arrivare alla determinazione dei minimi dettagli.Se introdotti portano a modelli senza sostanza. Un modello dettagliato prende troppo tento e soccombe per paralisi nell’ analisi. Invece concentrarsi su dettagli importanti porta ad un modello migliore.La prototipatura è necessaria. Sae si adotta un linguaggio di programmazione in questa fase non è detto che poi sia lo stesso che verrà usato per la successiva implementazione. (smalltalk in fase di prototipatura, e poi c++ in fase di finalizzazione per l’implementazine globale).

Planning

Istituire una serie di iterazioni per la costruzione e assegnare use cases alle iterazioni.Un piano è terminato quando ogni use case è in una iterazione e possiede un momento di inizio. Occorre categorizzare gli use cases. Occorre anche categorizzare le priorità.Le domande chiave da porsi sono:

Si può stare senza questa funzione per un breve periodo Si può sopravvivere senza questa funzione per un certo periodo

Occorre avere una chiara idea dei rischi legati alle priorità tenendo conto delle varie fasi.Occorre fare una stima dello sforzo per ogni use case.Le domande da porsi e le successive valutazioni sono le seguenti:

So quanto tempo occorre Si può dare una stima in mesi-uomo Non ho idea

Costruzione

Il sistema viene costruito in una serie di iterazioni. Ognuna è caratterizzata come un mini progetto con tutte le fasi caratterizzanti tipiche:dall’analisi al design, dalla codifica al test e integrazione. Al termine di questa fase occorre fornire un demo finale per lo user insieme a tests per confermare che gli use cases sono stati correttamente costruiti.Questi tests si possono dividere in due diverse categorie: quelli scritti da sviluppatori chiamati unit tests e quelli scritti da testatori (diversi dai precedenti) che si chiamano system tests.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 123

Page 123: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

124

Transizione

Al termine del processo di costruzione attraverso iterazioni si passa alla finalizzazione in questa fase.L’ ottimizzazione è ancora assente. L’ottimizzazione di un progetto riduce chiarezza ed estensibilità del sistema per migliorarne la performance. E’ quindi una fase successiva che viene preceduta dalla fase di bug fixes.

Strategie nello sviluppo di un progetto

Nello sviluppo di un progetto si possono delineare diverse fasi : Requisiti: che cosa l’utente vuole Analisi: la visione dell’informatico dei requisiti

Disegno: l’aspetto del sistema software

Produzione: codifica

Test: debug e verifica dei requisiti

Mantenimento: installazione del prodotto e controllo del funzionamento per il resto della sua vita.

L’esempio: il sistema solare

Supponiamo di voler progettare e realizzare un programma per la simulazione del sistema solare.Occorre prima una definizione del modello, poi una analisi dettagliata dell’applicazione prima di scrivere il codice, un disegno di un modello dell’applicazione utilizzando un linguaggio grafico formale nell’intento di individuare le caratteristiche delle classi che parteciperanno alla realizzazione dell’applicazione,per semplificare la realizzazione del progetto. Rendere disponibile la documentazione a tutti coloro che in futuro partecipano alla soluzione del problema. La produzione con il successivo test completano la fase di realizzazione del progetto, che però ha anche bisogno di essere mantenuto nel tempo in una fase successiva.Per far ciò si possono utilizzare diversi modelli tra cui quello a cascata del tipo indicato nella seguente schematizzazione:

Oppure quello evoluzionario del tipo indicato nel grafico seguente:

CORSO DI INFORMATICA PER LA FISICA

Analisi

Disegno

Produzione

Test

Requisiti

124

Page 124: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

125

Confronto tra i modelli di sviluppo

Il modello a cascata: Processo lineare (si torna al passo precedente solo in caso di problemi) Confinamento delle attività in ogni fase Facile da gestire (gestione delle scadenze) Difficile da modificare Prodotto utilizzabile solo alla fine del processo

Nel modello evoluzionario: Processo ciclico (brevi processi completi) Attività distribuite su più fasi Difficile da gestire Facile da modificare e integrare Prototipo utilizzabile fin dal primo ciclo

Requisiti

Definizione delle richieste da parte dell’utente del programma (o di una sua parte) sul sistemaSi parla di programmazione per contratto perchè l’utente richiede solamente la definizione del servizio richiesto NON la metodologia seguita per fornirglielo. E’ possibile delegare parte del lavoro richiesto ad altri: il sistema è indipendente da chi è il suo utente.

Analisi

Comprensione e razionalizzazione delle richieste dell’utente

Costruzione di un modello

astrazione (semplificazione delle relazioni)

rilevanza (identificazione degli oggetti chiave)

Da non trascurare: analisi delle soluzioni esistenti. Può far risparmiare molto tempo!!!

Disegno

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA

requisiti

analisi

disegno

Produzione

test

Definizione delle

interfacce

Definizione di oggetti e classi

Definizione

degli stati

e dell’implementazione

Definizione delle

relazioni

125

Page 125: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

126

Dopo ogni ciclo bisogna analizzare i rischi, la stabilità del disegno e la complessità delle classi

Se una classe è troppo complessa conviene dividerla

Ad ogni ciclo il numero di modifiche deve diminuire

Architetture troppo complesse devono essere modularizzate

Codifica

Non sopravvalutare questa fase. Come si vede nello schema precedente alla codifica è riservata una parte esigua del tempo globale (circa il 15%). Grossa parte del tempo di progettazione è presa invece dall’analisi e dal disegno (65%).

Test

Debugging: è ovvio… il codice non deve dare errori. Use cases: specificano il comportamento del sistema in una regione. Scenarios: sono esempi concreti di use cases. Per definizione se tutti gli scenari sono

soddisfatti correttamente il test è positivo.Metodi di sviluppo del software

Un metodo comprende:Una notazione: mezzo comune per esprimere strategie e decisioni.

Un processo: specifica come deve avvenire lo sviluppo.

CORSO DI INFORMATICA PER LA FISICA 126

Page 126: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

127

Gli scopi di un linguaggio unificato di modellizazione risiedono principalmente nel: Dare agli utenti un linguaggio espressivo e visuale per consentire la modellizzazione dei

sistemi utilizzando concetti OO Fornire meccanismi di estensibilità e specializzazione per estendere i concetti di base Essere indipendente da particolari linguaggi di programmazione Supportare lo sviluppo di concetti a più alto livello come

1. Collaborazioni2. Framework3. Patterns4. Compomenti

Creare un linguaggio di modellizzazione usabile da umani e da macchine

Diagrammi

In un linguaggio di modellizzazione ad oggetti hanno particolare risalto i diagrammi, che, data la storia passata e controversa dei diversi linguaggi di modelizzazione, continuano a persistere in diverse forme e catalogazione.Si possono classificare i diagrammi in grandi categorie:Class Diagrams: riguardano l’aspetto statico del sistema. Descrivono le classi con attributi e metodi e le relazioni tra di esse.Sequence e collaboration digrams: riflettono invece il comportamento dinamico del sistema. Sequenza dei messaggi scambiati fra gli oggetti.Use case diagrams: illustrano gli use cases, le relazioni fra di essi e gli attori che vi partecipano.State diagrams: descrivono gli stati in cui ogni oggetto si può trovare e le modalità con cui passa da uno stato all’altro.

Class diagrams

Un class diagram descrive i tipi di oggetti nel sistema e i vari tipi di relazioni statiche che esistono tra essi.Esistono due tipi principale di relazioni statiche:associazioni (un cliente può noleggiare diversi video)sottotipi (una infermiera è un tipo di persona)Un diagramma di questo tipo mostra gli attributi e le operazioni di una classe e i vincoli che si applicano al modo in cui gli oggetti sono connessi.I concetti tra le classi vengono rivisitati. Si valutano le relazioni tra i diversi oggetti e si attua una decomposizione funzionale all’interno di una classe. Si affida una responsabilità ai metodi.

Rappresentazione delle classi

Rappresentazione di una classe C++ in UML

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA

nome

+ metodo(arg)# metodo(arg)- metodo(arg)

-dato-

dato

operatori

attibutipubblico

protetto

privato

127

Page 127: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

128

Nome.hclass Nome {private: Tipo1 variabile1; Tipo2 variabile2; Tipo3 variabile3;public: Nome(); ~Nome(); Tipo4 funzione1 ( arg );protected: Tipo5 funzione2 ( arg );private: Tipo6 funzione3 ( arg );};

Attributi e metodi

Principali relazioni tra classi

associazione * 1 aggregazione by reference

(il composito non vive senza il componente) aggregazione by value

(aggregazione fisica: esistenza contemporanea) dipendenza generalizzazione (inheritance, ereditarieta’)

Associazioni

Esse rappresentano le relazioni tra le istanze delle classi (una persona lavora per una azienda, una società ha un numero di uffici).Da una prospettiva concettuale le associazioni rappresentano le relazioni.

CORSO DI INFORMATICA PER LA FISICA

Nome - variabile1:Tipo1 - variabile2:Tipo2 - variabile3:Tipo3

+ funzione1(arg):Tipo4# funzione2(arg):Tipo5- funzione3(arg):Tipo6

Plane_distance : double_nor : Vector_origin : Point

distance()derDist()

Surfaceid : int

distance()derDist()

Cylinder

Publico (+)

Privato (-)

Protetto (#)

** 1

ordine

clientedataRicevimento

PrepagatoNumero:stringPrezzo:denaro

NomeIndirizzo

Rateazione():string

* 1

associazioneassociazione

molteplicitàmolteplicità

classeclasse

128

Page 128: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

129

Il diagramma indica la relazione di associazione tra le classi, la molteplicità. L’asterisco tra Cliente e ordine indica che il cliente può avere molti ordini associati, l’ 1 indica che un orine viene de un unico cliente.In generale la molteplicità indica i limitiinferiori e superiori per il numero di oggetti partecipanti.Le associazioni indicano responsabilità.Esiste quindi uno ed un solo metodo associato ad un cliente che dice quali ordine un determinato cliente ha fatto.Similarmente ci sono anche metodi nella classe ordine che fanno conoscere quale cliente ha fatto un determinato ordine.

Aggregazione(contenimento)

By reference (condivisa)Un autista guida più automobili

By value (possesso)Una automobile possiede il suo motore

Composizione

La composizione è una aggregazione, ma sentita più fortemente, come appartenenza. Con la composizione l’oggetto parte può appartenere a solo un tutto. In più le parti sono attese vivere e morire con il tutto. Ogni annullamento del tutto prevede un annullamento a cascata delle parti.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA

Autista

Motore

Automobile

PointPolygone

1 1..*1..*1

-_points

129

Page 129: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

130

Nell’esempio del punto del poligono qui riportato la freccia aperta indica che il punto non è navigabile. Il punto non conosce i poligoni. Un punto può apparire in un poligono alla volta. Il poligono è costituito da punti.

Dipendenza

Non c’è nessuna associazione, ma c’è comunque relazione di uso.Un esempio illustra il concetto:

CORSO DI INFORMATICA PER LA FISICA 130

Page 130: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

131

Il CD non conosce il CDPlayer Il CDPlayer usa il CD: se cambia il formato del CD il CDPlayer deve essere modificato

Generalizzazione (ereditarietà)

Esempi di Class Diagram

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA

{virtual}

AutoSportiva AutoDiLusso

Ferrari

Autista

Automobile

#_autista

Motore#_motore

{virtual}

Shape

draw()cancel()moveBy()

Circleradius_ : double

draw()

Point2dCenteredShape

moveBy() 1 11

SquareCenterToUpperCorner_ : Vector2d

draw()

relazione di aggregazione

relazioni di ereditarietà

classi concrete

classi astratte

1

131

Page 131: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

132

Interaction Diagrams

Gli interaction diagrams sono modelli che descrivono come gruppi di oggetti collaborano in qualche comportamento.Generalmente un interaction diagram descrive il comportamento di un singolo use case. Il diagramma mostra un numero di oggetti-esempio e i messaggi che vengono passati tra di essi nello use case. Due sono i tipi principali di interaction diagrams: i sequence diagrams e i collaboration diagrams.Nei primi un oggetto è mostrato come una scatola in alto rispetto ad una linea verticale tratteggiata che parte da esso. Questa linea verticale è chiamata la lifeline dell’oggetto e rappresenta la vita dell’oggetto durante l’interazione. Ogni messaggio è rappresentato da una freccia tra le lifelines di due oggetti. L’ordine con cui questi messaggi vengono inviati è mostrato scorrendo il diagramma dall’alto in basso.

CORSO DI INFORMATICA PER LA FISICA 132

Page 132: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

133

Collaboration Diagrams

In un collaboration diagram gli oggetti esempio sono indicati entro rettangoli e i messaggi che caratterizzano uno use case sono numerati. Numerare i messaggi rende più difficile vederne la sequenza , ma in questo layout spaziale si possono mostrare altre informazioni più facilmente. Si può mostrare come gli oggetti sono connessi e usare il layout per sovrapporre altra informazione.

Altri diagrammi

Esistono altri tipi di diagrammi che vengono utilizzati ad esempio per la gestione di grandi pacchetti (pakage diagrams)di software o gli state diagrams che descrivono il comportamento di un sistema, cioè tutti i possibili stati in cui un oggetto può presentarsi o come i cambi di stato di un oggetto possano avvenire su un oggetto in relazione ad un evento che lo raggiunge, i deployment diagrams che indicano le relazioni tra

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 133

Page 133: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

134

componenti software e hardware di un sistema. Lo studio di questi particolari diagrammi esula però gli scopi di questo corso e la trattazione viene rimandata a testi specialistici.

CRC (Classi, Responsabilità, Collaborazioni)

Quando si inizia a pensare ad un progetto e a delinearne le classi che lo costituiscono diventa di fondamentale importanza attuareuna serie di operazioni che permettono di arrivare con maggior facilità a una progettazione ragionata e realistica del problema. Innanzitutto occorre identificare i protagonisti ed analizzare il ruolo dei vari oggetti. Inoltre concentrarsi sul comportamento degli oggetti e non sulla loro rappresentazione. Occorre cercare Oggetti con proprietà comuni: oggetti diversi appartengono a classi diverse, o sono solo oggetti diversi?e definirne le interfacce (le operazioni che soddisfano le responsabilità): una corretta assegnazione delle responsabilità è la chiave di una buona modularità e riuso.Le responsabilità vanno suddivise tra i vari oggetti del sistema e non deve esistere un controllo centralizzato. Un oggetto deve compiere le proprie responsabilità e delegare ad altri operazioni specifiche. Nell’attuazione di un progetto occorre identificare le relazioni attraverso alcune ricerche di base che aiutano a stilare un progetto realistico come ad esempio cercare collaborazioni, aggregazioni, generalizzazioni.Le relazioni di tipo logico si possono classificare in tre categorie principali:generalizzazioni (del tipo ln –s) che implicano uso di inheritanceaggregazioni (che rispondono alla domanda has) e che richiedono composizioni by valuedipendenze (che rispondono alla domanda knows) e che richiedono composizioni by reference.Uno dei punti critici è distinguere se il rapporto fra due oggetti è del tipo avere o essere:

Un LorentzVector è un Vector o ha un Vector? Una Traccia è un vector<Hit> o ha un vector<Hit> ? Un Rivelatore è una Superficie o ha una superficie?

Per risolvere il problema bisogna guardare a che cosa fanno!In C++ la scelta fra aggregazione by value o by reference può seguire questo schema:

Tipi semplici (int, float, …): by value Parte dello stato dell’oggetto: by value Oggetti condivisi: by reference Assegnati a run time: by reference Oggetti condivisi by reference: attenzione a chi ha la responsabilità di crearli e cancellarli!

(un new corrisponde a un delete! )Un approccio corretto è quello di guardare il sistema dall’esterno.Identificare prima di tutto gli oggetti che interagiscono con l’utente esterno e i messaggi a cui devono saper rispondere (think client!)In seguito identificare gli oggetti che forniscono servizi a questi ultimi e così via.Gli algoritmi vengono per ultimi!!!

CRC Workshop

Il CRC workshop è un metodo per la definizione di una architettura bilanciata.Ogni partecipante al workshop (persona fisica) svolge il ruolo di una classe. Il progetto da analizzare viene decomposto nei suoi componenti che vengono man mano identificati attraverso una discussione comune che porta alla individuazione di possibili classi. Ogni perosna fisica impersona una classe e la discussione continua con l’assegnazione deil comportamento delle classi, cioe’ dei meccanismi di interrelazione tra esse e delle funzionalita’ che ogni classe deve possedere. Quando si deve affrontare la risoluzione di un problema attraverso la stesura del progetto, prima di iniziare occorre passare attraverso le seguenti fasi:

Individuazione delle classi

CORSO DI INFORMATICA PER LA FISICA 134

Page 134: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

135

Contrattazione delle responsabilità Definizione delle collaborazioni

Occorre difendersi dal tentativo di assegnazione di responsabilità contrarie alla natura della classe e quindi occorre tentare di rifiutare le responsabilità. Ogni attore deve porsi le seguenti domande:Dovrei? (Non sono io che lo devo fare!)Potrei? (Non ho i mezzi, o lo stato per farlo!)Occorre cercare di fare poco lavoro. Se si è accettata una responsabilità, occorre cercare di far fare il lavoro a qualcun altro. Occorre potenziare i collaboratori, non interferire.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 135

Page 135: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

136

Design patterns

I design patterns sono elementi di software OO riutilizzabilePiccoli insiemi di classi che collaborano implementando dei comportamenti tipici. Alune categorie di patterns:

Creational patterns Structural patterns Behavioral patterns

I client possono richiedere la creazione di un prodotto senza dipenderviLa Factory dipende dai prodotti concreti, mentre i client dipendono solo da quelli astratti.

Una richiesta da un client a un server, può essere mediata dal Proxy, che può compiere anche altre operazioni (I/O, caching, etc.).

Composite

CORSO DI INFORMATICA PER LA FISICA

AbstractProduct

ConcreteProduct1 ConcreteProduct2

FactorycreateProduct1 () : AbstractProductcreateProduct2 () : AbstractProduct

Client

Subjectrequest( )

RealSubjectrequest( )

Proxy_subject : RealSubject

request( )11

Client

_subject

. . ._subject->request();. . .

Leafoperation( )

Componentoperation( )

Compositeoperation( )

1..*1..*

Client

for c in all _children c->operation();

_children

136

Page 136: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

137

Il client può trattare componenti e compositi usando la stessa interfaccia. La composizione può essere ricursiva. Esempio: programmi di grafica.

Gruppo di Shapes

Il gruppo di shapes è il CompositeLa shape è il ComponentLe shapes concrete (Circle, Square, ecc...) sono le Leaf.

Il codice del modello composite:

Shape.hclass Shape {public: Shape() {} virtual void draw() const = 0; // altri metodi virtuali ( = 0 )};

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA

Circle, Square, ...draw( )

Shape

draw( )

GroupofShapesdraw( )

1..*

1..*

Client

components

137

Page 137: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

138

Circle.h#include “Shape.h”class Circle: public Shape {public: Circle(Point2D c, double r): Shape(), center_(c), radius_(r) {} void draw() const { ; // draw circle } // altri metodi definiti per Circleprivate: double radius_; Point2D center_;};

GroupofShapes.h#include “Shape.h”class GroupofShapes : public Shape {public: typedef vector<Shape *> Container; typedef Container::const_iterator Iterator; GroupofShapes(){} void draw() const { Iterator p=components.begin(); Iterator pe=components.end(); while (p!=pe) { (*p)->draw(); p++; } return; } // gli altri metodi sono definiti operando // sui componentiprotected: Container components;};

Strategy

Il pattern Strategy permette di scegliere l’algoritmo da eseguire a run-time. Nuovi algoritmi possono essere introdotti senza modificare il codice utente.

Observer

CORSO DI INFORMATICA PER LA FISICA

ConcreteStrategyAdoAlgorithm( )

ConcreteStrategyBdoAlgorithm( )

ConcreteStrategyCdoAlgorithm( )

Client StrategydoAlgorithm( )

{ . . . Strategy* s; s->doAlgorithm(); . . .}

138

Page 138: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

139

Lo stato dell’Observer dipende dallo stato del Subject.Il Subject notifica a tutti gli Observer registrati che il suo stato è cambiato.

Open/Closed principle

In generale un buon codice deve essere aperto ad estensioni e chiuso a modifiche.Modificare un codice funzionante può introdurre bachi…L’Object Oriented, con il meccanismo delle classi virtuali, permette di applicare questo principio.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA

Observerupdate( )

Subject_observers : Observer

attach (Observer)notify ()

0..*0..*for all o in _observables o->update();

_observers

return _status;_status = _subject->status();

ConcreteSubject_status : Status

status( )

ConcreteObserver_status : Status_subject . ConcreteSubject

update( )

_subject

139

Page 139: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

140

HTML

HTML (HyperText Markup Language) è un linguaggio sviluppato presso i laboratori del CERN di Ginevra evoluto poi nel W3 Consortium (collaborazione tra il laboratori for Computer Science del MIT e l’ INRIA gruppo tecnologico francese in collaborazione con il CERN) che consente di formattare testo, aggiungere grafica, suoni, video in forma di un ASCII file che qualunque computer può leggere (per proiettare poi video e avere il suono occorre che il computer abbia l’hardware necessario). La chiave di comprensione di HTML sta nei tags, parole chiave che sono situate tra i simboli “<” e “>” e che indicano quale tipo di contenuto segua nella dichiarazione. HTML è quindi testo che contiene questi simboli e che può essere interpretato da un programma speciale, il browser. Quindi un browser può interpretare i tags di HTML e poi mostrare il documento formattato sullo schermo.Esso non è solo un modo per creare documenti dall’apparenza eccellente, ma è anche un Hypertext: documenti scritti in HTML possono contenere links ad altri documenti in HTML o a qualunque altro documento su internet per la creazione di links ad altri siti realizzando quindi un “web”. Molti programmi sul web consentono di scrivere intere pagine di HTML senza doverne necessariamente imparare le caratteristiche. I programmi piu’ diffusi sono:

Adobe Page Mill Microsoft Publisher Microsoft Front Page Il composer di Nestcape Macromedia Dream Weawer

In questo corso vi si insegna a programmare in HTML step-by-step utilizzando il linguaggio HTML direttamente nella sua versione 4.0.

DTML, XML HTML browsers

DHTML è una combinazione di tecnologie usate per creare un contenuto dinamico per pagine web. Si basa su HTML(4), Cascading Style Sheets e Java Script: questi elementi sono supposti lavorare insieme utilizzando le regole del Document Object Model (DOM) per cambiare il contenuto di una pagina anche dopo che è stata caricata nel browser.XML (Extensible Markup Language) linguaggio che può essere utilizzato per creare i propri markup languages particolarmente utili ed indicati per i propri specifici sviluppi.I tools più importanti per creare documenti in HTML format sono gli HTML Browsers: i più noti sono Netscape Communicator (comunemente chiamato Navigator, o Netscape) e Microsoft Internet Explorer. All’oggi la percentuale di users che normalmente utilizza Netscape è 60%, mentre il restante 40% è per Internet Explorer.

Utilizzatori e Programmatori

OGNI computer puo’ leggere HTML, ma ognuno lo fa a suo modo, in accordo con quanto concesso dal proprio sistema operativoAlcuni PC possono solo mostrare testo, vecchi PC possono mostrare al massimo 256 colori, i nuovi PC naturalmente no.Il modo con cui i visitatori di un sito si connettono a Internet puo’ influenzare il modo con cui i loro computers possono vedere le pagine webEs: Un MAC user puo’ non vedere la grafica di una vostra pagina se e’ connesso al web attraverso una shell Unix o con un ssh…

CORSO DI INFORMATICA PER LA FISICA 140

Page 140: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

141

Un visitatore su un computer lento con un modem lento odiera’ tutte le ‘fancy things’ della vs. pagina (pupazzetti in moto, figure con risoluzioni da fotografo professionista,

ecc.) Ogni persona che guarda la vostra pagina puo’ vederla in modo diverso da quello che voi pensate perche’ Dipende la sistema del suo computer Dal browser che ha scelto Dalle capacita’ di grafica della sua macchina Dalla velocita’ del suo modem Dal tipo di connessione al web Dai settings scelti per il proprio browser

Il programmatore ha controllo limitato sull’ appearance della pagina quando arriva allo userQuanto universale volete che il vostro documento sia? Tutti o pochi eletti?

Le basi di HTML

Si può creare un documento HTML con qualunque word processor o text editor (con nessuna esclusione, nemmeno Notepad WordPad in Windows o TeachText e SimpleText nel regno Macintosh.

tags

I tags sono comandi scritti tra una coppia di simboli di minore (<) maggiore (>), noti anche come angle brakets che indicano come il browser deve mostrare il testo. Entrambe le tag di apertura e chiusura utilizzano la stessa parola di comando (command word), il tag di chiusura porta un carattere “/” in più.

<EM>blue moon</EM>

attributes

Molti tag hanno speciali attributi che offrono una varietà di opzioni per il testo contenuto. L’attributo sta tra la opening tag e il simbolo di maggiore finale come nell’esempio seguente:

<TABLE BORDER>

BORDER in questo caso è l’attributo mentre TABLE è il tag.

values

Gli attributi hanno a loro volta dei valori. Talvolta si può scegliere un valore in un gruppo di opzioni possibili. Nell’esempio seguente CLEAR è un attributo di BR ed ha valore left. Si possono aggiungere anche i doppi apici “” per indicare il valore da attribuire ad un attributo, ma non sono indispensabili se i caratteri utilizzati sono lettere dell’alfabeto (maiuscole o minuscole) numeri o “-“ o il punto “.”.

<BR CLEAR=left>

I tag possono essere anche inclusi uno nell’altro per modificare un testo già modificato.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 141

Page 141: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

142

<H1>Cherry<EM>tomato</EM></H1>

La spaziatura o i caratteri di blank non vengono contati in un documento HTML, mentre un nuovo paragrafo è contrassegnato dal simbolo <P>. La fine dello stesso paragrafo è contrassegnata dal tag </P>.

Simboli speciali

Il set di caratteri ASCII standard ne contiene 128, ma altri di uso comune non sono inclusi. Per vederli nel proprio documento stampati correttamente occorre definirli utilizzando l’ISO Latin-1 standard set di caratteri. Nell’esempio seguente si vede l’effetto delle diverse richieste di stampa del carattere speciale:

<H1> Visca el Barça</H1> porta alla stampa della linea: Visca el Barÿa mentre la scritta:

<H1> Visca el Bar&#231;a</H1>

porta alla scritta voluta.Se invece non si vuole che l’autowrapping del test separi due parole contigue (es. Coca Cola) allora occorre frapporre tra le due parole i caratteri &nbsp.Anche la scritta x> 3 o x<2, ad esempio, e’ impossibile da scrivere direttamente dato che il simbolo di maggiore (minore) e’ parte di un tag del linguaggio. Si puo’ ottenere il risultato voluto scrivendo &gt o &lt. Sono caratteri speciali anche i doppi apici perche’ delimitano un campo nel linguaggio. Se si vuole che invece il doppio apice sia scritto nel testo occorre indicarlo come &quot. Se invece si desidera il simbolo +- occorre indicarlo come &plusmn.Se invece si desidera introdurre nella propria pagina web del testo preformattato (tipicamente stralci di codice programma) la cosa piu’ semplice e’ quella di far precdere al testo che si importa il tag <pre> seguito alla fine del testo dal tag </pre>. In questo modo tutte le indentazioni tipiche del linguaggiodi programmazione vengono salvate.

URL(Uniform Resource Locator)

URL, come Uniform Resource Locator, indica l’indirizzo di un file su internet: esso è unico.

“http://www.site.com/liz/file.html”“news:soc.culture.catalan”“mailto:[email protected]”“File:///harddisk/Web/home.html”

nell’esempio http:// è lo schema, www.site.com/ è il nome del server, /liz/ è il path e file.html è il nome del file.Esiste anche la possibilità di utilizzare path relativi:

“../info/data.html”

Questa scrittura significa che si vuole accede al file data.html nel direttorio info che e’ ad un livello superiore di quello in cui si opera.

Il design del proprio sito web

Esistono regole pratiche e di buon senso da utilizzare per la stesura di una propria pagina web. Essenzialmente rispondere alle seguenti domande può dare già una

CORSO DI INFORMATICA PER LA FISICA 142

Page 142: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

143

traccia. Seguire poi le semplici istruzioni può portare ad una buona stesura del proprio sistema di pagine.Quale informazione deve essere contenuta nella proprie pagine web?Qual è l’ audience a cui è rivolta?Quante pagine sono necessarie per comunicare quello che si desidera?Disegnare il proprio sito su CARTA con una PENNA, anche se sembra anacronistico.Informarsi facendo surfing su web. Organizzare i propri file in forma di una cartella centrale o di base e sottocartelle utilizzando nomi semplici senza punteggiatura ed uno schema consistente per nomenclatura per la creazione della propria home page.

Creare una pagina web

Aprire un text editorCreare il corpo del testo in HTMLSalvare come text o ASCII con estensione .htm o .htmlGuardare la propria pagina creata in un browser (Netscape o Internet Explorer)Per iniziare la propria pagina web:

<HTML>

</HTML>

Occorre che la pagina sia riconosciuta indipendentemente dal browser utilizzato, e questo sta nella dichiarazione della prima riga dell’esempio precedente.

HeaderIl campo delimitato dallo header si sviluppa tra <HEAD> e </HEAD>

TitleIl campo delimitato dal titolo si sviluppa tra <TITLE> e </TITLE>

BodyIl campo delimitato dal corpo del documento si sviluppa tra <BODY> e </BODY>

La dimensione dei caratteri può essere resa variabile dichiarando <Hn> </Hn> dove n è il numero dei pixel di un carattere

<BR> indica un line break e non ha il corrispettivo barrato. <P> indica un nuovo paragrafo che termina con </P>

Formattazione del testo

Non si può prevedere esattamente come uno user potrà visualizzare il testo a causa dei browsers diversi a disposizione e dell’hardware utilizzato, tuttavia alcune operazioni possono essere riconosciute dai vari browsers come:.

Cambiare le fonts<FONT FACE=“fontname1”>lklklk</FONT><FONT FACE=“Garamond Bold” COLOR=#rrggbb SIZE=10>aaaa</FONT>

Scrivere un testo in corsivo <I>aaaa</I> in testo in grassetto <B>bbbb</B> (anche EM o STRONG meno usati) Scegliere una grandezza di default per un testo (body text) Cambiare il font size rispetto al resto del testo <BIG> <SMALL> Creare apici o pedici <SUB> <SUP> con i relativi </SUB> </SUP> Usare testo preformattato <PRE> testo formattato </PRE> Fare lampeggiare il testo <BLINK>testo</BLINK> Aggiungere commenti al proprio testo in HTML <!- - commenti - ->

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 143

Page 143: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

144

Creare immagini

Formato

I formati più usati per le immagini sono GIF JPEG (PNG è meno diffuso).

Colore

Molti monitor (detti 8 bit) sono limitati a 256 colori, in più il sistema software e il browser ne riservano fino a 40 per il proprio uso.Alcuni monitor (browser safe palette) usano 216 colori (256-40).Se nella propria applicazione si usano più di 216 colori o colori diversi dai 216 disponibili il browser fa dithering, cioè combina alcuni colori esistenti per riprodurre i mancanti, su quelli mancanti con risultati non sempre ottimi.

Trasparenza

Caratteristica interessante per dare ad una immagine contorni non netti (GIF e PNG non JPEG)

Velocità

Di download : occorre ottimizzare la procedura per ottenere un tempo minimo. Per far questo occorre che:

le immagini siano piccole Se sono di grande formato occorre ridurle aggiustare la risoluzione: in questo modo la size è automaticamente aggiustata (con il crop

tool) Se possibile comprimerle Offrire un preview Il tempo di download proporzionale alla size delle immagini. Se possibile usare colori browser safe

Animazione

Solo immagini GIF possono essere animate.

Utilizzare le immagini

Inserire immagini in una pagina

<IMG SRC=“image.ext” BORDER=n>Offrire testo alternativo se le immagini non appaiono

…ALT=HTML 4 considera ALT come un attributo richiesto

Specificare una grandezza (size) per una visione più veloce

<IMG SRC=“image.ext” WIDTH=x HEIGTH=y>Connettere icone a immagini più grandi

<A HREF=image.location”> <IMG SRC=“icon.location”>Al termine </A>

Un esempio:

CORSO DI INFORMATICA PER LA FISICA 144

Page 144: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

145

<HTML><HEAD><TITLE> Providing alternate text </TITLE> </HEAD><BODY><H1>Snoopy</H1><P>Snoopy dorme sopra la cuccia</P><P><IMG SRC=“snoopy.gif” ALT=“Image of Snoopy sleeping”></BODY></HTML>

Testo attorno alle immagini

<IMG SRC=“image.location” ALIGN=left><BR CLEAR=left>Questa istruzione ferma il flusso di testo finchè non ci sono più immagini allineate al margine di sinistra.<BR CLEAR=all> effettua la stessa operazione ad entrambi i marginiHSPACE=x e VSPACE=y aumentano invece lo spazio attorno all’immagine(x e y sono i numeri di pixels da riservare)<HR SIZE=n WIDTH=w> per far apparire una riga di separazione della larghezza e della lunghezza voluta.

Layout

Per un corretto layout di una pagina occorre: specificare i margini

LEFTMARGIN=x TOPMARGIN=y

Creare indentazioni

<SPACER TYPE=“horizontal” SIZE=36> (36 è il numero di pixel per l’indentazione)

Centrare testo in una pagina

<CENTER>xxxx </CENTER>

Posizionare elementi in layers

<LAYER ID=name TOP=m LEFT=n WIDTH=x HEIGTH=h SRC=“source.html BGCOLOR=color BACKGROUND=“image.gif” Z-INDEX=z> Alla fine </LAYER>

Per utilizzare un’immagine come background basta dare un attributo a body :

<body background=”image.gif>

Si salva tempo al proprio utilizzatore se si usa la medesima pagina di backgound per un gruppo di pagine. In questo modo dopo che l’immagine e’ caricata per la prima pagina ogni pagina successiva usa una versione “cache” che si carica piu’ velocemente.Il comando <blockquote> con il corrispettivo </blockquote> alla fine fa indentare il testo in esso contenuto, l’analogo del comando tab in un testo word.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 145

Page 145: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

146

Links

Per creare un link ad un’altra pagina web:

<A HREF=“page.html”> </A>

Se invece si vuole cambiare il colore dei links non ancora visitati si usa LINK, quelli già visitati VLINK. Quando lo user sceglie un link il testo cambia colore con il comando ALINK

<A HREF=http://www.site.com/directory/page.html>Label text</A> (Figures 7.5 7.6).

Liste

Si possono: Creare liste ordinate <OL TYPE=x START=n> alla fine </OL> (ordered lists). Il valore di n

indica il numero dell’elemento della lista Creare liste non ordinate <UL> (unordered lists) sono liste con bullets iniziali Creare definition lists <DL e </DL> . In esse ci sono due campi il primo indica la lista dei

termini il secondo e’della loro definizione. Ad esempio per una deficition list:

<dl><dt> primo termine</dt><dd>la sua definizione<dt>secondo termine</dt><dd>la definizionne del secondo

termine</dd></dl>

Le liste possono essere una nell’altra.<ul><p> <li><a HREF=1elementiC.ppt>Elementi di C </a><br> <li><a HREF=2dalcalc++.ppt> Dal C al C++ </a><br> <li><a HREF=3classi.ppt> Classi </a><br> <li><a HREF=4templates.ppt> Templates </a><br> <li><a HREF=5stl.ppt> STL (Standard Template Library) </a><br> <li><a HREF=6polimorfismo_ereditarieta.ppt> Polimorfismo ed Ereditarieta' </a><br> <li><a HREF=7uml.ppt> UML (Unified Modeling Language) </a><br> <li><a HREF=8html.ppt> HTML (HyperText Markup Language) </a><br> <li><a HREF=9java.ppt> Introduzione al linguaggio Java </a><br> <br></li></ul>

Tabelle

Il comando da utilizzare è <TABLE>.<TR> definisce l’inizio della prima riga. <TH> crea uno header nella prima riga. <TD> crea un acella regolare. Alla fine </TABLE>Un esempio:

CORSO DI INFORMATICA PER LA FISICA 146

Page 146: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

147

…<table WIDTH="100%" BGCOLOR="#00AACC" NOSAVE > <tr NOSAVE> <td NOSAVE><img SRC="adele.jpg" height=150 width=200 align=CENTER> </td> <td ALIGN=CENTER VALIGN=CENTER WIDTH="100%"><h1> <font color="#FFFFFF">ADELE RIMOLDI</font></h1> <h3> <font color="#FFFFFF"> <a HREF=http://www.pv.infn.it/~dfntwww/> <font color="#CCBBEE">Dipartimento di Fisica Nucleare e Teorica</a></font> <br> Universit&agrave; degli Studi di Pavia & INFN<br> <font size=+0>Via Bassi, 6 - 27100 Pavia <br> phone 0382-507433 - fax 0382-423241 <br> e-mail <a href="mailto:[email protected]"><font color="#000000">[email protected]</a></font></font></h3> </td> <td NOSAVE><img SRC="dip.gif" height=150 width=150 align=CENTER> </td> </tr> </table>

Frames

Una pagina web è detta frameset. Per creare un frameset dopo </HEAD>:<FRAMESET ROWS=“a,b,c,…” NAME=“name”> </FRAMESET>La pagina può essere suddivisa in frames in modo da rendere visibile più di una pagina per volta, come finestra separata.contents frame: I dati contenuti cambiano ogni volta che un visitatore sceglie un nuovo argomento nella tavola dei contenuti. I frames possono essere combinati, si possono cambiare i colori dei bordi, nasconderli,modificare le dimensioni dei frames e gli spazi tra di essi…

Forms

Consentono ai visitatori di comunicare Struttura o shell: Consiste di campi, labels, bottoni che il visitatore vede sulla pagina e poi eventualmente riempie Si possono creare text boxes, bottoni per la radio, drop-down menu, immagini selezionabili..Il processing script poi prende l’informazione, la converte e la rende leggibile tramite il CGI (Common Gateway Interface): esso è uno script, è il tool scritto in Perl o in un altro linguaggio di programmazione che comunica con il server.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 147

Page 147: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

148

Java

Le pagine web sono ormai diffusissime e la competizione per il possesso del primato di audience ha forzato i designer ad essere sempre più evoluti per offrire un prodotto sempre più competitivo. Il linguaggio utilizzato per le pagine web e’ HTML (Hypertext Markup Language),statico.Una evoluzione da HTML ha portato a pensare ad un modo per rendere interattive le pagine web. Ad un primo approccio sembrerebbe possibile per uno sviluppatore poter scrivere un programma nel proprio linguaggio favorito (C,C++, Visual Basic o altro) compilarlo, renderlo eseguibile, caricarlo dal server attraverso la pagina HTML. Una aggiunta minore potrebbe essere quella di consentire al web browser di caricare automaticamente il programma dal server ed eseguirlo sul computer del cliente. Il programma potrebbe aprire finestre, finestre di dialogo, suonare ecc. Questo però genererebbe molti problemi.I linguaggi convenzionali non sono progettati per essere eseguiti attraverso il web. Essi non hanno le caratteristiche necessarie per effettuare le più basilari operazioni (il programmatore dovrebbe programmare le operazioni più basilari come ad esempio caricare un immagine da un server per essere poi visualizzata sulla macchina del cliente)

I programmi convenzionali hanno degli eseguibili massivi (5ooKB sono pochi se si sta eseguendo un programma sul proprio hard driver, ma diventano una pena se vanno trasferiti sulla rete alla velocità imposta dal proprio modem (28.8 Kbps)

La sicurezza: si desidererebbe proprio vedersi eseguire dei programmi sul proprio computer senza un controllo personale? (se un programma è stato scaricato sulla macchina del cliente ed inizia ad essere eseguito nulla può esser fatto per evitarlo.. e se il programma contenesse qualche istruzione che fa un remove dei file residenti?)

I diversi computer environments: al web sono attaccati i computer più disparati e quindi dovrebbe esistere una versione dell’eseguibile per ognuno dei diversi tipi (PCs, ma anche Macintoshes, e altri) e per ognuno dei diversi software installati (Microsoft Windows 3.1, Microsoft Windows 95,98,2000, Microsoft Windows NT, ecc.)

Il linguaggio Java è nato per risolvere questi problemi. Esso genera eseguibili estremamente contenuti in grandezza per facilitare un caricamento veloce supplendo alla lentezza delle linee di comunicazione. Un programma Java non può accedere a nulla a cui il computer client non dia accesso. Java è machine independent, semplice e potente.Ad un primo utilizzatore esso sembra simile ad un qualunque altro linguaggio OO (come il C++) ma esso ne differisce per alcuni aspetti fondamentali. Infatti il C++ era stato creato come estensione del linguaggio C (non OO oriented) e quindi per poterlo contenere ed ampliarsi verso l’OO è divenuto estremamente complesso.I designers di Java hanno cancellato la compatibilità all’indietro con il linguaggio C guadagnandoci in semplicità.Le trasparenze relative a questo capitolo del corso si trovano all’indirizzo web indicato nell’introduzione e sono raggiungibili mediante click alla posizione: Introduzione al linguaggio java (in formato powerpoint).

Che cosa c’è di nuovo in Java?

Questa panoramica, più che insegnare a programmare in Java, vuole chiarire quali sono gli aspetti originali di questo linguaggio e perché esso desta tanto interesse negli ultimi tempi

Java è un linguaggio di programmazione orientato agli oggetti Le applicazioni sono indipendenti dalla piattaforma in cui vengono prodotte Java è stato progettato con l’intento di creare un linguaggio semplice, robusto, sicuro Esso è particolarmente adatto per l’ambiente grafico e le applicazioni in rete.

CORSO DI INFORMATICA PER LA FISICA 148

Page 148: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

149

Java ed Internet

Java è un linguaggio OO come molti altri, tuttavia il suo sviluppo ha subito una enorme spinta dalla diffusione di Internet.Portabilità e sicurezza sono le caratteristiche che hanno decretato il successo di Java per le applicazioni di rete.L’indipendenza dalla piattaforma fa sì che un programma Java possa essere scaricato dalla rete e direttamente eseguito su tutte le più diffuse architetture di computer (PC, Unix, Mac ...)

Linguaggi compilati ed interpretati

Un linguaggio compilato è tale per cui il compilatore produce un eseguibile in codice macchina. L’esecuzione sarà molto veloce ma lo stesso eseguibile non può essere usato su piattaforme diverse.Invece un linguaggio interpretato è tale per cui il codice é indipendente dalla piattaforma, ma deve essere eseguito attraverso un interprete che in genere è molto poco efficiente.Java ha un compilatore ed un interprete.

Bytecode

E’ la novità di Java. Il compilatore non produce codice macchina, ma un insieme ottimizzato di istruzioni detto BYTECODE.Il sistema run-time di Java emula una macchina virtuale (Java Virtual Machine) che esegue il BYTECODE .Ogni architettura per la quale la Virtual Machine sia implementata, può eseguire lo stesso programma Java. L’efficienza di esecuzione di Java è superiore rispetto agli altri linguaggi interpretati (Tcl, Perl...), anche se non raggiunge quella dei linguaggi compilati.Inoltre l’interprete Java fornisce compilatori “just in time” per trasformare a run-time il BYTECODE in codice macchina, guadagnando in velocità, ma perdendone la portabilità. Possedere un BYTECODE significa intrinsecamente non minare la sicurezza dato che l’esecuzione di un BYTECODE Java é confinata nel sistema run-time che lo interpreta. Nel linguaggio, inoltre, non esistono i puntatori. L’ applet non può scrivere né leggere sul client, né aprire connessioni con altri sistemi. Ma procediamo per gradi, occorre prima definire una applicazione ed un applet e le differenze.

Applicazioni ed applets

In Java si possono produrre due tipi diversi di programmi: applicazioni ed applets. Un’applicazione viene eseguita sul proprio computer ed é equivalente ad un programma C

o C++. Un applet é fatto per essere trasmesso in rete tra un Web server ed un client, eseguito

attraverso un browser.In un programma Java tutto il codice è contenuto all’interno di classi. Java non è concepito per essere compatibile con altri linguaggi, tuttavia è possibile invocare “Metodi Nativi” in linguaggi compilati. Si perde però la portabilità.

Un esempio di applicazione

Occorre innanzitutto verificare che sul proprio computer java sia già installato, altrimenti occorre andare al sito www.sun.com e seguire le istruzioni per il download a seconda del tipo di sistema si possegga, ecc ecc e poi effettuare l’appropriato download. Scritto il codice in un file:

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 149

Page 149: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

150

Example.javaclass Example { public static void main (){

System.out.println(“Hello World!”); }}

Il “programma” è costituito da una classe che implementa un metodo main. Occorre poi compilare:

javac Example.java

ed eseguire l’applicazione:

java Example

Java vs. C++

Le principali caratteristiche sono indicate qui:La sintassi è fondata sul C++, con alcune semplificazioni.

Java non consente l’uso dei puntatori. Un sistema di garbage collection si occupa della gestione automatica della memoria. Non è possibile l’ereditarietà multipla, ma Java fornisce le interfacce. Le classi ed i metodi di I/O sono diversi da quelli del C++.

Creazione degli oggetti

La allocazione di nuovi oggetti avviene con new esattamente come in C++:

Box mybox = new Box( );

Gli oggetti non hanno un distruttore, sostituito dal sistema di garbage collection di

Java, associato al metodo finalize.Ereditarietà

Una sottoclasse viene creata con l’istruzione extends;

class HeavyBox extends Box {...}

Ogni sottoclasse può ereditare da una sola superclasse.È consentita la ridefinizione (override) dei metodi.Si possono definire classi abstract, di cui non si possono creare istanze, ma possono essere usate come riferimento alle sottoclassi, risolto a run-time (Polimorfismo).

Interfacce

Una interface è definita in modo analogo ad una classe, ma ha metodi non implementati e non ha variabili di istanza.Una interface può contenere la definizione di costanti, che sono condivise dalle classi che implementano l’ interface. Più classi possono implementare la stessa interfaccia, definendone tutti i metodi.

CORSO DI INFORMATICA PER LA FISICA 150

Page 150: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

151

class MyClass implements MyInterface { ... }

Un esempio

IntStack.javainterface IntStack { void push(int item); int pop( );}FixedStack.javaclass FixedStack implements IntStack { … variabili di istanza e metodi propri ... public void push(int item) { … corpo di push per FixedStack… } public int pop( ) { … corpo di pop per FixedStack… }}DynStack.javaclass DynStack implements IntStack { … variabili di istanza e metodi propri ... public void push(int item) { … corpo di push per DynStack… } public int pop( ) { … corpo di pop per DynStack… }}

Uso delle interfacce

InterfaceTest.javaclass InterfaceTest { public static void main (String args[]) { IntStack mystack; FixStack fs = new FixStack(8); DynStack ds = new DynStack(5); mystack = ds; for (int i=0; i<12; i++) mystack.push(i); mystack = fs; for (int i=0; i<8; i++) mystack.push(i); }}

Pacchetti

Un package raggruppa un insieme di classi correlate, che possono essere importate nelle applicazioni.L’appartenenza ad un pacchetto si realizza inserendo all’inizio del file l’istruzione :

package MyPackage;

Per importare in una applicazione le classi del pacchetto:

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 151

Page 151: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

152

import MyPackage.*;

java.lang, java.io java.util, java.net, java.applet, java.awt, java.awt.image, java.awt.peer sono importabili in un applet come nell’esempio sottostante:

Un Applet

import java.awt.*;import java.applet.*;public class SimpleApplet extends Applet { public void paint(Graphics g) { g.drawString(“Hello World!”); }}

L’applet è pilotato ad eventi. Un applet non ha metodo main. L’ I/O è realizzato attraverso AWT (Abstract Window Toolkit).

L’esecuzione dell’applet

Un applet può essere eseguito dall’ appletviewer oppure attraverso un web browser.Per accedere all’ applet bisogna inserirlo in un file HTML con il tag APPLET.Nell’applet si ridefiniscono i metodi delle classi Applet e AWT che vengono poi chiamati dall’applet viewer.

public void init( ){...}public void start( ){...}public void paint( ){...}public void stop( ){...}public void destroy( ){...}

Un esempio di applet

Scriviamo un esempio con 3 bottoni che provocano il cambio di colore dello sfondoImplementeremo i metodi:

init per definire lo stato iniziale action per rivelare gli eventi connessi alla pressione dei bottoni paint per ridisegnare l’applet

CORSO DI INFORMATICA PER LA FISICA 152

Page 152: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

153

import java.awt.*;import java.applet.*;public class ButtonDemo extends Applet {

String msg = “Ti piace Java?”;public void init() {

Button yes = new Button(“Si”);Button no = new Button(“No”);Button maybe = new Button(“Non so”);SetBackground(Color.white);add(yes);add(no);add(maybe);

}public void paint(Graphics g) {

g.drawString(msg,6,100); }

public boolean action(Event evtObj, Object arg) {

if (evtObj.target instanceof Button) { if (arg.equals(“Si”)) {

setBackground(Color.green); msg = “I love Java!”;

} if (arg.equals(“No”)) {

setBackground(Color.red); msg = “Io odio Java!”;

} if (arg.equals(“Non so”)) {

setBackground(Color.yellow); msg = “Non me ne importa niente!”;

} }

}

La programmazione multithread

Più parti del programma possono essere eseguite contemporaneamente, in diversi threads.Tutti i threads sono figli del main. Se un thread si blocca in attesa di un evento, gli altri continuano a girare. Si possono definire le priorità di esecuzione e sincronizzare l’esecuzione mediante semafori.Il metodo più semplice per creare un thread è creare una classe che implementa l’interfaccia Runnable e implementare il metodo run( ).La programmazione multithread consente quindi una esecuzione di tipo parallelo.

La gestione delle eccezioni

Una eccezione è una condizione di errore a run-time.In java una eccezione è un oggetto creato e lanciato nel metodo che ha provocato l’errore.

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 153

Page 153: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

154

class Exc1 { public static void main(String args[]) { int d, a; try { d = 0; a = 42 / d; System.out.println(“This will not be printed”); } catch (AritmeticException e) { System.out.println(“Division by zero”); }}}

Esiste un gestore default delle eccezioni. Si possono lanciare eccezioni con l’istruzione throw.

Un ulteriore esempio

In questo contesto l’esempio seguente porta alla visualizzazione di una applicazione Java per il web e di conseguenza alla visualizzazione di una pagina web d’uso dove l’applicazione e’ stata introdotta. Nella pagina HTML riportata <script LANGUAGE="JavaScript"> avverte la presenza di uno script di Java. Questo script genera sullo schermo un cursore elastico costituito da icône minimizzate di un’immagine. Il movimento del cursore provoca un trascinamento delle icone sullo schermo secondo patterns di ritardo ed eseguendo rimbalzi quando il cursore incontra un lato qualunque della pagina. I metodi sono implementati nella pagina e rendono conto del tipo di moto che poi verra’ eseguito.

CORSO DI INFORMATICA PER LA FISICA 154

Page 154: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

155

<body TEXT="#000000" BGCOLOR="#F7FFCE" LINK="#0000EE" VLINK="#551A8B" ALINK="#FF0000"><!-- Changed by: Adele Rimoldi, 26-February -2004 --><p><a HREF="http://www.cern.ch/"><img SRC="http://atlasinfo.cern.ch/Atlas/GROUPS/INNER_DETECTOR/cernhead.gif" HEIGHT=20 WIDTH=400></a>&nbsp;<a HREF="http://www.cern.ch/Atlas/"><img SRC="http://atlasinfo.cern.ch/Atlas/GROUPS/INNER_DETECTOR/atl_head.gif" HEIGHT=20 WIDTH=210></a>&nbsp;<a href="http://www.cern.ch/Atlas/GROUPS/MUON/muon_page.html"><img src="http://home.cern.ch/muondoc/software/Database/img/muonhead.gif" alt="Muon Home Page"></a><img SRC="http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/www0/muonspectadele.gif" HEIGHT=120 WIDTH=120 ALIGN=left VSPACE=20><h1><br>Muon Spectrometer<br> Simulation<br> using<br> Geant3</h1><p><body topmargin="5" leftmargin="5" background=" " bgcolor="#FFFFFF" text="#0000FF" link="#3366CC" vlink="#666666" alink="#996600"><!--mstheme--><font face="Tahoma"><div id="dot0" style="position: absolute; visibility: hidden; height: 11; width: 11;"><img src="http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/redball.gif" height="11" width="11"></div><div id="dot1" style="position: absolute; height: 11; width: 11;"><img src="http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/www0/muonspectadele.gif" height="21" width="21"></div><div id="dot2" style="position: absolute; height: 11; width: 11;"><img src="http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/www0/muonspectadele.gif" height="21" width="21"></div><div id="dot3" style="position: absolute; height: 11; width: 11;"><img src="http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/www0/muonspectadele.gif" height="21" width="21"></div><div id="dot4" style="position: absolute; height: 11; width: 11;"><img src="http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/www0/muonspectadele.gif" height="21" width="21"></div><div id="dot5" style="position: absolute; height: 11; width: 11;"><img src="http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/www0/muonspectadele.gif" height="21" width="21"></div><div id="dot6" style="position: absolute; height: 11; width: 11;"><img src="http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/www0/muonspectadele.gif" height="21" width="21"></div>

<script LANGUAGE="JavaScript">

<!-- hide code

/*Elastic Trail script (By Philip Winston @ [email protected], URL:http://members.xoom.com/ebullets)Script featured on Dynamicdrive.comFor this and 100's more DHTML scripts, visit http://dynamicdrive.com*/

// Thanks to Troels Jakobsen <[email protected]>// for fix which makes it work when the page is scrolled

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 155

Page 155: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

156

var nDots = 7;if (document.all&&window.print)document.body.style.cssText="overflow-x:hidden;overflow-y:scroll"var Xpos = 0;var Ypos = 0;

// fixed time step, no relation to real timevar DELTAT = .01; // size of one spring in pixelsvar SEGLEN = 10; // spring constant, stiffness of springsvar SPRINGK = 10; // all the physics is bogus, just picked stuff to // make it look okayvar MASS = 1;var GRAVITY = 50;var RESISTANCE = 10; // stopping criterea to prevent endless jittering // doesn't work when sitting on bottom since floor // doesn't push back so acceleration always as big // as gravityvar STOPVEL = 0.1;var STOPACC = 0.1;var DOTSIZE = 11; // BOUNCE is percent of velocity retained when // bouncing off a wallvar BOUNCE = 0.75;

var isNetscape = navigator.appName=="Netscape";

// always on for now, could be played with to // let dots fall to botton, get thrown, etc.var followmouse = true;

var dots = new Array();init();

function init(){ var i = 0; for (i = 0; i < nDots; i++) { dots[i] = new dot(i); } if (!isNetscape) { // I only know how to read the locations of the // <LI> items in IE //skip this for now // setInitPositions(dots) } // set their positions for (i = 0; i < nDots; i++) { dots[i].obj.left = dots[i].X; dots[i].obj.top = dots[i].Y; } if (isNetscape) { // start right away since they are positioned // at 0, 0 startanimate();

CORSO DI INFORMATICA PER LA FISICA 156

Page 156: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

157

} else { // let dots sit there for a few seconds // since they're hiding on the real bullets setTimeout("startanimate()", 2000); }}

function dot(i) { this.X = Xpos; this.Y = Ypos; this.dx = 0; this.dy = 0; if (isNetscape) { this.obj = eval("document.dot" + i); } else { this.obj = eval("dot" + i + ".style"); }}

function startanimate() { setInterval("animate()", 20);}

// This is to line up the bullets with actual LI tags on the page// Had to add -DOTSIZE to X and 2*DOTSIZE to Y for IE 5, not sure why// Still doesn't work greatfunction setInitPositions(dots){ // initialize dot positions to be on top // of the bullets in the <ul> var startloc = document.all.tags("LI"); var i = 0; for (i = 0; i < startloc.length && i < (nDots - 1); i++) { dots[i+1].X = startloc[i].offsetLeft startloc[i].offsetParent.offsetLeft - DOTSIZE; dots[i+1].Y = startloc[i].offsetTop + startloc[i].offsetParent.offsetTop + 2*DOTSIZE; } // put 0th dot above 1st (it is hidden) dots[0].X = dots[1].X; dots[0].Y = dots[1].Y - SEGLEN;}

// just save mouse position for animate() to usefunction MoveHandler(e){ Xpos = e.pageX; Ypos = e.pageY; return true;}

// just save mouse position for animate() to usefunction MoveHandlerIE() { Xpos = window.event.x + document.body.scrollLeft; Ypos = window.event.y + document.body.scrollTop; }

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 157

Page 157: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

158

if (isNetscape) { document.captureEvents(Event.MOUSEMOVE); document.onMouseMove = MoveHandler;} else { document.onmousemove = MoveHandlerIE;}

function vec(X, Y){ this.X = X; this.Y = Y;}

// adds force in X and Y to spring for dot[i] on dot[j]function springForce(i, j, spring){ var dx = (dots[i].X - dots[j].X); var dy = (dots[i].Y - dots[j].Y); var len = Math.sqrt(dx*dx + dy*dy); if (len > SEGLEN) { var springF = SPRINGK * (len - SEGLEN); spring.X += (dx / len) * springF; spring.Y += (dy / len) * springF; }}

function animate() { // dots[0] follows the mouse, // though no dot is drawn there var start = 0; if (followmouse) { dots[0].X = Xpos; dots[0].Y = Ypos; start = 1; } for (i = start ; i < nDots; i++ ) { var spring = new vec(0, 0); if (i > 0) { springForce(i-1, i, spring); } if (i < (nDots - 1)) { springForce(i+1, i, spring); } // air resisitance/friction var resist = new vec(-dots[i].dx * RESISTANCE, -dots[i].dy * RESISTANCE); // compute new accel, including gravity var accel = new vec((spring.X + resist.X)/ MASS, (spring.Y + resist.Y)/ MASS + GRAVITY); // compute new velocity dots[i].dx += (DELTAT * accel.X); dots[i].dy += (DELTAT * accel.Y); // stop dead so it doesn't jitter when nearly still if (Math.abs(dots[i].dx) < STOPVEL && Math.abs(dots[i].dy) < STOPVEL &&

CORSO DI INFORMATICA PER LA FISICA 158

Page 158: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

159

Math.abs(accel.X) < STOPACC && Math.abs(accel.Y) < STOPACC) { dots[i].dx = 0; dots[i].dy = 0; } // move to new position dots[i].X += dots[i].dx; dots[i].Y += dots[i].dy; // get size of window var height, width; if (isNetscape) { height = window.innerHeight + document.scrollTop; width = window.innerWidth + document.scrollLeft; } else { height = document.body.clientHeight + document.body.scrollTop; width = document.body.clientWidth + document.body.scrollLeft; } // bounce of 3 walls (leave ceiling open) if (dots[i].Y >= height - DOTSIZE - 1) { if (dots[i].dy > 0) { dots[i].dy = BOUNCE * -dots[i].dy; } dots[i].Y = height - DOTSIZE - 1; } if (dots[i].X >= width - DOTSIZE) { if (dots[i].dx > 0) { dots[i].dx = BOUNCE * -dots[i].dx; } dots[i].X = width - DOTSIZE - 1; } if (dots[i].X < 0) { if (dots[i].dx < 0) { dots[i].dx = BOUNCE * -dots[i].dx; } dots[i].X = 0; } // move img to new position dots[i].obj.left = dots[i].X; dots[i].obj.top = dots[i].Y; }}

// end code hiding -->

</script>

<br CLEAR=left><center><i><font COLOR ="teal"> This page is meant to be a reference for ongoing studies that use the current simulation with Geant3(DICE 3.21)</font></i></center> <p> The main web page of <a HREF="http://wwwinfo.cern.ch/asd/geant/"> GEANT3 </a> could give you some more information. <p><i><b><font SIZE=+1 COLOR ="navy">Available Documentation :</i></b></font><br><dd>

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 159

Page 159: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

160

<br> <dd><img SRC="http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/redball.gif" HEIGHT=14 WIDTH=14><b> <a HREF="http://atlasinfo.cern.ch/Atlas/GROUPS/PHYSICS/TDR/access.html"> Physics TDR </b></a>(main page)<dd> In particular in Chapter 2 you will be informed on<font COLOR="navy"> Simulation of detector and physics performance</font>.<br><dd> The simulation program is described here.</dd> <br><dd><img SRC="http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/yellowball.gif" HEIGHT=14 WIDTH=14><b><a HREF="http://www.cern.ch/Atlas/GROUPS/SOFTWARE/DOCUMENTS/DICE_320/dice320.html"> Use Geant3 </b></a><br>in this case you'll use the existing version of it built on the official ATLAS repository. Follow then the pointer to DICE from <a HREF="http://atlasinfo.cern.ch/Atlas/GROUPS/SOFTWARE/DOCUMENTS/DICE_320/dice_cvs.html">srt/cvs</a></dd> <p> Some pictures obtained with Geant3 are also availale here:<hr><center><a HREF=/afs/cern.ch/user/r/rimoldi/www0/muonspectadele.eps> <img SRC=http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/www0/muonspectadele.gif HEIGHT=70 WIDTH=70 ></a><a HREF=/afs/cern.ch/user/r/rimoldi/www0/precisionadele.eps> <img SRC=http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/www0/precisionadele.gif HEIGHT=70 WIDTH=70 ></a><a HREF=../../afs/cern.ch/user/r/rimoldi/www0/triggeradele.eps> <img SRC=http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/www0/triggeradele.gif HEIGHT=70 WIDTH=70 ></a><a HREF=../../afs/cern.ch/user/r/rimoldi/www0/results/3dd.eps> <img SRC=http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/www0/results/3dd.gif HEIGHT=70 WIDTH=70 ></a><a HREF= ../../afs/cern.ch/user/r/rimoldi/www0/nofcha3d.eps> <img SRC=http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/www0/nofcha3d.gif HEIGHT=70 WIDTH=70></a><a HREF= /afs/cern.ch/user/r/rimoldi/www0/rphi.eps> <img SRC=http://atlasinfo.cern.ch/Atlas/GROUPS/MUON/www0/rphi.gif HEIGHT=70 WIDTH=70></a></center><hr><dd>Figures captions:<dd>1: 3D view of the Muon Spectrometer (MDT + RPC + TGC + CSC)<dd>2: 3D view of the Precision Chamber System (MDT + CSC)<dd>3: 3D view of the Trigger System (RPC + TGC)<dd>4: Muon Spectrometer Longitudinal view<dd>5: Barrel system (calorimeters + RPC + MDT)<dd>6: Radial view for barrel: MDT(green), RPC(tourquoise), tile cal(blue), ecal(red), TGC (violet)</li></p><p>Page updated : 18-January-2004<imgSRC="http://atlasinfo.cern.ch/Atlas/SUB_DETECTORS/TILE/icons/line1.gif"></b><address>Maintained by<a HREF="http://consult.cern.ch/xwho/people/03306">AR</a></address>

CORSO DI INFORMATICA PER LA FISICA 160

Page 160: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

161

Python

Il linguaggio Python e’ in linguaggio interpretato (compilazione e link non sono necessari), interattivo e object-oriented. Esso e’ spesso paragonato al linguaggio Perl e Java e combina una grande potenza con una sistassi molto pulita. Esso ha moduli, classi, eccezioni, data types ad alto livello dinamico e dynamic typing. Esistono interfacce a molte chiamate di sistema, librerie e a vary sistemi di windowing (X11, Motif, Mac….). Nuovi moduli built-in possono esser scritte in C o C++. Python e’ usabile come linguaggio di estensione per applicazioni che necessitano una interfaccia programmabile. L’implementazione in Python e’ portabile, essa infatti puo’ lavorare su UNIX, Windows, Mac… e molte altre piattaforme. Il linguaggio Python ha copyright ma e’ liberamente usabile e distribuibile anche per uso commerciale.Immaginiamo un tipo di conversazione telefonica che puo’ aver luogo tra due persone su diversi continenti cosicche’ puo’ esistere un ritardo di comunicazione di un minuto tra i due. Poi immaginiamo un discorso tra due persone che stanno in stanze attigue o faccia a faccia. Lo stesso discorso viene affrontato con procedure diverse. In Python sviluppare software e’ come trovarsi faccia a faccia in una conversazione. Sviluppare software e testare il proprio codice mentre lo si sviluppa e’ simulataneo. La diversita’ di metodo e di apprendimento e’ la stessa che tra due persone al telefono. Il tipo di programmazione e’ diverso, non solo piu’ veloce, ma anche differente. Python ha un set completo di operazioni su stringhe e non richiede allo user una manipolazione della memoria diretta; questa caratteristica lo rende un linguaggio ideale per sviluppare prototipi.Un programma in Python puo’ essere costituito da un numero di moduli ognuno dei quali definisce il proprio namespace e i moduli possono definire classi che quindi offrono una ulteriore incapsulazione. L’exception handling rende possibile trovare gli errori di programmazione dove necessario. Un debugger per Python puo’ essere scritto in Python.Il nome del linguaggio deriva dal nome dello show sulla BBC “Monthy Python Flying Circus”, non dal nome del rettile.

Un esempio di una funzione che inverte una tavola:

def invert(table): index = {} # empty dictionary for key in table.keys(): value = table[key] if not index.has_key(value): index[value] = [] # empty list index[value].append(key) return index

Python usa l’indentazione per definire i blocchi di programma. Invece per introdurre un commento si usa il carattere “#” .ed un esempio dell’uso interattivo di questa funzione (“>>>” e’ il prompt dell’interpreter):

>>> phonebook = {'guido': 4127, 'sjoerd': 4127, 'jack': 4098}>>> phonebook['dcab'] = 4147 # add an entry>>> inverted_phonebook = invert(phonebook)>>> print inverted_phonebook{4098: ['jack'], 4127: ['guido', 'sjoerd'], 4147: ['dcab']}>>>

Page 161: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

162

Usare l’interpreter di Python

L’interpreter di Python e’ installato in /usr/local/bin/python sulle machine in cui e’ disponibile. Ponendo /usr/local/bin nella propria UNIX shell si puo’ invocarlo scrivendo semplicemente:

python

Dato che la scelta del direttorio in cui l’interpreter sta e’ una opzione di installazione sono possibili anche altre locazioni (/usr/local/python e’ un’alltra alternativa popolare). Scrivendo poi un end-of-file (Control-D su UNIX, Control-z su Windows) quando appare il prompt fa si che l’interpreter esca con exit code uguale a zero. Se non funzionasse basta scrivere “import sys; sys.exit()”.La risposta dell’interpreter e’ usualmente:

Python 1.5.2b2 (#1, Feb 28 1999, 00:02:06) [GCC 2.8.1] on sunos5Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam>>>

Quando si immettono piu’ linee occorrono 3 punti all’inizio linea per dichiarare la continuazione della scrittura, come nell’esempio seguente:

>>> the_world_is_flat = 1>>> if the_world_is_flat:... print "Be careful not to fall off!"... Be careful not to fall off!

Usare python come una calcolatrice

L’interpreter agisce come una calcolatrice. Basta scrivere l’espressione e l’interpreter scrivera’ il risultato di essa. La sintassi e’ diretta, le parentesi possono essere usate per raggruppare le operazioni. Un esempio:

>>> 2+24>>> # This is a comment... 2+24>>> 2+2 # and a comment on the same line as code4>>> (50-5*6)/45>>> # Integer division returns the floor:... 7/32>>> 7/-3-3

altre caratteristiche generali del linguaggio

il segno = indica un’assegnazione

CORSO DI INFORMATICA PER LA FISICA 162

Page 162: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

163

>>> width = 20>>> height = 5*9>>> width * height

900

un valore puo’ essere assegnato a diverse variabili simulataneamente:

>>> x = y = z = 0 # Zero x, y and z>>> x0>>> y0>>> z0

Operazioni a typing misto subiscono le trasformazioni aspettate:

>>> 3 * 3.75 / 1.57.5>>> 7.0 / 23.5

I numeri complessi sono supportati e si possono scrivere direttamente nella forma reale + immaginario o creati attraverso una funzione complex(real, imag):

>>> 1j * 1J(-1+0j)>>> 1j * complex(0,1)(-1+0j)>>> 3+1j*3(3+3j)>>> (3+1j)*3(9+3j)>>> (1+2j)/(1+1j)(1.5+0.5j)

Per estrarre la parte reale o immaginaria di un numero complesso z basta usare i metodi z.real z.imag:

>>> a=1.5+0.5j>>> a.real1.5>>> a.imag0.5

stringhe

Un programma in python puo’ manipolare stringhe in vari modi. Esse sono scritte tra serie di doppi apici o di apici singoli:

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 163

Page 163: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

164

>>> 'spam eggs''spam eggs'>>> 'doesn\'t'"doesn't">>> "doesn't""doesn't">>> '"Yes," he said.''"Yes," he said.'>>> "\"Yes,\" he said."'"Yes," he said.'>>> '"Isn\'t," she said.''"Isn\'t," she said.'

Stringhe su piu’ linee si ottengono utilizzando il carattere \n per indicare la continuation line.

hello = "This is a rather long string containing\n\several lines of text just as you would do in C.\n\ Note that whitespace at the beginning of the line is\ significant."

print hello

docstrings

help rende accessibile la documentazione a stringhe di oggetti. Ogni stringa letterale che appare come primo elemento nella definizione di una classe, funzione, metodo o modulo e’ consderata essere la propria docstring.

Tipi numerici

Int, floating double… siamo ormai abituati a questi tipi..Complesso: 1+ 1jLong

>> Scrivere una funzione in C++ che calcoli il fattoriale di 100

CORSO DI INFORMATICA PER LA FISICA 164

Page 164: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

165

moduli

importare moduli

sequences

lists

tuples

strings

unpacking tuples

indexing and slicing

sequence operations

binding – call by value

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 165

Page 165: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

166

Bibliografia

1.Stephen G.Kochan

Programming in ANSI C

HaydenBooks

2.Koenig Moo

Accelerated C++

Addison Wesley

3.B.Stroustrup

The C++ Programming Language

Addison Wesley

4.Herbert Schildt

C++

McGraw Hill

5.Lippman Lajoie

C++ Primer – Third Edition

Addison Wesley

6.Meyers

Effective C++

Addison Wesley

7.C.Savy

CORSO DI INFORMATICA PER LA FISICA 166

Page 166: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

167

Da C++ a UML

McGraw Hill

8.Sinan Si Alhir

UML in a nutshell

O’Reilly

9.N. Josuttis

The C++ Standard Library

Addison Wesley

10.E.Castro

HTML for the World Wide Web 4

Peachpit Press

11.P. Naughton, H.Schildt

Java

McGraw Hill

12.D. Flanagan

Java in a Nutshell

O’ Really

13.S.R.Davis

Learn Java now

Microsoft Press

14.A.Wu

ADELE RIMOLDI DIPARTIMENTO DI FISICA NUCLEARE E TEORICA - UNIVERSITÀ DI PAVIA 167

Page 167: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

168

Java per la programmazione a oggetti

McGraw Hill

15.

python

website

CORSO DI INFORMATICA PER LA FISICA 168

Page 168: elementi di C++rimoldi/corsoword.doc  · Web viewLe dimensioni di un intero sono generalmente uguali alle dimensioni di una word nell’ambiente di esecuzione del programma. Negli

169