Java: Compilatore e Interprete Il Linguaggio Java •È un linguaggio totalmente ad oggetti • Si basa strettamente sul concetto di classe e di oggetto • Un programma è un insieme di classi. Anche il main è in una classe! • Il linguaggio definisce alcuni tipi primitivi/di base Il Linguaggio Java • Una classe Java può: • contenere dati/operazioni proprie • definire un tipo di dato astratto • Una classe Java è un’entità sintatticamente in grado di contenere sia i dati che le funzioni che operano su quest’ultimi. Sia i dati che le operazioni hanno differenti livelli di visibilità/protezione: pubblico: visibile anche dall’esterno della classe (keyword public) privato: visibile solo dentro la classe (keyword private) • E’ essenziale rispettare maiuscole/minuscole (Java è case-sensitive) Classe Una classe public viene definita utilizzando la seguente notazione: public class NomeClasse {....} All’interno del costrutto class,è necessario dichiarare: Metodi e dati associati alla classe Metodi e dati associati agli oggetti Nel primo caso, i dati appartengono alla classe e sono unici all’interno della JVM. Nel secondo caso, invece, essi appartengono ad ogni singola istanza. public class Esempio1 { private int value; .... } public class Esempio1 { private static int value; .... } Classe In definitiva, la dichiarazione di una variabile segue la sintassi: [private|public] [static] Tipo Nome; mentre, per dichiarare un metodo, usiamo la sintassi: [private|public] [static] TipoDiRitorno Nome(TArg1 nome1,…){ Istruzioni da eseguire }; Esempio public class Esempio1 { public int getValue(){…} public void setValue(int newValue){…} } Classe public class Esempio1 { private int value; public int getValue() { return value; } public void setValue(int newValue){ value = newValue; } } • La classe Esempio1 dichiara un unico campo (value) privato e quindi non accessibile dall’esterno. • Ogni oggetto di tipo Esempio1 ha un proprio campo value •Gli oggetti di tipo Esempio1 espongono un metodo getValue() che ritorna il valore attuale di value •Gli oggetti di tipo Esempio1 espongono un metodo setValue(int newValue) che consente di impostare il valore di value Oggetto Una classe può fungere da “stampo” per creare oggetti. Per creare un oggetto, bisogna: Definire la classe che modella il nuovo tipo di dato Definire un riferimento, il cui tipo è il nome della classe modello Creare dinamicamente l'oggetto tramite l'operatore new Ipotizzando che sia stata già definita la classe Esempio1: Esempio1 esempio = new Esempio1(); Per invocare i metodi offerti da un oggetto, si usa la notazione puntata riferimento.nomeMetodo(…). Ad esempio, per invocare getValue() sull’oggetto esempio, scriveremo esempio.getValue(); Esecuzione di un programma Un programma Java è un insieme di classi e oggetti: Le classi sono componenti statici, che esistono già all'inizio del programma Gli oggetti sono invece componenti dinamici, creati su necessità e durante l'esecuzione Il più semplice programma Java è costituito da una singola classe che, come minimo, dovrà definire una singola funzione statica, il main(): public class Esempio0 { public static void main(String args[]) { System.out.println("Hello World!"); } } Per convenzione, in Java i nomi delle classi iniziano sempre con la lettera maiuscola e i nomi dei singoli campi (dati e funzioni) iniziano sempre con la lettera minuscola. Java main Il main() in Java è una funzione pubblica con la seguente struttura: public static void main(String args[]) {…} Deve essere obbligatoriamente dichiarato: public: Il main deve essere visibile all’esterno della classe per consentire l’invocazione da parte della JVM static: È statico dato che esiste ancora prima di qualunque oggetto void: Non deve avere valore di ritorno String args[]: Deve sempre prevedere gli argomenti dalla linea di comando, anche se non vengono usati, sotto forma di array di String Esempio public class Esempio { public static void main(String args[]) { System.out.println(“Ciao Mondo!"); } } Importante: • L’uso della notazione puntata System.out.println(“Hello World”) invoca il metodo println(String input) sull’oggetto out, che è un campo (statico) della classe System predefinita in Java • Sia il main che la classe devono essere public per consentire l’invocazione da parte della JVM Un altro esempio public class Esempio2 { public static void main(String args[]) { int x = 3, y = 4; int z = x + y; System.out.println("La somma vale: "+z); } } Importante: • L’operatore + è utilizzato per la concatenazione delle stringhe Esempio: creazione Oggetto contatore Vogliamo creare un oggetto contatore. Ogni contatore deve avere un proprio valore, e deve offrire tre metodi: inc(): consente di incrementare il valore attuale del contatore reset(): consente di portare a zero il valore del contatore getValue(): consente di reperire il valore attuale del contatore SimpleCounter.java Il campo val è privato (keyword private): può essere acceduto solo dalle operazioni definite nella medesima classe (reset, inc, getValue). Usiamo SimpleCounter Inseriamo un main nella classe SimpleCounter. All’interno, creiamo un oggetto ed invochiamo i suoi metodi. Infine, recuperiamo il valore attuale e lo stampiamo public static void main(String args[]){ SimpleCounter counter = new SimpleCounter(); counter.reset(); counter.inc(); counter.inc(); int x = counter.getValue(); System.out.println("Il contatore vale "+x); } Cosa viene stampato? Usiamo SimpleCounter E se invece … public static void main(String args[]){ SimpleCounter counter1 = new SimpleCounter(); SimpleCounter counter2 = new SimpleCounter(); counter1.inc(); counter1.inc(); counter2.reset(); int x1 = counter1.getValue(); int x2 = counter2.getValue(); System.out.println("Il contatore1 vale "+x1); System.out.println("Il contatore2 vale "+x2); } Cosa viene stampato? Tipi primitivi Il linguaggio Java offre alcuni tipi di dato primitivi Una variabile di tipo primitivo può essere utilizzata direttamente.. Tipi primitivi Ad esempio, il codice seguente dichiara una variabile di tipo intero, le assegna il valore 5 e stampa a schermo il suo contenuto: public static void main(String args[]){ int x; x = 5; System.out.println("X = "+x); } Riferimenti Le classi sono utilizzate per modellare nuovi tipi di dato astratto: il nome della classe rappresenta un nuovo tipo di dato Una variabile che referenzia un oggetto è un riferimento. Non contiene il valore dell’oggetto ma solo l’indirizzo di memoria a cui è allocato quest’ultimo Un riferimento appena creato è automaticamente inizializzato con il valore null; ogni oggetto è creato mediante l’operatore new Se provate ad utilizzare un riferimento con valore null, otterrete un errore durante l’esecuzione del programma Esempio: public static void main(String args[]){ SimpleCounter x; x = new SimpleCounter(); x.reset(); x.inc(); System.out.println("X = "+x.getValue()); } Riferimenti Dichiaro un riferimento (x vale null) Counter x; Creo un nuovo oggetto con new e inizializzo xx = new Counter(); Invoco reset() e inc() sull’oggetto attualmente puntato da x Operatore di uguaglianza Operatore di uguaglianza Nel caso di oggetti, l’operatore di uguaglianza verifica l’uguaglianza dei riferimenti. Quindi due riferimenti sono uguali solo se essi puntano allo stesso oggetto (stesso indirizzo di memoria). Nel primo caso, i riferimenti (indirizzi) sono uguali per via dell’assegnamento Nel secondo caso, i riferimenti sono diversi: il new alloca due istanze diverse di contatore! Attenzione ai riferimenti Riprendiamo il primo esempio ed estendiamolo in: SimpleCounter c1 = new SimpleCounter(); SimpleCounter c2 = c1; c2.inc(); System.out.println("c1 vale: " + c1.getValue()); L’oggetto é condiviso: entrambi i riferimenti puntano allo stesso oggetto Questo significa che viene stampato --> c1 vale: 1 I riferimenti c1 e c2 permettono di accedere/modificare la stessa istanza della classe SimpleCounter Uguaglianza tra dati primitivi Attenzione: per i tipi primitivi, le cose sono diverse. La variabile contiene il valore e non l’indirizzo di memoria a cui è allocato … Cosa restituisce quindi questo listato? int c1 = 5; int c2 = 5; if(c1==c2) System.out.println("Si"); else System.out.println("No"); In questo caso viene ovviamente stampato Si. Questo perché si tratta di un confronto fra variabili intere (quindi di tipo primitivo) Questi non sono oggetti! L’operatore d’uguaglianza confronta il valore. I costruttori Molti errori di programmazione sono causati dalla mancata inizializzazione delle variabili Nella programmazione ad oggetti, il costruttore é il metodo che automatizza l’inizializzazione dell’oggetto • Non viene mai chiamato esplicitamente dall’utente •Viene invocato implicitamente dal sistema ogni volta che si crea un nuovo oggetto mediante l’operatore new Un costruttore • deve avere lo stesso nome della classe • non ha tipo di ritorno (nemmeno void). D’altronde, il suo compito é solo quello di inizializzare l’oggetto Ogni classe può avere da zero ad infiniti costruttori (purché essi siano differenziati per lista dei parametri) I costruttori public class SimpleCounter { private int val; public SimpleCounter(){ val = 0; } public SimpleCounter(int value) { val = value; } } Potete ora creare un oggetto scrivendo “new SimpleCounter()”. In questo caso, il contatore ha valore iniziale 0 (viene invocate il primo costruttore) Altrimenti, se scrivete “new SimpleCounter(5)”, create un contatore con valore iniziale 5 (viene invocate il secondo costruttore) I costruttori Il costruttore senza parametri é detto di default Anche se non dichiarato, la JVM lo fornisce automaticamente. E’ il costruttore che viene usato quando non si passano i parametri Il costruttore di default fornito dalla JVM fa pochissimo: in pratica, inizializza tutti i singoli campi dell’oggetto secondo particolari convenzioni (ad esempio 0 per i numeri, false per i boolean e null per i campi riferimento) Controllo di flusso L’esecuzione delle istruzioni avviene in maniera sequenziale, per modificare il flusso di esecuzione bisogna utilizzare apposite istruzioni Il costrutto if consente di eseguire del codice a seconda che la condizione di test fornita è vero o falsa //codice A if(condizione){ //codice B } else{ //codice C } //codice D Controllo di flusso Le istruzioni while e do...while consentono di eseguire ripetutamente un blocco di codice fino a che una condizione è vera La formulazione con while esegue il blocco da 0 a più volte, mentre il do…while da 1 a più volte //codice A while(condizione){ //codice B } //codice C //codice A do{ //codice B }while(condizione); //codice C Controllo di flusso Java offre l’istruzione for … del tutto equivalente ad un’istruzione while: consente di specificare contemporaneamente inizializzazione della variabile condizione, test di terminazione e istruzione di aggiornamento della variabile condizione for(inizializzazione; condizione d’uscita; aggiornamento){ //codice } Ad esempio, i seguenti blocchi di codice sono del tutto equivalenti for(int i=0; i<10; i++){ //codice } int i=0; while(i<10){ //codice i++; } Esercizio 1 Create un tipo di dato Counter che abbia: un valore attuale un valore massimo di conteggio uno stato interno che indica se si è verificato un errore. Il valore massimo è selezionabile dall’utente alla costruzione. Se si tenta di superarlo, viene modificato lo stato del contatore per memorizzare l’avvenuta condizione d’errore e le successive operazioni di modifica non devono avere effetto Il contatore deve offrire i seguenti metodi: void inc(),void reset(),int getValue(),boolean isError() Infine, scrivete un’applicazione Java che: Crea e inizializza un nuovo Counter con valore massimo n Incrementa il contatore per n+1 volte e visualizza, ogni volta, il valore attuale e lo stato interno (errato/corretto) Soluzione Esercizio 1 public class ContatoreEsteso { private int valore; private int valore_massimo; private boolean errore; //Costruttore public ContatoreEsteso(int vm){ //Limite massimo del contatore valore_massimo=vm; //Valore iniziale valore=0; //E' possibile incrementare il contatore errore=false; } //Metodo per incrementare il valore void inc(){ //Se il contatore è in stato di errore, esco senza cambiare il valore if (errore) return; // Se tento di incrementare oltre il limite, setto errore true if (valore==valore_massimo) {errore=true;} //Incremento il valore del contatore di 1 else valore=valore+1; } //Metodo per resettare il valore void reset(){ //Porto a 0 il valore del contatore valore=0; //Porto a 0 il valore del contatore errore=false; } //Metodo per ottenere il valore del contatore int getValue(){ return(valore); } //Metodo per ottenere informazioni sullo stato interno boolean isError(){ return errore; } //Metodo main public static void main(String[] args) { ContatoreEsteso c= new ContatoreEsteso(5); for(int i=0; i<6; i++){ c.inc(); System.out.println("Valore del contatore: " + c.getValue()); System.out.println("Stato di errore: " + c.isError()); } } } Esercizio 2: classe Rettangolo Creare un tipo di dato Rettangolo tale che un oggetto sia definito da: •Un intero per la base •Un intero per l’altezza •Un intero per la coordinata di ascissa x •Un intero per la coordinata di ordinata y • Due costruttori: uno che crea rettangoli con dimensioni fissate, il secondo che permette all’utente di inizializzare i valori. • Metodi: li dividiamo in più categorie • Metodi contenenti la dicitura get che restituiscono il valore della dimensione richiesta (es. getAltezza…) oppure effettuano un’operazione specifica (ad es. per il calcolo dell’area o del perimetro) • Metodi contenenti la dicitura set permettono di assegnare un nuovo valore alla variabile d’istanza (ad es. setAltezza) Creare poi un main che crei un oggetto rettangolo e ne visualizzi perimetro e area. Libreria standard Java possiede un’enorme libreria di classi standard organizzata in vari package che raccolgono le classi secondo un’organizzazione basata sul campo d’utilizzo. I principali package sono: java.io contiene classi per realizzare l’input – output in Java java.awt contiene classi per realizzare interfacce grafiche java.net contiene classi per realizzare connessioni, come Socket java.applet contiene un’unica classe Applet che permette di realizzare applet java.util raccoglie classi d’utilità, come Date java.lang è il package che contiene le classi nucleo del linguaggio, come System e String. Programmazione JAVA libreria standard Per utilizzare una classe della libreria, bisogna prima importarla. Supponiamo di voler utilizzare la classe Date del package java.util. Prima di dichiarare la classe in cui abbiamo intenzione di utilizzare Date dobbiamo scrivere: import java.util.Date; oppure, per importare tutte le classi del package java.util: import java.util.*; Di default in ogni file Java è importato automaticamente tutto il package java.lang, senza il quale non potremmo utilizzare classi fondamentali quali System e String. Classe String In Java le stringhe, a differenza della maggior parte dei linguaggi di programmazione, non sono array di caratteri (char), bensì oggetti, e in quanto oggetti, dovrebbero essere istanziate con la solita sintassi tramite la parola chiave new. Per esempio: String nome = new String("Mario Rossi"); Java però semplifica la vita del programmatore permettendogli di utilizzare le stringhe, come se si trattasse di un tipo di dato primitivo. Per esempio, String nome = "Mario Rossi"; Programmazione JAVA Classe String Per assegnare un valore ad una stringa bisogna che esso sia compreso tra virgolette, a differenza dei caratteri per cui vengono utilizzati gli apici singoli. Il fatto che String sia una classe ci garantisce una serie di metodi di utilità, semplici da utilizzare e sempre disponibili, per compiere operazioni con le stringhe. Ad esempio toUpperCase(), toLowerCase(), trim() (restituisce la stringa senza gli spazi), equals(String). La classe String è una classe particolare: un oggetto String è immutabile, ossia i metodi di cui sopra, infatti, non vanno a modificare l'oggetto su cui sono chiamati ma, semmai, ne restituiscono un altro. Programmazione JAVA Classe String String a = "claudio"; String b = a.toUpperCase(); System.out.println(a); // a rimane immutato System.out.println(b); // b è la stringa maiuscola produrrebbero il seguente output: claudio CLAUDIO Per conoscere la classe String e tutte le altre classi, basta andare sul sito http://java.sun.com. Programmazione JAVA Array In Java gli array, in quanto collezioni costituite da vari elementi accessibili tramite indici interi, sono oggetti, e per utilizzarli bisogna dichiararli, crearli ed infine come per tutti gli oggetti inizializzarli. char alfabeto []; //dichiarazione di un array di char (tipo primitivo) char [] alfabeto1; //ulteriore modo di dichiarare un array di char Button bottoni [];//array di istanze di Button (classe del package java.awt) Button [] bottoni; //ulteriore modo di dichiarare un array di Button In pratica, per dichiarare un array, basta posporre o anteporre una coppia di parentesi quadre all’identificatore. Un array è un oggetto speciale in Java e la sintassi per l’istanziazione è la seguente: alfabeto = new char[21]; bottoni = new Button[3]; Programmazione JAVA Array Al momento dell’istanza dell’array si deve dichiarare la dimensione, e tutti gli elementi dell’array vengono inizializzati automaticamente ai relativi valori nulli, e per inizializzare un array, bisogna inizializzarne ogni elemento singolarmente: alfabeto [0] = 'a'; alfabeto [1] = 'b';. . . . . . . . . .alfabeto [20] = 'z'; bottoni [0] = new Button();bottoni [1] = new Button();bottoni [2] = new Button(); Comunque è possibile eseguire i tre passi con un’unica istruzione. char alfabeto [] = {'a', 'b', 'c', 'd', 'e',…, 'z’}; Button bottoni [] = { new Button(), new Button(), new Button()} ; La variabile length di un array, restituisce la sua dimensione. X=alfabeto.length; // X varrà 21. Programmazione JAVA Array bidimensionale Struttura di un programma in JAVA Operatori e Gestione del flusso di esecuzione Gli operatori che andremo ad analizzare si suddividono in: Operatori aritmetici. Comprendono somma, sottrazione, moltiplicazione, divisione intera, divisione con modulo ecc. Operatori di confronto. Operatori che permettono di verificare determinate condizioni, come ad esempio l'uguaglianza o la disuguaglianza. Operatori logici. Da utilizzare con le istruzioni condizionali ed iterative. Programmazione JAVA Operatori aritmetici Oltre l'assegnamento = esistono i seguenti operatori aritmetici: Operatore + * / % += -= *= /= %= ++ -- Descrizione Somma o concatenazione di stringhe Sottrazione Moltiplicazione Divisione Modulo Somma ed assegnazione Sottrazione ed assegnazione Moltiplicazione ed assegnazione Divisione ed assegnazione Modulo ed assegnazione Pre-Post incremento o di un’unità Pre-Post decremento o di un’unità Esempio a=a+1; a=b+”Ciao”; a=a-1; a=a*2; a=a/2; a=a%2; a+=1; a-=1; a*=2; a/=2; a%=2; ++a; a++ --a; a-- Programmazione JAVA Operatori di confronto Gli operatori di confronto restituiscono un valore true o false Operatore == != < > <= >= Descrizione Uguale ad Diverso da Minore Maggiore Minore uguale Maggiore uguale Applicabile Tutti i tipi Tutti i tipi Tipi Numerici Tipi Numerici Tipi Numerici Tipi Numerici La classe String gode di una singolare particolarità nell’utilizzo dell’operatore == Programmazione JAVA Operatori di confronto String a = "Java"; String b = a; String c = new String("Java"); System.out.println(a==b); System.out.println(b==c); /* produrrà il seguente output: true false a e b puntano allo stesso oggetto, mentre per c, utilizzando new, verrà creato un oggetto ex novo*/ System.out.println(a.equals(b)); System.out.println(b.equals(c)); /*produrrà il seguente output: true true*/ Programmazione JAVA Operatori logico–booleani Gli operatori logico–booleani utilizzano solo operandi di tipo booleano ed il risultato è di tipo boolean: Operatore & ! | ^ && || &= |= ^= Descrizione AND logico NOT logico OR logico XOR logico Short circuit AND Short circuit OR AND e assegnazione OR e assegnazione XOR e assegnazione Restituisce Vero se uno solo degli operandi è Vero Le versioni short circuit (“corto circuito”) di AND ed OR fanno evitare il secondo controllo in caso di fallimento del primo. Programmazione JAVA Operatori logico–booleani Essi sono stati pensati basandosi sull’osservazione che mettendo in AND o in OR due valori booleani, spesso è possibile conoscere il risultato dell’espressione solo in base al primo valore. Se, infatti, due valori booleani sono in AND, quando il primo ha valore false, il risultato sarà comunque un valore false indipendentemente dal valore del secondo. Analogamente se il primo operando in un OR ha valore true, il risultato sarà comunque true. Gli operatori short circuit && e || si comportano quindi rispettivamente come & e | ma evitano di valutare il secondo valore booleano nei casi in cui non è necessario. Questo comportamento è utile nei casi in cui il secondo operando dipende dal primo per un corretto funzionamento. Nell’esempio seguente a != 0 && b / a > 100 Programmazione JAVA Operatori logico–booleani l’utilizzo di un operatore short circuit evita che venga effettuata una divisione per 0 che genererebbe un’eccezione in esecuzione. Nei programmi si utilizzano di solito questi operatori short circuit in quanto tipicamente si risparmiano operazioni e perché i programmatori C sono abituati a usarli, mancando quel linguaggio di operatori AND e OR effettivi. Questo di solito non ha controindicazioni, tranne in alcuni casi in cui la valutazione di entrambi gli operandi è richiesta. Nell’esempio seguente a != 0 & (b = c) > 0 il valore della variabile c viene assegnato alla variabile b in ogni caso; se avessimo utilizzato un operatore short circuit, l’assegnamento sarebbe dipeso dal valore della variabile a. Programmazione JAVA Gestione del flusso In Java le istruzioni di controllo del flusso sono: if else L’operatore ternario while if (espressione-booleana) { istruzione_1; ...........; istruzione_k; } else { istruzione_k+1; ...........; istruzione_k+n; } variabile = (espr-booleana) ? espr1 : espr2; [inizializzazione;] while (espr. booleana) { corpo; [aggiornamento iterazione;] } Programmazione JAVA Gestione del flusso For do while for (inizializzazione; espr. booleana;aggiornamento) {istruzione_1; … istruzione_n;} for (variabile_temporanea : oggetto_iterabile) { corpo; } Es. int [] arr = {1,2,3,4,5,6,7,8,9}; for (int tmp : arr) { System.out.println(tmp);} [inizializzazione;] do { corpo; [aggiornamento iterazione;] } while (espr. booleana); Programmazione JAVA Gestione del flusso Switch switch (variabile di test) { case valore_1: istruzione_1;break; case valore_2: { istruzione_2;.......; istruzione_k; }break; case valore_3: case valore_4: { //blocchi di codice opzionale istruzione_k+1; ..........; istruzione_j;} break; default: { //clausola default opzionale istruzione_j+1; ...........; istruzione_n; } } Programmazione JAVA Break e Continue In Java come in C la parola chiave break è un comando capace di far terminare un qualsiasi ciclo, mentre la parola chiave continue, fa terminare non l’intero ciclo,ma solo l’iterazione corrente //Il seguente di codice stampa i primi dieci numeri interi: int i = 0; while (true) //ciclo infinito{ if (i > 10) break; System.out.println(i); i++;} i = 0; Il seguente codice stampai primi dieci numeri, escluso il cinque: do{ i++; if (i == 5) continue; System.out.println(i);} while(i <= 10); Programmazione JAVA Break e Continue In Java sia break sia continue possono utilizzare etichette (label) per specificare, solo nel caso di cicli annidati, su quale ciclo devono essere applicati. //Il seguente di codice stampa i primi dieci numeri interi: int j = 1; etichetta1: //possiamo dare un qualsiasi nome ad una label while (true){ while (true){ if (j > 10) break etichetta1; System.out.println(j); j++; } } Una label può essere posizionata solo prima di un ciclo, non dove si vuole. In Java non esiste il comando goto. Esercizio 3 Scrivere un programma con i seguenti requisiti. Utilizzare una classe Persona che dichiara le variabili nome, cognome, età. Si dichiari inoltre un metodo dettagli() che restituisce in una stringa le informazioni sulla persona in questione. Utilizzare una classe Principale che, nel metodo main(), istanzia due oggetti chiamati persona1 e persona2 della classe Persona, inizializzando per ognuno di essi i relativi campi. Dichiarare un terzo riferimento (persona3) che punti ad uno degli oggetti già istanziati. Controllare che effettivamente persona3 punti allo oggetto voluto, stampando i campi di persona3. Oppure fare queste operazioni nel metodo main all’interno della classe Persona. Esercizio 4 Scrivere un programma con i seguenti requisiti. Utilizzare una classe Impiegato che dichiara le variabili nome, cognome, salario. Si dichiari un metodo dettagli() che restituisce in una stringa le informazioni sulla persona in questione. Si dichiari un metodo aumentasalario() che aumenti lo stipendio secondo una certa percentuale. Utilizzare un metodo main nella classe Impiegato oppure una classe Principale oppure che, nel metodo main(), istanzia due oggetti chiamati impiegato1 e impiegato2 della classe Impiegato,inizializzando per ognuno di essi i relativi campi. Si aumenti il salario di impiegato1 del 10% e poi si verifichi se il salario di impiegato 1 è maggiore di quello di impegato2.