Capitolo 4.

Il linguaggio Pascal.

 


  Indice

4.1 Introduzione.
4.2 Pascal.
     4.2.1 Espressioni e istruzioni.
         assegnamento
     4.2.2 Istruzioni di ingresso e uscita.
         differenze tra READ e READLN: esempio
     4.2.3 Istruzioni di controllo.
         Istruzione composta:
         Istruzioni condizionali:
             a. IF espr THEN i1;
             b. IF espr THEN ... ELSE
             c. CASE espr1 OF
         Istruzioni di ciclo:
             a. WHILE espr DO i1;
             b. REPEAT i1;i2;...in UNTIL espr;
             c. FOR i:=a TO b DO i1;
 4.3 Tipi di dato.
     4.3.1 Il tipo BOOLEAN.
         pred( x ) e succ( x )
     4.3.2 Il tipo INTEGER.
     4.3.3 Rappresentazione degli integer.
         4.3.3.1 Rappresentazione posizionale.
         4.3.3.2 Rappresentazione in complemento a due.
         Esempi.
     4.3.4 Il tipo CHAR.
         ord e chr
     4.3.5 Il tipo REAL.
         round(r); trunc(r)
     4.3.6.1 Rappresentazione scientifica.
     4.3.6.2 Rappresentazione in virgola mobile.
     Esercizi: da decimale a binario
     Esercizi: da binario a decimale
     Esercizi: trasformare in complemento a due
     Eseguire le sguenti opreazioni in complemento a 2 con 6 bit
     Rappresentare i seguenti numeri in notazione scientifica
     Eseguire le seguenti operazioni in notazione scientifica
     Fornire un esempio di numeri in notazione scientifica con 3 bit che non verificano le seguenti uguaglianze
     Fornire un esempio di numeri in notazione scientifica con 4 bit di mantissa che verificano le seguenti uguaglianze
 4.4 Il programma.
     L'intestazione:
     La parte dichiarativa:
         CONST
         TYPE
         BEGIN/END.
 Esercizi.
     1. Scrivere in Pascal le seguenti espressioni:
     2. Indicare quali tra le seguenti espressioni sono sintatticamente corrette
     3. Indicare le istruzioni
     4. Per ogni esercizio indicare la risposta esatta
     5. Risolvere in linguaggio Pascal i seguenti problemi.
 


4.1 Introduzione.

 

Nel capitolo 3 abbiamo introdotto l'esecutore URM. Abbiamo poi definito risolvibili tutti i problemi URM risolubili. La sintassi della macchina U.R.M. è semplicissima ma molto lontana dal modo naturale con cui in genere si descrive un algoritmo. Lo sforzo che si deve compiere per adattare il linguaggio alle esigenze del programmatore è molto grande. Ci serve un linguaggio universale che sia più vicino al linguaggio naturale. E` quello che ci accingiamo a realizzare introducendo il linguaggio di programmazione Pascal.

4.2 Pascal.

 

Ogni linguaggio di programmazione si basa su un dizionario. Le frasi del linguaggio vengono costruite componendo i simboli base attraverso le regole sintattiche che devono essere semplici e facilmente applicabili.

Vediamo allora quali sono le prime regole sintattiche del Pascal rimandando all'appendice A per il dizionario completo, e riservandoci di introdurre le altre man mano che se ne sentirà il bisogno.

 

4.2.1 Espressioni e istruzioni.

La prima distinzione che occorre fare affrontando la definizione di un linguaggio di programmazione è tra espressione e istruzione. Un'espressione è una formula che specifica un risultato. E` composta da operatori e operandi. Gli operandi possono essere delle costanti o delle variabili. Gli operatori possono essere con un solo argomento o con due argomenti. Quando un'espressione contiene più di un operatore è necessario specificare l'ordine secondo cui eseguire le operazioni attraverso le parantesi altrimenti verrà accettato l'ordine definito implicitamente dalle regole del linguaggio. Nel Pascal compariranno operatori additivi e operatori moltiplicativi. Questi ultimi avranno la precedenza sugli additivi. Vediamo alcuni esempi di espressioni:
 

x + y + z è equivalente a (x + y) + z
x + y * z è equivalente a x + (y * z)
10 - y * z è equivalente a 10 - (y * z)
x * y / z è equivalente a (x * y) / z
x / y / z è equivalente a (x / y) / z
 

In questi esempi abbiamo 4 tipi di operatori, due additivi (+, -) e due moltiplicativi (*, /). x, y, z sono identificatori di variabili. Il Pascal permette di usare come identificatore qualunque combinazione di lettere e numeri, con il primo carattere sempre lettera, e non fa differenze tra lettere maiuscole o lettere minuscole. In piu è possibile utilizzare il carattere "_" per dare più significatività ad un identificatore. Sono corretti i seguenti identificatori:
 

Aa , A1 , switch , lato_maggiore , lato_123

Sono scorretti i seguenti:

1a , 1_a , lato maggiore , lato-maggiore , lato*?

Un'istruzione è un'operazione che produce un effetto. L'istruzione più semplice è l'assegnamento:
 

V:=espr

dove V è una variabile ed espr è un'espressione il cui risultato viene assegnato a V. Si può pensare alle variabili come a dei contenitori di una determinata forma. In questo modo la seguente sequenza di simboli
 

V:=V+1
 

è corretta poichè il simbolo utilizzato alla destra dell'assegnazione significa il contenuto della variabile V che deve essere incrementato di 1 e assegnato nuovamente a V.

 

