Logo

Marco Cantù
Essential Pascal


Tradotto dall'inglese da: Paolo Rossi

Capitolo 2
Scrivere codice in Pascal

Prima di passare alla scrittura di codice Pascal, e' importante sottolineare alcuni elementi di stile di programmazione Pascal. La questione che vorrei affrontare e' questa: A parte le regole di sintassi, come scrivere il codice? Non esiste una singola risposta a questa domanda, visto che le preferenze personali generano diversi stili. Comunque ci sono alcune regole da seguire riguardo ai commenti, maiscole, spazi e la cosidetta pretty-printing. In generale l'obbiettivo di ogni stile di programmazione e' la chiarezza. Le decisioni di formattazione, che si prendono sono una forma di stenografia indicante la funzione di un dato pezzo di codice. Un essenziale strumento per la chiarezza e' la coerenza ovunque dello stile che si sceglie, quindi assicurarsi di seguirlo attraverso tutto il progetto.

Commenti

In Pascal, i commenti sono racchiusi tra parentesi graffe o parentesi tonde seguite da un asterisco. Delphi accetta anche i commenti nello stile C++, che si possono mettere anche alla fine di una riga:

{this is a comment}
(* this is another comment *)
// this is a comment up to the end of the line

La prima forma e' la piu' breve e la piu' usata. La seconda forma e' spesso preferita in Europa visto che diverse tastiere Europee non hanno il simbolo della parentesi graffa. La terza forma di commento e' stata presa dal C++ ed e' disponibile soltanto nelle versioni di Delphi a 32 bit. I commenti alla fine della linea sono di grande aiuto per brevi commenti e per commentare una specifica linea di codice.

Nota: Nei listati di questo libro cerchero' di scrivere i commenti in corsivo (e le keyword in grassetto), per essere consistente con i settaggi della sintassi in Delphi.

Avere tre differenti tipi di commenti puo' essere d'aiuto per costruire commenti nidificati. Se si cerca di commentare diverse righe di codice per disabilitarle e queste linee contengono gia' alcuni commenti, non si puo' usare lo stesso stile di commento:

{  ... code
{comment, creating problems}
... code }

Con un secondo stile di commento, si puo' scrivere il seguente codice corretto:

{  ... code
//this comment is OK
... code }

Da notare che se la parentesi graffa o la parentesi-asterisco e' seguita dal simbolo del dollaro ($), essa diventa una direttiva del compilatore, come in {$X+}.

