Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Pascal - Significato e utilizzo del simbolo @
Forum - Pascal - Significato e utilizzo del simbolo @

Avatar
a_butta (Member)
Expert


Messaggi: 578
Iscritto: 16/03/2010

Segnala al moderatore
Postato alle 12:53
Sabato, 02/10/2010
Ciao ragazzi.
Scusate l'ignoranza, ma girando un po' di esempi qua e la ho trovato molto spesso il simbolo @ all'interno del codice (sia puro pascal, sia utilizzato sotto delphi).
La mia domanda è: cosa fa? Cioè cosa significa e qual'è la sua funzione?

Grazie mille!

PM
Avatar
Alex (Ex-Member)
Expert


Messaggi: 441
Iscritto: 15/08/2005

Up
0
Down
V
Segnala al moderatore
Postato alle 18:07
Domenica, 03/10/2010
Testo quotato

Postato originariamente da a_butta:

Testo quotato

Postato originariamente da Alex:
inoltre si usano per allocare dinamicamente la memoria



cioè?



in pratica puoi allocare uno spazio che può contenere una variabile mentre il programma è in funzione..e per accederci usi il puntatore a quell'oggetto nella RAM.
(in pascal non so bene come si fa, mi pare che si usi la funzione New...prova a cercare nella guida del tuo compilatore...)

cmq ripeto..in pascal non è usatissimo...

PM
Avatar
Saladino (Member)
Pro


Messaggi: 90
Iscritto: 30/05/2010

Up
0
Down
V
Segnala al moderatore
Postato alle 19:12
Domenica, 03/10/2010
Come ti dovrebbe essere noto ogni varibile occupa in memoria un determinato indirizzo :

con l'operatore @ accedi semplicemente all'indirizzo della variabile.
Dato che le uniche variabili che possono contenere indirizzi sono i puntatori,è legale scrivere :
Codice sorgente - presumibilmente Pascal

  1. var
  2.  I : integer;
  3.  PI : ^Integer;
  4. begin
  5.  ....
  6.  PI := @I;



Ora,ogniqualvolta ti riferiarai al contenuto di PI ogni suo cambiamento modifichera' la nostra variabile :

Codice sorgente - presumibilmente Plain Text

  1. PI^ := 50;



Se noti ,molte funzioni usano l'operatore @  : per esempio quella della creazione di uno thread.

(Preso da > http://www.pierotofy.it/pages/sorgenti/browse/18444/4146/)

Codice sorgente - presumibilmente Pascal

  1. #
  2. exitproc := nil;
  3. #
  4. ThreadScan := CreateThread(nil, 0, @ThreadScanRete, nil, 0, ThIDSCAN);
  5. #
  6. repeat
  7. #
  8.  getexitcodethread(ThreadSCAN, @ris);



In Createthread ,la parte con @ indica che tu parti dall'indirizzo iniziale di ThreadScanRete.
Mentre con getexitcodethread modifichi con @ il contenuto della variabile ris.

Comunque il mio consiglio e' quello di partire dalla pratica dopo un poco di teoria :
ricordati che i puntatori sono uno strumento molto potente quindi usali bene!:)

PM
Avatar
Poggi Marco (Member)
Guru


Messaggi: 969
Iscritto: 05/01/2010

Up
-1
Down
V
Segnala al moderatore
Postato alle 14:02
Sabato, 02/10/2010
Il simbolo @ di solito si trova davanti ad una variabile, e il suo scopo è quello di ricavare l' indirizzo di memoria associato all' oggetto.

Ecco un esempio di come si usano i puntatori in Pascal e c:
http://www.di.uniba.it/~buono/labasd0304/materiale/C_Pasca ...

PM
Avatar
a_butta (Member)
Expert


Messaggi: 578
Iscritto: 16/03/2010

Up
-1
Down
V
Segnala al moderatore
Postato alle 15:11
Sabato, 02/10/2010
ok ho capito adesso che è un puntatore e che "punta" quindi salva l'indirizzo di memoria di un'altra variabile. Ma non riesco a capire l'utilizzo. Cioè quando potrei usare il puntatore? Per quali scopi?
Premetto che dei puntatori conosco solo la definizione e su molte guide, sinceramente oltre a questa (e cioè che punta alla memoria di una variabile) non trovo nulla altro di interessante.
Potreste aiutarmi a capire a cosa servono pragmaticamente sti puntatori?

Grazie mille! :D

PM
Avatar
Alex (Ex-Member)
Expert


Messaggi: 441
Iscritto: 15/08/2005

Up
-2
Down
V
Segnala al moderatore
Postato alle 18:18
Sabato, 02/10/2010
allora, in pascal (e potete contraddirmi benissimo) non si fa un gran uso dei puntatori, non quanto il C,di sicuro.

ad esempio in C si usano per passare le variabili alle funzioni come riferimento invece che come valore (in pascal si usa la parola var all'interno dell'argomento),
oppure si usano molto con gli array (ad esempio in C il nome di un array rappresenta l'indirizzo al primo elemento dell'array)

inoltre si usano per allocare dinamicamente la memoria

e infine sono molto comodi per creare liste concatenate....