4.2.2 Istruzioni di ingresso e uscita.

 

Le istruzioni di ingresso permettono ad un programma di ottenere dei valori da un ambiente esterno. Sono:
 

a. READ( x, y, t );
b. READLN( x, y );
 

La sintassi delle due istruzioni è identica. Tra parentesi, separate dalla virgola, vengono indicate le variabili nelle quali finiranno i dati ottenuti dall'esterno.

Esempi.

1.

READ( a, b );

Se dall'esterno vengono forniti i seguenti valori:
 

3 5

a conterrà 3 e b conterrà 5.

Stessa cosa se si sostituisce READLN a READ.

2. Per comprendere alcune differenze tra READ e READLN osserviamo i seguenti esempi:
 

a. READ( x, y );
   READ( c, d );
b. READLN( x, y );
   READLN( c, d );

Se dall'esterno vengono forniti su due linee i seguenti valori:
 

3 5 7 9
4 6

Dopo a x conterrà 3, y conterrà 5, c conterrà 7, d conterrà 9

Dopo b x conterrà 3, y conterrà 5, c conterrà 4, d conterrà 6 mentre 7 e 9 andranno persi.

Altre differenze tra le due istruzioni saranno introdotte in seguito.

Le istruzioni di uscita permettono ad un programma di far conoscere all'ambiente esterno il risultato delle espressioni racchiuse tra parentesi. Sono:
 

a. WRITE( x, y, ...);
b. WRITELN( x, y, ... );

Le espressioni possono essere 0, 1 o più di una se separate da virgola.

Esempi.

1.

WRITE( a, b );

Verrà mostrato all'esterno il contenuto della variabile a e della variabile b consecutivamente. Se a=5, b=6 si avrà
 

5 6

Similmente nel caso di WRITELN.

2. Per comprendere alcune differenze tra WRITE e WRITELN osserviamo i seguenti esempi:
 

      1. WRITE( x, y );
        WRITE( c, d );
      2.  

      3. WRITELN( x, y );
        WRITELN( c, d );

 

Se x=5, y=6, c=7, d=8 si avrà dopo a:
 

5 6 7 8

Mentre dopo b:

5 6
7 8

I riultati in b appaiono su due linee successive.

 

3. WRITE( a+b );

Se a=5 e b=6 verrà mostrato 11.

 

4.2.3 Istruzioni di controllo.

 

Nel Pascal sono definiti tre tipi di istruzioni di controllo:

Istruzione composta: è una sequenza di istruzioni racchiusa tra BEGIN/END. L'operatore punto e virgola ( ; ) tra due istruzioni indica che l'istruzione che segue deve essere eseguita quando è terminata la precedente. Nel seguito ogni qual volta indicheremo una singola istruzione sarà implicita la possibilità di utilizzare anche una istruzione composta. Ad esempio:
 

BEGIN
READLN( x, y );
somma:=x+y;
WRITELN( somma );
END
 

Calcola la somma di due nuemri forniti dall'esterno e visualizza il risultato all'esterno.
 
 

Istruzioni condizionali: sono di tre tipi:
 

a. IF espr THEN i1;

 

b. IF espr THEN i1
   ELSE i2;

 

c. CASE espr1 OF
     v1: i1;
     v2: i2;
     vn: in;
   END;

dove con espr si intende un'espressione logica, con espr1 una espressione, con i1, i2, .. in istruzioni qualsiasi e con v1, v2, .., vn valori compatibili con l'espressione espr1.
 

La a. significa:
Se VdV(espr)=vero allora esegui i1. [VdV = Valore di Verità]
 
La b. significa:
Se VdV(espr)=vero allora esegui i1
altrimenti esegui i2.
 
La c. significa:
Se espr1=v1 esegui i1;
Se espr1=v2 esegui i2;
Se espr1=vn esegui in;

L'istruzione CASE eseguirà una e solo una delle possibili istruzioni i1..in.

 

Esempi:

1. IF ab THEN WRITELN( a )
   ELSE WRITELN( b );

Viene visualizzato il valore più grande tra a e b.

 

2. IF a<0 THEN a:=-a;

Viene calcolato il valore assoluto di a.

 

3. IF massimo<minimo THEN BEGIN
        sup:=massimo;
        massimo:=minimo;
        minimo:=sup
   END

Pone in massimo il valore maggiore e in minimo quello minore. In questo esempio abbiamo utilizzato l'istruzione composta.

 

4. IF ab THEN BEGIN
        IF bc THEN
            WRITELN( a )
   END ELSE
        WRITELN( b );

In questo esempio è necessario utilizzare un'istruzione composta per poter riferire l'ELSE alla prima IF e non alla seconda. Infatti nel caso di utilizzo di più IF annidate, l'ELSE sarà sempre riferito all'ultima IF utilizzata.

 

5. CASE i OF
    1: WRITELN( 'Primo classificato ' );
    2: WRITELN( 'Secondo classificato ');
    3: WRITELN( 'Terzo classificato ');
END;

Viene stampato un messaggio opportuno per una classifica.