Nota: Attualmente, le direttive del compilatore sono ancora commenti. Ad esempio, {$X+ Questo e' ancora un commento} e' valido. E' sia una valida direttiva sia un valido commento, anche se un buon progammatore tendera' probabilmente a separare direttive e commenti.

Uso del Maiuscolo

Il compilatore Pascal (diversamente da altri linguaggi) ignora la capitalizzazione dei caratteri. Di conseguenza, gli identificatori Myname, MyName, myname, myName, e MYNAME sono esattamente equivalenti. Nel complesso cio' e positivo, visto che nei linguaggi case-sensitive, diversi errori di sintassi sono causati da un'errata capitalizzazione.

Nota: C'e' solo un'eccezione in Object Pascal: La procedura di registrazione di un componente Register deve sempre cominciare con la R maiuscola, a causa di problemi di compatibilita' con C++ Builder.

Ci sono comunque leggeri inconvenienti. Primo, bisogna comprendere che questi identificatori sono veramente gli stessi, bisogna quindi evitare di usarli come elementi diversi. Secondo, bisogna tentare di essere coerenti nell'uso del maiuscolo per aumentare la leggibilita' del codice.

Una coerenza nell'uso del maiuscolo non e' forzata dal compilatore, ma e' buona abitudine seguirla. Un comune approccio e' quello di mettere maiuscolo solo il primo carattere di ogni identificatore. Quando un identificatore e' formato da diverse parole (non si possono inserire spazi in un identificatore), ogni prima lettera di ogni singola parola va in maiuscolo:

MyLongIdentifier
MyVeryLongAndAlmostStupidIdentifier

Altri elementi ignorati dal compilatore sono spazi, a capo e tabulazioni inseriti nel codice sorgente. Tutti questi elementi sono conosciuti come spazi bianchi. Gli spazi bianchi sono usati per aumentare la leggibilita' del codice e non influenzano la compilazione.

Diversamente dal BASIC, il Pascal permette di scrivere un'istruzione composta da diverse linee di codice, dividendo una singola istruzione su due o piu' righe. L'inconveniente (almeno per i programmatori BASIC) di permettere istruzioni su piu' righe, e' che bisogna ricordare di terminarle con un punto e virgola. Da notare che la sola restrizione a questa regola sono le stringhe letterali, le quali non possono continuare su diverse linee.

Non ci sono nemmeno regole prefissate per l'uso di spazi bianchi e istruzioni multi-riga, soltanto alcuni consigli:

Pretty-Printing

L'ultimo suggerimento sull'uso degli spazi bianchi in relazione alla formattazione del codice Pascal e' conosciuta come pretty-printing. La regola e' semplice: ogni volta che si deve scrivere un'istruzione composta, rientrare di due spazi a destra. Un'istruzione composta nidificata in un'altra istruzione e' rientrata di quattro spazi e cosi' via:

if ... then
  statement;

if ... then
begin
  statement1;
  statement2;
end;

if ... then
begin
  if ... then
    statement1;
  statement2;
end;

Nota: La formattazione sopra e' basata sulla pretty-printing, ma i programmatori danno differenti interpretazioni a questa regola generale. Alcuni programmatori rientrano le istruzioni begin-end al livello del codice interno, altri rientrano il begin-end ed anche il codice interno, altri infine mettono il begin sulla stessa riga dell'if. Questa e' una questione solo di gusti personali.

Un simile formato rientrato, e' spesso usato per le liste di variabili o tipi di dato e per continuare un'istruzione dalla precedente riga:

type
  Letters = set of Char;
var
  Name: string;
begin
   { long comment and long statement, going on in the
     following line and indented two spaces }
   MessageDlg ('This is a message',
     mtInformation, [mbOk], 0);

Ovviamente queste convenzioni vuogliono solo essere un suggerimento per rendere il codice piu' leggibile agli altri programmatori, visto che sono completamente ignorate dal compilatore. Ho cercato di usare queste convenzioni in tutti gli esempi e frammenti di codice di questo libro. I sorgenti di Delphi, i manuali e gli esempi inclusi nell'help in linea usano uno stile di formattazione simile.

Syntax Highlighting

Per rendere piu' facile la lettura e la scrittura del codice Pascal, l'editor di Delphi ha una funzionalita' chiamata color syntax highlighting. In relazione al significato che assumono, le parole scritte nell'editor, sono visualizzate usando differenti colori e stili. Di default le parole riservate sono in grassetto, le stringhe e i commenti sono colorate (spesso in corsivo) e cosi' via.

Le parole riservate, i commenti e le stringhe sono probabilmente i tre elementi che beneficiano maggiormente di questa funzionalita'. Si possono immediatamente vedere le keyword digitate non correttamente, le stringhe non terminate e la lunghezza dei commenti multi-linea.

Si possono facilmente personalizzare i settaggi della colorazione della sintassi usando la pagina Editor Color della finestra di dialogo Environment Options (vedere Figura 2.1). Se si lavora in gruppo con altri programmatori bisogna optare per i settaggi di default. Trovo infatti che lavorare su un computer con un diverso schema di colori e' veramente difficile.

Figura 2.1: La finestra di dialogo usata per cambiare i settaggi.

Nota: In questo libro ho tentato di applicare una sorta di sintassi colorata ai listati. Spero che risulti piu' leggibile.

Usare i Code Template

Delphi 3 ha introdotto una nuova funzionalita' riguardo la scrittura del codice sorgente. Siccome nella scrittura di istruzioni in linguaggio Pascal spesso si ripetono le stesse sequenze di keyword, Borland ha messo a disposizione un nuovo strumento chiamato Code Template. Un code template e' semplicemente un pezzo di codice richiamabile con un testo chiave. Si digita il testo chiave, si preme Ctrl-J ed il pezzo di codice appare. Ad esempio scrivendo arrayd e premendo Ctrl-J, l'editor di Delphi espandera' il testo in:

array [0..] of ;

Siccome i code template predefiniti normalmente includono diverse versioni dello stesso costrutto, il testo chiave termina con una lettera indicante la versione alla quale si e' interessati. Comunque si puo' scrivere anche la parte iniziale del testo chiave. Per esempio se si scrive ar e si preme Ctrl-J, l'editor visualizzera' un menu con una lista di scelte disponibili con una breve descrizione, come si puo' vedere in Figura 2.2.

Figura 2.2: Selezione dei Code Template

Si possono completamente personalizzare i code template, modificando quelli gia' esistenti oppure aggiungendo nuovi pezzi di codice. In questo caso ricordarsi che il testo del code template generalmente include il carattere '|' per indicare dove si posizionera' il cursore ad operazione conclusa, ovvero, dove si parte a scrivere per completare il code template con il proprio codice.

Istruzioni del Linguaggio

Una volta definiti gli identificatori, si possono usare per costruire istruzioni ed espressioni che fanno parte di altre istruzioni. Il Pascal offre diverse istruzioni ed espressioni.

Keyword

Le keyword sono identificatori riservati dell'Object Pascal, che hanno un ruolo nel linguaggio. L'help di Delphi distingue tra parole riservate e direttive: le parole riservate non possono essere usate come identificatori, mentre le direttive potrebbero, in teoria, essere usate come identificatore anche se in pratica e' meglio non farlo.

Nella Tabella 2.1 si puo' vedere una lista completa di identificatori che hanno uno specifico ruolo in Object Pascal (in Delphi 4), incluse parole chiave e parole riservate.

Tabella 2.1: Keywords e altre parole riservate nel linguaggio Object Pascal:

Keyword Ruolo
absolute directive (variables)
abstract directive (method)
and operator (boolean)
array type
as operator (RTTI)
asm statement
assembler backward compatibility (asm)
at statement (exceptions)
automated access specifier (class)
begin block marker
case statement
cdecl function calling convention
class type
const declaration or directive (parameters)
constructor special method
contains operator (set)
default directive (property)
destructor special method
dispid dispinterface specifier
dispinterfacetype
div operator
do statement
downto statement (for)
dynamic directive (method)
else statement (if or case)
end block marker
except statement (exceptions)
export backward compatibility (class)
exports declaration
external directive (functions)
far backward compatibility (class)
file type
finalizationunit structure
finally statement (exceptions)
for statement
forward function directive
function declaration
goto statement
if statement
implementationunit structure
implements directive (property)
in operator (set) - project strucure
index directive (dipinterface)
inherited statement
initializationunit structure
inline backward compatibility (see asm)
interface type
is operator (RTTI)
label declaration
library program structure
message directive (method)
mod operator (math)
name directive (function)
near backward compatibility (class)
nil value
nodefault directive (property)
not operator (boolean)
object backward compatibility (class)
of statement (case)
on statement (exceptions)
or operator (boolean)
out directive (parameters)
overload function directive
override function directive
package program structure (package)
packed directive (record)
pascal function calling convention
private access specifier (class)
procedure declaration
program program structure
property declaration
protected access specifier (class)
public access specifier (class)
published access specifier (class)
raise statement (exceptions)
read property specifier
readonly dispatch interface specifier
record type
register function calling convention
reintroduce function directive
repeat statement
requires program structure (package)
resident directive (functions)
resourcestringtype
safecall function calling convention
set type
shl operator (math)
shr operator (math)
stdcall function calling convention
stored directive (property)
string type
then statement (if)
threadvar declaration
to statement (for)
try statement (exceptions)
type declaration
unit unit structure
until statement
uses unit structure
var declaration
virtual directive (method)
while statement
with statement
write property specifier
writeonly dispatch interface specifier
xor operator (boolean)

Espressioni ed Operatori

Queste non sono regole generali per costruire espressioni, visto che principalmente dipendono dagli operatori sui set, piu' diversi altri. Le espressioni possono essere usate per determinare il valore da assegnare ad una variabile, per calcolare il parametro di una funzione o procedura, o per testare una condizione. Le espressioni possono anche includere chiamate a funzioni. Ogni volta che si esegue un'operazione sul valore di un identificatore, invece di usare l'identificatore stesso, questa e' un'espressione.

Le espressioni sono comuni a quasi tutti i linguaggi di programmazione. Un'espressione e' una qualsiasi combinazione valida di costanti, variabili, valori letterali e risultati di funzione. Le espressioni possono anche essere passate ai parametri valore di una procedura o funzione, ma mai ad un parametro passato per riferimento (il quale richiede un valore al quale assegnarlo).

Operatori e Precedenza

Se si e' scritto almeno un programma, si sa che cosa e' un'espressione. Qui mettero' in evidenza elementi specifici degli operatori Pascal. Si puo' vedere una lista di operatori raggruppati per precedenza (Tabella 2.1).

Nota: Contrariamente a diversi altri linguaggi di programmazione, gli operatori and e or hanno la precedenza sugli operatori relazionali. Cosi' se si scrive a < b and c < d, il compilatore valutera' per prima l'operazione and, generando quindi un errore. Per questa ragione bisogna racchiudere ogni espressione < in parentesi: (a < b) and (c < d).

Diversi operatori hanno diversi significati a seconda dei tipi di dato. Per esempio l'operatore + puo' essere usato per sommare due numeri, concatenare due stringhe, unire due insiemi e anche aggiungere un offset ad un puntatore PChar. In Pascal pero', non si possono sommare due caratteri come in C.

Un altro strano operatore e' div. In Pascal, si puo' eseguire la divisione tra due numeri qualsiasi (reali o interi) con l'operatore /, invariabilmente si otterra' un risultato reale. Se bisogna dividere due interi ed ottenere un risultato di tipo integer, si deve usare l'operatore div.

Tabella 2.2: Operatori del linguaggio Pascal, raggruppati per Precedenza

Operatori Unari (Precedenza piu' alta)
@ Indirizzo di una variabile o funzione (ritorna un puntatore
not Not booleano o bitwise
Operatori di moltiplicazione
* Moltiplicazione aritmetica o intersezione di insiemi
/ Divisione floating-point
div Divisione intera
mod Modulo (il resto di una divisione intera)
as Typecast sicuro (RTTI)
and And booleano o bitwise
shl Left Shift bitwise
shr Right Shift bitwise
Operatori di addizione
+ Somma aritmetica, unione di insiemi, concatenazione di stringhe, somma di offset
- Sottrazione aritmetica, sottrazione di insiemi, sottrazione di offset
or Or booleano o bitwise or
xor Or esclusivo boolean o bitwise
Operatori relazionali e comparativi (Precedenza piu' bassa)
= Test di uguaglianza
<> Test di non uguaglianza
< Test minore di
> Test maggiore di
<= Test minore o uguale di, o sottoinsieme di un insieme
>= Test maggiore o uguale di, o sovrainsieme di un insieme
in Test di appartenenza ad un insieme
is Test di compatibilita' di tipo (operatore RTTI)

Operatori sui Set

Gli operatori sugli insiemi (set) includono l'unione (+), la differenza (-), l'intersezione (*), test sugli elementi contenuti (in) piu' diversi altri operatori relazionali. Per aggiungere un elemento ad un insieme, si puo' fare l'unione del set con un altro che contiene solo l'elemento che serve. Ecco un esempio in Delphi relativo ai font:

Style := Style + [fsBold];
Style := Style + [fsBold, fsItalic] - [fsUnderline];

Come alternativa, si possono usare le procedure standard Include e Exclude, che sono molto piu' efficienti (ma non possono essere usate con le proprieta' di tipo set dei componenti, siccome richiedono un parametro l-value):

Include (Style, fsBold);

Conclusioni

Adesso che si conosce lo schema di base di un programma Pascal, si e' pronti per comprenderne i dettagli. Partiremo con l'esplorazione delle definizioni di tipi di dato predefiniti e creati dall'utente, continuando con l'uso delle keyword per formare istruzioni nei programmi.

Prossimo Capitolo: Tipi, variabili e costanti

© Copyright Marco Cantù, Wintech Italia Srl 1995-2000