HACKING 120% {Hacking, programmazione, computer & molto altro}

Votes taken by Revø

view post Posted: 21/8/2013, 15:58     +1presentazione - Presentazioni
Non mi era mai capitato di leggere un messaggio del genere.
I requisiti per entrare in questo forum sono saper accendere il PC e saper usare mouse e tastiera

Tutti gli utenti sono venuti qui e sono entrati nella community con lo scopo di imparare e non di insegnare, indipendentemente dalle conoscenze che avevano prima di entrare...

Resta :smile: nel peggiore dei casi saresti un'utente inattivo ;)

Pace :)
view post Posted: 17/8/2013, 22:44     +1[Supporto] Hacking - Supporto
CITAZIONE (Sn0w* @ 17/8/2013, 01:16) 
Anyway vi ringrazio tutti per le risposte ^^ questa community mi stà dando un grosso aiuto spero d poterlo ricambiare, nel mio piccolo per adesso con la guida per creare videogiochi :D

We're all here to help each other :smile:
Non sentirti in dovere di ricambiare a tutti i costi, se ti senti di condividere qualcosa (guide ecc) fallo e basta :)

Pace
view post Posted: 8/7/2013, 12:40     +2[Assistenza] Mouse e tastiera smettono di fungere - Supporto
io spengo
tu spegni
egli spegne
noi spegnamo
voi spegnete
essi spengono

Bella Nik :D

CITAZIONE
praticamente quando spenge il pc si azzerano tutti i driver, ogni volta che spenge.
view post Posted: 26/2/2013, 15:33     +1Identificativi Thread - Regolamento e Annunci
Ciao a tutti! Come sapete, è sempre stata di nostro interesse la pulizia e la tutela di questo forum.
Da quello che noi dello staff vediamo ogni giorno, l'ordine sta calando: sezioni piene di discussioni inutili, titoli inappropriati e altro.

Tutti questi fattori abbassano il livello di attendibilità che questo forum si è guadagnato in tanto tempo.

Tutti noi vogliamo tenere il forum in buone condizioni, no?

Per questo, lo Staff ha deciso di introdurre un nuovo metodo di postare le discussioni:
quando andrete a creare un nuovo thread, dovrete stare attenti che nel titolo ci sia il giusto identificativo per ciò che andrete a postare.

Esempio.
[tutorial]Come assemblare un pc.

Così facendo chi leggerà quel titolo capirà già che in quella discussione c'è un tutorial e quindi se non gli serve, non entra.

Il fine di questo nuovo metodo è quello di rendere la navigazione nel forum più sicura e diretta.

Ecco degli identificativi:
[tutorial]
[news]
[assistenza]


p.s. Naturalmente potrete usarne anche altri o dei sinonimi... l'importante è che ci sia almeno un identificativo nel titolo della discussione
p.p.s. Per chi non dovesse seguire queste direttive più volte anche dopo molti richiami verranno presi dei provvedimenti

/*questi identificativi sono stati scelti dopo aver valutato il contenuto della maggior parte delle discussioni in questo forum*/

Pace :truzzo:

Lo Staff.
view post Posted: 22/2/2013, 23:12     +1Richiesta grafica - Grafica
Se prendo solo testa e cartella e allungo l'immagine esce un alieno xD in pratica dovrei allngare a 200 O.O ... vabbe vedo che posso fare ;)

13ynk8p6tfq1f21jvi2qnzwvp
view post Posted: 17/2/2013, 23:43     -1Domande varie - Supporto
CITAZIONE (Mr 5 @ 17/2/2013, 17:40) 
No, se posso, perché me lo chiedi?

In pratica se andavi a scuola e frequentavi l'istituto tecnico con ramo di informatica avresti imparato MOLTE cose... cmd, programmazione con diversi linguaggi e altri cazzi utili ;)
view post Posted: 12/2/2013, 13:15     +2[Guida] Linguaggio Pascal - Pascal & Delphi

Guida approfondita sul Pascal



Oggi ho deciso di postare questa guida dettagliata che seguii qualche anno fa per imparare a programmare in Pascal. Molti dicono che questo sia un linguaggio obsoleto, è vero, però è ottimo per entrare nell'ottica della programmazione per chi cominciasse da zero.

Siccome sarà utile che facciate degli esercizi su di ogni argomento è opportuno che scarichiate un compilatore Pascal. Potete scarice Turbo Pascal 7.0
(QUI) oppure Bloodshed DevPascal (QUI).
Tutti i codici sorgenti descritti in questa guida sono compilati usando un compilatore Turbo Pascal 7.0 e potrebbero essere incompatibili con alcune librerie del Bloodshed DevPascal.

Termini specifici

Prima di iniziare la guida vera e propria è doveroso dare una piccola descrizione di alcuni termini usati nel suo corso che non tutti magari conoscono:

File: area di memoria contenente dati;

Estensione: è il tipo di file. Infatti un file di testo, non è la stessa cosa di un file musicale. L’estensione è la sigla che li contraddistingue, che di solito è formata da 3 lettere dopo un punto alla fine del nome.

Codice sorgente o sorgente: è il file in cui viene scritto il programma con un linguaggio di programmazione;

Compilatore: è il software che converte le istruzioni contenute nel sorgente, sottoforma di testo, in un programma vero e proprio, un’applicazione in formato eseguibile (*.exe o altre volte anche *.com).

Parola riservata: di solito le parole riservate vengono evidenziate dal compilatore in modo differente rispetto alle altre. Infatti queste parola sono importanti perchè usate per definire delle istruzioni particolari. Pertanto il loro nome è inutilizzabile come variabile.

Libreria: insieme di metodi, istruzioni, operatori, variabili, costanti, classi, procedure o funzioni raccolte in un solo file, che può essere richiamato da un programma Pascal per usufruire delle operazioni che in esso sono descritte;

Implementazione: implementare una procedura o una funzione vuol dire definirne il corpo, ossia le istruzioni e le operazioni che la compongono e ne definiscono il funzionamento.


Intestazione.

Un programma scritto in Pascal deve avere delle parti essenziali per il suo funzionamento. Ognuna di queste parti contiene istruzioni particolari. L'intestazione, in particolare è una delle parti più importanti.
Vediamo un esempio dell'intestazione di un programma in Pascal:
Codice sorgente
________________________________________
program MioProgramma;
________________________________________


Allora: la parola program è una parola riservata che indica al compilatore il tipo di file prodotto in output. In particolare indica che una volta compilato, il sorgente dovrà essere un programma eseguibile. La parola 'MioProgramma' non è importante, ma ha un fine puramente descrittivo: infatti ha la funzione di ricordare al programmatore di che programma si tratta fornendone il titolo. Benchè non essenziale, dopo 'program' deve sempre essere dichiarato il nome del programma.
Codice sorgente
________________________________________
unit MiaUnita;
________________________________________


La parola riservata unit indica al compilatore che il prodotto in output sarà una libreria. Per ulteriori informazioni vedere la parte dedicata alla scrittura delle librerie.


Dichiarazione

In questa parte vengono definite le librerie, le variabili ed eventualmente le procedure e le funzioni.
La libreria essenziale e più usata si chiama crt.

Le variabili sono aree di memoria in cui sono posti valori numerici o di parole (stringhe). Esistono parecchi tipi di dati, qui c’è l’elenco completo dei più conosciuti:
Byte = occupa 1 byte e può assumere valori da 0 a 255;
Shortint = occupa 2 bytes e può assumere valori da -128 a 127;
Word = occupa 2 bytes e può assumere valori da 0 a 65535;
Integer = occupa 2 bytes e può assumere valori da -32768 a 32767;
Longint = occupa 4 bytes e può assumere valori da -2147483648 a 2147483647;
Real = occupa 6 bytes e può assumere valori da -2,9e+39 a 1,7e+38 (11-12 cifre decimali);
Boolean = occupa 1 bit e può assumere due valori, true o false;
Char = occupa 1 byte e può assumere il valore di un carattere;
String = occupa un numero variabile di bytes (minimo 10), che varia a seconda della sua lunghezza. Può contenere sequenze di caratteri (frasi);
Text = serve per modificare i file (assume valori solo tramite la procedura assign).

Un esempio di dichiarazione:
Codice sorgente
________________________________________
uses crt;
var carattere:char;
numero:integer;
________________________________________


La parola riservata uses indica al compilatore quali libreria includere, mentre la prola riservata var indica al compilatore che dopo di essa si comincerà a dichiarare delle variabili, quindi di tenersi pronto per allocare della memoria (ossia disporre un pezzo della memoria RAM per le variabili).