in definitiva in C sono molto usati, in pascal un pò meno....(al massimo per allocare inamicamente la memoria)

PM
Avatar
a_butta (Member)
Expert


Messaggi: 578
Iscritto: 16/03/2010

Up
-2
Down
V
Segnala al moderatore
Postato alle 0:03
Domenica, 03/10/2010
Testo quotato

Postato originariamente da Alex:
inoltre si usano per allocare dinamicamente la memoria



cioè?

PM
Avatar
Phi (Member)
Expert


Messaggi: 241
Iscritto: 30/12/2009

Up
-2
Down
V
Segnala al moderatore
Postato alle 18:11
Domenica, 03/10/2010
ecco intanto i puntatori spiegati dalla guida di Totem


Capitolo 28° - Appendice 9 I puntatori

A cura di: Totem
    
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 - presumibilmente Pascal

  1. type
  2. IntegerPointer=^Integer
  3. 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 - presumibilmente Pascal

  1. 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 - presumibilmente Delphi

  1. Program Puntatori;
  2. uses crt;
  3. type IntPoint=^Integer;
  4. var B:IntPoint;
  5. begin
  6.     New(B);
  7.     B^:=34;
  8.     writeln('La variabile B punta ad una cella di memoria contenente',B^);
  9.     readln
  10. 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 - presumibilmente Delphi

  1. Program Puntatori2;
  2. uses crt;
  3. var a,b:integer;
  4.     c:^integer;
  5. begin
  6.     clrscr;
  7.     new(c);
  8.     a:=56;
  9.     b:=98;
  10.     c:=@a;
  11.     writeln('Ora la cella di memoria puntata da c contiene ',c^);
  12.     c:=@b;
  13.     writeln('Ora invece contiene ',c^);
  14.     readln
  15. end.


L'output prodotto dal programma sarà:
Codice sorgente - presumibilmente Plain Text

  1. Ora la cella di memoria puntata da c contiene 56
  2. 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 - presumibilmente Delphi

  1. Program Puntatori3;
  2. uses crt;
  3. type
  4.    valori=record
  5.    val1,val2:real;
  6. end;
  7. var a,b:valori;
  8.     c:^valori;
  9. begin
  10.     clrscr;
  11.     new(c);
  12.     a.val1:=56.87;
  13.     a.val2:=23.76;
  14.     b.val1:=98.32;
  15.     b.val2:=2.4e5;
  16.     c:=@a;
  17.     writeln('Ora la cella di memoria puntata da c contiene ',c^.val1:4:2,' e ',c^.val2:4:2);
  18.     c:=@b;
  19.     writeln('Ora invece contiene ',c^.val1:4:2,' e ',c^.val2:6:1);
  20.     readln
  21. end.


L'output prodotto sarà:
Codice sorgente - presumibilmente Plain Text

  1. Ora la cella di memoria puntata da c contiene 56.87 e 23.76
  2. 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:
c^.val1 (*Giusto*)
c.val1^ (*Sbagliato*)
Ma se avessimo avuto il record scritto in questo modo:
Codice sorgente - presumibilmente Pascal

  1. type
  2.    valori=record
  3.    val1,val2:real;
  4.    val3:^real;


Sarebbe stato lecito scrivere:
Codice sorgente - presumibilmente Plain Text

  1. (*...*)
  2. c^.val3:=@b.val1;
  3. writeln('La cella di memoria puntata dal c^.val3 contiene ',c^.val3^:4:2);


E avrebbe prodotto in output:
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.



Testo quotato

Postato originariamente da a_butta:
Testo quotato

Postato originariamente da Alex:
inoltre si usano per allocare dinamicamente la memoria


cioè?


Cioè tipo al posto di array dinamici, per esempio al posto di scrivere array of interger potrei scrivere ^integer, dovrei logicamente cambiare funzioni e sintassi nel trattare la variabile.

Poi posso anche usarli per leggere o scrivere file velocemente, per esempio questo programma legge una finestra di edit (usando le API windows) e ne scrive  il contenuto su un file testuale(tipo txt):
Codice sorgente - presumibilmente Delphi

  1. var
  2. len : longint; //lunghezza del testo
  3. p : pchar; //puntatore di caratteri (^char)
  4. edit:hwnd;//finestra edit(API windows)
  5. f : file; //il file
  6.  
  7. procedure scrivi(nome:pchar);
  8. begin
  9. Len := getwindowtextlength(edit)+1;
  10. getmem(p,len);
  11. getwindowtext(edit,p,len);
  12. {$i-}
  13. Assign(f,nome);
  14. rewrite(f,1);
  15. Blockwrite(f,p^,len);
  16. close(F);
  17. {$i+}
  18. freemem(p,len);
  19. end;



Sono anche essere usati per leggere immagini, se vuoi posto la procedura per leggere un file BMP.

Quasi tutte le API li usano, non troverai mani una funzione con paramentri string o array ma sembre pointer, pchar, o altri puntatori.

Inoltre facilitano molto la gestione di grandi variabili

Ultima modifica effettuata da Phi il 03/10/2010 alle 18:17
PM