Java  »  Guide  »  Guida Java 

Istruzioni e costrutti fondamentali



In questa lezione esaminiamo i costrutti principali del linguaggio Java. Ci occuperemo rapidamente dei commenti, per dedicarci poi alle istruzioni condizionali, alle dichiarazioni di variabili e oggetti e ai costrutti per i cicli:

I commenti al codice

Abbiamo già incontrato i commenti nelle scorse lezioni, possiamo aggiungere però che essi non possono essere annidati. Ad esempio non è lecito inserire un commento di questo tipo:

/* Questo è sicuramente un commento	

  /* Anche questo lo è */ 
  
*/

Possiamo però inserire commenti "inline", quelli con il doppio slash ('//') per intederci, all'interno di blocchi di commento (delimitati da /* e */). Ad esempio è lecito scrivere:

/* Questo è sicuramente un commento	

  // Anche questo lo è 

*/

A volte risulta utile, specie quando vogliamo isolare parti intere di codice senza perdere informazioni su ciò che fa ogni singola riga.

La dichiarazione delle variabili

Osserviamo le istruzioni di dichiarazione che in Java servono per definire variabili locali. Esse ci permetto di assegnare alle variabili un valore iniziale, all'interno della stessa dichiarazione. Abbiamo già incotrato queste istruzioni e sono simili alla dichiarazione di attributi, tranne che per la mancanza di modificatori. È importante ricordare che le variabili locali prima di essere usate devono essere inizializzate.

Le variabili locali possono essere dichiarate in un punto qualsiasi di un blocco, e non per forza all'inizio, ed esse esistono solo all'interno del blocco in cui sono dichiarate. Possiamo considerare un blocco di istruzioni come un'istruzione composta da altre istruzioni racchiuse tra parentesi graffe (i simboli { e }). Al suo interno un blocco può contenere anche altri blocchi.

{
  istruzione 1;
  istruzione 2;
  // ...
  istruzione j-1;
  
  {
    sottoistruzione 1;
    sottoistruzione 2;
    //...
    sottoistruzione n;
  }; // è l'istruzione j
  
  istruzione j+1;
  //...
  istruzione m;
} // Questo blocco può essere il corpo di un metodo oppure un blocco

Se pensiamo ad un metodo così definito:

void pippo() 
{
  int j=0;
  {
    int k=0;
    k++; // istruzione A
  };
  
  j++; // istruzione B
  k++; // istruzione C
}

L'istruzione A non dà problemi, in quanto usa una variabile locale inizializzata, dichiarata all'interno del suo stesso blocco. L'istruzione B lo stesso, mentre l'istruzione C è errata, in quanto la variabile che usa è dichiarata in un blocco interno e non è visibile all'esterno. Se nel blocco interno scrivessimo j++; non avremmo problemi perché la variabile j è dichiarata in un blocco esterno (Dentro si vede quello che c'è fuori ma fuori non si vede quello che c'è dentro, come accade in tutti i linguaggi di programmazione a blocchi).

Abbiamo visto nell'esempio che anche j++ è una istruzione, essa è sia una espressione che una istruzione, come la sua altra forma ++j e la speculare di decremento. Altre sono le espressioni che si possono considerare delle istruzioni, esse sono le chiamate di metodi che restituiscono o meno un valore, e le istruzioni di creazione di oggetti, quelle con new, ad esempio new Object(); è una istruzione valida.

Un'altra istruzione molto simile ad una espressione è l'istruzione di assegnamento, quella del tipo:

NomeVariabile = espressione;

Nota: è importante ricordare che tutte le istruzioni terminano con un punto e virgola (;)

if else

if è un'istruzione condizionale, permette cioè di eseguire un'altra istruzione o un blocco a seconda del verificarsi di una certa condizione, Ecco un semplice esempio:

if (condizione) istruzione();

Questa riga di codice esegue istruzione(), che può essere una qualsiasi istruzione del linguaggio, solo se l'espressione booleana condizione è vera, altrimenti viene saltata.

Se vogliamo controllare cosa succede anche quando la nostra condizione è falsa possiamo indicare anche il caso alternativo con la parola chiave else:

if (condizione) istruzione1();
else istruzione2();

Da notare che istruzione1(); e istruzione2(); sono istruzioni generiche, quindi possono essere anche blocchi o altre istruzioni condizionali, in questo secondo caso si parla di if annidati.

switch case