Esecuzione
In questa parte viene definito il programma principale, usando istruzioni ed operazioni particolari.
Prima di cominciare la guida vera e propria, vorrei soffermarmi un attimo sulle procedure e le funzioni, mediante le quali il programmatore impartisce ordini al cmputer.

Una procedura è un insieme di istruzioni che il computer esegue. Per funzionare può avere dei parametri oppure no. Un esempio di procedura:
Writeln(x,y,z...) : è una procedura che accetta un numero qualsiasi di parametri;
OutText(s:string) : è una procedura che accetta un parametro di tipo stringa;
Nosound : è una procedura che non accetta nessun parametro.

Una funzione è una procedura che restituisce un valore:

Sqrt(x:real):real : è una funzione che accetta un parametro di tipo real e restituisce un valore dello stesso tipo;
Eof(t:text):boolean : è una funzione che acceta un parametro text e restituisce un valore booleano.

Ora, le procedure e le funzioni sono il mezzo mediante il quale viene scritto un programma. Per scrivere messaggi sullo schermo, per leggere un file o per cncellare dei dati, per calcolare la radice quadrata, il logaritmo o il coseno di un numero si useranno delle procedure o delle funzioni.
Codice sorgente
________________________________________
Program PrimoProgramma;
Uses Crt;
Var a,b,c:integer;

begin
clrscr;
write(‘Inserire un numero intero: ‘);
readln(a);
write(‘Inserire un altro numero intero: ‘);
readln(b);
c:=a+b; (*Somma dei numeri*)
writeln(‘La soma di ‘,a,’ e ‘,b,’ è : ’,c);
readln
end.
________________________________________


Non è difficile, specialmente se si conosce l’inglese, ma vediamo di vedere nel dettaglio cosa significa:

Program PrimoProgramma; : è un’istruzione che serve al compilatore per determinare il tipo di file prodotto dalla compilazione (in questo caso un eseguibile, *.exe). Il nome che viene dopo non ha nessuna importanza, ma ci aiuta solo a ricordare a cosa serve quel programma.

Uses Crt; : la parola riservata Uses, indica al compilatore quale librerie si devono usare per la compilazione. In pratica, una libreria, come suggerisce il nome, è un insieme di metodi, procedure e funzioni che vengono usate per scrivere il programma (come write o read). Per la scrittura di una libreria, vedi oltre. In questo caso, si usa la libreria Crt, essenziale.

Var a,b,c:integer; : la parola riservata Var serve per dichiarare le variabili. Dopo di essa va inserito uno spazio e poi il nome della variabile (va bene qualsiasi nome, senza restrizioni sulla lunghezza; può contenere caratteri, numeri o underscore; non può iniziare con un numero). Dopo il nome della stessa, viene posto un ‘:’ e poi il tipo di dato (in questo caso integer, ma avremmo potuto mettere anche real o word, per esempio). E’ possibile dichiarare più variabili insieme, sempre dello stesso tipo, semplicemente separandole con una virgola.

