Informatica Java sulla base degli appunti di Paola Nicosia, Manuel Bruzzi, Alessio Jin, Sebastiano Pace e Alessandro Perri rivisti e corretti da Carlo Schenone 1 Sommario Sommario .......................................................................................................................................................... 2 Algoritmo ....................................................................................................................................................... 6 Istruzioni per chiamare un numero con il telefono: .................................................................................. 6 Algoritmo telefonata: ................................................................................................................................ 6 Software e Hardware..................................................................................................................................... 6 Hardware ................................................................................................................................................... 7 Sistema Operativo ..................................................................................................................................... 7 Interfaccia di sistema................................................................................................................................. 7 Software di base ........................................................................................................................................ 7 Software applicativo .................................................................................................................................. 8 Processo di creazione del Software .............................................................................................................. 8 Preparazione del testo del programma..................................................................................................... 8 Compilazione del programma ................................................................................................................... 8 Esecuzione del programma compilato ...................................................................................................... 9 Sintassi e metalinguaggio ............................................................................................................................ 10 Incolonnamento .......................................................................................................................................... 10 Commenti .................................................................................................................................................... 11 Commento a riga ..................................................................................................................................... 11 Commento racchiuso............................................................................................................................... 11 Commento racchiuso javadoc ................................................................................................................. 11 Dati .............................................................................................................................................................. 11 Tipi ........................................................................................................................................................... 11 Numeri Interi: ...................................................................................................................................... 11 Numeri Reali ........................................................................................................................................ 12 Caratteri ............................................................................................................................................... 12 Booleani ............................................................................................................................................... 12 Identificatori e Parole Chiave .................................................................................................................. 12 Scoping di un identificatore..................................................................................................................... 12 Variabili .................................................................................................................................................... 12 Variabili locali ...................................................................................................................................... 13 Variabili globali .................................................................................................................................... 13 Matrici ..................................................................................................................................................... 13 Dichiarazione ....................................................................................................................................... 13 Allocazione .......................................................................................................................................... 13 Espressioni ................................................................................................................................................... 13 Espressioni aritmetiche ........................................................................................................................... 13 Espressioni logiche .................................................................................................................................. 13 Opertatore modulo e divisione intera ..................................................................................................... 13 Left value ................................................................................................................................................. 14 Operatori assegnazione ........................................................................................................................... 14 Operatori di autoincremento e autodecremento ................................................................................... 14 Operatore condizionale ........................................................................................................................... 15 Funzioni, metodi e procedure ................................................................................................................. 15 Parametri di una funzione ................................................................................................................... 15 Firma di una funzione .......................................................................................................................... 15 Comandi....................................................................................................................................................... 15 Return ...................................................................................................................................................... 16 Sintassi ................................................................................................................................................. 16 Semantica ............................................................................................................................................ 16 If ............................................................................................................................................................... 16 2 Sintassi ................................................................................................................................................. 16 Semantica ............................................................................................................................................ 16 While........................................................................................................................................................ 16 Sintassi ................................................................................................................................................. 16 Semantica ............................................................................................................................................ 16 For ............................................................................................................................................................ 16 Sintassi ................................................................................................................................................. 16 Semantica ............................................................................................................................................ 16 Switch ...................................................................................................................................................... 17 Sintassi ................................................................................................................................................. 17 Semantica ............................................................................................................................................ 17 Do-while .................................................................................................................................................. 17 Sintassi ................................................................................................................................................. 17 Semantica ............................................................................................................................................ 17 Try ............................................................................................................................................................ 17 Sintassi ................................................................................................................................................. 17 Semantica ............................................................................................................................................ 18 Throw e throws........................................................................................................................................ 18 Sintassi ................................................................................................................................................. 18 Semantica ............................................................................................................................................ 18 Break ........................................................................................................................................................ 18 Sintassi ................................................................................................................................................. 18 Semantica ............................................................................................................................................ 18 Continue .................................................................................................................................................. 18 Sintassi ................................................................................................................................................. 18 Semantica ............................................................................................................................................ 18 I metodi iterativi e ricorsivi.......................................................................................................................... 19 Lo stack e la ricorsione ............................................................................................................................ 19 Input da tastiera e output su monitor ......................................................................................................... 19 Input di valori........................................................................................................................................... 19 Output di valori........................................................................................................................................ 19 Programmazione ad oggetti ........................................................................................................................ 19 Concetto e rappresentazione .................................................................................................................. 20 Variabili .................................................................................................................................................... 20 Variabili di istanza ................................................................................................................................ 20 Variabili di classe ................................................................................................................................. 20 Costruttore .......................................................................................................................................... 20 Il metodo main .................................................................................................................................... 20 Pacchetti Java .............................................................................................................................................. 20 Classi e sottoclassi ................................................................................................................................... 21 this e super .......................................................................................................................................... 21 Sovrascrittura di metodi ...................................................................................................................... 21 Overloading di metodi ......................................................................................................................... 21 Recast .................................................................................................................................................. 21 Metodi e classi astratti ........................................................................................................................ 22 Interfacce ............................................................................................................................................. 22 Classi notevoli .......................................................................................................................................... 22 Object .................................................................................................................................................. 22 Alcuni metodi della classe Object .................................................................................................... 22 Vector .................................................................................................................................................. 23 Alcuni metodi della classe Vector.................................................................................................... 23 Scanner ................................................................................................................................................ 24 3 Classi involucro per tipi semplici ......................................................................................................... 24 Sintassi di Java ............................................................................................................................................. 25 Glossario: ..................................................................................................................................................... 27 Esempi ......................................................................................................................................................... 28 Algoritmi .................................................................................................................................................. 28 Algoritmo semplice di somma ............................................................................................................. 28 Codice .............................................................................................................................................. 28 Tracing ............................................................................................................................................. 28 Algoritmo sommatoria ........................................................................................................................ 29 Codice .............................................................................................................................................. 29 Tracing ............................................................................................................................................. 29 Algoritmo conteggio occorrenze ......................................................................................................... 30 Codice .............................................................................................................................................. 31 Algoritmo del Minimo Comune Multiplo ............................................................................................ 31 Codice .............................................................................................................................................. 31 Tracing ............................................................................................................................................. 32 Codice .............................................................................................................................................. 32 Tracing ............................................................................................................................................. 32 Algoritmo Minimo tra 3 numeri .......................................................................................................... 30 Codice .............................................................................................................................................. 30 Tracing ............................................................................................................................................. 30 Algoritmo Somma elementi di matrice (errato) .................................................................................. 33 Codice .............................................................................................................................................. 33 Tracing ............................................................................................................................................. 33 Algoritmo Somma elementi di una matrice (corretto)........................................................................ 34 Codice .............................................................................................................................................. 34 Tracing ............................................................................................................................................. 34 Algoritmo Inversione di matrice .......................................................................................................... 35 Codice .............................................................................................................................................. 35 Tracing ............................................................................................................................................. 35 Algoritmo Massimo positivo in matrice .............................................................................................. 36 Codice .............................................................................................................................................. 36 Tracing ............................................................................................................................................. 37 Algoritmo Minimo in matrice .............................................................................................................. 36 Codice .............................................................................................................................................. 36 Algoritmo Somma positivi in matrice .................................................................................................. 37 Codice .............................................................................................................................................. 37 Algoritmo Ordinamento decrescente di matrice ................................................................................ 38 Codice .............................................................................................................................................. 38 Tracing ............................................................................................................................................. 38 Algoritmo Ordinamento crescente valori assoluti di elementi di matrice .......................................... 39 Codice .............................................................................................................................................. 39 Algoritmo Conta occorrenze di un valore in matrice .......................................................................... 40 Codice .............................................................................................................................................. 40 Algoritmo Somma elementi entro estremi ......................................................................................... 40 Codice .............................................................................................................................................. 40 Tracing ............................................................................................................................................. 40 Algoritmo Matrice in ordine crescente ............................................................................................... 41 Codice .............................................................................................................................................. 41 Tracing ............................................................................................................................................. 41 Algoritmo Massimo Comune Divisore ................................................................................................. 42 Codice .............................................................................................................................................. 42 4 Algoritmo Picchi in una matrice .......................................................................................................... 42 Codice .............................................................................................................................................. 42 Algoritmi con autoincremento e operatori assegnazione ................................................................... 42 Codice .............................................................................................................................................. 42 Tracing ............................................................................................................................................. 43 Codice .............................................................................................................................................. 43 Tracing ............................................................................................................................................. 43 Algoritmo con classe Scanner: ............................................................................................................. 43 Codice .............................................................................................................................................. 43 Algorimo che stampa matrice di interi ................................................................................................ 44 Codice .............................................................................................................................................. 44 Algoritmo Triangolo di Tartaglia: ......................................................................................................... 44 Codice .............................................................................................................................................. 44 Tracing: ............................................................................................................................................ 45 Algoritmo ricorsivo: ............................................................................................................................. 45 Codice .............................................................................................................................................. 45 Tracing: ............................................................................................................................................ 45 Algoritmo ricorsivo: ............................................................................................................................. 46 Codice .............................................................................................................................................. 46 Tracing: ............................................................................................................................................ 46 Classi ........................................................................................................................................................ 47 Classe Minimo ..................................................................................................................................... 47 Classe Punto ........................................................................................................................................ 47 Classe Segmento .................................................................................................................................. 48 5 Algoritmo Si dice algoritmo un procedimento composto di più azioni in sequenza logica che risolve un problema. Uno stesso problema può essere risolto con un numero illimitato di algoritmi diversi tra loro. Ciò che può cambiare è la complessità dell’algoritmo, cioè il numero di azioni che è necessario intraprendere e il tempo necessario a portare a compimento il procedimento, ma più algoritmi possono svolgere perfettamente lo stesso compito, partendo dagli stessi dati e producendo gli stessi risultati. Un algoritmo è indipendente dal linguaggio in cui è descritto. Uno stesso algoritmo può essere descritto in linguaggi diversi, non solo in lingue diverse ma anche con grammatiche e termini diversi. Istruzioni per chiamare un numero con il telefono: Ripeti le seguenti tre operazioni partendo dalla prima cifra C fino a quando non sei arrivato all’ultima cifra Guarda la cifra e cerca la stessa cifra sulla tastiera del telefono Premi il tasto C è la cifra successiva a destra Premi il tasto verde Algoritmo telefonata: void telefonata (int numero [ ]) { int ic = 0 while ( ic < numero.length) { int c = numero [ic]; tastiera.premi(c); ic = ic + 1; } tastiera.premi (VERDE); } void -> non torna nessun valore ic -> contatore while -> si ripete fin tanto che la condizione logica non è falsa Software e Hardware Per eseguire un algoritmo tramite un computer si scrive del codice, il software, che controlla l’elettronica, l’hardware. Il software va a stratificarsi sopra l’hardware 6 Hardware L’hardware è la parte meccanica ed elettronica di un qualsiasi dispositivo elettronico, mentre il software è il codice di un programma in grado di eseguire operazioni in base all’hardware a disposizione. Sistema Operativo Il Sistema Operativo nei computer o nei cellulari è un software che aggiunge diverse funzionalità all’hardware rendendone più agevole l’utilizzo e permettendo di gestire le sue risorse. Di per se il sistema operativo non svolge nessun compito di interesse per l’utente. Interfaccia di sistema L’utente per interagire con il sistema operativo fa uso di interfacce di sitema che spesso vengono considerate parte unica del sistema operativo. In effetti un sistema operativo può avere anche interfacce diverse che si adattano ad utenti ed usi diversi. Le interfacce permettono di interagire con il sistema operativo per gestire le sue risorse e chiedere l’avvio delle applicazioni. Il software di base in genere sfrutta le funzionalità messe a disposizione dal sistema operativo e a volte anche quelle messe a disposizione dall’interfaccia. Software di base I Software Applicativi sono software a volte preinstallati nei computer, che sono in grado di esplicare determinate funzioni di tipo generico per cui sono stati programmati. Svolgono compiti non specifici per un dato dominio di applicazione. Sono per esempio i pacchetti per l’automazione di ufficio (word processor, foglio elettronico e così via) che servono per scrivere testi e fare calcoli tabellari in qualsiasi genere di contesto o i programmi per la acquisizione e modifica di immagini generiche. 7 Il software di base in genere sfrutta le funzionalità messe a disposizione dal sistema operativo e a volte anche quelle messe a disposizione dall’interfaccia. Software applicativo I Software applicativi invece sono software professionali per come sono concepiti e svolgono funzioni ad alto livello specifiche per un dato dominio applicativo. Per esempio programmi per la gestione della contabilità, per la elaborazione di immagini mediche. Il software applicativo in genere sfrutta tutte le funzionalità messe a disposizione dal sistema operativo e a volte anche quelle messe a disposizione dall’interfaccia e dal software di base. Processo di creazione del Software Per creare una applicazione in un linguaggio compilato come C, C++, C# o Java serve passare alcune fasi: Per rendere più veloce la sviluppo di software ci sono delle applicazioni, gli ambienti di sviluppo, che permettono di svolgere queste fasi in un unico ambiente senza doversi curare dei singoli passaggi. Preparazione del testo del programma La preparazione del testo di un programma comporta la scrittura di un file contenente il programma (il codice sorgente). Per un programma Java il nome del file deve essere <nome classe>.java dove <nome classe> è il nome della classe definita dal programma. Il nome della classe possibilmente comincia per maiuscola. Es. Primo.java Negli altri linguaggi il codice sorgente deve essere contenuto in uno o più files con le estensioni relative (“.c”, “.cpp”, “.cs” rispettivamente per C, C++ e C#). La scrittura di un programma può essere effettuata con qualsiasi programma che consenta la scrittura di un testo (editor) senza notazioni tipografiche. Compilazione del programma Serve poi tradurre il programma in una sequenza di istruzioni direttamente eseguibili dal calcolatore o da un interprete come nel caso della Java Virtual Machine (JVM). Il compilatore Java standard, fornito con il Java Standard Development Kit (Java SDK), si chiama javac. Per usarlo occorre eseguire il comando: javac <nome classe>.java La compilazione produce come risultato un file chiamato <nome classe>.class che contiene i comandi direttamente eseguibili dal calcolatore o dall’interprete nel caso di Java (il bytecode). Ad esempio: javac Primo.java crea il file Primo.class. Per i linguaggi non interpretati come C e C++ i files prodotti dal compilatore (che si chiama cc, gcc o simili) sono parti di codice macchina e hanno estensione “.obj”. La fase di compilazione può dividersi in due passaggi. Nel primo viene prodotto un codice mnemonico (assembler) che nel secondo passaggio viene convertito in codice eseguibile. Di solito questi due passaggi risultano trasparenti al programmatore che vede solo il codice macchina finale. 8 Collegamento del programma compilato Dopo la compilazione, nel caso di codice eseguibile direttamente dal computer, bisogna assemblare il codice appena compilato con le parti di codice presenti nelle librerie di sistema. Questa funzione viene svolta dal linker (collegatore) che produce un file eseguibile. Esecuzione del programma compilato L'esecuzione di un programma si può effettuare solo dopo la compilazione, cioè quando si ha il file <nome classe>.class. In Java l'esecuzione del programma avviene attraverso la JVC che interpreta il byte code con il comando java <nome classe> (senza .class). Ad esempio il comando java Primo comporta l'esecuzione del programma Primo (o meglio del metodo main della classe Primo) Nel caso di Java il codice eseguibile non viene eseguito direttamente dalla macchina ma sarà la Java Virtual Machine che interpreta il codice e lo esegue sulla macchina ospite. La classe (o le classi) che derivano dalla compilazione vengono utilizzate dalla JVM assieme alle classi dei packages forniti con Java per svolgere il compito. Nel caso di C e C++ il processo è un po’ diverso dato che il codice oggetto collegato dal linker con il codice oggetto delle funzioni presenti nelle librerie di sistema viene eseguito direttamente dalla macchina. In tal caso l’esecuzione del codice avviene semplicemente nominando il nome della applicazione. Al momento dell’esecuzione il codice può utilizzare librerie dinamiche (DLL) che vengono caricate a seconda della necessità. 9 Sintassi e metalinguaggio Per descrivere la sintassi di un linguaggio si può usare la Bakus Naur Form (BNF) come metalinguaggio, cioé linguaggio per descrivere un linguaggio, in cui si scrivono tra parentesi angolate le categorie sintattiche, che stanno a rappresentare insiemi di frasi ben formate, cioé che rispettano la sintassi. Il meta linguaggio utilizza poi altri simboli per descrivere le parti del linguaggio. Il simbolo | significa “oppure”. Le parentesi grafe { } rappresentano parti opzionali, che possono essere o meno presenti. le parentesi quadre [ ] rappresentano parti che sono alternative separandole con virgole, per cui una delle sottoparti elencate deve essere presente. Le [ ] possono essere usate per indicare uno tra i simboli elencati all’interno delle parentesi. Le parentesi tonde ( ) racchiudono una parte vedendola come un oggetto unico. Il simbolo + indica la ripetizione di ciò che precede una o più volte, mentre iil simbolo * indica la ripetizione di ciò che precede zero, una o più volte. Infine il carattere ‘ serve per racchiudere delle parti del linguaggio che hanno la stessa forma delle parti del metalinguaggio. Ciò significa che se nel linguaggio bisogna inserire una parentesi grafa { si indicherà ‘{‘ per non confonderla con il simbolo del metalinguaggio che racchiude parti opzionali. Bisogna fare attenzione a non confondere simboli che fanno parte del linguaggio con simboli che fanno parte del metalinguaggio. Per indicare i caratteri del metalinguaggio come parti del linguaggio si racchiudono tra apici. Per esempio per dire che nel linguaggio è prevista una parentesi grafa aperta si scrive ‘{‘ . In tal caso i simboli *, + e – possono essere utilizzati per le ripetizioni: * significa 0 o più volte, + significa 1 o più volte, - identifica i simboli racchiusi (per esempio nell’ordine lessicografico) tra il simbolo precedente e quello successivo. Incolonnamento Il codice di un programma Java, C++ o C può essere scritto anche tutto su una riga in quanto il compilatore distingue le parti del programma trattando in maniera analoga gli spazi bianchi o i salti di linea. E’ per il programmatore che è importante incolonnare correttamente il codice per riuscire a riconoscerne subito la struttura. Un codice in cui gli identificatori sono scelti con attenzione e che è incolonnato correttamente spesso è comprensibile e una persona esperta riesce a capire l’algoritmo che rappresenta. 10 L’incolonnamento non fa quindi parte della sintassi ma descrivendo la sintassi dei costrutti Java verrà proposto una modalità di incolonnamento. Ognuno può scegliere un tipo di incolonnamento che preferisce tra i diversi utilizzati ma è importante mantenere in tutto il codice la stessa modalità. Commenti Anche se un codice ben incolonnato con gli identificatori scelti correttamente è auto esplicativo, i commenti permettono di comprendere le singole parti del codice anche per persone meno esperte o per algoritmi più complessi. Per fare commenti è possibile adottare tre diverse tipologie di commenti Commento a riga Per considerare come commento la parte finale di una riga di testo si inseriscono due barre trasversali // all’inizio del commento Commento racchiuso Il testo racchiuso tra /* e */ , anche se su più righe, verrà ignorato e considerato come commento. Commento racchiuso javadoc Se un commento racchiuso inizia con /** il commento potrà essere utilizzato da javadoc A seconda di dov'è collocato descrive ciò che viene dopo. /** **/ All’interno del commento, se precede un metodo, è possibile identificare i parametri e i valori di ritorno usando le forme @param <id> <descrizione parametro> @return <descrizione valore> Dati Tipi I tipi di dati sono insiemi di valori rappresentati con una rappresentazione uniforme. Ci possono essere tipi diversi per rappresentare con precisione diversa lo stesso tipo di valore, come per i numeri interi e i numeri reali. Numeri Interi: I numeri interi, sia negativi che positivi hanno precisioni molto diverse tra loro e possono essere indicati in diverse basi. ● 26 26 in forma decimale (inizia con cifra diversa da 0) ● 032 26 in forma ottale (inizia con la cifra 0) ● 0x1a / 0x1A 26 in forma esadecimale (inizia con 0x) ● 0b00011010 26 in forma binaria (inizia con 0b) ○ byte 1 byte ○ -128 ÷ 127 (-27 ÷ 27-1) short 2 byte ○ -32’768 ÷ 32’767 (-215 ÷ 215-1) int 4 byte ○ -2’147’483’648 ÷ 2’147’483’647 (-231 ÷ 231-1) long 8 byte 11 -9’223’372’036’854’775’808 ÷ 9’223’372’036’854’775’807 (-263 ÷ 263-1) Numeri Reali I numeri reali possono essere rappresentati in virgola e decimali o in forma esponenziale (mantissa e esponente) usando il punto per separare la parte intera da quella decimale ● 3.1415 3,1415 in virgola e decimali ● 314.15e-2 3,1415 in forma esponenziale 314,15 x 10-2 ● 0.031414e2 3,1415 in forma esponenziale 0,031415 x 102 ○ double 4 byte. precisione di 7 cifre significative ○ float 8 byte. precisione di 16 cifre significative Caratteri Si mettono i caratteri tra apici come carattere oppure con il codice della tabella Unicode: ● ‘A’ cioé A come carattere ● ‘\65’ cioè A in decimale. ● ‘\0101’ cioè A in ottale. ● ‘\x41’ cioè A in esadecimale ○ char 2 byte. Booleani Rappresentano valori logici ● true, false. ○ boolean 1 byte. Identificatori e Parole Chiave Un identificatore è una parola che consente di dare un nome a variabili, funzioni, classi e altro. Gli identificatori in Java vengono scritti usando lettere minusole distinguendo le diverse parole che li compongono con lettere maiuscole. In genere gli identificatori seguono una regola generale per cui hanno l’iniziale minuscola per varabili e funzioni mentre per le classi si usano iniziali maiuscole. Gli identificatori sono composti da lettere maiuscole e minuscole, da cifre e dal carattere sottolineato composti a piacere escluso per il fatto che l’iniziale non può essere una cifra. Le parole chiave sono parole che il compilatore riconosce a priori e non possono essere usate come Identificatori. Ogni linguaggio ha il suo insieme di parole chiave. In Java le parole chiave sono tutte minuscole. Ciò significa che anche se la parola “for” è una parola chiave, è possibile dichiarare una variabile con identificatore “foR” o una classe “For”. Scoping di un identificatore Lo scoping di un identificatore è costituito dalla parte del codice in cui l’identificatore è visibile e quindi in cui ci si può riferire all’identificatore. Variabili Una variabile è un Identificatore a cui è possibile associare un valore che può variare nel tempo. 12 Variabili locali Le variabili locali sono variabili che esistono in un blocco, al di fuori di fuori di esso non esistono. Il loro scoping è il blocco in cui sono dichiarate dal punto in cui sono dichiarate. Variabili globali Le variabili globali sono dichiarati al di fuori di una funzione. Il loro scoping è globale e sono visibili da tutte i blocchi delle funzioni. In C sono visibili solo dal punto in cui sono dichiarate in poi. In Java e C++ si distinguono in variabili di istanza e di classe e sono visibili in tutti i metodi della classe indipendentemente dal punto in cui sono dichiarate. Matrici La matrice è un insieme di elementi appartenenti ad uno stesso tipo di dato; il numero degli elementi è determinato dalla proprietà <nome matrice>.length. Per richiamare un determinato elemento bisogna indicare la sua posizione. Le posizioni sono designate da numeri interi, partendo da 0 per il primo elemento. Dichiarazione La dichiarazione di una matrice non va confusa con la sua allocazione <tipo><id>[ ] Allocazione L’allocazione di una matrice permette di creare fisicamente l’insieme, cioè di riservare in memoria lo spazio per la matrice. new <tipo>’[‘<espressione intera>’]’ Espressioni Espressioni aritmetiche Tutte le espressioni matematiche possono essere indicate in una espressione. Le espressioni devono essere scritte su una unica riga rispettando le precedenze degli operatori, aiutandosi eventualmente con le parentesi tonde e inserendo l’asterisco per indicare la moltiplicazione e lo slash (/) per la divisione. diventa (a+b)/(x+1)*(3+a*b) Per le espressioni e funzioni più complesse si fa ricorso alla classe Math. Per esempio Math.sqrt(x) mentre diventa diventa Math.pow(b,1/a). Espressioni logiche Le espressioni che derivano da una relazione di confronto si esprimono con gli operatori == (uguale), != (diverso), > (maggiore), <(minore), >=(maggiore o uguale), <=(minore o uguale). Le espressioni che derivano da altre espressioni logiche si esprimono con gli operatori || (or), && (and), ! (not). (a Λ b V c Λ ~d) diventa (a && b || c && !d) Opertatore modulo e divisione intera La divisione tra due numeri interi dà un risultato intero che tronca le cifre decimali. Bisogna fare attenzione perché anche se si assegna il risultato di una divisione tra due valori interi ad una variabile reale il risultato sarà la divisione intera. L’operatore modulo (%) serve per calcolare il resto della divisione intera tra due numeri. Il risultato è ovviamente un numero intero. 13 l’espressione 8.0/5.0 ha come risultato 1.6 mentre 8/5 ha come risultato 1 e l’espressione 8%5 ha come risultato il valore 3 perché 8/5 è uguale a 1 con resto 3. Left value Una espressione ritorna un left value quando il valore calcolato può essere messo alla sinistra di una assegnazione, cioè quando è possibile assegnarvi un valore. Tipicamente una variabile è un left value, come pure l’espressione che indica un elemento di una matrice. Un left value può essere il risultato di una espressione anche molto complessa che implica altre espressioni di vario tipo. Per esempio l’espressione v[f(i+1)] calcola il left value richiamando prima la funzione f a cui viene passato come parametro la somma tra i e 1. Se un left value si trova a sinistra della assegnazione indica a cosa deve essere associato il valore assegnato, cioè dove deve essere depositato una volta calcolato, se si trova a destra di una assegnazione ha come valore quello associato al left value indicato. Operatori assegnazione Una assegnazione è a sua volta anche una espressione con un proprio valore. Se assegno un valore ad un left value il valore che viene assegnato è anche il valore dell’espressione assegnazione. Esistono operatori assegnazione che prima di assegnare un valore ad un left value eseguono una operazione. operatore nome esempio = assegnazione x=y=z=w (il valore di w viene assegnato a z, y ed x) corrisponde a x=(y=(z=w)) += assegnazione con somma x+=3*y corrisponde a x=x+3*y -= assegnazione con sottrazione x-=3+y corrisponde a x=x-(3+y) *= assegnazione con moltiplicazione x*=3/y corrisponde a x=x*3/y /= assegnazione con divisione x/=3/y corrisponde a x=x/(3/y) %= assegnazione con modulo x%=3 corrisponde a x=x%3 Le espressioni con un operatore di assegnamento hanno come valore il valore assegnato. Bisogna tenere in considerazione che le espressioni assegnazione corrispondono alle espressioni indicate solo nel caso il calcolo dell’espressione non modifichi tramite un effetto laterale il calcolo del left value a cui assegnare il valore. Per esempio se si scrive v[i]+=i+=3 non corrisponde a v[i]=v[i]+(i=i+3) perché nel secondo caso il calcolo di v[i] nella parte destra dell’assegnazione avviene prima della modifica di i mentre nell’altro caso avviene dopo. Operatori di autoincremento e autodecremento Dato che l’azione di incrementare o decrementare una variabile o in generale un left value si presenta molto spesso all’interno degli algoritmi, sono stati introdotti due operatori che eseguono l’incremento e il decremento di un left value. Questi due operatori a loro volta sono in forma anticipata o posticipata. Gli operatori di autoincremento incrementano di 1 il left value: <left value>++ incrementa di 1 dopo aver calcolato il valore associato al left value ++<left value> incrementa di 1 prima di calcolare il valore associato al left value Gli operatori di autodecremento decrementano di 1 il left value: <left value> - - decrementa di 1 dopo aver calcolato il valore associato al left value 14 - - <left value> decrementa di 1 prima di calcolare il valore associato al left value Il risultato dell’operazione è il valore calcolato prima o dopo a seconda della posizione dell’operatore. Operatore condizionale E’ possibile inserire in una espressione un valore a seconda del valore di una condizione logica. Il funzionamento è analogo al comando condizionale if ma in questo caso non è un comando ma una espressione che può essere inserita all’interno di altre espressioni. La sintassi dell’operatore ternario “?” è <espr bool> ? <espr1> : <espr2> e il valore è uguale alla prima espressione se l’espressione booleana è vera, mentre è uguale alla seconda espressione se l’espressione booleana è falsa. La prima e la seconda espressione devono essere di tipo compatibile e il risultato è del tipo più “capiente” tra i tipi delle due espressioni. Per esempio l’espressione (x<y)? x : y vale x se x è minore di y e y altrimenti. Funzioni, metodi e procedure Alcune sequenze di istruzioni possono dover essere ripetute più volte all’interno di un programma. Risulta quindi comodo poter scrivere tali sequenze una volta sola e poter fare riferimento ad esse all’interno del programma tutte le volte che la loro esecuzione risulta necessaria. Le funzioni e le procedure costituiscono lo strumento di programmazione che realizza quanto descritto. Una funzione o una procedura raggruppa una sequenza di istruzioni che realizzano una funzionalità del programma e assegna loro un nome; la sequenza di istruzioni è chiamata definizione o corpo della funzione o della procedura. Ogni qualvolta è necessario eseguire una funzionalità, è sufficiente richiamarla attraverso il nome. Quando si usa una funzione o una procedura, si dice che si invoca o chiama la funzione o la procedura. Una funzione permette di definire un algoritmo parametrico e identificarlo tramite un nome. Per una funzione di solito sono indicati un insieme di parametri e viene ritornato un valore. Le funzioni che non ritornano un valore, il cui tipo di ritorno è perciò “void”, si chiamano ‘procedure’. I metodi sono funzioni o procedure legati ad una istanza o a una classe, ma non tutte le funzioni o le procedure sono metodi, per esempio nei linguaggi di programmazione non a oggetti. Parametri di una funzione A seconda del punto di vista si distinguono due tipi di parametri: i parametri formali e i parametri attuali. I parametri formali sono quelli dichiarati per tipo, numero e ordine nella definizione del metodo, mentre i parametri attuali sono quelli che vengono passati al metodo all’atto della chiamata. I parametri formali permettono di dare un nome, che potrà essere utilizzato all’interno della funzione o procedura, ai valori che verranno passati come parametri attuali. Al momento della chiamata della funzione o della procedura il valore dei parametri attuali viene assegnato al parametro formale. Un esempio di parametri formali sono n e m nella dichiarazione seguente: int g(int n, int m) Un esempio di parametri attuali sono 4 e 6 nella chiamata seguente: a=g(4, 6) Nell’esempio il valore 4 verrà associato al parametro n e il valore 6 verrà associato al parametro m e quindi il codice dichiarato nel corpo della funzione g verrà eseguito. Alla fine dell’esecuzione della funzione g il valore ritornato dalla funzione verrà assegnato alla variabile a. Firma di una funzione La firma di una funzione è costituita dal nome della funzione, il numero dei parametri, il tipo dei parametri e l’ordine dei parametri. Comandi Sono utilizzabili come comandi tutte le espressioni, tra cui, ovviamente, le assegnazioni e le chiamate di funzioni, e le chiamate di procedure. 15 Ci sono poi comandi più complessi detti comandi strutturati che consentono di combinare in alternative o cicli i comandi più semplici. Qui di seguito sono i comandi di Java. Return Sintassi return {<espressione>} Semantica Il comando permette di far ritornare da una funzione il valore che deriva dal calcolo dell’espressione. Nel caso di una procedura, una funzione che non ritorna un valore, il comando return non avrà l’espressione. If Sintassi if (<espressione booleana>) 2→ <comando> { 1→ else 2→ <comando> } ⇒facoltativo Semantica - Si verifica l’espressione booleana; - se l’espressione è verificata si esegue il comando, altrimenti si esegue, se presente, il comando contenuto nell’else. While Sintassi while (<espressione booleana>) 2→ <comando> Semantica - Il comando viene eseguito fintanto che è vera l’espressione booleana; - l’espressione booleana viene valutata per prima, per cui il comando può anche essere eseguito 0 volte. For Sintassi for (<espressione1>; <espressione booleana>; <espressione3>) 2→ <comando> Semantica - Viene valutata la prima espressione per averne gli effetti laterali e ignorandone il risultato; - si verifica l’espressione booleana; - se è falsa finisce l’esecuzione del comando for - se è vera, verrà eseguito il comando del ciclo; - si valuta la terza espressione per averne gli effetti laterali ignorandone il risultato; - si verifica nuovamente la seconda espressione 16 - il ciclo terminerà quando l’espressione booleana non sarà più verificata. Switch Sintassi switch ’(‘ <espressione integral> ’)’ 2→ ‘{‘ 2→ case <cost integral>: 4→ <lista di comandi> 4→ { break; } 2→ { case <cost integral>: 4→ <lista di comandi> 4→ { break; } } * 2→ { default: 4→ <lista di comandi> 4→ { break; } } 2→ { case <cost integral>: 4→ <lista di comandi> 4→ { break; } } * 2→ ‘}’ ⇒facoltativo ⇒0 o più volte ⇒0 o più volte Semantica - Si valuta l’espressione. - Se il valore calcolato è presente in un ‘case’ si esegue la lista di comandi che lo segue e poi le liste di comandi dei successivi ‘case’ finché non si arriva ad un break o alla fine del blocco. - Se il valore calcolato non è presente in nessun ‘case’ ed è presente l’entrata di default viene eseguita la lista di comandi che segue il ‘default’ e gli eventuali case successivi fino al primo break o alla fine del blocco, altrimenti, se non c’è il ‘default’ non viene eseguito nulla. Do-while Sintassi do 2→ 2→ <comando> while ‘(‘ <espressione bool> ‘)’ Semantica - Si esegue il comando nel do. - Si valuta l’espressione nel while e finché è vera continua ad eseguire il comando e quando è falsa termina l’esecuzione Try Sintassi try 2→ <blocco> 1→ { catch ’(‘<dichiarazione eccezione>’)’ 2→ <blocco> } * 1→ { finally 2→ <blocco>} 17 Semantica - Si esegue il blocco - Se in un punto del blocco avviene una eccezione si interrompe l’esecuzione del blocco. - In caso di eccezione, se c’è un ramo catch in cui è dichiarata l’eccezione, si esegue il blocco dopo il ‘catch’, se non c’è nessun ramo catch relativo all’eccezione avvenuta, si esegue il blocco di finally, se questo è presente. Throw e throws “Tirare” un’eccezione è un modo per segnalare un’anomalia nell’esecuzione di un metodo. Una volta tirata l’eccezione, si potrà cercare di risolverla o semplicemente inoltrarla ad un ulteriore livello che possa risolverla. Se invece l’eccezione non viene gestita l’esecuzione del programma verrà interrotta. Sintassi throw <eccezione> throws <tipo eccezione> Semantica L’esecuzione del metodo viene interrotta e l’eccezione, che è un oggetto di classe o sottoclasse di Exception che di solito viene creato sul momento con le informazioni relative al problema riscontrato, viene data da gestire al metodo chiamante. Il metodo che tira l’eccezione deve dichiararlo nell’intestazione tramite la parola chiave throws. Per esempio il metodo seguente: public int sommaPositivi(int add1, int add2) throws Exception { if (add1<0 || add2<0)) throw new Exception(“valore negative”); else return add1+add2; } crea e tira una eccezione nel cui commento c’è scritto “valore negativo” quando uno dei due parametri è negativo. Break Sintassi break [<etichetta>] Semantica - Quando viene eseguito interrompe il ciclo più interno in quel punto o la sequenza dei comandi di uno switch. Se è presente l’etichetta, si continua oltre il ciclo più esterno al cui inizio è indicata l’etichetta seguita da ‘:’. Continue Sintassi continue [<etichetta>] Semantica - Quando viene eseguito interrompe il ciclo più interno facendo andare al ciclo successivo. Se è presente l’etichetta, si continua al prossimo ciclo più esterno al cui inizio è indicata l’etichetta seguita da ‘:’. 18 I metodi iterativi e ricorsivi Un processo ripetitivo è definito iterazione ed un metodo che implementi tale processo è detto iterativo. Accade spesso, però, che il modo più naturale per progettare un algoritmo implichi l’applicazione dell’algoritmo stesso. Un metodo che contiene una chiamata a se stesso è detto ricorsivo. Lo stack e la ricorsione Quando incontra una chiamata ricorsiva, il computer interrompe l’esecuzione in corso sull’ultimo record di attivazione per determinare il risultato della chiamata ricorsiva. Prima di fare questo, salva le informazioni necessarie per poter continuare l’elaborazione rimasta in sospeso una volta determinato il risultato della chiamata ricorsiva. Queste informazioni vengono scritte su un nuovo record di attivazione che viene posto in cima alla pila (lo stack). Il computer sostituisce sul nuovo record di attivazione i parametri con gli argomenti passati al metodo e inizia l’esecuzione della chiamata ricorsiva. Quando arriva una nuova chiamata ricorsiva, ripete il processo di salvataggio delle informazioni sullo stack e usa un nuovo record di attivazione per la nuova chiamata ricorsiva. Input da tastiera e output su monitor Input di valori Per l’input di valori si utilizza la classe java.util.Scanner applicata a System.in . Si dichiara uno scanner per l’input standard e si prelevano i valori da questo con i metodi next, nextInt, nextFloat, nextDouble … #import java.util.*; …. Scanner input=new Scanner(System.in); int a=in.nextInt(); Output di valori Il comando System.out.println(<valore>) mostra sullo schermo il valore che viene passato. Il valore deve essere una stringa che può derivare dalla concatenazione di stringhe e valori vari. Il comando System.out.print(<valore>) E’ analogo ma non va a capo dopo avere scritto il valore Programmazione ad oggetti 19 Una classe è un insieme di istanze e in una classe ci sono dei metodi e delle proprietà. Concetto e rappresentazione Java è uno linguaggio di programmazione ad oggetti. Questi si basano su 4 principali elementi: ● Il concetto: è l’astrazione di ciò che vogliamo rappresentare; aggrega più oggetti in una unica descrizione. ● La classe: è la rappresentazione del concetto, nella quale descrivo la struttura delle istanze. Nella classe identifico le proprietà del concetto e i metodi, cioè le azioni che gli oggetti sono in grado di svolgere che intendo rappresentare. ● Gli oggetti: sono tutti gli elementi che concretizzano il concetto. ● Le istanze: sono la rappresentazione degli oggetti associati ad un concetto rappresentato nella classe. In una classe ci possono essere più istanze. Variabili Le variabili globali in una classe si distinguono in variabili di istanza o di classe.. Variabili di istanza Sono dichiarate al di fuori del blocco e possiedono un valore proprio per ogni istanza. Le variabili di istanza sono legate ad ogni singola istanza. In ogni istanza hanno un proprio valore che determina le caratteristiche dell’oggetto rappresentato. Per riferirsi ad una variabile di istanza all’interno di un metodo di istanza basta indicare l’identificatore della variabile. Per riferirsi ad una variabile di istanza da un qualsiasi punto basta indicare l’istanza a cui si riferiscono con la notazione sassone premettendo all’identificatore della variabile l’espressione che ritorna il riferimento all’istanza, seguito da punto. Variabili di classe Sono anch’esse dichiarate al di fuori del blocco ma possiedono un valore unico per tutta la classe. Le variabile di classe sono legate ad una intera classe. Si dichiarano premettendo la parola chiave static. Per riferirsi ad una variabile di istanza dall’interno della classe a cui appartengono basta indicare il loro identificatore. Per riferirsi ad una variabile di classe da qualsiasi punto del codice basta usare la notazione sassone e premettere al suo identificatore il nome della classe a cui appartiene seguito dal punto oppure il riferimento ad una istanza di quella classe. Costruttore Un costruttore è un metodo che inizializza e crea le istanze utilizzabili dai diversi metodi nelle classi, esso non può essere eseguito come una funzione ma deve essere attivato tramite l’operatore “new” che ritorna un valore che è un riferimento all’istanza creata. Nella intestazione dei costruttori non è presente il <tipo> e devono chiamarsi come la classe. Il metodo main Il metodo main è una procedura che deve essere dichiarata per poter eseguire una classe. Soltanto le classi che vengono eseguite come programmi devono avere un metodo main, tuttavia ogni classe può averne uno, per esempio a scopo di prova, per verificare che la classe funzioni correttamente. Se una classe ha un metodo main, ma non viene eseguita come un programma, il metodo main viene semplicemente ignorato. L’intestazione del metodo main deve essere la seguente: public static void main(String[] a) potendo però dare un nome qualsiasi al parametro. Pacchetti Java In Java esistono dei pacchetti chiamati package che contengono più classi e si possono importare prima di scrivere il programma. Per importare un pacchetto bisogna scrivere: 20 import <nome package>.*; L’asterisco (*) serve per importare tutte le classi presenti in quel pacchetto. Classi e sottoclassi Una classe può essere sottoclasse di un’altra classe. Ciò significa che i metodi e le variabili della nuova classe vanno ad aggiungersi a quelli dell’altra classe detta superclasse. Una classe A che è sottoclasse di un’altra B si dice che estende la classe B. <sottoclasse>::=<[public] class <id>{ extends <id>} Le classi che non estendono esplicitamente un’altra classe sono implicitamente sottoclassi della classe Object che è superclasse di tutte le classi. Dichiarando una classe come sottoclasse di un’altra classe implica che la nuova classe ha tutte le variabili di istanze e di classe e tutti i metodi di istanza e di classe della superclasse. Per esempio tutte le classi, essendo tutte sottoclasse della classe Object hanno implicitamente i metodi di Object come toString e equals. this e super Le parole chiave this e super servono a due scopi. this serve per riferirsi all’oggetto utilizzato attualmente, utile per risolvere situazioni di ambiguità per esempio nel caso di sinonimia tra nome di una variabile di istanza e variabile locale o parametro. Analogamente super si riferisce all’oggetto utilizzato visto come istanza della superclasse. Per esempio avendo un parametro di nome x ed una variabile di istanza con lo stesso nome posso assegnare il valore del parametro alla variabile di istanza con this.x=x; this serve anche per richiamare un costruttore della stessa classe ma con firma diversa. Analogamente super serve per richiamare i costruttori della superclasse. Per esempio se un costruttore senza parametri deve comportarsi come il costruttore con un parametro con valore 0 il corpo del costruttore senza parametro può essere this(0); che richiama il costruttore con un parametro passandogli il valore 0, selezionandolo tramite la sua firma. Sovrascrittura di metodi Nel caso un metodo abbia la stessa firma di un metodo della superclasse il nuovo metodo va a sovrascrivere il metodo della superclasse. Ciò significa che invece di venire richiamato il metodo della superclasse, per le istanze della sottoclasse verrà attivato il metodo della sottoclasse con la stessa firma. Overloading di metodi Non possono esserci in una classe due metodi o costruttori con la stessa firma. In una classe possono essere presenti metodi con lo stesso nome ma con diversa firma. Grazie alla firma quasi sempre si riesce a capire quale dei metodi deve essere attivato. In alcuni casi serve specificare il tipo dei parametri attuali tramite recast. Recast Un valore di un tipo può essere trattato come valore di altro tipo. Per esempio un intero viene automaticamente riconvertito in double nel caso venga utilizzato (per esempio come parametro) come un double. Quando però una tale conversione fa perdere precisione bisogna fare un recast esplicito, cioè dire esplicitamente che si desidera venga fatta la conversione. Per esempio per utilizzare un numero double come un intero (eventualmente troncando la sua parte decimale) basta premettere al valore tra parentesi il tipo (long)(3.5*2.0) 21 Metodi e classi astratti Nella dichiarazione di un metodo astratto è presente l'intestazione ma non il corpo, ovvero non è descritto il suo funzionamento. Un metodo astratto può essere presente solo in una classe astratta. In una classe astratta possono essere dichiarati metodi astratti. Una classe astratta non può essere istanziata, quindi non è possibile creare istanze di quella classe ma solo di sottoclassi di quella classe in cui sono stati implementati tutti i metodi astratti. Una classe astratta permette di definire parzialmente delle classi lasciando all’estensione della classe l’implementazione solo di alcune parti specifiche. Interfacce Una interfaccia assomiglia ad una classe astratta in quanto è costituita solo da intestazioni di metodi non implementati. In una interfaccia però tutti i metodi non sono implementati. L’interfaccia è, quindi, un insieme di metodi di cui si ha l'intestazione ma non il corpo. Una interfaccia permette di descrivere un concetto tramite le sue funzioni ma non le sue proprietà. Le classi che implementeranno una interfaccia dovranno implementare tutti i metodi elencati nell’interfaccia. In compenso una classe può estendere solo una classe astratta mentre può implementare più interfacce permettendo un meccanismo simile alla ereditarietà multipla. Classi notevoli Object La classe Object è la superclasse, diretta o indiretta, di ogni classe Alcuni metodi della classe Object Essendo la superclasse di tutte le classi, i metodi della classe Object vengono ereditati da tutte le classi. metodo toString Tutte le classi hanno a disposizione il metodo di istanza toString che ritorna una stringa contenete una descrizione dell’istanza. Il metodo toString ha la seguente intestazione. public String toString() Se non viene sovrascritto la stringa ritornata contiene il nome della classe ed un numero univoco che identifica l’istanza. metodo equals Tutte le classi hanno anche a disposizione il metodo equals che permette di avere il confronto semantico tra due oggetti. Il metodo equals ha la seguente intestazione public boolean equals(Object ob) Il metodo ritorna true se l’oggetto che viene passato come parametro è semanticamente uguale all’istanza, cioé se, anche se non è fisicamente la stessa istanza, va considerato equivalente ad essa. Mentre l’uguaglianza fisica può essere verificata tramite l’operatore ==, il metodo equals fornisce l’uguaglianza semantica. Per esempio due punti cartesiani, anche se distinti perché creati in due momenti diversi possono coincidere, cioè avere le stesse coordinate. In tal caso i due punti, anche se distinti, possono essere considerati semanticamente uguali. metodo clone Il metodo public Object clone() ritorna una nuova istanza rappresenta una copia della stessa istanza. La sovrascrittura serve soprattutto a richiamare correttamente il metodo clone per le istanze che sono contenute nell’oggetto. 22 metodo getClass Il metodo public final Class getClass() ritorna un oggetto di classe Class, che è una rappresentazione a runtime della classe dell’oggetto Vector La classe java.util.Vector definisce degli oggetti, chiamati vettori, che consentono di rappresentare sequenze di lunghezza variabile di oggetti. Come per le matrici, ciascun oggetto in un vettore è identificato da un numero intero, detto indice, che ne indica la posizione nel vettore. Grazie all'indice è possibile accedere indipendentemente a ciascun elemento della sequenza. L'accesso ad una posizione inesistente provoca un errore (viene lanciata un'eccezione). Al momento della dichiarazione o creazione di un vettore, il tipo base degli elementi del vettore può essere indicato tra parentesi angolate dopo il nome della classe. Se non viene indicato, si assume sia Object. I vettori sono dunque simili alle matrici (array). Le differenze principali sono due: la dimensione di un vettore può variare durante l'esecuzione di un programma; il tipo base di un vettore NON può essere un tipo primitivo (int, double ...). Per rappresentare un vettore con tali valori bisogna usare (esplicitamente o implicitamente) le classi wrapper che rappresentano tali valori. Alcuni metodi della classe Vector metodo size Il metodo int size() restituisce il numero di elementi contenuti nel vettore. metodo elementAt Il metodo elemenAt(int index) fornisce l’elemento del vettore in una determinata posizione indicata dal parametro. metodo get Il metodo Object get (int index) restituisce l'elemento di indice index. metodo set Il metodo Object set (int index, Object ob) sostituisce ob all'oggetto di posizione index che viene restituito. metodo add Il metodo void add (int index, Object ob) inserisce ob nella posizione index e sposta tutti gli elementi, da index in poi, di una posizione. Il metodo boolean add (Object ob) aggiunge ob dopo l'ultimo elemento; restituisce true. metodo remove Il metodo void remove (int index) rimuove l'oggetto presente nella posizione index e sposta all'indietro di una posizione tutti gli elementi successivi a quello rimosso. Il metodo boolean remove (Object ob) rimuove l'oggetto ob se presente e restituendo true, oppure restituendo false altrimenti. 23 metodo indexOf Il metodo int indexOf (Object elem) restituisce l’indice della prima posizione in cui è collocato l'oggetto 'elem' nel vettore, -1 se non esiste. metodo toString Il metodo String toString () che sovrascrive il corrispondente metodo di Object restituisce una stringa contenente il risultato dell’applicazione del metodo toString su tutti gli elementi del vettore nella forma "[<el-1>,<el-2>, ...,<el-n>]". metodo equals Il metodo boolean equals (Object vet) che sovrascrive il corrispondente metodo di Object restituisce true se l'argomento è un vettore con lo stesso numero di elementi (size) e l’applicazione del metodo equals a tutti gli elementi corrispondenti ritorna true. Scanner La classe Scanner serve per ricevere input da tastiera. Esempio: Scanner <id>=new Scanner(System.in) int <id2>=<id>.nextInt() Scanner sc=new Scanner(System.in) int ncerchi= sc.nextInt() Il metodo nextInt riceve l’input da tastiera del tipo scritto dopo “next” quindi in questo caso solo un tipo intero. Per cambiare il tipo basta scrivere il tipo che si vuole dopo next. Es. nextDouble, nextBoolean… Classi involucro per tipi semplici I tipi semplici (numeri, caratteri e valori booleani) in Java non sono oggetti, quindi per esempio non è possibile inserirli direttamente in un Vector. Per memorizzare sequenze di numeri interi, numeri in virgola mobile, o valori di tipo boolean in un Vector, si devono usare le classi involucro. Le istanze di queste classi sono usate per incapsulare valori primitivi (di tipi semplici) all'interno di un oggetto. Questo permette di trattare in maniera omogenea tipi primitivi ed oggetti. Gli oggetti involucro possono naturalmente essere inseriti in un Vector. Ci sono classi involucro per tutti i tipi primitivi. Normalmente hanno un nome simile al corrispondente tipo primitivo, ma iniziano con maiuscola: Bignum, Boolean, Byte, Character, Double, Float, Integer, Long, Number, Short. Ciascuna di queste classi ha (oltre ai soliti metodi toString e equals): • un costruttore con parametro di tipo primitivo (ad esempioCharacter(char c) o Integer(int value)); • un costruttore con parametro String (ad esempio Integer(String s)); • un metodo <tipo>Value che produce il valore di tipo primitivo corrispondente (ad esempio intValue()); Per esempio la classe Integer è la classe involucro per numeri interi. Ha un costruttore che crea un oggetto di tipo Integer a partire da un valore di tipo int: Integer numero = new Integer(30); Viceversa, il metodo intValue restituisce il valore di tipo int memorizzato nell'oggetto di tipo Integer: int n = numero.intValue(); Ecco come si può aggiungere un numero intero a un vettore: Vector dati = new Vector(); int n = 30; Integer numero = new Integer(n); dati.addElement(numero); 24 Nelle versioni recenti di Java è possibile anche ottenere una conversione automatica per cui se scrivo dati.add(3) la costante viene convertita in un oggetto Integer che incapsula il valore 3. Per recuperare il numero, si deve convertire con un cast il riferimento restituito dal metodo elementAt in modo da ottenere un oggetto di tipo Integer (il metodo restituisce un Object), per poi invocare il metodo intValue: Integer numero = (Integer)dati.elementAt(0); int n = numero.intValue(); Sintassi di Java <tipo>::= byte | short | int | long | double | float | char| <classe> <identificatore>::= [_a-zA-Z]+[_a-zA-z0-9]* <espressione>::= <costante> | <espressione><operatore binario><espressione> | <autoincremento>| <autodecremento>| <operazione condizionale>| <operatore unario><espressione> | <allocazione>| <identificatore>’(‘<parametri>’)’ | <identificatore>’[‘<espressione intera>’]’ | <left value>::=<identificatore>|<identificatore>’[‘<espressione intera>’]’ <operatore binario>::= + | - | * | / | % <operatore unario>::= + | op. unario = un operatore con un solo operante <parametri>::= <espressione> | <parametro> , <espressione> <ciclo>::= while (<espressione booleana>) ->2 <comando> ->2 = spostato a destra di due caratteri <espressione booleana>::= <espressione><operatore booleano di relazione><espressione> | <espressione booleana><operatore booleano><espressione booleana> <operatore booleano di relazione>::= < | > | <= | >= | != | = = != significa: diverso <operatore booleano>::= && | ‘|’’|’ | ! && = and || = or ! = not <autoincremento>::=<left value>++|++<left value> <autodecremento>::==<left value>--|--<left value> <operatore condizionale>::=<espr bool> ? <espr1> : <espr2> Se l’espr bool è vera, fa l’espr1, se è falsa fa l’espr 2. <comando>::= <assegnazione> | <dichiarazione di variabile> | <dichiarazione con assegnazione> | <espressione> | <blocco>| <ritorno>| <condizione>| <ciclo> <tentativo> <blocco>::=’{‘ <lista comandi> ‘}’ <lista comandi>::= <comando>; | 25 <comando><lista comandi>; <dichiarazione di variabile>::= <tipo><identificatore> | <tipo> <identificatore> ‘[‘’]’ <dichiarazione con assegnazione >::= <tipo><identificatore> = <espressione> <assegnazione>::= <left value> = <espressione>| <left value>+=<espr>| <left value>-=<espr> <allocazione>::= new <tipo>’[‘<espressione intera>’]’ <dichiarazione di metodo>::= <tipo><identificatore> ‘(‘<lista dichiarazione parametri> ’)’ <corpo di funzione> <lista dichiarazione parametri>::= <dichiarazione parametro> | <dichiarazione parametro>,<lista dichiarazione parametri> <dichiarazione parametri>::= <tipo><identificatore> | <tipo><identificatore> ‘[’ ‘]’ <corpo del funzione>::= <blocco> <condizione>::= if ‘(‘ <espressione booleana> ‘)’ <comando> { else <comando> } { } racchiude parti che sono opzionali <ciclo>::= <ciclo while> | <ciclo for> <ciclo while>::= while ‘(‘ <espressione booleana> ‘)’ <comando> <ciclo for>::= for ‘(‘ <espressione 1>;<espressione booleana>;<espressione 2> ‘)’ <comando> <ritorno>::=return {<valore>} <tentativo>::= try <blocco> { catch ’(‘<dichiarazione eccezione>’)’ <blocco> } * { finally <blocco>} <classe>::= {public} class <id> ‘{‘ <lista di proprietà e metodi> ‘}’ <lista di proprietà e metodi>::= <dichiarazione di variabile>;| <dichiarazione di funzione>; | <lista di proprietà e metodi><dichiarazione di variabile>; | <lista di proprietà e metodi><dichiarazione di funzione>; <dichiarazione di funzione>::= <dichiarazione di metodo> | < dichiarazione di costruttore> <dichiarazione di costrutture>::= <identificatore> ‘(‘<lista dichiarazione parametri> ’)’ <corpo di funzione> <sottoclasse>::=<[public] class <id> extends <id> In Java le parentesi tonde racchiudono parametri, le parentesi quadrate racchiudono indici, le paratesi graffe racchiudono comandi. 26 Glossario: Classe: Rappresentazione di un concetto, il nome inizia con una lettera maiuscola. In una classe si identificano le informazioni da conservare per descrivere il concetto. Concetto: Astrazione di un insieme di oggetti. Istanza: rappresentazione di un oggetto all’interno di una classe. Matrice (array): è un insieme ordinato dello stesso tipo di dati. Gli elementi si identificano attraverso un indice, detto “indice della matrice” che parte sempre da 0. Metodo: Funzione che descrive delle azioni e può modificare il contenuto delle proprietà. Parametro: Identificatore a cui si associa un valore al momento della chiamata ed è dichiarato nell’intestazione. Parametro ATTUALE: Da actual, effettivo. E’ il valore che viene assegnato al parametro al momento della chiamata. Parametro FORMALE: E’ il nome che viene utilizzato per rappresentare un parametro all’interno di una funzione. Procedure: Funzioni che non ritornano un valore. Variabile: Identificatore a cui posso associare un valore che può variare nel tempo. 27 Esempi Algoritmi Algoritmo semplice di somma Codice int f( ) { a = 0; i = 0; while (i < 10) { a = a+i ; i = i+1; } return a; } Tracing fA() A 45 A : punto di chiamata a 0 0 1 3 6 10 15 21 28 39 45 i 0 1 2 3 4 5 6 7 8 9 10 28 Algoritmo sommatoria Codice /** * Ritorna la sommatoria dei primi n numeri * @param n il numero massimo * @return la sommatoria dei primi n-1 numeri, 0 se n<1 **/ int s(n) { a=0 i=0 while (i < n) { a=a+i i=i+1 } return a } Tracing s B (3) B n 3 3 a 0 0 1 3 i 0 1 2 3 s C (-2) C n 0 -2 a 0 i 0 s D (5) D n 10 5 a 0 0 1 3 6 10 i 0 1 2 3 4 5 Questo algoritmo calcola: ● 0 se n < 1; ● la somma dei prmi (n-1) numeri e cioé (n * (n – 1)) / 2 29 Algoritmo per il minimo tra 3 numeri Codice /** * Calcola il minimo tra tre numeri * @param a il primo numero * @param b il secondo numero * @param c il terzo numero * @return il minimo tra a, b e c **/ int min3(int a, int b, int c) { int d=0; if (a<b) { If (b<c) d=c; else d=b; } else { if (a<c) d=c; else d=a; } return d; } Tracing min3 C (3,7,-2) C a b 7 3 7 min3 E (15,8,12) E a b 15 15 8 c -2 c 12 d 0 7 d 0 15 min3 D (-3,2,10) D a b 10 -3 2 c 10 d 0 10 min3 F (7,7,7) F a 7 7 c 7 d 0 7 b 7 30 Algoritmo conteggio occorrenze Codice /** * Conta le occorrenze di un valore in una matrice * @param mat la matrice entro cui cercare il valore * @param val il valore da cercare * @return il numero di occorrenze di val nella matrice **/ public static int conta(int mat[], int val) { int b=0; for(int i=0; i<mat.length; i=i+1) { if(mat[i]==val) b=b+1; } return b; } Algoritmo del minimo comune multiplo Codice /** * Calcola il minimo comune multiplo tra due numeri * @param n il primo numero * @param m il secondo numero * @return il minimo comune multiplo tra m e n **/ int mcm(int n,int m) { int a=n, b=m; while (a!=b) { If (a<b) a=a+n; else b=b+n; } return a; } 31 Tracing mcm A (4, 6) A n 12 4 m 6 a 4 8 12 b 6 12 B 42 mcm B (7,6) n m 7 6 a 7 14 21 28 35 42 b 6 12 18 24 30 36 42 Codice /** * Calcola il minimo comune multiplo tra due numeri * @param a il primo numero * @param b il secondo numero * @return il minimo comune multiplo tra a e b **/ public int mcm (int a, int b) { int a1, b1; for (a1=a, b1=b; a1 != b1;) { if (a1<b1) a1= a1+a; else b1= b1+b; } return (a1+b1)/2; } Tracing mcm A (3,5) A 15 a 3 mcm C (9,15) b 5 a1 3 6 9 12 15 b1 5 10 15 b 4 a1 12 b1 4 8 12 C 45 a 9 b 15 a1 9 18 27 36 45 b1 15 30 45 mcm B (12,4) B 12 a 12 32 Algoritmo per la somma degli elementi di una matrice (errato) Codice /** * Somma gli elementi di una matrice * @param v la matrice di cui sommare gli elementi * @return la somma degli elementi della matrice v **/ int somma(int v[]) { int t1=0; int i=0; while (i<v.length) { t1=t1+v[i]; } return t1; } N.B. v.length -> lunghezza della matrice; v[i] -> elemento della matrice di indice i. Tracing somma A (mat) mat: 5 -3 10 6 A v mat t1 0 5 10 ….. i 0 Tracing infinito perché c’è un errore nell’algoritmo 33 Algoritmo di somma degli elementi di una matrice (corretto) Codice /** * Somma gli elementi di una matrice * @param v la matrice di cui sommare gli elementi * @return la somma degli elementi della matrice v **/ int somma(int v[]) { int t1=0; int i=0; while (i<v.length) { t1=t1+v[i]; i=i+1; } return t1; } Tracing somma A (mat) mat: 5 -3 10 A 18 v mat t1 0 5 2 12 18 somma B (m1) m1: 3 7 -5 6 i 0 1 2 3 4 B -7 v m1 t1 0 3 10 5 -7 -12 i 0 1 2 3 4 34 Algoritmo inversione di matrice Codice /** * Inverte gli elementi di una matrice * @param m la matrice da invertire * @return la matrice invertita **/ int [] inverti(int m[]) ritorna una matrice { int i=0; while (i<m.length/2) { int t=m[i]; m[i]=m[m.length-1-i]; m[m.length-1-i]=t; i=i+1; } return m; } Tracing inverti A (q) q: 3 7 4 9 A q 5 m q 9 4 7 3 i 0 1 2 t 3 7 35 Algoritmo minimo in matrice Codice /** * Il numero più piccolo tra gli elementi di una matrice * @param m la matrice di cui cercare il minimo tra gli elementi * @return il più piccolo degli elementi della matrice m **/ int min(int m[]) { int p=0; int x=m[p]; while (p<m.length-1) { p=p+1; if (x>m[p]) x=m[p]; } return x; } Algoritmo per il massimo positivo in una matrice Codice /** * Il numero positivo più grande tra gli elementi di una matrice * @param m la matrice di cui cercare il massimo positivo tra gli elementi * @return il più grande degli elementi positivi della matrice m, 0 se sono tutti negativi **/ int maxPos(int m[]) { int ax=0; int p=0; while (p<m.length) { if (ax<m[p]) ax=m[p]; p=p+1; } return ax; } 36 Tracing maxPos O (v1) v1: 3 9 O 33 4 m v1 maxPos D (neg) neg: 33 ax 0 3 9 33 15 p 0 1 2 3 4 5 -2 D 0 m neg -5 -12 ax 0 -4 -1 p 0 1 2 3 4 5 Algoritmo di somma dei positivi in una matrice Codice /** * Somma degli elementi positivi di una matrice * @param v la matrice in cui cercare i numeri positivi da sommare * @return la somma degli elementi positivi della matrice v, -1 se sono tutti negativi **/ int sommaPositivi(int v[]) { int p=o; int s=o; while (p<v.length) { if (v[p]>0) s=s+v[p]; i=i+1; } if (!pos) s=-1; return s; } 37 Algoritmo Ordinamento decrescente di matrice Codice /** * Ordina una matrice in ordine decrescente * @param v la matrice da ordinare * @return la matrice in ordine decrescente **/ int[] ord(int v[]) { for (int i=0; i<v.length;i=i+1) for (int j=i+1;j<v.length;j=j+1) if (v[i]<v[j]) { int t=v[i]; v[i]=v[j]; v[j]=t; } return v; } Tracing ord A (mat) mat: 3 7 5 4 9 7 3 3 3 7 9 5 4 4 5 7 5 4 3 A mat v mat i 0 1 2 3 4 5 j 1 2 3 4 5 2 3 4 5 3 4 5 4 5 5 t 3 7 3 5 3 4 3 38 ord B (m) m: 8 3 6 6 B m 3 v m 2 2 i 0 1 2 3 4 5 j 1 2 3 4 5 2 3 4 5 3 4 5 4 5 t 3 Algoritmo ordinamento crescente valori assoluti di elementi di matrice Codice /** * Ordina una matrice in ordine crescente di valore assoluto * @param v la matrice da ordinare * @return la matrice in ordine decrescente per valore assoluto **/ public int[] ordina (int v[]) { for (int i=0; i<v.length; i++) for (int j=0; j<v.length; j++) if ((v[i]>0 ? v[i] : -v[i])<(v[j]>0 ? v[j] : -v[j]) { int t= v[1]; v[i]=v[j]; v[j]=t; } return v; } 39 Algoritmo conta occorrenze di un valore in matrice Codice /** * Conta quante volte un valore è presente in una matrice * @param mat la matrice in cui cercare il valore * @param val il valore da cercare nella matrice * @return il numero di volte che il valore è nella matrice **/ int conta(int mat[], int val) { int a=0; for (int i=0; i<mat.length; i=i+1) if (mat[i]==val) a=a+1; return a; } Algoritmo somma degli elementi entro estremi Codice /** * Conta quante volte un valore è presente in una matrice * @param b la matrice in cui cercare i valori da sommare * @param c il valore minimo da cercare nella matrice * @param d il valore massimo da cercare nella matrice * @return la somma dei valore di b compresi tra c e d, 0 se non ce ne sono **/ int sommaInclusi (int b[], int c, int d) { int s=0; for (int i=0; i<b.length; i=i+1) if (b[i]>=c && b[i]<=d) s=s+b[i]; return s; } Tracing sommaInclusi C (mt, 8, 6) mt: 3 5 C 0 4 9 11 b c >mt 8 33 d 6 s 0 i 0 1 2 3 4 5 40 sommaInclusi R (m,3,7) m: 8 3 6 2 2 R 9 b >m c 3 d 7 s 0 3 9 i 0 1 2 3 4 5 Algoritmo riconoscimento di matrice in ordine crescente Codice /** * Stabilisce se la matrice è in ordine crescente: se lo è torna vero altrimenti torna falso. * @param b la matrice in cui cercare i valori da sommare * @param c il valore minimo da cercare nella matrice * @param d il valore massimo da cercare nella matrice * @return se la matrice è in ordine crescente, true altrimenti false. **/ boolean crescente (int b[]) { int i=0; for (int i=0; i<b.length-1; i=i+1) if (b[i]>b[i+1]) return false; return true; } Tracing crescente A (matr) matr: 7 9 A false 12 15 14 b i >matr 0 1 2 3 4 41 Algoritmo Massimo Comune Divisore Codice /** * Calcola il massimo comune divisore tra due numeri * @param a il primo numero * @param b il secondo numero * @return il massimo comune divisore tra a e b **/ int mcd(int a, int b,) { int div=0,mcd=0; if (a<b) div=a; else div=b; for (; mcd==0; div = div-1) if (a%div==0 && b%div==0) mcd=div; return mcd; } Algoritmo di ricerca dei picchi in una matrice Codice /** * Calcola il numero di picchi (valori maggiori dei valori a loro adiacenti). * @param v la matrice in cui cercare i picchi * @return il numero di picchi nella matrice **/ public int picchi (int v[]) { int pic=0; for (int i=1; i<v.length-1; i++) if (v[i-1]<v[i] && v[i]> v[i++]) pic++; return pic; } Tracing con autoincremento e operatori assegnazione Codice int a=10, b=3, c=7, d=13; b + =a + + + - - c; c = b + = d + a + = 3; System.out.println (a,b,c,d); System.out.println (a++,a,a+=3, = - a) 42 Tracing a 10 11 14 b 3 19 46 c 7 6 46 d 13 output 14 32 46 13 14 15 18 17 Codice int x=12, y=3, <=9, w= -3; w - = -y++; x + = z + = - (w++); System.out.println (x+” “+y+” “+z+” “+w) Tracing x 12 21 y 3 4 3 z 9 9 w -3 0 1 output 21 3 9 1 Algoritmo di lettura e somma di valori con classe Scanner: Codice /** * Legge da tastiera una sequenza di valori e ne scrive la somma e la media a monitor **/ static public void main (String s[]) { Scanner input=new Scanner(System.in) double v=0; int i; for (i=0; input.hasNextDouble(); i++) { v+=input.nextDouble(); } System.out.println(“la somma è”+v); System.out.println(“la media è”+v/i); } 43 Algorimo che stampa matrice di interi Codice /** * Stampa il contenuto di una matrice fino a che non incontra un 1 saltando gli 0 * @param v la matrice da stampare */ public void elenco(int v[]) { for (int i=o; i<v.lenght; i++) { if (v[i]==0) continue; if(v[i]==1) break; System.out.println(i+” “+v[i]); } } Algoritmo Triangolo di Tartaglia: Codice /** * Calcola i valori del triangolo di tartaglia * @param n la linea dell’elemento da calcolare * @param p la colonna dell’elemento da calcolare * @return l’elemento del triangolo di tartaglia alla riga n e colonna p **/ public int t(int n, int p) { if (p==1 || p==n) return 1; else return tB(n-1,p-1)-tC(n-1,p); } 44 Tracing: A t(5,3) A n p 3+3 5 3 6 B n p 1+2 4 2 3 B n p 1 3 1 C n p 1+1 3 2 2 C n p 2+1 4 3 3 B n p 1+1 3 2 2 B n p 1 2 1 C n p 1 2 2 B n p 1 2 1 C 1 n p 2 2 C n p 1 3 3 Tracing ricorsivo: Codice int f(int a, int b) { int ris; System.out.println(a+”,”+b); if (a<b) ris = fB(a+1,b)+fC(a,b-1); else if (a>b) ris = fD(a-1,b)+fE(a,b+1); else ris=a+b; System.out.println(ris); return ris; } Tracing: fA (-2,-4) A a b ris -24 -2 -4 -14-10 B a b ris -14 -3 -4 -8+(-6) C a b ris -10 -2 -3 -6-4 B -8 C 6 B -6 C -4 a b -4 -4 a b -3 -3 a b -3 -3 a b -2 -2 ris -8 ris -6 ris -6 ris -4 45 output -2 , -4 -3 , -4 -4 , -4 -8 -3 , -3 -6 -14 -2 , -3 -3 , -3 -6 -2 , -2 -4 -10 -24 Tracing ricorsivo: Codice public int f(int a, int b) { int ris; switch (a-b) { default: case 0: ris = a+b; break; case 1: ris =fB(a+1,b)+fC(a-1,b); break; case -1: ris= fD(a,b+1)+fE(a,b-1); break; } return ris; } Tracing: fA(3,4) A a b ris 14 3 4 8+6 D 8 E 6 a 3 a 3 b 5 b 3 ris 8 ris 6 46 Classi Classe Minimo public class Minimo { public static int min(int m[]) { int p=0; int x=m[p]; while (p<m.length-1) { p=p+1; if (x>m[p]) x=m[p]; } return x; } public static void main(String a[]) { int m[]={7,4,10,5,-9,40}; System.out.println("Valore minimo: "+min(m)); } } Classe Punto public class Punto { double x,y,x1,y1; public Punto () { this(0.0,0.0); } public Punto (double x1, double y1) { x=x1; y=y1; } public double distaDa (Punto p) { return Math.sqrt((p.x-x)*(p.x-x)+(p.y-y)*(p.y-y)); } public void muoviDi(double dx,double dy) { x+=dx; y+=dy; } public double getX() { return x; } public double getY() { 47 return y; } public void setX(double x1) { x=x1; } public void setY(double y1) { y=y1; } public String toString() { return "("+x+","+y+")"; } public boolean equals(Object pp) { if (pp instanceof Punto) { Punto p=(Punto)pp; if (getX()==p.getX() && getY()==p.getY()) return true; else return false; } else return false; } } // Math.sqrt(x) radice quadrata di x Classe Segmento public class Segmento { Punto p1,p2; public Segmento(double x1, double y1, double x2, double y2) { this (new Punto(x1,y1), new Punto(x2,y2)); } public Segmento(Punto v1, Punto v2) { p1=v1; p2=v2; } } 48