E` importante sottolineare che l'istruzione CASE prevede sempre che una delle condizioni sia verificata. Nell'esempio precedente se i3 o i<1 non si può prevedere il risultato. Per questo motivo in alcune versioni di Pascal l'istruzione CASE è stata così modificata:
 

CASE espr1 OF
    v1: i1;
    v2: i2;
    vn: in;
OTHERWISE i;
END;
 

Se nessuno dei valori v1..vn è uguale ad espr1 verrà eseguita l'istruzione i. In alcune versioni di Pascal si usa al posto di OTHERWISE la parola chiave ELSE con lo stesso significato.

 

6. CASE c OF
    'A','E','I','U','O': WRITELN( 'Vocale ' );
   ELSE WRITELN( 'Consonante ');
   END;

Se c è una vocale stampa il messaggio Vocale, in tutti gli altri casi stampa Consonante.

 

Istruzioni di ciclo: sono di quattro tipi.
 

a. WHILE espr DO i1;

che significa: mentre VdV(espr)=vero esegui i1

In un ciclo while VdV(espr)=vero rappresenta la condizione per eseguire le istruzioni del ciclo.

 

Esempio.

1.

fattoriale:=1;
WHILE k0 DO BEGIN
    fattoriale:=fattoriale*k;
    k:=k-1
END

Calcola il fattoriale di k. Se k è negativo fattoriale sarà 1.
 

b. REPEAT i1;i2;...in UNTIL espr;

che significa: ripeti i1 i2 .... in  finchè VdV(espr)=vero

In un ciclo repeat VdV(espr)=vero rappresenta la condizione per interrompere il ciclo. E` importante sottolineare che il controllo di espr viene effettuato per ultimo. Ciò significa che i1 viene eseguita sempre almeno una volta.

 

Esempio.

fattoriale:=1;
REPEAT
    fattoriale:=fattoriale*k;
    k:=k-1;
UNTIL k<=1;

Calcola il fattoriale di k. Se k è negativo fattoriale sarà k.
 

c. FOR i:=a TO b DO i1;

che significa: per i che assume valore a sino a quando non ha assunto il valore b ripeti i1. Ad ogni ripetizione i assume il valore del successivo. L'istruzione i1 non può modificare il valore di i.

Esempi.

1.

somma:=0;
FOR i:=1 TO 100 DO
somma:=somma+i;

Calcola la somma dei primi 100 numeri interi.

2.

FOR c:='A' TO 'Z' DO
WRITELN( c );

Stampa le lettere comprese tra A e Z.
 

d. FOR i:=a DOWNTO b DO i1;

che significa: per i che assume valore a sino a quando non ha assunto il valore b ripeti i1. Ad ogni ripetizione i assume il valore del precedente. L'istruzione i1 non può modificare il valore di i.

Esempi.

1.

somma:=0;
FOR i:=100 DOWNTO 1 DO
    somma:=somma+i;

Calcola la somma dei primi 100 numeri interi.

2.

FOR c:='z' DOWNTO 'a' DO
WRITELN( c );
 

Stampa le lettere comprese tra z e a.

Esempi.

I seguenti esempi sono sintatticamente corretti:

1.  BEGIN                                                     2. BEGIN
        IF ab THEN                                                  IF ab THEN
            IF bc THEN                                                  FOR i:=1 TO n DO BEGIN
                WRITE( a )                                                 REPEAT
            ELSE                                                              b:=a+b; k:=k+1;
                WRITE( b )                                                 UNTIL b=a;
        ELSE                                                               WRITE( k );
            WRITE( c );                                                  END;
    END;                                                             WRITE( b );
                                                                 END;

3. BEGIN                                                     4. BEGIN
     WHILE x=y DO                                                 WHILE ab DO;
        IF x=z THEN x:=x+1;                                         WRITE( a );
   END;                                                         END;

I seguenti esempi sono sintatticamente scorretti:

1. BEGIN                                                     2. BEGIN
      IF ab THEN                                                 IF a< b THEN
          x:=i;                                                         WRITE( b )
      ELSE                                                        a:=3;
          x:=2;                                                 END;
   END;

 

Esercizi.

1- Indicare, quando possibile, il valore finale di r.

BEGIN

r:=0;  

FOR i:=1 TO 0 DO r:=1

END

BEGIN

r:=0;

FOR i:=1 TO 1 DO r:=1

END

BEGIN

r:=0;

FOR i:=1 DOWNTO 1 DO r:=1

END

BEGIN

r:=0;

FOR i:= 0 DOWNTO 1 DO r:=1

END

BEGIN

r:=0;

WHILE r=0 DO r:=1

END

BEGIN

r:=0;

WHILE r<0 DO r:=0

END

BEGIN

r:=1;

REPEAT r:=0 UNTIL r=0

END

BEGIN

r:=1;

REPEAT r:=r+1 UNTIL r0

END

BEGIN 

r:=0; i:=1;

WHILE i=1 DO BEGIN

i:=0;

r:=3

END

END 

BEGIN

r:=0;

IF r=0 THEN

IF r=0 THEN

REPEAT

r:=r+1;

UNTIL r=4

ELSE r:=6;

END

BEGIN

r:=0;

WHILE r=0 DO r:=1

END

BEGIN

r:=1;

REPEAT r:=0 UNTIL r=1

END

 

 
4.3 Tipi di dato.

 

Negli esempi di esecutori abbiamo visto come sia importante avere a disposizione dei contenitori (le variabili) per memorizzare temporaneamente dei dati. Ogni contenitore può essere di forma differente e viene individuato attraverso un nome (identificatore). Quando si utilizza una variabile è utile indicare prima qual'è l'insieme dei valori che potrà contenere e quali sono le operazioni consentite. Tutte queste informazioni vengono fornite con la dichiarazione di tipo. Per convenzione tutte le variabili di cui abbiamo bisogno devono essere indicate in una lista, precisando il nome e il tipo, prima del loro utilizzo. La lista è introdotta dalla parola chiave VAR.