begin : va sempre messo dopo le variabili (o la dichiarazione di procedure o funzioni, ma vedremo in seguito) ed indica l’inizio del programma (per chi conosca il C, equivarrebbe ad una ‘{’).

clrscr; : pulisce lo schermo da qualsiasi carattere.

write(‘Inserire un numero intero: ‘); : scrive sullo schermo la frase indicata fra gli apici. Quindi, quando avrete bisogno di scrivere qualcosa userete write() o writeln(), mettendo tra le parentesi la frase che volete scrivere, racchiudendola fra apici.

readln(a); : aspetta che l’utente digiti un input da tastiera, seguito da un invio. Tutto ciò che si preme, viene memorizzato nello spazio di memoria indicato dalla variabile a, mediante una semplice pressione del pulsante invio. Quindi, quando vorrete memorizzare un dato da tastiera, utilizzerete read() o readln(), mettendo tra le parentesi il nome di una variabile.
A differenza di read, readln manda il cursore a capo.

c:=a+b; : esegue l’operazione aritmetica di somma fra a e b e assegna alla variabile c il valore risultante. Bisogna notare che l’operatore di assegnamento è ‘:=’. Si possono eseguire tutte le operazioni matematiche:
+ somma * moltiplicazione
- sottrazione mod modulo
/ divisione div divisione intera

(*Somma dei numeri*) : questa non è un istruzione, ma viene definito ‘commento’. E’ esclusivamente facoltativo, non influisce in nessun modo sul programma, serve solo a rendere più chiaro il codice sorgente.

writeln(‘La somma di ‘,a,’ e ‘,b,’ è : ‘,c); : una normale istruzione writeln, ma è da notare che è possibile scrivere a video anche il contenuto delle variabili, semplicemente chiudendo gli apici e racchiudendo fra due virgole il nome della variabile.

readln : ferma il programma in attesa della pressione del pulsante invio (senza ; ).

end. : indica al compilatore che il programma è terminato.

Come avrete certamente notato, dopo ogni istruzione è presente un ‘;’, che serve per separare le stessa l’una dall’altra. Volendo si potrebbero scrivere anche più istruzioni sulla stessa riga.
Codice sorgente
________________________________________
Program password;
Uses Crt;
Var parola:string[40];
begin
clrscr;
writeln(‘Immettere la password: ‘);
readln(parola);
if parola=’Pascal’ Then (*Se parola=Pascal, allora...*)
writeln(‘Bravo!’)
else (*Altrimenti, esegui questo:*)
begin
TextColor(5);
TextBackGround(15);
writeln(‘Sbagliato!’);
end;
readln
end.
________________________________________


Come si vede, il costrutto if…then…else, corrisponde all’italiano se…allora…altrimenti. Serve per far eseguire al programma un 'controllo': in questo caso, il programma deve 'controllare' se la parola immessa è uguale è 'Pascal' ed in quel caso, eseguire un blocco di istruzioni.
Il costrutto If è tipico di tutti i linguaggi di programmazione ed è molto utile: è quasi impossibile trovare un programma senza almeno un If. E' la struttura di controllo per eccellenza.
In questo caso, dopo if va messa una espressione di comparazione. Le più frequenti sono:
= uguale >= maggiore o uguale <= minore o uguale <> diverso.
Dopo Then viene un ciclo di istruzioni, che, se composto da una solo funzione, non necessita di un begin…end (ossia la dichiarazione di un blocco di istruzioni). Prima di else, che si può anche tralasciare, non ci vuole mai il punto e virgola. Il ciclo di istruzioni dopo else ha la stessa composizione di quello che succede al Then, ma alla fine è di dovere un ;.
In questo esempio ho usato anche le istruzioni TextColor() e TextBackGround(), che servono, rispettivamente, per cambiare il colore al testo o allo sfondo del testo (5=rosso, 15=bianco).


If nidificati
Codice sorgente
________________________________________
Program password;
Uses Crt;
Var parola:string[40];
begin
clrscr;
writeln(‘Immettere una parola: ‘);
readln(parola);
if parola<>’Pascal’ Then
if parola=’Ciao’ Then
writeln(‘Ciao pure a te!’)
else
writeln(‘Non saluti?’)
else
begin
TextColor(5);
TextBackGround(15);
writeln(‘Giusto!’);
end;
readln
end.
________________________________________


Piccola osservazione prima di iniziare: il numero indicato fra parentesi quadre accanto alla parola string indica che le variabili stringa dichiarate con quel tipo non possono avere più di 40 caratteri. In genere, si usa questo procedimento per restringere il numero di bytes occupati per un programma, dato una stringa normale contiene fino a 255 caratteri.
Gli if cosiddetti nidificati sono solo delle strutture if dentro alter strutture if. Una struttura iterativa non ha bisogno della dichiarazione di un blocco di istruzioni (begin…end) e mantiene le stesse regole del punto e virgola. Nonostante ciò, non è assolutamente sbagliato scrivere:
Codice sorgente
________________________________________
if parola<>’Pascal’ Then
begin
if parola=’Ciao’ Then
writeln(‘Ciao pure a te!’)
else
writeln(‘Non saluti?’);
end
else
begin
TextColor(5);
TextBackGround(15);
writeln(‘Giusto!’);
end;
________________________________________


Connettivi logici

Con la struttura if…then…else, eì possibile usare i connettivi logici ‘e’, ‘o inclusivo’ e ‘o esclusivo’. Ogni condizione deve essere racchiusa tra parantesi. Se, per esempio, scriviamo:
Codice sorgente
________________________________________
if (a=b) and (b<c) then
... (*Blocco di istruzioni numero 1*)
else
begin
if (a<b>a) then
... (*Blocco di istruzioni numero 2*)
if (c>a) xor (b=c) Then
... (*Blocco di istruzioni numero 3*)
end;
________________________________________


Il blocco di istruzioni 1 viene eseguito se e solo se a è uguale a b e b è minore di c, ossia quando entrambe le espressioni sono vere.
Il blocco di istruzioni 2 viene eseguito se a è minore di b o c è maggiore di a, ossia quando almeno una delle espressioni è vera.
Il blocco di istruzioni 3 viene eseguito quando una e una soltanto delle espressioni è vera: se entrambe sono vere, il ciclo di istruzioni non viene eseguito.


Altri operatori e connettivi logici

Esistono altri operatori rispetto a quelli visti prima, qui ce n’è un breve elenco:
not : preposto ad un valore booleano o ad un’espressione, restituisce come valore il contrario dell’espressione designata.
Codice sorgente
________________________________________
var t:boolean;
...
t:=not true; (*t=false*)
if not (a>b) then (*if (a<b>b then*)
...
if (a>b) and not (b=c) (*if (a>b) and (b<>c) then*)
________________________________________


shr e shl: sono chiamati shift. Operano, cioè uno spostamento verso destra o verso sinistra di x bit (vedi appendice 1).

2 shr 1 = 4
2 shl 1 = 1
8 shl 2 = 2
Case…of
Il costrutto case…of prende in esame una variabile e, per ogni valore specificato esegue un’istruzione diversa. Supporta l’else e vuole l’end alla fine. La variabile non deve essere di tipo string. E’ possibile l’inserimento di un or:
Codice sorgente
________________________________________
Program Esempio;
Uses Crt;
Var n:byte;
c:word;

begin
clrscr;
write(‘Inserisci un numero: ‘);
readln(n);
case n of
1: writeln(‘E’’ stato premuto il pulsante 1’);
2: begin
sound(440);
delay(1000);
nosound;
end;
3 or 4 or 5: write(‘Il numero premuto è fra 3 e 5’);
else
begin
c:=sqr(n);
writeln(c,’ è il quadrato di ‘,n);
end;
end;
readln
end.
________________________________________


Non è molto difficile, vero? Per prima cosa si considera n: se è uguale a 1 scrive una frase (da notare che, per scrivere un apostrofo bisogna inserire due apici, perché altrimenti si terminerebbe la frase al primo); se n è uguale a 2, emette un suono (la procedura sound(x) emette un suono di x hertz, la procedura nosound ferma il suono e la procedura delay(x) genera un’attesa di x millisecondi); se n è uguale a 3, a 4 o a 5, scrive un’altra frase; se n non è nessuno dei valori specificati, alla variabile c viene assegnato il valore di x2 (la funzione sqr(x) ritorna x2) e poi viene stampata a video una frase che esplicita il valore di c; l’end prima di readln termina il ciclo case...of ed è obbligatorio anche se non c’è else.

Questa istruzione è molto utile quando bisogna considerare valori diversi di una stessa variabile senza dover usare moltissimi if...then...else. In particolare, il case...of può essere usato con un buon profitto nella scrittura di piccoli giochi come il tetris o pacman in cui bisogna far corrispondere alle freccette direzionali un movimento (in questo caso si prende una variabile char e si considera il suo valore per ogni freccia direzionale).

E' stato possibile notare, come avrete certamente visto, che ogni volta che in corrispondenza di un valore si devono eseguire più operazioni è obbligatorio specificare il blocco di operazioni con un begin che termina con un end;. In generale, nel Pascal, quando si deve fare eseguire un blocco di istruzioni, lo si chiude sempre tra un begin ed un end;. Il programma principale, infatti è racchiuso tra begin ed end..
Codice sorgente
________________________________________
Program Esempio2;
Uses Crt,WinDos;
Var nome1,nome2,stringa:string;
file1,file2:text;

begin
clrscr;
write(‘Inserire il nome di un file: ‘);
readln(nome1);
write(‘Inserire il nome del file copia: ‘);
readln(nome2);
Assign(file1,nome1);
Assign(file2,nome2);
Reset(file1);
Rewrite(file2);
repeat
readln(file1,stringa);
writeln(file2,stringa);
until eof(file1);
Close(file1);
Close(file2);
writeln(‘Copia completata!’);
readln
end.
________________________________________


Bene, questo programma non è di immediata comprensione, poiché contiene un concentrato di procedure e regole nuove non indifferente. Procediamo con calma:

Assign(nome1,file1); : questa procedura assegna alla variabile file1 di tipo text il nome del file contenuto nella stringa nome1.
Per questo, è doveroso aprire una parentesi su come Pascal legge i nomi dei file: innanzitutto, un nome può essere composto da al massimo 8 caratteri, estensione esclusa; se il nome supera gli 8 caratteri viene troncato a 6 e si aggiunge un ‘~1’ (il codice ASCII di ~ è 126). Perciò il nome ‘testouno.txt’ è giusto e viene mantenuto così; ‘testoquattro.txt’ è sbagliato e il compilatore vi manderà un messaggio di errore (error 2: File not found); ‘testoq~1.txt’ è la versione giusta dell’esempio precedente: i caratteri vengono troncati a 6 e aggiunto un ‘~1’. Inoltre, il nome può contenere anche l’indirizzo completo di un file, dove ogni cartella deve sottostare alla legge degli 8 caratteri, perciò: ‘C:\Documents and settings\Proprietario\Fileone.txt’ è sbagliato, mentre ‘C:\Docume~1\Propri~1\Fileone.txt’ è giusto.
Per non convertire tutti i nomi a mano, potete scaricare il codice sorgente vb nella sezione Sorgenti->VB.NET, che contiene delle funzioni vb per convertire il nome normale di un file in nome corto.

Reset(file1); : l’istruzione reset(x), dove x è una variabile inizializzata con Assign e di tipo text o file, serve per aprire il file x, in vista di operazioni di lettura/scrittura su di esso.

Rewrite(file2); : valgono le stesse regole di reset. Rewrite(x:text o file) è una procedura che crea un nuovo file x (se non è specificata la directory nel suo nome, viene creato nel path corrente). Se esiste già un file di nome x, lo sovrascrive.

repeat...until eof(file1); : ripete un ciclo di istruzioni finché l’espressione indicata dopo until è vera. Nel nostro caso, il programma continua a leggere, riga per riga, ogni sequenza di caratteri contenuta in file1 e la copia in file2, finché la variabile reimpostata eof (che significa End Of File; supporta solo parametri di tipo text o file) non è vera (se non si mette un segno di comparazione, il compilatore sottintende un ‘=true’), e quindi il file da cui leggere è al termine.

Close(file1); : la procedura close chiude un file.

Questo programma è già di un livello più alto: meriterebbe uno studio più accurato per capire il funzionamento, da parte del lettore.

Come si è ben visto, il ciclo repeat...until serve per ripetere un istruzione o un blocco di istruizioni fino a che una condizione non è vera: come avrete sicuramente notato, in questo caso non serve racchiudere il blocco di istruzioni fra un begin ed un end, poichè i confini del blocco sono già repeat e until.
Un ultima osservazione: si può trovare anche un ciclo repeat...until senza istruzioni, così:
Codice sorgente
________________________________________
(*ripete un ciclo di istruzioni vuoto finchè non viene premuto un pulsante*)
repeat until keypressed;
________________________________________


Anche se è un caso usato non molto spesso, è giusto saperlo.

Nelle strutture iterative, ossia le istruzioni che fanno ripetere sempre uno stesso blocco di istruzioni un certo numero di volte o finchè una condizione è vera, è opportuno controllare sempre che le condizioni di uscita siano giuste. per esempio:
Codice sorgente
________________________________________

Program CicloInfinito;
Uses crt;
var n:longint;

begin
clrscr;
writeln('Inserire un numero: ');
readln(n);
repeat
n:=n+2;
until n mod 2=0;
readln
end.
________________________________________


Come si vede, viene letta una variabile longint n che viene aumentata di 2 fino a che il resto di n/2 è 0. Ma se n è dispari il ciclo non finirà mai, in quanto n è sempre dispari e perciò n/2 dà come resto sempre 1.
E' bene stare in guardia dai cicli infiniti, sebbene qualche volta possano essere utili.

Per esempio, PRobot è un programma, che forse qualcuno di voi conoscerà, che permette di programmare un robot virtuale con il linguaggio Pascal e di farlo poi combattere. Ecco, in questo case si deve usare un ciclo infinito con molte istruzioni if al suo interno:
Codice sorgente
________________________________________
repeat
(*ciclo di istruzioni*)
if ... then
...
...
until false;
________________________________________


Il codice ripete sempre il ciclo finchè false non è uguale a true, il che non può mai accadere, in quanto falso è sempre diverso da vero.
Anche se casi border-line, può essere utile conoscerli.
Codice sorgente
________________________________________
Program esempio3;
Uses Crt;
Var x,y:word;

begin
clrscr;
write(‘Inserire due coordinate: ‘);
readln(x,y);
while (x<>0) and (y<>0) do
begin
read(x,y);
gotoxy(x,y);
write(‘(‘,x,’;’,y,’)’);
end;
readln
end.
________________________________________


Questo programma legge da tastiera due coordinate, sposta il cursore a quelle date coordinate e scrive in quel punto le ascisse e le ordinate tra parentesi, separate da un punto e virgola.
Il ciclo si ripete ogni volta che la condizione indicata è vera: in questo caso quando sia x che y sono diversi da 0.
La procedura gotoxy(x,y:word) sposta il cursore alle coordinare (x;y) sullo schermo.
In pratica, scrivere:

while (x<>0) and (y<>0) do
begin
...
end;

è come scrivere:

repeat
...
until (x=0) and (y=0);

Anche con while è opportuno stare attenti ai cicli infiniti e bisogna notare che con il while è necessario inlcudere il blocco di istruzioni fra begin ed end;.
Codice sorgente
________________________________________
Program Esempio4;
Uses Crt;
Var soldi,incremento,percentuale:longint;
anni,i:word;

begin
clrscr;
write(‘Inserire l’’ammontare attuale del denaro: ‘);
readln(soldi);
write(‘Inserire l’’interesse mensile del denaro: ‘);
readln(percentuale);
write(‘Inserire il numero di anni: ‘);
readln(anni);
for i:=1 to anni do
begin
incremento:=soldi*percentuale/100;
soldi:=soldi+incremento;
end;
write(‘Fra ‘,anni,’ anni possederai ‘,soldi,’ euro.’);
readln
end.
________________________________________


Questo programma è molto più alla vostra portata.
Iniziamo subito con il dire che, dopo la parola for, ci vuole l’assegnamento ad una variabile di un valore (in questo caso i:=1). Questa stessa variabile verrà incrementata automaticamente dal computer ad ogni step e, una volta uguale al numero (o alla variabile) dopo il to (in questo caso anni), il ciclo terminerà.
L’incremento è la percentuale detta dell’ammontare totale (incremento:soldi=percentuale:100) ed è stato calcolato mediante una semplice proporzione.
Da notare è anche il fatto che il valore di una variabile può essere incrementato anche usando la stessa variabile come riferimento. Infatti l’algebra non permetterebbe espressioni del tipo x=x+q, perché, risolvendo l’equazione, si otterrebbe 0=q e sarebbe (con q diverso da 0) una cosa assurda (se invece q fosse 0, verrebbe x=x, che è abbastanza ovvio). Il Pascal invece, come del resto tutti gli altri linguaggi, permette questa sintassi, molto comoda (anche se non la migliore, infatti, linguaggi di alto livello come il C++ e il Vb.Net, nonché il Java, hanno una sintassi ancora più breve, x+=q, che equivale a quanto scritto in precedenza).
Tornando a noi, il ciclo for...to...do ripete un blocco di istruzioni un numero determinato di volte, ragion per cui, sono assolutamente vietati valori reali decimali prima e dopo il to.
In pratica, scrivere:

For i:=5 to n do
begin
...
end;

equivale a scrivere:

i:=5;
repeat
...
i:=i+1;
until i=n+1;

oppure:

i:=5;
while i<n>26 then
goto caso1
else
goto caso2;

caso1: begin
write(‘Inserisci un altro valore intero: ‘);
read(b);
if b>90 then
goto caso1
else
goto caso2;
end;
caso2: begin
write(‘Inserisci un altro valore intero: ‘);
read(a);
if a<87 then
goto caso1;
end;
readln
end.
________________________________________


Questo è un programma che non ha molto senso, ma illustra bene il costrutto goto. Analizziamo.
Innanzitutto, le label (cioè le etichette) vanno dichiarate nella parte relativa alle variabili, con la seguente sintassi:

label <nome1>,<nome2>,...,<nomen>;

Una volta dichiarate, potranno essere usate. E’ importantissimo che le label si trovino nello stesso segmento di codice in cui si trova la procedura goto, poiché non si può balzare dentro altre procedure o funzioni.
La label si dichiara scrivendone il nome, seguito da un punto e virgola, dopo il quale si pone il codice da eseguire.
In sostanza il programma fa questo: se a, introdotto da tastiera, è maggiore di 26, salata alla label caso1, altrimenti alla label caso2; nella label caso1, se b, introdotto da tastiera è uguale a 90, ritorna indietro a ricomincia la stessa label, altrimenti, salta alla label caso2; nella label caso2, se a, introdotto da tastiera, è maggiore o uguale a 87, allora il programma termina, altrimenti salta alla label caso1.
Le librerie sono raccolte di metodi, procedure e funzioni, compilate in estensione *.tpu (turbo pascal unit). La struttura di una libreria è questa:
Codice sorgente
________________________________________
Unit <nome>;

interface

Uses Crt,<altre>;

<dichiarazioni>

implementation

Uses Crt,<altre>;
<dichiarazione>

end.
________________________________________


Questo argomento è un po’ più complesso, ma vediamo un esempio:
Codice sorgente
________________________________________
Unit Esempio;

interface
Uses Crt;

const Nome_corto:byte=1;
Senza_spazi:byte=2;

function Modifica_stringa(modo:byte;stringa:string):string;

implementation
Uses Crt;

function Modifica_stringa;
begin
if modo=Nome_corto Then
begin
if Length(stringa)>8 then
begin
delete(stringa,7,Length(stringa)-7)
stringa:=concat(stringa,’~1’);
end;
Modifica_stringa:=stringa;
end
else
begin
while Pos(‘ ‘,stringa)>0 do
delete(stringa,Pos(‘ ‘,stringa),1);
Modifica_stringa:=stringa;
end;
end;

end.
________________________________________


A prima vista potrebbe sembrare complicato, e in effetti lo è. Esaminiamo con calma:

Unit Esempio; : la parola riservata unit indica al compilatore che questo codice sorgente è una libreria (e darà origine ad un file di estensione *.tpu, ossia una Turbo Pascal Unit). Questa volta, però, è importante che il nome che segue ‘unit’ sia uguale al nome con cui il file contenete il codice è salvato (per esempio, se scrivete Unit Ciao; , il file che contiene il codice sorgente sarà Ciao.pas).

interface : come suggerisce il nome, la parte che segue questa parola riservata e che viene prima di implementation, è l’interfaccia. In questo segmento di codice, si possono dichiarare le costanti e le variabili che potranno essere usate al di fuori della libreria. Inoltre, l’interfaccia può contenere, opzionalmente, un prospetto di tutte le procedure e le funzioni scritte nella parte di implementazione. Infatti, dopo, per scrivere il corpo della procedura o funzione, useremo solo il suo nome, senza bisogno di specificare ancora i parametri.

Const Nome_corto:byte=1; : la parola chiave const serve per dichiarare costanti, aree di memoria in cui risiede uno e un solo valore, che non può mai essere cambiato. Il tipo di costante va specificato dopo il nome, mentre il valore che rappresenta, dopo un ‘=’, successivamente al nome. Quindi, quando vorrete dichiarare una costante, userete la seguente sintassi:

Const <nome>:<tipo>=<valore>

implementation : Da qui inizia la parte di implementazione del codice, dove si scrive il vero e proprio corpo della funzione/procedura.

function Modifica_stringa; : dato che nell’interfaccia esiste già una dichiarazione dei parametri e dei tipi della funzione, questa linea di codice serve solo a dire al compilatore che il segmento di codice che sta per iniziare è il corpo di quella funzione.

<corpo> : questa funzione è molto semplice: se il parametro modo è uguale al valore rappresentato dalla costante Nome_corto, allora esegue una serie di trasformazioni sul parametro stringa che daranno come risultato la versione corta del parametro (vedi lezione sulla struttura repeat...until), altrimenti, toglie tutti gli spazi dal parametro stringa.

Delete(stringa,7,Length(stringa)-7); : questa procedura cancella dal parametro stringa, un numero di caratteri pari alla lunghezza di stringa meno 7, a partire dal carattere 7. In pratica, cancella tutti i caratteri dopo il sesto. Quindi, quando vorrete eliminare parti di una stringa userete la procedura delete(s:string;x,y:byte), dove s è la stringa che si vuol modificare, x è il carattere di partenza e y è il numero di caratteri da eliminare. Se y è maggiore alla lunghezza di s, verranno cancella tutti i caratteri da x alla fine.

Modifica_stringa:=concat(stringa,’~1’); : la funzione concat non fa altro che concatenare due o più stringhe, come dice il nome. Ogni stringa viene aggiunta alla fine della precedente.

Pos(‘ ‘,stringa)>0 : la funzione Pos(a,b:string) restituisce il valore che indica la posizione della stringa a nella stringa b. In questo caso, la funzione Pos restituisce la posizione del primo spazio nella stringa ‘stringa’. Se Pos è uguale a 0, non ci sono istanza della stringa a nella b.

Mi sembra di aver spiegato tutto, fin qui.


Scoprire nuove procedure e funzioni
Con il compilatore è sempre, o quasi sempre, fornita una guida in linea con l’elenco e la descrizione (spesso in inglese) delle procedure e delle funzioni standard, in ordine alfabetico. E’ utilissimo, specialmente quando si è agli inizi.
Le classi fanno in qualche modo parte dei tipi derivati. Una classe può contenere variabili, costanti e campi come le normali strutture, ma, addizionalmente a questi, può contenere anche funzioni, procedure, costruttori e distruttori. Per questo verso, la classe è paragonabile ad un oggetto, che ha una determinata serie di istruzioni per ogni operazione che compie: una classe può essere un pulsante, una finestra, una lista o qualsiasi altra cosa. Tant'è vero, questo, che nella dichiarazione di una classe si usa la parola riservata object (oggetto).
Vediamo intanto come si dichiara una classe:
Codice sorgente
________________________________________
type
<nome>=Object
(*Corpo della classe, in cui ci possono essere:
procedure
funzioni
costruttore
distruttore
costanti
variabili
strutture
enumeratori
ecc...*)
end;
________________________________________


I membri private e i membri public

In una classe, i membri possono essere di 2 tipi differenti: private e public. I membri private, come suggerisce il nome, sono privati, cioè accessibili solo dai membri della stessa classe. Infatti i membri private non sono modificabili da qualunque ente esterno che non siano le stesse procedure e funzioni (o costruttori e distruttori) della classe mdesima.
D'altra parte, i membri public possono liberamente essere modificati da ogni ente esterno. Per esempio:
Codice sorgente
________________________________________
(*...*)
type
classe=object
private
i:integer;
public
l:longint;

procedure myproc;
begin
i:=2; (*Corretto, i è membro della stessa classe di myproc*)
end;
end;

var es:classe;

(*...*)
begin
(*...*)
es.l:=98; (*Corretto, l è public*)
es.i:=98; (*Errato, i è private*)
(*...*)
end;
________________________________________


E' evidente la differenza fra le due.

I membri di una classe

In una classe si possono dichiarare, come già detto, procedure, funzioni, variabili, costanti, costruttori e distruttori, che possono essere tutti public o private.
Per sapere come dichiarare correttamente i vari membri, studiate questo esempio:
Codice sorgente
________________________________________
program esempio;
uses crt;

type
classe=object

private
i:integer;

procedure modify(u:integer);

public
const MAX:byte=5;

procedure show;
function MAXi:integer;
procedure Seti(x:integer);
end;

procedure classe.modify(u:integer);
begin
i:=u;
end;

procedure classe.show;
begin
writeln('Integer: ',i);
end;

function classe.MAXi:integer;
begin
MAXi:=i*MAX;
end;

procedure classe.Seti(x:integer);
begin
modify(x);
end;

(*...*)
________________________________________


Oppure, nelle librerie:
Codice sorgente
________________________________________
unit esempio;
interface

type
classe=object

private
i:integer;

procedure modify(u:integer);

public
const MAX:byte=5;

procedure Show;
function MAXi:integer;
procedure Seti(x:integer);
end;

implementation

procedure classe.modify;
begin
i:=u;
end;

procedure classe.show;
begin
writeln('Integer: ',i);
end;

function classe.MAXi;
begin
MAXi:=i*MAX;
end;

procedure classe.Seti;
begin
modify(x);
end;

end.
________________________________________


I costruttori e i distruttori

Questo particolare tipo di procedure ha molti usi: il più semplice è quello di inizializzare le variabili e gli spazi di memoria necessari al funzionamento della altre parti della classe. Ad esempio:
Codice sorgente
________________________________________
(*...*)
type
tipi=object
private
i:ineteger;
l:longint;
c:char;
s:string;

public
constructor Create;
end;

constructor tipi.Create;
begin
i:=0;
l:=0;
c:='';
s:='';
end;

(*...*)
________________________________________


La sua vera funzione è quella di inizializzare classi contenenti metodi virtuali, ma vedremo in seguito.
Codice sorgente
________________________________________
program set_esempio;
uses crt;
type
c=set of char;

var f:c;

begin
f:=['a','b'];
if 'b' in f then
write('ciao');
readln
end.
________________________________________


c è dichiarata come set di char, perciò può contenere un elenco di valori char: in questo caso, la variabile f di tipo c contiene i valori 'a' e 'b'.
Nella struttura if viene considerato se 'b' si trova nell'elenco dei valori di f. In effetti 'b' è un elemento di f e perciò viene eseguita l'istruzione write.
In genere, per dichiarare i set si usa:
Codice sorgente
________________________________________
type
<nome>:set of <tipo>;
________________________________________


Include ed exclude

Per aggiungere un valore ad un set o escluderlo, si usano le procedure include ed exclude. La sintassi è la seguente:
Codice sorgente
________________________________________
procedure Include(s:set of T;i:T);
procedure Exclude(s:set of T;i:T);
________________________________________


Dove T è un tipo qualunque ed i l'elemento da includere/escludere. Ad esempio:
Codice sorgente
________________________________________
type
a:set of integer;
b:set of char;

var v1:a;
v2:b;

begin
clrscr;
a:=[1,5];;
b:=['1','5'];
if not (2 in a) then
include(a,2);
end.
Con i numeri real capita di dover scrivere numeri molto grandi, che spesso è scomodo porre per esteso. Se dovessimo scrivere, ad esempio, centotrentaseimilasettecentoventotto miliardi dovremmo scrivere: 136728000000000 (per semplificare la lettura: 136.728.000.000.000), ma con la notazione scientifica, questo numero diventa: 1,36728 per 10 elevato alla 14. In pascal è possibile scrivere numeri in notazione scientifica usando il segno dell’esponenziale ‘e’, quindi sarebbe 1,36728e14, dove ‘e’ significa “per dieci elevato alla”. Alcuni esempi:

0,0000000000065 = 6,5*(10 elevato alla -11) = 6.5e-11
1560000000000000000000 = 1,56*(10 elevato alla 21) = 1.56e21
0,0000000163 = 1,63*(10 elevato alla -8) = 1.63e-8

Nella notazione scientifica, il numero moltiplicato per una potenza di dieci deve essere sempre compreso fra 0 e 9.

Se nella procedure writeln non si usano i restrittori di campo per i numeri real (vedi indietro), il numero verrà automaticamente scritto in notazione scientifica.

Il codice binario, o notazione binaria, è usato sempre dal computer, per ogni operazione, soltanto che noi non lo sappiamo perché questo è il modo più semplice per le macchine di scambiare informazioni. Quando si compila un programma, il compilatore trasforma ogni istruzione in una serie di 0 e 1, che l’elaboratore poi esegue.
E’ il più semplice sistema di notazione esistente e ha due cifre, 0 e 1. Essendo binario, ogni cifra viene moltiplicata per 2 elevato alla posizione che occupa nel numero meno 1 (le cifre a destra occupano le prime posizioni). Ma è molto più comprensibile un esempio:

1 = 1*2e(1-1) = 1*20 = 1
101 = 1*2e2 + 0*2e1 + 1*2e0 = 4 + 0 + 1 = 5
110101 = 1*2e5 + 1*2e4 + 0*2e3 + 1*2e2 + 0*2e1 + 1*2e0 = 32+16+0+4+0+1 =53

Se nella notazione decimale (quella che usiamo normalmente) abbiamo le decine, le centinaia e le migliaia, nel sistema binario ci sono le duine, le quartine e le ottine, per metterla su un piano molto banale e semplicistico. Un altro esempio:

95 = 90 + 5 = 9*101 + 5*100 (*Sistema decimale*)
95 = 64 + 16 + 8 + 4 + 2 + 1 = 26 + 24 + 23 + 22 + 21 + 20 =
1*2e6 + 0*2e5 + 1*2e4 + 1*2e3 + 1*2e2 + 1*2e1 + 1*2e0 = 1011111 (*Binario*)

Ogni 1 e 0 è un bit, perciò lo shift a destra shr sposta tutti i bit a destra di x posti, mentre shl fa lo stesso a sinistra. Bisogna, però, considerare il tipo di variabile, perché un byte occupa meno di un integer e quindi avrà mano bit a disposizione, per esempio:
Codice sorgente
________________________________________
var b:byte; (*range: 0..255*)
(*...*)
b=128
b shl 1 = 1000000 shl 1 = 0000000 = 0

var b:integer; (*range: -32768..32767*)
(*...*)
b=128
b shl 1 = 000000010000000 shl 1 = 000000100000000 = 256
Per chi non ha capito il sistema binario consiglio di lasciar perdere questa lettura subito e tornarci fra un po’ di tempo.
Come la notazione binaria o decimale, quella esadecimale dispone di 16 cifre:
Codice sorgente
________________________________________

Hex: 0 1 2 3 4 5 6 7 8 9 A B C D E F
Dec: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
________________________________________


E, come avrete già intuito, il fattore di moltiplicazione è 16. Esempio:

6A = 6*16e1 + 10*16e0 = 96 + 10 = 106
FF = 15*16e1 + 15*16e0 = 240 + 15 = 255 = 11111111

In pascal si indicano i numeri esadecimali preponendoci un ‘$’

$FF = FF = 255
$0A = A = 10

Di solito, si usa indicare con un valore esadecimale determinate costanti che riguardano il sistema. Al contrario del C, il Pascal non fa un uso molto abbondante di questi tipi di notazione: se si escudono le librerie precompilate e fornite con il compilatore (come la crt o la windos), valori esadecimali non vengono quasi mai usati.
Può capitare diverse volte di aver bisogno di generare numeri casuali:
Codice sorgente
________________________________________
program rnd_sim;
uses crt;
var x,ir:integer;
rr:real;

begin
clrscr;
writeln('Inserisci un numero intero: ');
readln(x);
(*Comunica all'elaboratore di tenersi pronto per la generazione
di numeri casuali*)
randomize;
(*Ottiene un numero intero casuale fra 0 e x (estremi inclusi) con la
funzione random e lo deposita in ir*)
ir:=random(x+1);
(*Ottiene un numero a tre cifre decimali tra 0 e 1 con la funzione
random e lo deposita in rr*)
rr:=random;
writeln('Numero intero casuale fra 0 e ',x,': ',ir);
writeln('Numero reale casuale (tre cifre decimali) fra 0 e 1: ',rr:4:3);
readln
end.
________________________________________


La procedura randomize comunica al computer di tenersi pronto per la generazione di numeri casuali. E’ obbligatorio prima di ogni chiamata a random().
La funzione random(x:word) restituisce un valore scelto a caso nell’intervallo 0..x-1 (estremi inclusi), dove x è un numero intero. Se non si specifica un numero tra parentesi, viene scelto un numero casuale da 0 a 1, con tre cifre decimali, così:

randomize;
m:=random;

Quindi, quando si vogliono generare numeri casuali, si usa la sintassi:
Codice sorgente
________________________________________
(*...*)
Randomize;
(*...*)
<variabile>:=Random(<range>);
________________________________________


Vediamo ora un caso, più complesso, in cui per esempio si vuole estrarre a sorte i partecipanti ad un torneo:
Codice sorgente
________________________________________
program sel_cas;
uses crt;
var nome:array[0..300] of string[50];
scelto,index,i:word;
abbinamenti,volte:word;
s:string;

begin
clrscr;
index:=0; (*Setta index a 0*)
repeat (*inizia un ciclo repeat...until*)
write('Inserire il nome del partecipante: ');
readln(nome[index]); (*legge il nome*)
index:=index+1; (*e incrememnta index di uno*)
until nome[index-1]=''; (*finchè il nome immesso è uguale ad una stringa vuota*)
clrscr;
write('Abbina 2 partecipanti alla volta, per volte.');
gotoxy(39,1); (*sposta il cursore tra ‘per’ e ‘volte’*)
read(volte); (*legge il numero di combinazioni da fare*)
randomize; (*inizializza la randomizzazione*)
for i:=1 to volte do (*per volte volte*)
begin
abbinamenti:=random(index-1); (*sceglie un numero a caso*)
write(i,'- ',nome[abbinamenti],' con ');(*e scrive il nome*)
abbinamenti:=random(index-1); (*corrispondente*)
writeln(nome[abbinamenti],'.'); (*2 volte*)
end;
readln; (*aspetta pressioni del pulsante invio*)
readln
end.
________________________________________


Usare le procedure

Ho riscritto lo stesso programma, però usando esclusivamente le procedure e dichiarando un nuovo tipo vettore, che poi non è altro che un array di 100 valori.
Codice sorgente
________________________________________
program sel_cas;
uses crt;
type vettore=array[0..100] of string[50];
var nomi:vettore;
index:integer;

(*Questa procudera acquisisce tutti i nomi dei partecipanti*)
procedure acquisisci(var val:vettore;var contatore:integer);
begin
repeat
write(contatore,'- Inserire il nome del partecipante: ');
(*Legge il nome inserito*)
readln(val[contatore]);
(*Incrementa l'indice di 1*)
contatore:=contatore+1;
until val[contatore-1]='';
(*E' da notare che, quando l'utente vuole uscire dal ciclo, immette
una stringa vuota, ma il contatore, dopo, viene comunque aumentato
di 1: perciò è necessario diminuire di 1 il contatore per ottenere
l'indice reale dei dati immessi, altrimenti se ne avrebbe uno in
più (l'ultimo sarebbe vuoto)*)
contatore:=contatore-1;
end;

(*Questa procedura scrive gli abbinamenti*)
procedure abbina(val:vettore;max:integer);
var i,volte,abbinamenti,riserva:integer;
begin
clrscr;
write('Abbina 2 partecipanti alla volta, per quante volte? ');
(*Legge il numero di combinazioni da fare*)
readln(volte);
(*Inizializza la randomizzazione: poichè il computer non è già di
per sè predisposto a generare numeri casuali, questa istruzione
comunica all'elaboratore di tenersi pronto a quest'operazione*)
randomize;
(*Per volte volte abbina casualmente due nomi diversi*)
for i:=1 to volte do
begin
(*Sceglie un numero a caso*)
abbinamenti:=random(max);
(*E scrive il nome associato a quel numero nel vettore*)
write(i,'- ',nomi[abbinamenti],' con ');
(*Sceglie il secondo membro del sorteggio*)
riserva:=random(max);
(*Controlla che non sia uguale al precedente: in questo caso
aumenta o diminuisce di uno il numero scelto a caso senza,
però, uscire dai limiti del vettore*)
if riserva=abbinamenti then
if riserva<max>0 then
begin
trovato:=true;
break;
end;
FindNext(DirInfo);
end;
if trovato=true then
write(‘Il file è stato trovato!’)
else
write(‘Il file non è stato trovato!’);
readln
end.
________________________________________


Il programma legge da tastiera la directory e il nome del file da cercare, poi usa una procedura speciale, FindFirst(ext:const string;type:byte;var data:TSearchRec), che cerca tutti i file di estensione ext (l’estensione non può essere un dato i introdotto da tastiera, quindi una variabile, ma deve sempre essere specificata dal programmatore come stringa tra apici) e di tipo type (il file di tipo FaArchive sono tutti i file normali, per approfondimenti, vedi appendice 7) e usa la variabile DirInfo per depositare tutti i propri dati.
La struttura iterativa while...do fa si che il ciclo continui se e solo se esistono ancora altri file di estensione ext, mentre la procedura FindNext(var data:TSearchRec) prosegue la ricerca (nel parametro data bisogna specificare la stessa variabile usata nel medesimo parametro nella procedura FindFirst).
Ad ogni step, i dati contenuti nella strutture DirInfo si rinnovano e nel campo Name possiamo trovare il nome del file preso attualmente in esame che corrisponda alla descrizione di estensione e tipo fornita in input da FindFirst. Se la variabile stringa 'nome' è presente come sottostringa nel nome del file, allora il file è stato trovato e il ciclo si interrompe (ovviamente, risulta un solo file con quel nome, ma lascio a voi la raffinazione del programma per scrivere tutti i file trovati). L’istruzione break, spezza il ciclo in cui è contenuta (cioè il costrutto while...do) e balza all’istruzione immediatamente successiva.

Comunque, è fornita dall’unità WinDos una procedura, FileSearch che permette di trovare un file il cui nome sia di tipo pchar (ossia non può essere una variabile). Un piccolo esempio:
Codice sorgente
________________________________________
(*...*)
var S:array[0..fsPathName] of char;
(*...*)
FileSearch(S,‘Turbo.exe’,GetEnvVar(‘PATH’));
if s[0]=#0 then
writeln(‘File turbo.exe non trovato!’)
else
writeln(‘File turbo.exe trovato come’,FileExpand(S,S));
(*...*)
________________________________________


La procedura FileSearch cerca il file turbo.exe nella path corrente e deposita il suo nome nella variabile S, array di char di lunghezza variabile (fsPathName è una variabile globale preimpostata). Se il primo carattere è uguale a #0 (il primo carattere della tabella ASCII, che corrisponde ad un carattere nullo), allora il file non è stato trovato, altrimenti S contiene il suo nome. FileExpand(s,s:array of char) è una funzione che restituisce il nome (esiste anche Fexpand(s:pathstr), che ha lo stesso effetto), completo di path, del file specificato tra parentesi.

Esiste anche una funzione abbreviata di FileSearch, che è FSearch(name,dir:PChar):PathStr, che restituisce direttamente il nome del file e può essere usata, perciò, in operazioni di assegnamento:
Codice sorgente
________________________________________
var s:pathstr;
(*...*)
s:=FSearch(‘Turbo.exe’,GetEnvVar(‘PATH’));
if s=’’ then
writeln(‘Il file non è stato trovato!’)
else
writeln(‘File trovato come ’,Fexpand(s));
(*...*)
________________________________________


Pathstr, come TSEarchRec sono tipi definiti nella libreria WinDos. Pathstr è un tipo che può contenere una path sotto forma di stringa, metre TSearchRec contiene i dati relativi ad una ricerca inizializzata con FindFirst. Mentre PChar, è un tipo molto particolare, che usa i puntatori (argomento molto avanzato, ma che nel C si tratta quasi agli inizi), ossia variabili che contengono l'indirizzo di un'area di memoria, per esprimere una stringa. In questo modo, i PChar non possono essere nè letti nè scritti a video, proprio perchè la loro natura di puntatori lo impedisce (non si può leggere da tastiera un indirizzo, anche se scriverlo sarabbe possibile).


Per rendere un file nascosto, o di sola lettura, o anche di sistema, esiste una semplice procedura: SetFAttr(file:text;attr:word) (il parametro file può essere anche di tipo file). Nel parametro attr vanno inseriti dei numeri che rappresentano il nuovo stato del file: fortunatamente, ci sono delle costanti definite null’unità WinDos, che ci permettono di ricordare facilmente tali valori:
Codice sorgente
________________________________________
faArchive : file d’archivio (normali)
faReadOnly : sola lettura
faHidden : nascosto
faSysFile : di sistema
faAnyFile : qualunque file
faDirectory : cartella
________________________________________


Queste sono anche le costanti rappresentanti i valori restituiti dalla funzione GetFAttr(t:text). Ecco un esempio di come settare e analizzare il tipo di file:
Codice sorgente
________________________________________
var t:text;
(*...*)
Assign(t,’C:\Funzio~1.txt’);
if GetFAttr(t)=faReadOnly then
SetFAttr(t,faArchive)
else
SetFAttr(t,faReadOnly);
(*...*)
________________________________________


Se il file C:\Funzio~1.txt è un file di sola lettura, viene convertito in un normale file d’archivio, altrimenti viene settato come file di sola lettura.
Il linguaggio del Pascal mette a disposizione una serie di funzioni e procedure finalizzate al disegno di figure sullo schermo e alla modifica dei pixel che lo compongono. Per inizializzare la modalità grafica sono necessarie alcune righe di codice, queste:
Codice sorgente
________________________________________
(*...*)
var gd,gm:integer;
(*...*)
gd:=detect; (*Rileva la scheda video*)
InitGraph(gd,gm,’’); (*Inizializza la modalità grafica*)
if graphresult<>grOK then (*Se si sono verificati errori...*)
halt; (*...termina immediatamente il programma*)
(*...*)
CloseGraph;
(*...*)
________________________________________


La procedure InitGraph accetta 3 parametri: il primo è un valore numerico che la funzione detect assegna automaticamente alla variabile gd e rappresenta il tipo di scheda video; il secondo è un valore che rappresenta il driver sul quale dovrà girare la modalità grafica (vedi appendice 5, la funzione GetDir); il terzo è una stringa che rappresenta l’indirizzo del file di estensione *.bgi il quale contiene i dati per inizializzare il driver alla modalità grafica (in questo caso la stringa è vuota perché si suppone che il file si trovi nella stessa directory del programma).
Graphresult è una variabile che contiene, se se ne sono verificati, un valore indicante l’errore avvenuto: la costante grOK indica che non sono avvenuti errori e la modalità grafica è stata inizializzata con successo.
Halt è una procedura, tra l’altro usata abbastanza spesso, che termina all’istante il programma.
CloseGraph è una procedura che va posta alla fine del programma per chiudere la modalità grafica (se il programma inizia e finisce in modalità grafica, che chiameremo d’ora in poi mg, senza cambi di modalità, allora questa istruzione può anche essere tralasciata, poiché l’end finale chiuderà automaticamente tutto).
Se si vuole tornare alla modalità normale, si usa la procedura RestoreCrtMode: tutto ciò che è stato disegnato verrà cancellato.

Prima di illustrare brevemente le procedure e le funzioni più usate, vorrei soffermarmi un attimo sulla scrittura di testi a schermo. Infatti, nella mg, la procedura write (e anche writeln e writebuf) non funziona e viene usata, quindi, l’istruzione OutText(s:string), assai svantaggiosa per 2 motivi: non supporta parametri multipli, ossia accetta uno e un solo parametro di tipo stringa, quindi non potrete scrivere a video, nella stessa istruzione, i valori delle variabili (per esempio, non scriverete
Codice sorgente
________________________________________
OutText(‘Nino ha ‘,x,’ anni’)
________________________________________


ma
Codice sorgente
________________________________________
var s:string;
x:byte;
OutText(‘Nino ha’);
str(x,s); (*converte l'intero x nella stringa s*)
OutText(s);
OutText(‘ anni‘);
________________________________________


Inoltre, secondo svantaggio, non è possibile scrivere numeri e caratteri speciali (come ‘ ‘,’|’,’<’ ecc..): se ci provate troverete una macchia informe di pixel colorati.
Una forma più complessa di OutText è OutTextXY(x,y:word;s:string), che sposta il cursore al pixel di coordinate (x;y) e scrive la stringa s.

Un breve elenco delle procedure e funzioni + importanti (P=procedure, F=funzione):
• P Arc(x,y,a1,a2:word)
Disegna una arco che rappresenta la parte di circonferenza con centro in (x;y) compresa tra gli angoli a1 e a2
• P Circle(x,y,d:word)
Disegna un cerchio di diametro d alle coordinate x;y
• F GetColor
Restituisce il colore con cui si sta disegnando
• F GetMaxX
Restituisce il massimo numero delle ascisse
• F GetMaxY
Restituisce il massimo numero delle ordinate
• F Getpixel(x,y:word)
Restituisce il colore del pixel alle coordinate x e y
• F GraphResult
Restituisce il numero di un errore se l’inizializzazione della modalità grafica è fallita
• P initGraph(gd,gm:integer;path:string)
Gd e gm sono parametric che indicano le caratteristiche della scheda video; in base a quelle viene inizializzata la modalità grafica. In path viene specificato il percorso del file bgi che serve al funzionamento della modalità grafica
• P Line(x, y, x1, y1:word)
Traccia una linea da x,y a x1,y1
• P MoveTo(x, y:word)
Muove il cursore al punto di coordinate x e y
• P OutText (s:string)
Scrive una e una sola stringa s a schermo
• P OutTextXY(x,y:word;s:string)
Muove il cursore a (x; y) e scrive s
• P PutPixel(x, y, c:word)
Illumina un pixel a (x; y) del colore c (range: 1..15)
• P rectangle(x, y, x1, y1:word)
Disegna un rettangolo date le coordinate
• P SetColor(c:byte) Definisce il colore per disegnare in c
I puntatori sono molto utilizzati in linguaggi come il C, C++. Al contrario, nel Pascal, trovano poche applicazioni pratiche, se non nelle librerie precompilate, in partcolare in quelle che descrivono le procedure e le funzioni generali del TVision (il Pascal ad oggetti). Sebbene appunto, il loro uso sia ristratto nell'ambito di questo linguaggio, ritengo che ,per completezza, debba essere trattato comunque.

Cos'è un puntatore?

Un puntatore è una variabile che contiene l'indirizzo di memoria di un altro dato, ossia contiene un codice che identifica univocamente una delle celle di memoria usate per racchiudere le variabili di un programma. Come ogni altra variabile, i puntatori possono essere di più tipi: integer, real, string, char ecc... Il perchè risiede nel fatto che ogni tipo di dato (anche quelli derivati, come i record, gli enumeratori, i set ecc...) occupa una spazio diverso nella memoria fisica nel computer: ci sono i tipi che occupano 4 bytes (integer), altri che ne occupano 8, altri 16, altri 3 e così via. Tramite un puntatore si può conoscere anche il valore di una variabile.


L'uso dei puntatori

I puntatori si dichiarano mediante il contrutto type, che abbiamo già ampiamente visto.
Codice sorgente
________________________________________
type
IntegerPointer=^Integer

var B:IntegerPointer
________________________________________


In questo pezzo di codice si è dichiarato un tipo di puntatore chiamato IntegerPointer, che 'punta' (ossia contiene un indirizzo di memoria) ad un intero. Anche se questa è versione più usata, esiste anche una sintassi contratta di dichiarare una variabile come puntatore:
Codice sorgente
________________________________________
var B:^Integer
________________________________________

In questo caso si è dichiarata la variable B come puntatore ad un intero.

Un semplice programma per vedere l'uso dei puntatori:
Codice sorgente
________________________________________
Program Puntatori;
uses crt;

type IntPoint=^Integer;

var B:IntPoint;

begin
New(B);
B^:=34;
writeln('La variabile B punta ad una cella di memoria contenente',B^);
readln
end.

La procedura new(p:pointer) alloca un'area di memoria abbastanza grande da contenere un valore dello stesso tipo del puntatore passato come parametro: in questo caso alloca 4 bytes per contenere un intero.
L'uso del ^ dopo la variabile puntatore ci dice che non stiamo assegnando un indirizzo al puntatore, bensì un valore alla cella di memoria puntata. Perciò B^ è come se fosse una normalissima variabile di tipo Integer.

Un uso più specifico dei puntatori è illustrato in questo programma:
Codice sorgente
________________________________________
Program Puntatori2;
uses crt;
var a,b:integer;
c:^integer;

begin
clrscr;
new(c);
a:=56;
b:=98;
c:=@a;
writeln('Ora la cella di memoria puntata da c contiene ',c^);
c:=@b;
writeln('Ora invece contiene ',c^);
readln
end.
L'output prodotto dal programma sarà:
Codice sorgente
________________________________________
Ora la cella di memoria puntata da c contiene 56
Ora invece contiene 98
________________________________________


Usando l'operatore @ davanti ad un qualsiasi tipo di variabile si ottiene l'indirizzo di quella variabile. Quindi con las sintassi c:=@a abbiamo assegnato a c l'indirizzo in memoria di a, ed ora il puntatore c punta ad a (ossia contiene il suo indirizzo di memoria). Infatti si è visto che, scrivendo c:=@a, la variabile c^ contiene il valore di a, mentre con c:=@b la variabile c^ contiene il valore di b.
Perchè questo? Perchè quando si usa c^, il programma legge l'indirizzo contenuto in c, si 'reca' a quell'indirizzo e 'preleva' il valore contenuto in quella cella di memoria, quindi lo restituisce.

Tutto quello che abbiamo visto fin'ora, può essere fatto con tutti i tipi di variabile, anche derivati. Un esempio:
Codice sorgente
________________________________________
Program Puntatori3;
uses crt;

type
valori=record
val1,val2:real;
end;

var a,b:valori;
c:^valori;

begin
clrscr;
new(c);
a.val1:=56.87;
a.val2:=23.76;
b.val1:=98.32;
b.val2:=2.4e5;
c:=@a;
writeln('Ora la cella di memoria puntata da c contiene ',c^.val1:4:2,' e ',c^.val2:4:2);
c:=@b;
writeln('Ora invece contiene ',c^.val1:4:2,' e ',c^.val2:6:1);
readln
end.
________________________________________



L'output prodotto sarà:
Codice sorgente
________________________________________
Ora la cella di memoria puntata da c contiene 56.87 e 23.76
Ora invece contiene 98.32 e 240000.0
________________________________________


Da notare è che l'operatore ^ si usa sempre dopo la variabile puntatore, non dopo il campo del record:
Codice sorgente
________________________________________
c^.val1 (*Giusto*)
c.val1^ (*Sbagliato*)
________________________________________


Ma se avessimo avuto il record scritto in questo modo:
Codice sorgente
________________________________________
type
valori=record
val1,val2:real;
val3:^real;
________________________________________


Sarebbe stato lecito scrivere:
Codice sorgente
________________________________________
(*...*)
c^.val3:[email protected];
writeln('La cella di memoria puntata dal c^.val3 contiene ',c^.val3^:4:2);
________________________________________


E avrebbe prodotto in output:
Codice sorgente
________________________________________
La cella di memoria puntata dal c^.val3 contiene 98.32
________________________________________


Per concludere i puntatori costituiscono uno strumento potente, ma solo se li si sa usare bene.


Spero che vi sia di aiuto come lo è stato per me :)

Pace :B):

Edited by ¬Revo¯ - 12/2/2013, 14:10
view post Posted: 11/2/2013, 14:03     +1casino totale - Supporto
Rifare le sezioni sarebbe molto impegnativo e terrebbe il forum disordinato per un po (ammeno che qualcuno che ha voglia non lo faccia velocemente)
view post Posted: 1/2/2013, 15:03     +1È nato Eurora, il supercomputer italiano più efficiente del mondo - Hardware
sisi... ora... ma pensa prima se non ci fossero state le persone che ho detto xD aaaaaah e che mi so ricordato... rendiamo grazie a Berners-Lee **
view post Posted: 29/1/2013, 18:07     +1So che amate le richieste quindi... - Hacking e computer
CITAZIONE (Ares0011 @ 29/1/2013, 17:55) 
CITAZIONE
Poco palese diciamo xD dritto allo scopo

Caro Revo tanto di cappello e per la tua risposta ribatto dicendo "sì" vado dritto allo scopo senza pensare alle conseguenze potrebbe essere una definizione di sbagliato o pazzo,ma sono così però scusa per questa mia seguente affermazione...La tua risposta è al quanto inutile,io ho aperto una discussione che per il sottoscritto è al quanto seria e se dovevi commentare potevi farlo con le discussioni più inutili e comunque ti ringrazio per la tua osservazione e ti chiedo ancor scusa per la mia affermazione :)
CITAZIONE
Whitehat....e poi, ti sei registrato oggi, non forniamo tecniche avanzate a degli utenti casuali....forse, puoi trovare qualcosa nella sezione "68:61:63:6b:73"

Per il caro admin molto simpatico...Posso risponderti solo che diventerò membro del "68:61:63:6b:73" in breve tempo e non penso che questa è una richiesta in stile CIA o FBI...nei tempi passati le telecamere delle banche si accecavano con led a infrarossi in stile "Inside" però ora non penso che le banche utilizzano telecamere così obsolete quindi volevo sapere se c'era qualcosa che interrompeva anche per breve tempo la registrazione di questi carissimi occhi elettronici :) Cordiali saluti e ringrazio per le vostre risposte. -Ares

C'e sempre posto per scherzare caro Ares ;) non essere troppo serio nella vita :truzzo: ... Pace ^_^
view post Posted: 26/1/2013, 22:09     +2JAVA - Software
Forse ho capito... Tu vuoi programmarlo con una usb come di consueto e poi controllarlo e amministrarlo a distanza tramite wifi?
view post Posted: 26/1/2013, 20:05     +1Iniziare con FL STUDIO - Software
bella wet ;)

mettiti su soundcloud e facci sentire qualcosa comunque ;)
view post Posted: 14/1/2013, 11:28     +1[Consigli] Nuovo progetto Pokemon in cantiere - Videogame
il fatto e che non ho tempo... se inizio un progetto, devo finirlo e quindi ci penso due volte
19 replies since 12/1/2013