Il costrutto switch serve a scegliere l'istruzione successiva a seconda del valore di una certa espressione:

switch (exp)
{
  case cost11: cost12: ... : case cost1N: istruzione1();
  case cost21: cost22: ... : case cost2N: istruzione2();
  ...
  case costm1: costM2: ... : case costMN: istruzioneM();

  default istruzioneK();
};

Dove exp è una espressione e costIJ sono delle costanti dello stesso tipo dell'espressione. Il programma confronta il risultato dell'espressione exp con le costanti dei case, se ne trova una uguale esegue l'istruzione corrispondente.Ecco un esempio pratico:

switch (5+1)
{
  case 6  : System.out.println ("Bravo");
  default : System.out.println ("Asino, è sei!");
};

Se nessuna costante è uguale al risultato di exp viene eseguida l'istruzione che abbiamo impostato con default. Possiamo anche omettere l'istruzione di default, in questo caso, se il valore di exp non è contemplato dai case tutto il costrutto switch viene saltato.

for

Il ciclo for esegue un'istruzione o un blocco per un certo numero di volte:

for (inizializzazione; condizione; incremento) istruzione();

Il programma quindi esegue istruzione() un numero di volte pari ai valori contenuti in un intervallo:

  • l'istruzione di inizializzazione tipicamente stabilisce il valore iniziale dell'intervallo assegnano ad una variabile ad un valore
  • questa variabile viene incrementata (o decrementata) dalla istruzione di incremento
  • la condizione che abbiamo fissato serve a controllare che la variabile assuma i valori voluti, quando essa risulta falsa si esce dal ciclo for

Facciamo un esempio, diciamo di voler inizializzare i valori di un array di 100 interi tutti a zero. Invece di scrivere 100 assegnamenti usiamo il for:

int v = new int[100];
for (int i=0; i<100; i++) v[i] = 0;

Come si vede la variabile si può anche dichiarare nell'istruzione di inizializzazione, così si vedrà solo all'interno del for.

while

While è piu semplice di for: esegue un'istruzione o un blocco finché risulta vera una certa condizione:

while(condizione) istruzione();

Possiamo ad esempio realizzare l'inizializzazione di prima in questo modo:

int v = new int[100];

int i=0;
while(i<100) {
  
  v[i] = 0;
  i++;
}

Possiamo utilizzare anche una forma più compatta, sfruttando l'incremento:

int v = new int[100];

int i=0;
while(i<100) v[i++] = 0;

do while

È come il while, ma in questo caso si esegue l'istruzione almeno una volta e solo dopo si controlla la condizione, se essa risulta vera si continua a ciclare, si esce altrimenti.

do { istruzione(); } while(condizione);

L'inizializzazione precedente diviene:

int i=0;
do { v[i++] = 0; } while(i<100);

Labels, break e continue

labels

È possibile etichettare delle istruzioni, come in assembly o in alcuni dialetti Basic, questo consente di compiere salti incondizionati all'interno del codice in combinazione con le istruzioni break e continue.

Ecco come si dichiara un'etichetta:

etichetta: istruzione;

break

L'istruzione break viene utilizzata per uscire da un blocco o da uno switch, quando si incontra un break si esce dal blocco più interno, mentre se si mette una etichetta, si salta fino al punto indicato dall'etichetta. Ecco un esempio:

{
  while (condizione1)
  {
    while (condizione2)
	{
	  if (condizione_di uscita) break;
	}
  }
}

Si esce in questo caso dal while interno, mentre:

{
  pippo: while (condizione1)
  {
    while (condizione2)
	{
	  if (condizione_di_salto) break pippo;
	}
  }
}

Si esce fuori da entrambi i while.

continue

Continue ci permette, in un ciclo, di saltare tutte le istruzioni che lo seguono e andare direttamente a valutare l'espressione booleana, ad esempio:

while(condizione)
{
  istruzioni;
  if (ColpoDiScena) continue;
  altre istruzioni;
};

Si entra nel ciclo, si eseguono istruzioni, se ColpoDiScena è true salta altre istruzioni e torna a valutare condizione, se essa ancora vera continua il ciclo.

return

Provoca la conclusione dell'esecuzione del metodo in cui si trova e il ritorno al chiamante. Se il metodo è void basta scrivere return, senza parametri, altrimenti dobbiamo passargli una espressione dello stesso tipo del metodo, ad esempio:

