Oppure

Loading
02/10/10 10:53
a_butta
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!
aaa
02/10/10 12:02
Poggi Marco
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:
di.uniba.it/~buono/labasd0304/materiale/…
aaa
02/10/10 13:11
a_butta
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
aaa
02/10/10 16:18
Alex
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)
aaa
02/10/10 22:03
a_butta
Postato originariamente da Alex:
inoltre si usano per allocare dinamicamente la memoria


cioè?
aaa
03/10/10 16:07
Alex
Postato originariamente da a_butta:

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...
aaa
03/10/10 16:11
Phi
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.

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:
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:
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:
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à:
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:
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à:
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:
c^.val1 (*Giusto*)
c.val1^ (*Sbagliato*)
Ma se avessimo avuto il record scritto in questo modo:
type
   valori=record
   val1,val2:real;
   val3:^real;
Sarebbe stato lecito scrivere:
(*...*)
c^.val3:=@b.val1;
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.


Postato originariamente da a_butta:
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):
var
len : longint; //lunghezza del testo
p : pchar; //puntatore di caratteri (^char)
edit:hwnd;//finestra edit(API windows)
f : file; //il file

procedure scrivi(nome:pchar);
begin
Len := getwindowtextlength(edit)+1;
getmem(p,len);
getwindowtext(edit,p,len);
{$i-}
Assign(f,nome);
rewrite(f,1);
Blockwrite(f,p^,len);
close(F);
{$i+}
freemem(p,len);
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 03/10/10 16:17
aaa
03/10/10 17:12
Saladino
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 :
var
 I : integer;
 PI : ^Integer;
begin
 ....
 PI := @I;


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

PI^ := 50;


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

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

#
exitproc := nil;
#
ThreadScan := CreateThread(nil, 0, @ThreadScanRete, nil, 0, ThIDSCAN);
#
repeat
#
 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!:)
aaa