Esempio.

VAR

a1:T1;
b,c,d:T2;
 

dove
 

a, b, c, d sono i nomi delle variabili ( identificatori )
T1, T2 il tipo

Inizialmente considereremo solo i quattro tipi standard che sono: il tipo BOOLEAN, il tipo INTEGER, il tipo REAL e il tipo CHAR. Per ciascuno di essi descriveremo sinteticamente l'insieme dei valori e le operazioni permesse.

 

4.3.1 Il tipo BOOLEAN.

 

Ha come valori possibili FALSE e TRUE. Sui boolean sono definiti i seguenti operatori logici:
 

OR o logico
AND e logico
NOT negazione logica
 

L'operatore OR ha la precedenza più debole, l'operatore NOT, che è unario, ha la precedenza più forte.

Sono definiti gli operatori di relazione che sono binari e che forniscono come risultato un boolean. Sono:
 

= uguale
< diverso
maggiore
= maggiore uguale
< minore
<= minore uguale
 

Sono definiti inoltre due funzioni pred( x ) e succ( x ) che restituiscono rispettivamente il valore precedente e quello successivo di x.

Esempio.
 

VAR
b1,b2,b3 :BOOLEAN;
 
b1:=FALSE; { a b1 viene assegnato il valore false }
b1:=b2 AND b3; { a b1 viene assegnato il risultato dell'espressione }
b1:= b2 = b3; { a b1 assegno il risultato del confronto b2 = b3 }
b1:=succ(false) { a b1 assegno true }
b1:=pred(true) { a b1 assegno false }
 

4.3.2 Il tipo INTEGER.

 

Specifica un intervallo dei numeri interi e precisamente l'intervallo tale che -max <= i < max, dove max è un valore predefinito. Sul tipo integer sono definiti i seguenti operatori:
 

+ addizione
- sottrazione
* moltiplicazione
DIV divisione intera
MOD resto della divisione intera
 

Inoltre sono definite anche le operazioni di confronto viste per i boolean e le due funzioni pred(i) e succ(i).

Esempi.
 

VAR
i1,i2,i3 :INTEGR;
b :BOOLEAN;
 
i1:=3; { Alla variabile i1 assegno il valore 3 }
i1:=i2+i3*3; { Alla variabile i1 assegno il risultato di i2+(i3*3) }
b:=i1i2; { Alla variabile b assegno il risultato del confronto }
i1:=pred(3) { Alla variabile i1 assegno il valore 2 }
i2:=succ(3) { Alla variabile i2 assegno il valore 4 }
 

Con il tipo integer si possono riscontrare due problemi:

1- la divisione per 0, che non ha significato e produce un errore in esecuzione.

2- Il superamento degli estremi dell'intervallo di definizione. In questo caso si potrebbero verificare due situazioni dipendenti dalla particolare implementazione del Pascal: o verrà segnalato un errore, o il risultato proposto sarà privo di significato.

 

4.3.3 Rappresentazione degli integer.

 

4.3.3.1 Rappresentazione posizionale.

Con rappresentazione posizionale pesata dei numeri intendiamo dire che essi sono visti come una successione di simboli S, la loro posizione e la base:
 

(Sn Sn-1 .. S4 S3 S2 S1 S0)b

ad esempio 1234 in base 10 è una forma abbreviata di:
 

1*10^3 + 2*10^2 + 3*10^1 + 4*10^0

Un numero in base due è costituito solo da due simboli (0 e 1) detti bit. Ad esempio
 

10011 = 1*2^4 + 0*2^3 + 0*2^2 + 1*2^1 + 1*2^0

Nota la rappresenatazione di un numero in base 2, si ottiene rapidamente la sua rappresentazione in base 10 riscrivendo così:
 

11010b = 2^4 + 2^3 + 2^1 = 16d + 8d + 2d = 26d

Nota la rappresentazione di un numero in base 10 si ottiene quella in base 2 scrivendolo come somma di potenze di 2:
 

105d = 64d + 32d + 8d + 1d = 2^6 + 2^5 + 2^3 + 2^0 = 1101001b

Nel seguito faremmo seguire dalla lettera d i numeri decimali e dalla lettera b quelli binari.

Esempi
 

725d = 512d + 128d + 64d + 16d + 4d + 1d =
= 2^9 + 2^7 + 2^6 + 2^4 + 2^2 + 2^0 = 1011010101b
 
385d = 256d + 128d + 1d = 2^8 + 2^7 + 2^0 = 110000001b
 
1200d = 1024 + 128d + 32d + 16d = 2^10 + 2^8 + 2^4 = 1010010000b
 

4.3.3.2 Rappresentazione in complemento a due.

 

Il problema che ci si propone di risolvere e' trovare una rappresentazione dei numeri interi relativi che permetta di svolgere l'addizione con un semplice algoritmo e senza utilizzare i simboli + e - per il segno del numero. Ad esempio calcoliamo 13d - 8d.

Potremmo trasformare il numero negativo nel seguente modo:
 

- 8d = 100d - 8d - 100d = 92d - 100d

Allora
 

13d - 8d = 13d + 92d - 100d = 105d - 100d = 5d

92d e' il complemento a 100d di 8d

Calcoliamo 1324d - 675d
 

1324d - 675d = 1324d + 9325d - 10000d = 10649d - 10000d = 649d

In base 10 il vantaggio di tutti questi passaggi non si vedono. Anzi per eliminare il segno - si sono eseguite piu' sottrazioni. Vediamo in base 2.

Calcoliamo in base due 13d - 8 d.

13d -- 01101b
8d -- 01000b
 

Al posto del complemento a 100d = 10^2 utilizziamo il complemento a 2^5 = 100000b
 

- 8d = 100000b - 01000b - 100000b = 11000b - 100000b.

 

13d - 8d = 01101b + 11000b - 100000b = 100101b - 100000b = 00101b.

L'ultima sottrazione del calcolo precedente puo' essere svolta dimenticandosi del primo 1. Anche il complemento a due -8d si puo' calcolare senza sottrazioni, sostituendo nella rappresentazione in base 2 ogni 1 con 0 e viceversa e addizionando 1. Così:
 

01000b = 10111b + 1b = 11000b

 

Il limite di tale approccio e' che va indicato il numero di cifre con cui si lavora a priori. Infatti - 8d puo' essere rappresentato in infiniti modi.

-8d = 11000d = 111000d = 11111000d etc., Dipende dal numero di cifre.

Un altro esempio e' -1 che sara' rappresentato da una sequenza di 1 di lunghezza uguale alle cifre con cui si opera.

 

Esempi.

1. Si supponga di lavorare con 6 bit. Si svolgano i seguenti calcoli:

a) 12d + 13d;