int pippo()
{
  return 10;
}

con l'istruzione return è possibile anche bloccare l'esecuzione di un costruttore o di un metodo static.


Esempi

Fatta una panoramica sulle istruzioni, possiamo costruire un paio di esempi, iniziamo a scrivere un programmino che stampi i primi numeri, quelli minori di 500 della famosa serie di Fibonacci. Per chi non la conoscesse la serie di Fibonacci è una sequenza infinita di numeri, i cui primi due elementi sono: 1, 1, e gli altri elementi vengono calcolati come somma dei precedenti due, ad esempi, l'i-esimo numero di Fibonacci è dato dalla somma dell' i-1 esimo numero e dell' i-2 esimo, formalmente, vedendo Fibo come una funzione:

Fibo ( i ) = Fibo ( i - 1 ) + Fibo ( i - 2 );

Il programma da scrivere in Fibo.java è il seguente:

class Fibo
{
  public static void main (String[] args)
  {
    int basso=1;
	int alto=1;
	
	System.out.println (basso);
	
	while (alto<500)
	{
	  System.out.println(alto);
	  
	  alto += basso;
	  basso = alto - basso;
	}
  }
}

Per esercizio si potrebbe provare a fare un programma che calcola 10! (fattoriale) , sapendo che 1! = 1 e che dato n intero, n! = n * ((n-1)!).

Proviamo invece a scrivere un nostro crivello di Eratostene fatto in casa, ovvero un modo per calcolare tutti i numeri primi fino ad un dato numero, sia questo ad esempio 100;
L'algoritmo procede così:

1 è primo.
2 è primo, tolgo i suoi multipli
3 è primo, tolgo i suoi multipli

e così via fino a trovare il massimo.

class Eratostene {
  
  static int MAX=100;
  int []     numeri    = new int[MAX]; 
  boolean [] primi = new boolean[MAX];
  
  public Eratostene() { 

	for (int i=0; i<MAX; i++) {
	  
	  numeri[i] = i+1;
	  primi[i] = true;
	}
  } 
  
  void elMul(int a) {
  
    for (int j=2; j*a<=MAX; j++)ù
	  primi[(j*a)-1] = false;
	
  }
  
  int prossimo(int n) {

    int tmp = n; 
	while (!primi[tmp]) {
	  tmp++;
	  if (tmp>=MAX) break;
	} 
	return tmp+1;
  }
  
  void calcolaPrimi() {
    
	int num=2;
	while (num <= MAX) {
	
	  elMul(num);
	  num = prossimo(num);
	}
  }
  
  void scriviPrimi() { 
    
	System.out.println("I numeri primi fino a "+MAX+" sono:"); 
	
	for (int i=0; i<MAX ; i++)
	  if (primi[i]) System.out.print(numeri[i]+" "); 
  }
  
  public static void main(String[] args) {
  
    Eratostene e = new Eratostene(); 
	e.calcolaPrimi(); 
	e.scriviPrimi(); 
  }
}

Ultimi articoli Java

Utilizzare OSGi in Eclipse

Articolo di introduzione all'utilizzo di OSGI in ambiente Eclipse

Jsoup: parsing semplice di HTML5 in java

Presentazione della libreria JSOUP: un parser molto semplice per...

The Cube: una demo 3D per Android con JMonkey

Un progetto di demo passo-passo per gestire gli eventi 3d di base in...

Parsing JSON semplice con google GSON

Breve ed essenziale introduzione alla libreria di google per la...

AppFuse: realizzare un'applicazione completa (implementare i servizi)

Prosegue la serie per realizzare una app completa con AppFuse....

Altri articoli

Guide Java

Guida Apache Struts

Il primo e più utilizzato tra i framework MVC del mondo Java,...

Guida Java Spring

Scoprire il lightweight container più famoso del mondo Java....

Guida Java 6

Prendendo le mosse dalla guida Java, già presente su HTML.it,...

Altre guide

Newsletter @Programmazione

Ogni mese, direttamente nella tua e-mail: articoli, script e guide su Java, Visual Basic, VB.Net ed i più diffusi linguaggi di programmazione.

Iscriviti alla newsletter

Altre newsletter

Corsi in aula

Corso Google AdWords Base

25 Giugno 2012 a Milano
Disponibilità: 7 Posti

Corso Google AdWords Base

05 Giugno 2012 a Roma
Disponibilità: 7 Posti