Imparare
a programmare è un'impresa tutt'altro che facile.
Chi non ha mai lavorato su un computer potrebbe restare
disorientato dalla terminologia specialistica, o faticare
ad apprendere l'uso corretto dei vari strumenti: compilatori,
debugger, editor....
La
difficoltà maggiore, per chi trova alla prima
esperienza, è senza dubbio quella di riuscire
a capire come ragiona una macchina. Il programmatore
deve imparare a trattare con un'entità assolutamente
priva di senso dell'umorismo, completamente dedita al
lavoro e che ha la sconcertante abitudine di prendere
alla lettera qualunque richiesta. Con il tono autoritario
di una maestrina, bacchetta ogni errore con argomentazioni
che non ammettono repliche.
Ma
una volta superati i primi ostacoli, cresce l'entusiasmo
per un'attività che si presenta stimolante e
ricca di sfide, una professione in cui la creatività
è l'unico strumento che pemette di sopperire
alla totale assenza di creatività della macchina.
Lo
studio di Java: un percorso a tappe
Lo
studio di Java può essere suddiviso in tre tappe:
- Studio
dei costrutti del linguaggio
-
Sudio della filosofia della programmazione ad oggetti
- Introduzione
all'uso dei principali strumenti di libreria
Chi
si avvicina a Java dopo anni di esperienza su linguaggi
procedurali (tipo C o Pascal), di programmazione batch
in Cobol o di programmazione host su mainframe IBM,
può incontrare altrettante difficoltà
di chi si trova alla prima esperienza. Il modo migliore
per iniziare un percorso di studio consiste nel ripasso
di quell'insieme di concetti che stanno alla base di
qualunque linguaggio di programmazione.
Codice
sorgente, Virtual Machine e compilatore
Un
computer è una macchina capace di eseguire rapidamente
ed in modo automatico una sequenza di operazioni, seguendo
le istruzioni contenute in un programma.
Formalmente
un programma Java è un semplice file di testo,
detto "file sorgente", scritto dal programmatore
in un linguaggio simile, per certi versi, al linguaggio
naturale: il linguaggio Java.
Un
programma scritto in questa forma non può essere
eseguito direttamente da un calcolatore: prima deve
essere processato da uno strumento detto compilatore,
che traduce il file sorgente in un linguaggio diverso:
il Bytecode. Tale linguaggio, sebbene sia incomprensibile
per un essere umano, è ideale per un calcolatore,
che lo esegue grazie ad un programma speciale detto
Interprete o Virtual Machine. La traduzione dei programmi
Java in Bytecode garantisce la piena portabilità
del codice eseguibile, che, al contrario di quanto avviene
con altri linguaggi, può essere eseguito su qualunque
computer che disponga di una Virtual Machine.
Questa
descrizione, decisamente semplificata, nella maggior
parte dei casi è tutto quello che un programmatore
deve sapere sul funzionamento di un computer.
Il
primo approccio con la programmazione
Per
prendere confidenza con i concetti di codice sorgente,
compilatore e interprete, è utile portare a termine
un'esercitazione. La carriera del programmatore, in
ossequio ad una tradizione oramai consolidata, prende
il via con un gioioso saluto: Hello World! Hello World
è senza dubbio uno dei programmi più longevi
della storia dell'informatica: tradotto in decine di
linguaggi differenti, svolge da anni un ruolo da anfitrione,
guidando l'aspirante programmatore alla scoperta dei
primi segreti dello sviluppo software. Se lo sconosciuto
autore avesse avuto la lungimiranza di registrarne il
brevetto, certamente avrebbe fatto fortuna.
Il
testo del programma in versione Java è il seguente:
public
class HelloWorld {
public static void main(String
argv[]) {
System.out.println("Hello
World!");
}
}
Figura 1 - Attraverso il semplice notepad è
possibile scrivere il primo programma
Il primo compito da svolgere è quello di copiare
il testo del programma all'interno del Notepad, rispettando
diligentemente le spaziature e la distinzione tra maiuscole
e minuscole. Una volta terminata la trascrizione, è
necessario salvare il file con il nome di "HelloWorld.java",
in una posizione nota del disco, come la radice del
disco C. Per evitare che il Notepad aggiunga l'estensione
.txt al file, è necessario specificare il nome
tra virgolette, come in figura.
Figura 2 - nel salvare il documento, prestare
attenzione alle maiuscole
Il
file "HelloWorld.java" appena creato è
un esempio di file sorgente; per poterlo eseguire dobbiamo
azitutto tradurlo in Bytecode con il compilatore. Il
compilatore standard per Java è un programma
a riga di comando, privo di interfaccia grafica. Per
poterlo eseguire, è necessario aprire la console
di comandi MS Dos, che si trova normalmente sotto la
voce "Programmi" del menu "Start".
Figura 3 - Per compilare ed eseguire un programma
occorre attivare il prompt di comandi
Ora
bisogna portarsi sulla directory nella quale il file
"HelloWorld.java" è stato salvato:
se, come consigliato, fosse stato posto nella root del
disco C, bisogna digitare il comando "cd c:\",
e premere invio. A questo punto bisogna digitare la
seguente riga:
javac
HelloWorld.java
Dopo
pochi secondi ricomparirà il cursore, segnalando
che la compilazione è andata a buon fine. Nella
directory di lavoro, oltre al file "HelloWorld.java"
ci sarà ora un file "HelloWorld.class"
contenete il programma in Bytecode.
Figura 4 - Il file sorgente "HelloWorld.java"
e il file "HelloWorld.class"
risultato della compilazione
Per
eseguire il programma ora bisogna digitare
java
HelloWorld
Il
sistema si metterà al lavoro, e dopo qualche
istante sulla console comparirà la scritta:
HelloWorld
Benvenuti
nel mondo della programmazione!
Figura 5 - Esempio di uso dei tools Javac e Java
del JDK
NOTA: Le istruzioni presenti in questo paragrafo sono
valide per la piattaforma Windows. L'utente Unix o Linux,
sicuramente più esperto di ambienti a riga di
comando, non dovrebbe incontrare particolari difficoltà
nell'adattare, attraverso piccole modifiche, le istruzioni
al proprio caso.
I
costrutti fondamentali della programmazione
Dopo
aver visto come si scrive, si compila e si esegue un
semplice programma, è il momento di mostrare
alcune possibili variazioni. I linguaggi di programmazione
assomigliano al linguaggio naturale inglese, ma rispetto
a quest'ultimo prevedono dei vincoli sintattici molto
più rigidi, regolati da un insieme di regole
formali che prendono il nome di grammatica. Lo studio
di queste regole è la chiave che permette di
comporre in maniera autonoma dei programmi.
Struttura
base di un programma Java
La
struttura base di un programma, in questi primi esempi,
sarà sempre di questo tipo:
public
class NomeProgramma {
public static
void main(String argv[]) {
}
}
Il
nome del programma (che compare dopo la parola "class")
può essere scelto liberamente dal programmatore:
l'unico vincolo è che il file sorgente che lo
contiene abbia lo stesso identico nome, con l'estensione
".java" alla fine. Quando si lavora con Java
è bene fare attenzione alla distinzione tra lettere
maiuscole e minuscole: il nome "HelloWorld.java"
viene considerato diverso da "helloWorld.java",
dal momento che, nel secondo caso, la lettera 'h' è
minuscola.
Tra
seconda e la terza parentesi graffa, quelle che compaiono
dopo la scritta main(String argv[]), possiamo inserire
le istruzioni che studieremo via via.
Istruzione
elementare
L'istruzione
è l'unità base del programma: essa descrive
un compito da eseguire, tipo "somma due numeri"
o "disegna un cerchio sullo schermo".
L'istruzione
alla quarta riga del programma "HelloWorld.java"
ha come effetto quello di visualizzare sullo schermo
la scritta racchiusa tra virgolette. Possiamo divertirci
a modificare il sorgente del programma cambiando la
frase con qualcosa del tipo "Abbasso la Squola
:-P" o "Viva (mettere qui il nome della squadra
del cuore)"; per mettere in atto le modifiche sarà
necessario risalvare il file su disco, ed eseguire di
nuovo la compilazione e l'esecuzione.
Alcune
istruzioni che verranno usate nei prossimi esempi sono:
System.out.print("FRASE");
stampa
su schermo la frase contenuta tra virgolette, senza
andare a capo
System.out.println("FRASE");
stampa
su schermo la frase contenuta tra virgolette, e quindi
va a capo
System.out.print("\t");
stampa
su schermo un carattere di tabulazione.
Sequenza
La
maniera più semplice di fornire istruzioni ad
un calcolatore è quella di scrivere un elenco
di operazioni da eseguire una di seguito all'altra.
L'interprete eseguirà le istruzioni in sequenza,
una alla volta, nello stesso ordine in cui sono state
elencate nel testo del programma.
Proviamo
a modificare il programma precedente in questo modo:
public
class HelloWorld {
public
static void main(String argv[]) {
System.out.println("Hello
World!");
System.out.println("Every
day is a very nice day");
}
}
Le
istruzioni di stampa ora sono due, e verranno eseguite
in sequenza. Possiamo istruire il computer ad eseguire
una qualunque sequenza di istruzioni:
System.out.println("Nel
mezzo del cammin di nostra vita");
System.out.println("Mi ritrovai per una selva oscura");
System.out.println("Che la diritta via era smarrita");
....
Se
le istruzioni sono formulate correttamente, il computer
le eseguirà una ad una.
Variabili
intere: dichiarazione ed assegnamento
Se
un computer si limitasse a stampare un elenco di frasi
sullo schermo, la sua utilità sarebbe decisamente
limitata. Ciò che rende veramente utile un computer
è la capacità di eseguire calcoli arimetici
con grande velocità e precisione, mantenendo
in memoria i risultati temporanei.
Il
principale strumento di manipolazione numerica è
la variabile, una cella di memoria al cui interno è
possibile memorizzare un numero. Il programmatore può
ricorrere alle variabili per per effettuare calcoli,
memorizzare i risultati di espressioni anche moltocomplesse
ed effettuare dei confronti.
Il
linguaggio Java permette di gestire variabili di diversi
tipi; per il momento ci limiteremo a descrivere l'uso
delle variabili intere.
Dichiarazione
Prima
di utilizzare una variabile, è necessario eseguire
una dichiarazione, in modo da segnalare al computer
la necessità di riservare una cella di memoria.
Per dichiarare una variabile intera è necessario
usare la parola "int", seguita da un nome
scelto dal programmatore e da un carattere punto e virgola:
int
a;
int operando;
int risultato;
Il
nome della variabile deve essere composto da una combinazione
di lettere e numeri, di lunghezza arbitraria: normalmente
viene scelto in base al contesto di utilizzo, in modo
da rendere il programma più leggibile.
Assegnamento
Per
memorizzare un valore all'interno di una variabile,
devo effettuare un assegnamento. La struttura di un
assegnamento è data dal nome della variabile,
seguito dal carattere "=" e da un'espressione
numerica:
a
= 10;
operando = 15;
Nella
parte destra di un assegnamento, dopo il carattere "=",
posso inserire un'espressopme artimetica che faccia
uso di parentesi e dei normali operandi aritmetici:
+ per la somma, - per la sottrazione, * per la moltiplicazione,
/ per la divisione e % per l'operazione di modulo (resto
di una divisione intera); in questi casi la variabile
a sinistra assumerà il valore dell'espressione
a destra. Ad esempio, l'istruzione:
risultato
= (10 + 5) * 2;
assegnerà
il valore 30 alla variabile 'risultato'.
La
dichiarazione di una variabile e il primo assegnamento
(detto anche inizializzazione) possono essere eseguiti
in un'unica istruzione, come nel seguente esempio:
int
a = 10;
Uso
delle variabili
Una
variabile, una volta inizializzata, si comporta, all'interno
di un programma, come il numero che gli viene assegnato.
Essa può dunque comparire all'interno di espressioni,
e comparire a sua volta in un assegnamento:
a
= 10;
b = a * 2;
In
questo esempio, alla variabile 'b' viene assegnato il
valore di 'a' moltiplicato per due: dal momento che
a vale 10, b assumerà il valore 20.
Cosa
succede se l'espressione nella parte destra di un assegnamento
contiene la variabile da assegnare? Ad esempio, ha senso
la seguente istruzione?
a
= a + 2;
In
un caso come questo, la variabile 'a' assume il valore
che si ottiene valutando l'espressione a destra in base
al valore "precedente" della variabile. Vediamo
ad esempio come vengono eseguite le seguenti istruzioni:
a
= 10;
a = a + 2;
La
prima istruzione assegna alla variabile 'a' il valore
10; la seconda invece assegna il valore 12, dato dalla
somma del precendente valore di 'a', in questo caso
10, con il numero 2.
Struttura
di controllo decisionale: il costrutto 'if - else'
Nel
descrivere una sequenza di operazioni, capita talvolta
di dover illustrare delle distinzioni. Se vogliamo descrivere
ad un amico come preparare una festa, possiamo ricorrere
ad una serie di istruzioni di questo tipo:
comprare
patatine;
comprare torta;
comprare piatti;
....
Ma
se vogliamo che la festa sia un successo, dobbiamo prendere
in considerazione alcuni fattori, ed agire di conseguenza:
se
gli invitati sono maggiorenni ----> comprare birra;
in caso contrario ------------------> comprare aranciata;
Questo
modo di operare viene detto 'condizionale': si valuta
una condizione e si agisce in modo differente a seconda
che la condizione sia vera o falsa. La formulazione
generale del costrutto condizionale in Java è
la seguente:
if(CONDIZIONE)
{
ISTRUZIONI DA ESEGUIRE SE LA CONDIZIONE E' VERA
}
else {
ISTRUZIONI DA ESEGUIRE SE LA CONDIZIONE E' FALSA
}
La
clausola 'else' è opzionale; se non abbiamo la
necessità di specificare un percorso alternativo,
possiamo ricorrere alla seguente formulazione:
if(CONDIZIONE)
{
ISTRUZIONI DA ESEGUIRE SE LA CONDIZIONE E' VERA
}
Formulazione
di una condizione
Dal
momento che siamo in grado di trattare solo variabili
intere, la condizione deve essere espressa come confronto
tra variabili e numeri, o tra variabili e variabili.
Per verificare l'uguaglianza tra due variabili, dobbiamo
usare l'operatore '==' (due caratteri '=' senza spaziature):
if(a
== b) {
ISTRUZIONI DA ESEGUIRE SE a E' UGUALE A b
}
else {
ISTRUZIONI DA ESEGUIRE SE a E' DIVERSO DA b
}
L'operatore
'!=' è l'inverso del precedente: esso permette
di verificare se due valori sono differenti. Altri operatori
importanti sono:
'<'
per valutare la condizione "minore di"
'<=' per "minore uguale"
'>' per "maggiore di"
'>=" per "maggiore o uguale"
Riprendendo
in esame l'esempio della festa, possiamo esprimere la
condizione in linguaggio pseudo - Java:
if(età
>= 18) {
comprareBirra();
}
else {
comprareAranciata();
}
Struttura
di controllo iterativa: l'istruzione while
In
una celebre scena del film Shining, l'attrice Shelley
Duval scopre, su un tavolo da pranzo nel soggiorno dell'Overlook
Hotel, un'intera risma di fogli per macchina da scrivere
con sopra stampata un'unica frase, ripetuta migliaia
di volte:
Il
mattino ha l'oro in bocca
Il mattino ha l'oro in bocca
Il mattino ha l'oro in bocca
Il mattino ha l'oro in bocca
Il mattino ha l'oro in bocca
Il mattino ha l'oro in bocca
Questa
scoperta fornisce la prova inconfutabile della pazzia
del marito, magistralmente interpretato dal bravissimo
Jack Nicolson.
Secondo
la leggenda, il regista Stanley Kubrick, insoddisfatto
dalla bassa qualità degli strumenti di riproduzione
fotostatica dell'epoca, pretese che i cinquecento fogli
fossero battuti a mano, in quattro lingue diverse, dai
suoi fedeli assistenti, al fine di ottenere il massimo
realismo.
Al giorno d'oggi le tecnologie di stampa hanno raggiunto
la qualità tipografica, e persino Kubrick, di
cui era nota la pignoleria, avrebbe acconsentito ad
assegnare un simile folle lavoro ad un computer, attraverso
un programma di questo tipo:
public
class Shining {
public static void main(String
argv[]) {
int
i = 0;
while(i<25000)
{
System.out.println("Il
mattino ha l'oro in bocca");
i
= i + 1;
}
}
}
La
parola "while", in inglese, significa "fino
a quando": lo scopo del while, infatti, è
quello di ripetere un gruppo di istruzioni "fino
a quando" una certa condizione è vera. Nel
piccolo programma di esempio le istruzioni
System.out.println("Il
mattino ha l'oro in bocca");
i = i + 1;
in
settima ed ottava riga vengono ripetute "fino a
quando" il valore di i, posto inizialmente a zero,
rimane minore di 25000. Ad ogni iterazione, la variabile
i viene incrementata di 1: questo incremento fornisce
la garanzia che, dopo esattamente 25000 ripetizioni,
il ciclo arriverà a termine.
Figura 6 - Un computer può eseguire indefinitamente
un'azione ripetitiva.... senza ridursi a questo modo
Struttura
generale del ciclo while
La
struttura generale del while è
while(CONDIZIONE)
{
ISTRUZIONE1;
ISTRUZIONE2;
....
}
La
condizione è una espressione del tutto simile
a quella che correda l'istruzione 'if'. Se si desidera
che un ciclo venga ripetuto all'infinito, è sufficiente
specificare una condizione sempre vera, tipo
while(0
== 0) {
ISTRUZIONE1;
ISTRUZIONE2;
...
}
Solitamente,
comunque, si desidera che il ciclo venga ripetuto un
numero prefissato di volte: in questo caso, è
necessario che nel gruppo di istruzioni che compongono
il ciclo compaia anche un assegnamento sulla variabile
presente nella condizione. Il tipico ciclo ascendente
assume la forma:
i
= 0;
while(i<=100) {
ISTRUZIONI
DA RIPETERE
i
= i + 1;
}
E'
possibile realizzare anche cicli discendenti, modificando
in modo opportuno l'inizializzazione della variabile
indice, la condizione di uscita e l'operazione di incremento:
i
= 100;
while(i>=0) {
ISTRUZIONI
DA RIPETERE
i
= i - 1;
}
Conclusioni
Questo
mese abbiamo affrontato i primi passi sul linguaggio
Java. Attraverso un percorso guidato, abbiamo visto
come sia possibile, senza ricorrere a complessi ambienti
di sviluppo, realizzare il primo programma. Abbiamo
anche fatto la conoscenza di alcuni importanti costrutti
del linguaggio: il mese prossimo vedremo come sia possibile
scrivere alcuni semplici programmi di esempio ricorrendo
solo alle nozioni apprese fino ad ora.
Esempi
Scarica gli esempi
descritti in questo articolo
|