b) 12d - 13d

c) - 12d - 13d

d) - 12d + 13d
 

12d = 001100b -12d = 110100b
13d = 001101b -13d = 110011b
 

a) 12d + 13d = 001100b + 001101b = 011001b = 25d

 

b) 12d - 13d = 001100b + 110011b = 111111b = - 000001b = -1d

 

c) -12d - 13d = 110100b + 110011b = 100111b = - 011001b = -25d

 

d) -12d + 13d = 110100b + 001101b = 000001b = 1d

 

Come si puo' osservare nei casi c e d si ha un 1 di riporto che va perso.

 

2. Sempre con 6 bit si eseguano i seguenti calcoli.

a) 16d + 16d

b) -16d - 16d;
 

16d = 010000b -16d = 110000b
 

a) 16d + 16d = 010000b + 010000b = 100000b = - 32d (errato !!!)

 

b) -16d -16d = 110000b + 110000b = 100000b = - 32d

 

In questo caso il complemento a due non funziona. I numeri diversi rappresentabili con 6 bit sono 2^6=64, cioe' da +31 a - 32.

Il numero 32 non puo' essere memorizzato con soli 6 bit in complemento a due.

 

3. Verifichiamo che, in complemento a 2 con 6 bit,

(31d + 1d) * 2d = -32d * 2d = 0

Posto

31d = 011111b 1d = 000001b 2d = 000010b

si ottiene:

(011111b + 000001b) * 000010b = 100000b * 000010b = 000000b

 

4.3.4 Il tipo CHAR.

 

Indica un campo finito e ordinato di simboli che servono per comunicare con l'esterno. Il più diffuso insieme di simboli è il codice A.S.C.I.I. (American Standard Code for Information Interchange).
 
 

0

1

2

3

4

5

6

7

0

nul

dle

 

0

@

P

`

p

1

soh

dc1

!

1

A

Q

a

q

2

stx

dc2

"

2

B

R

b

r

3

etx

dc3

#

3

C

S

c

s

4

eot

dc4

$

4

D

T

d

t

5

enq

nak

%

5

E

U

e

u

6

ack

syn

&

6

F

V

f

v

7

bel

etb

'

7

G

W

g

w

8

bs

can

(

8

H

X

h

x

9

ht

em

)

9

I

Y

i

y

10

lf

sub

*

:

J

Z

j

z

11

vt

esc

+

;

K

[

k

{

12

ff

fs

,

<

L

\

l

|

13

cr

gs

-

=

M

]

m

}

14

so

rs

.

 

N

^

n

~

15

si

us

/

?

O

_

o

del

 
 

I primi 32 caratteri e il carattere 127 sono caratteri di controllo:

nul - nullo

soh - inizio della testata

stx - inizio del testo

etx - fine del testo

eot - fine della trasmissione

enq - (enquire) indagine

ack - (acknowledge) riconoscimento

bel - campanello o allarme

bs - backspace

ht - tabulazione verticale

lf - (line feed) alimentazione linea

vt - tabulazione verticale

ff - alimentazione form

cr - (carriage return) ritorno carrello

so - sposta fuori

si - sposta dentro

dle - dati uscita dal link

dc - controllo dispositivo

nak - riconoscimento negativo

syn - attesa sincrona

etb - fine del blocco di trasmissione

can - cancello

em - fine del mezzo

sub - sostituto

esc - (escape) fuga

fs - separatore di fila

gs - separatore di gruppo

rs - separatore di disco

us - separatore di unità

del - (delete) cancella

 

 

Poichè l'insieme dei simboli è ordinato è possibile utilizzare le operazioni di confronto viste in precedenza, ricordandosi però che il confronto avviene utilizzando la tabella, e le due funzioni pred(c) e succ(c). Per distinguere una costante di tipo char da un identificatore di variabile si racchiude la costante tra due apici.
 

a nome variabile
'a' costante a di tipo char
 

Utilizzando la tabella si può verificare che

a. 'A' < 'Z'         b. 'Z' < 'a'         c. '0' < '9'         d. '9' < 'a'

 

Esistono due funzioni che operano sulla tabella dei caratteri e sono ord(c) e chr(i).
 

- ord(c) restituisce il numero d'ordine corrispondente al carattere contenuto nella variabile c.
- chr(i) restituisce se possibile il carattere corrispondente all'intero contenuto nella variabile i.
 

Allora sarà
 

ord('0') = 48 ; ord('A')= 65 ;
chr(91) = [ ; chr(47) = / ;
 

e
 

ord(chr(i)) = i { i variabile di tipo INTEGER }
chr(ord(c)) = c { c variabile di tipo CHAR }
 

Esempi.
 

VAR
c1,c2 :CHAR;
i1 :INTEGER;
b1 :BOOLEAN;
 
c1:='A'; { A c1 assegno la costante A }
c2:=c1; { A c2 assegno il contenuto della variabile c1 }
c1:='9'; { A c1 assegno la costante di tipo carattere 9 }
i1:=9; { A intera i1 assegno la costante intera 9 }
i1:=ord('9')-ord('0'); { A i1 assegno il valore intero 9 }
b1:=c1'7'; { A b1 assegno il risultato del confronto c1'7' }
c1:=succ('A'); { A c1 assegno il carattere B }
c1:=pred('c'); { A c1 assegno il carattere b }
 

Le seguenti istruzioni sono scorrette.
 

b1:=c17;     i1:='7';     i1:=chr(49);     c1:=8;     i1:=c1+c2;
 

4.3.5 Il tipo REAL.

 

Rappresenta un insieme finito di reali. Per il tipo real sono definite le seguenti operazioni:
 

+ addizione
- sottrazione
* moltiplicazione
/ divisione
 

Su variabili di tipo real è possibile operare con i confronti visti in precedenza. E` possibile inoltre assegnare ad una variabile di tipo real una costante integer mentre per il viceversa è necessario utilizzare una delle seguenti funzioni:

i:=round(r); { ad i variabile INTEGER viene assegnato l'intero che meglio approssima r }
i:=trunc(r); { ad i variabile INTEGER viene assegnata la parte intera di r }

Se in una espressione compaiono dei valori real e dei valori integer il risultato dell'espressione sarà real ed i valori integer saranno convertiti implicitamente in real. Questo significa che la seguente assegnazione
 

i:=4.5+3; { i di tipo INTEGER }

è errata perchè il risultato dell'espressione è di tipo real.

Sui real non sono definite le funzioni pred e succ.

 

4.3.6 Rappresentazione dei Real.

 

4.3.6.1 Rappresentazione scientifica.

 

Ogni numero è rappresentabile come prodotto di un numero compreso tra 0 e 1, con la prima cifra dopo la virgola diverso da 0, per una potenza di 10.

Ad esempio.
 

122,34 = 0,12234 * 10^3
0,4567 = 0,4567 * 10^0
-156 = -0,156 * 10^3
0,003 = 0,3 * 10^(-2)

Chiameremo mantissa il valore compreso tra 0 e 1; ogni numero è quindi rappresentato da una terna: segno, mantissa, esponente.
 

122,34 = (+, 0.12234, 3)

La moltiplicazione si ottiene sommando gli esponenti e moltiplicando le mantisse:
 

(+, 0.23, 2) * (+, 0.5, 1) = (+, 0.115, 3)

L'addizione viene svolta in due passaggi: il numero minore viene modificato in modo che l'esponente diventi uguale a quello del numero maggiore e poi si sommano le mantisse:
 

(+, 0.23, 2) + (+, 0.5, 1) =
(+, 0.23, 2) + (+, 0.05, 2) = (+, 0.28, 2)
 

4.3.6.2 Rappresentazione in virgola mobile.

 

La rappresentazione in virgola mobile è una rappresentazione nella quale vengono fissate un numero massimo di cifre per la mantissa e con l'esponente compreso tra -E < esp < E, dove E dipende dall'implementazione.

Negli esempi che seguono il numero di cifre della mantissa è 4. Sorgono alcuni problemi:

1- Numeri diversi possono avere la stessa rappresentazione.
 

123.456 = (+, 0.1234, 3)
123.478 = (+, 0.1234, 3)
 

2- Sommando un numero A con un numero B diverso da zero, il risultato puo' essere uguale ad A.
 

(+, 0.3554, 8) + (+, 0.2, 2) =
(+, 0.3554, 8) + (+, 0.0000, 8) = (+, 0.3554, 8)
 

3- Dati tre numeri A,B,C in generale ((A+B)+C) è diverso da (A+(B+C))
 

A= (-, 0.1, 15) B=(+, 0.1, 15) C=(+, 0.1, 7)
((A+B)+C) = (+, 0.1, 7) -- 1000000
(A+(B+C)) = (+, 0.0000, 15) -- 0
 

4- Dati due numeri A,B in generale A^2 - B^2 è diverso da (A+B)*(A-B)
 

A= (+, 0.3345, 0) B= (+, 0.2925, 0)
A^2 =(+, 0.1118, 0) B^2= (+, 0.8555, -1)
A^2 - B^2 = (+, 0.2625 , -1)
A+B = (+, 0.627, 0) A-B = (+, 0.42, -1)
(A+B)*(A-B) = (+, 0.2633, -1)
 

Possiamo notare come le operazioni con i real non soddisfano le leggi consuete dell'algebra.

Esercizi.

 

1. Rappresentare in binario i seguenti numeri decimali

1- 12d 25d 128d 33d 45d 255d

2- 100d 200d 16d 17d 298d 1024d

3- 256d 196d 75d 512d 99d 257d

4- 111d 63d 64d 65d 1000d 180d

2. Rappresentare in decimale i seguenti numeri binari

1- 110011b 10011101b 1101b 1001b 1001011b

2- 1111b 11001100b 110b 11100b 110011b

3- 111111b 11001111b 10101010b 10011001b 10000000b

4- 110110010b 110011b 10b 1000b 1001b 10001b 1010b

3. Rappresentare i seguenti numeri in complemento a 2 con 8 bit

1- 23d 120d -1d -112d 130d

2- 128d -128d 1d -2d -64d

3- 12d -13d -32d 64d -132d

4- -12d -33d -129d -36d -5d

4. Eseguire le sguenti opreazioni in complemento a 2 con 6 bit

1- -12d + 23d -10d 2- -11d + 20d + 21d

3- 13d + 10d + 20d 4- 20d + 21d - 12d

5- -13d -10d -17d 6- -1d + 3d -7d + 9d -16d

7- 2d -30d + 9d -4d 8- -32d -32d

5. Rappresentare i seguenti numeri in notazione scientifica con mantissa di 5 cifre.

1- 123 456.023 0.00345128 12.00234 9911.102 0.000034512303

2- 4.2345 0.000123 0.8912 1212777555 12.0089 0.00000005689123

3- 0.0023 0.00234587 120001234 3456123 34 0.0003456

4- 0.34512 2345612 0.00034512 0.45612 0.2 0.002 112386341

6. Eseguire le seguenti operazioni in notazione scientifica con mantissa di 3 cifre.

1- 23 + 7.21 2- 15 + 312 3- 0.00345 + 0.00072183

4- 1230045 + 34012 5- 9823 + 68.34 6- 0.000234 + 0.00007812

7- 0.02341 + 0.0099 8- 123.12 + 23.23 9- 12398756 + 186734283

7. Fornire un esempio di numeri in notazione scientifica con 3 bit di mantissa che non verificano le seguenti uguaglianze

1- A * (B + C) = (A * B) + (A * C)

2- (A + (B + C)) + D = ((A + C) + (D + B))

3- (A * A) - (B * B) = (A + B) * (A - B)

8. Fornire un esempio di numeri in notazione scientifica con 4 bit di mantissa che verificano le seguenti uguaglianze

1- ((A + B) + C) = (A + B) con C 0

2- (A * B) = (A * C) con B diverso da C

3- (A + C) = (A + B) con B diverso da C e (A + C) A

 

4.4 Il programma.

 

Dopo aver discusso di alcune delle istruzioni fondamentali del Pascal e dopo aver visto come si definiscono le variabili vediamo ora come comporre in un programma unico tutte queste istruzioni.

Tutti i programmi Pascal sono divisi in tre parti: l'intestazione, la parte dichiarativa e la parte eseguibile.

a- L'intestazione: è una singola istruzione introdotta dalla parola riservata PROGRAM con la quale si assegna un nome all'intero programma. Ad esempio:
 

PROGRAM esempio;

Dopo il nome è possibile indicare da dove debbono essere letti o scritti i dati esterni. Ad esempio:
 

PROGRAM esempio1( INPUT, OUTPUT );

specifica che il programma esempio1 utilizzerà due supporti esterni chiamati INPUT e OUTPUT sui quali saranno compiute le operazioni di ingresso e di uscita dei dati. I due supporti si chiamano standard input e standard output.

b- La parte dichiarativa: vengono descritti tutti gli oggetti che serviranno durante l'esecuzione. Oltre all'elenco delle variabili è possibile definire tipi, costanti e nuovi oggetti chiamati PROCEDURE e FUNCTION che descriveremo in seguito.

Per definire le costanti è sufficiente utilizzare la parola riservata CONST seguita dalla lista delle costanti. Ad esempio:
 

CONST
massimo_intero=32767;
minimo_intero=-32768;
tappo='*';
 

Esiste una costante predefinita, chiamata maxint, che indica il massimo valore intero rappresentabile in una variabile di tipo integer.

Per definire nuovi tipi si utilizza la parola riservata TYPE seguita dalla lista dei tipi. Ad esempio:
 

TYPE
intero=INTEGER;
reale=REAL;
 

c- La parte esecutiva: è delimitata dalle parole chiave BEGIN/END. e contiene le istruzioni che debbono essere eseguite. Ad esempio il seguente programma calcola la potenza n-esima di un numero.
 
 

PROGRAM esp ( INPUT,OUTPUT);
VAR
    base,
    risultato : REAL;
    esponente,
    i :INTEGER;
BEGIN
    WRITE('Inserisci base ');
    READLN(base);
    REPEAT
        WRITE ('Inserisci esponente ');
        READLN(esponente)
    UNTIL esponente = 0;
    risultato := 1;
    FOR i:=1 TO esponente DO
        risultato:= risultato * base;
    WRITELN (' risultato = ', risultato);
END.
 

Esercizi.
 

1. Scrivere in Pascal la seguenti espressioni:

 

            2 a

a.     a + b + ------------------------------------

c

b * c + -------------------------

e

d + ------------------

f + g

 

2. Indicare quali tra le seguenti espressioni sono sintatticamente corrette ed indicarne il tipo, sapendo che le variabili in esame sono così definite:
 

VAR

i1, i2, i3:INTEGER;
r1, r2, r3:REAL;
b1, b2, b3:BOOLEAN;
a1 + a2 * i1 
i1 MOD( i2 + r3 )
a1:=a2 AND b1
i1 + i2 / i3
i1 DIV i2 AND b3
i1 - round( i2 + r1 )
r1 - r2 + trunc( i3 )
b1 = b2
i1 DIV trunc( r1 )
i1 / i2 MOD i3
b1 b2 AND b3
i1 DIV i2 / r3

3. Con le variabili definite nell'esercizio precedente indicare quali tra le seguenti sequenze di caratteri sono istruzioni.

r1=r2;

2:=i1;

BEGIN i1:=3 END

IF r1:=2 THEN WRITE( a );

WHILE r10 DO;

IF 2=3 THEN WRITE( 2 );

REPEAT UNTIL b1;

IF r1 < r2 THEN;

IF i1i2 THEN ELSE;

FOR r1:=1 TO 100 DO r3:=r3+r1;

FOR i1:=1 TO 100 DO;

b1:=b2 AND (r1 r2);

FOR i1:=1 TO 10 DO

i1:=i1+1;

REPEAT

IF i1i2 THEN i1:=1

UNTIL b1;

WHILE true DO i1:=i1+1;

 

4. Per ogni esercizio indicare la risposta esatta supponendo che:

VAR

r1, r2, r3, r4:REAL;
b1, b2, b3, b4:BOOLEAN;
c1, c2, c3, c4:CHAR;
i1, i2, i3, i4:INTEGER;
  
  1. REPEAT READ( i1 )
    UNTIL i10;
    WRITELN( i1 );
  2. Se in Input vengono forniti i seguenti valori: -1 0 3 5

    Il risultato sarà:

    a) -1         b) 0         c) 3         d) 5

  3. b1:=FALSE; c1:='a';
  4. WHILE b1 AND c1='a' DO
    READ( c1 );
    WRITE( c1 );

    Se in Input vengono forniti i seguenti valori: a b c d

    Il risultato sarà:

    a) a         b) b         c) c          d) d

     

  5. READ( i1, i2 );
    b1:=i1=i2;
    IF NOT b1 THEN WRITE i1;
    WRITE( i2 );
  6. Se in Input vengono forniti i seguenti valori: 1 1 2 3 3

    Il risultato sarà:

    a) 1 2         b) 1 1         c) 2 3         d) 3 3 e) 1 f) 3

     

  7. i1:=1; r1:=0;
    WHILE i1<3 DO BEGIN
            r1:=r1+i1;
            i1:=i1+1;
    END;
    WRITE( i1, r1 );
  8. Il risultato sarà:

    a) 1 0 b) 4 6 c) 3 3 d) 3 6 e) 3 2

     

  9. r1:=0;
    READ( i1, i2 );
    FOR i1:=1 TO i2 DO
        r1:=r1+i1;
    WRITE( r1 );
  10. Se in Input vengono forniti i seguenti valori: 3 3

    Il risultato sarà:

    a) 0         b) 3         c) 6         d) 10         e) 7

     

  11. r1:=1;
    REPEAT
            READ( r2 );
            r1:=r1*r2;
    UNTIL r2=0;
    WRITELN( r1 );
  12. Se in Input vengono forniti i seguenti valori: 3 2 4 0 1 2

    Il risultato sarà:

    a) 24         b) 0         c) 2         d) 1         e) 48

     

  13. r1:=0; r2:=0;
    READ( i1 );
    WHILE i1=0 DO
            IF (i1 MOD 2)=0 THEN r1:=r1+i1
            ELSE r2:=r2+i1;
    WRITE( r1, r2);
  14. Se in Input vengono forniti i seguenti valori: 3 2 4 6 5 0 1

    Il risultato sarà:

    a) 12 8         b) 12 9         c) 0 0         d) 0 3

     

     

  15. i1:=3; i2:=0;
    FOR i1:=2 DOWNTO 1 DO BEGIN
            WRITE( i2 );
            i2:=i1+1;
    END;
  16. Il risultato sarà:

    a) 0 3 2         b) 3 2 1         c) 0 3         d) 4 3 2 1         e) 0 4 3 2

     

  17. i1:=0; i2:=0 c1:='A'; c2:='Z';
    READ( i1, i2, c1, c2 );
    b1:=i1<i2; b2:=c1c2;
    b3:=b1 AND b2;
    IF b3 THEN WRITE( i1, c1 )
    ELSE WRITE( i2, c2 );
  18.  

    Se in Input vengono forniti i seguenti valori: 3 4 a Z

    Il risultato sarà:

    a) 3 a         b) 4 Z         c) 0 A         d) 0 Z

     

     

  19. READ( i1, i2 );
     i3:=1;i5:=i1;
    WHILE i3<i2 DO BEGIN
            i4:=0;
            WHILE i4<i5 DO BEGIN
                i4:=i4+1;
                i1:=i1+1
            END;
            i3:=i3+1;
    END;
    WRITE( i1, i2 );

Se in Input vengono forniti i seguenti valori: 4 3

Il risultato sarà:

a) 12 3         b) 9 3         c) 4 3         d) 0 3         e) 16 3

 

5. Risolvere in linguaggio Pascal i seguenti problemi.

a. Utilizzando addizione e sottrazione moltiplicare tra loro due numeri interi positivi.

b. Utilizzando addizione e sottrazione calcolare la divisione intera tra due numeri interi positivi.

c. Utilizzando solo addizione e uguaglianza verificare se x y dove x e y sono numeri interi positivi.