Pointeurs

Signaler
Messages postés
13
Date d'inscription
jeudi 13 mars 2003
Statut
Membre
Dernière intervention
23 novembre 2005
-
jlen100
Messages postés
1606
Date d'inscription
samedi 10 juillet 2004
Statut
Membre
Dernière intervention
25 juillet 2014
-
Bonjour,
j'aurai besoin d'aide concernant les pointeurs...C'est ma deuxieme année de pratique de delphi et j'attaque les pointeurs... J'ai trois exos a faire dit 'de base' d'après mon prof...
Malgrés tout, et apres de nombreuses sur ce site et sur d'autre je ne comprend toujours pas ce que je dois faire !
En effet je crois avoir compris plusieurs choses sur ce sujet mais je bloque .
HELP ME !!!
Je ne demande bien sur pas à que l'on me serve tout cuit, mais j'aimerai comprendre!!!
Alors à votre bon coeur, voilà l'énoncé :

1) Les pointeurs
a) Définir un type enregistrement de 5 champs et afficher les adresses des champs d’une variable du type précédent.
b) En utilisant un pointeur, faire afficher les caractères d’une chaîne.
c) Idem pour un tableau de réels
d) Concevoir un tableau pouvant contenir aussi bien des réels, des chaînes ou des booléens.
e) Même chose avec un tableau dynamique.

Voilà une ebauche de ce que j'ai fais pour la question 1 par exemple mais ne comprenant rien à ce que je dois faire, j'imagine que ça ne vaut rien :

type Tpersonne = record
nom : string;
prenom : string;
age : integer;
ville : string;
villenatal : string;
end;
PPersonne = ^TPersonne;
implementation


{$R *.dfm}


procedure TForm1.Button1Click(Sender: TObject);
var
PersTest: PPersonne;

begin
New(PersTest);
PersTest^.Nom := 'dupont';
PersTest^.Prenom := 'pierre';
PersTest^.age := 22;
PersTest^.ville := 'Bordeaux';
PersTest^.villenatal := 'paris';
perstest:= addr(perstest^.nom);
label1.caption := inttostr(essai);;
Dispose(PersTest);

14 réponses

Messages postés
1606
Date d'inscription
samedi 10 juillet 2004
Statut
Membre
Dernière intervention
25 juillet 2014
10
salut;

les pointeurs servent à ecrires directement à une adresse moimoire.

dans ton exemple

procedure TForm1.Button1Click(Sender: TObject);
var
PersTest: PPersonne;

pointeur,essai:^integer;

begin
New(PersTest);


with PersTest^ do // ça simplifie l'écriture

begin

Nom := 'dupont';
Prenom := 'pierre';
age := 22;
ville := 'Bordeaux';
villenatal := 'paris';


essai:=@pointeur;//on
pointe sur le pointeur en fait on fait un transtypage du pointeur en
integer la fonction inttostr n'acceptant pas directement un pointeur
comme argument mais selement le contenu du pointeur

pointeur:= addr(nom); // ou pointeur:= @nom ; l'@ remplaçant addr() ici on charge l'adresse dans le pointeur




end;

label1.caption : ='adresse du nom'+ inttostr(essai^);// on affiche l'adresse contenue dans le pointeur;
Dispose(PersTest);

end;

pour afficher les caracteres d'une chaine à l'aide d'un pointeur

caractere:^char;

chaine:string='abcdecf';



for i:=1 to lenght(chaine) do

begin


caractere:=@chaine[i]; edit.text:=edit.text+caractere^;

end;

c'est un peu tordu pour afficher une chaine!!!!!

pour les tableaux tu fais pareil:

tu definis un pointeur du type de ce tu veux utiliser et tu pointes sur l'elemnt en utilisant addr() ou@

pour faire un tableau compatible avec tout les type tu le declares :

tableau:array[0..XX]of pointers; et declarer les pointeurs dont tu as besoin

ainsi tu peux ranger tout type de donnees dans le tableau attention ce sont les adresses qui sont rangées
Messages postés
1606
Date d'inscription
samedi 10 juillet 2004
Statut
Membre
Dernière intervention
25 juillet 2014
10
vas voir egalement: Guide Pascal et Delphi de Frédéric BEAULIEU. qui donne pas mal d'explications sur les pointeurs
Messages postés
135
Date d'inscription
jeudi 14 août 2003
Statut
Membre
Dernière intervention
12 octobre 2006

Alors ce qui est clair c'est que c'est pas des exos "de base" ton prof a dû fumer, je sais pas lol. Donner ça a des élèves qui viennent de voir les pointeurs c'est du suicide... il a dû vouloir vous coller ^^

pour faire ces exos il faut déjà que tu comprenne plusieurs choses:
ce qu'est un pointeur ( t'as l'air de savoir )
comment sont "mémorisés" les String ( ce sont des tableaux dynamiques de caractères )
comment sont "mémorisés" les tableaux dynamiques ( c'est un pointeur implicite vers un tableau )
enfin comprendre ce qui est demandé ( là ton prof t'as franchement pas aidé )

je vais te donner simplement quelques indications par manque de temps désolé lol
question a:
ce que tu a fait est presque juste, mais la question n'est pas pour le type PPersonne mais TPersonne ( dans cette question ils ne te parlent pas encore de pointeurs ^^ ). Pour avoir l'adresse d'une variable un opération existe c'est @
exemple @Personne => Adresse de Personne
@(Personne.Prenom) => Adresse de Personne.Prenom

question b:
une chaine est en fait un pointeur vers un tableau dynamique de caractères
exemple:
var S: String;
C: ^Char; //Pointeur de caracères plus souvent appelés PChar;
Begin
S:='Voici une chaine longue';
C:=Pointer(S);
//C^ = 'V'
end;
le second caractère se trouve 1octet plus loin que 'V' ( car 1caractère est codé sur 1 octet ) donc il fait incrementer C de 1 octet ( là je te laisse voir )

question c:
il est dit un tableau donc:
var
TabReel: Array[1..50]Of Float;
PReel: ^Float;
// PReel devra pointer vers chaque "case" du tableau de la même manière que precedemment ( je te laisse voir )

question d:
Un tableau de n'importe quoi ? ok si on sait pas ce que c'est, on ne connait pas la taille, on ne peux donc pas stoker les valeurs directement.
On sera donc obligé d'utiliser des pointeurs vers des variables, d'où l'utilisation d'un tableau de pointeurs
Var
Tab: Array[0..50] Of Pointer;
Begin
Tab[0]:=New(Integer);
Tab[0]^:=1;
etc...
End;

question e: je te laisse faire ^^
Messages postés
1606
Date d'inscription
samedi 10 juillet 2004
Statut
Membre
Dernière intervention
25 juillet 2014
10
-->neko

la question 1 est d'autan plus tordue que l'on ne peut pas afficher
directement l'adresse de la variable @ ne renvoyant qu'un type pointeur
et la fonction inttostr(@nom) donne une erreur de compilation (
...aucune surcharge de la fonction n'est admise..) je crois ou quelque
chose comme cela .Ceci oblige à passer par un pointeur auxiliaire :

le premier pointe sur la variable ---> il contient l'adresse de la variable

le second pointe sur le premier ----> la valeur pointée est bien un
integer (l'adresse de la variable) comme il est déclaré comme un
^integer il est accepté par la fonction inttostr.

CQFD. mais pas tres simple mais simplement un transtypage!!
Messages postés
13
Date d'inscription
jeudi 13 mars 2003
Statut
Membre
Dernière intervention
23 novembre 2005

Merci à tous pour toute votre aide !!!
Bon avant de me mettre à décortiquer vos messages pour bien tous comprendre, j'aurai déjà une question à propos de la réponse de jlen100 ...

Je ne comprend bien pourquoi on a besoin de passer par une variable "temporaire" pour récupérer l'adresse ...
En effet pourquoi pas :
pointeur:= addr(nom
essai:=@pointeur
essai2 := addr(prenom);
pointeur2 := addr(age);
essai3 := @pointeur2;
essai4 := addr(ville);
essai5 := addr(villenatal);

J'ai fais comme çà pour récuperer toutes les adresses...mes résultats sont-ils éronés ou est-ce un cas particulier..??
Merci encore de votre aide.
Messages postés
13
Date d'inscription
jeudi 13 mars 2003
Statut
Membre
Dernière intervention
23 novembre 2005

Bon en me relisant,mon dernier message ne me semble pas trés clair...


Pour résumé : jlen100 m'as proposé ceci pour récupérer l'adresse du nom par exemple : pointeur:= addr(nom);
essai:=@pointeur;
Et je me demande si on est obligé de passer par la variable pointeur?

Moi j'ai fais comme ça et je me demande si c bon :


pointeur:= addr(nom);
essai:=@pointeur;
essai2 := addr(prenom);
pointeur2 := addr(age);
essai3 := @pointeur2;
essai4 := addr(ville);
essai5 := addr(villenatal);
end;
label1.caption :='L'' Adresse du nom est :'+ ' ' + inttostr(essai^);// on affiche l'adresse contenue dans le pointeur;
label2.caption :='L'' Adresse du prénom est :'+ ' ' + inttostr(essai2^);
label3.caption :='L'' Adresse de l''age est :'+ ' ' + inttostr(essai3^);
label4.caption :='L'' Adresse de la ville est :'+ ' ' + inttostr(essai4^);
label5.caption :='L'' Adresse du pays est :'+ ' ' + inttostr(essai5^);

Voilà ....Merci
Messages postés
1606
Date d'inscription
samedi 10 juillet 2004
Statut
Membre
Dernière intervention
25 juillet 2014
10
salut, comme je te l'ai dit le probleme c'est que l'instruction
inttostr n'accepte pas le pointeur comme variable mais seulement son
cotenu. ainsi si tu fais inttostr(pointeur) tu auras un message
d'erreur à la compilation.

Physiquement un pointeur est une adresse donc un integer seulement il
est declare comme type pointer et l'instruction inttostr() ne le
reconnais pas comme integer ... c'est C.. mais c'est comme ça; d'ou la
nécessité de convertir l'adresse en integer (transtypage) c'est le role
du pointeur auxiliare: il pointe sur l'adresse mémoire contenant
l'adresse l'adresse de la variable initiale

par exemple si nom est à l'adresse 1000

le pointeur à l'adresse 2000

quand on fait :

pointeur:= @nom;

test:=@pointeur;

en final pointeur=1000 ; test=2000 et test^=1000; on à bien récupéré l'adresse de la variable initiale.

j'espére que je suis assez clair.

Dans ce que tu as besoin tu dois répeter l'opération pour chaque pointeur ainsi :

pointeur:= addr(nom);

essai:=@pointeur;

essai2 := addr(prenom);

pointeur2 := addr(age);

essai3 := @pointeur2;

essai4 := addr(ville);

essai5 := addr(villenatal);

end;

label1.caption :='L'' Adresse du nom est
:'+ ' ' + inttostr(essai^);// on affiche l'adresse contenue dans
le pointeur;

label2.caption :='L'' Adresse du prénom est :'+ ' ' + inttostr(essai2^);

label3.caption :='L'' Adresse de l''age est :'+ ' ' + inttostr(essai3^);

label4.caption :='L'' Adresse de la ville est :'+ ' ' + inttostr(essai4^);

label5.caption :='L'' Adresse du pays est :'+ ' ' + inttostr(essai5^);

ici essai2 contient l'adresse du prenom mais quand tu fais inttostr(essai2^ )
tu convertiras la valeur des carctéres contenus à l'adresse pointée qui
seront consideres comme un integer. fais le test en changeant le prenom
et ta valeur doit changer

ton code devient:



pointeur: = addr(nom);


essai:=@pointeur;

label1.caption :='L'' Adresse du nom est :'+ ' ' + inttostr(essai^);// on affiche l'adresse contenue dans le pointeur;

pointeur:= addr(prenom);


essai:=@pointeur;

label2.caption :='L'' Adresse du prénom est :'+ ' ' + inttostr(essai^);

pointeur:= addr(age);



essai:=@pointeur;

label3.caption :='L'' Adresse de l''age est :'+ ' ' + inttostr(essai^);

pointeur:= addr(ville);




essai:=@pointeur;

label4.caption :='L'' Adresse de la ville est :'+ ' ' + inttostr(essai^);

pointeur:= addr(villenatal);





essai:=@pointeur;

label5.caption :='L'' Adresse du pays est :'+ ' ' + inttostr(essai^);

......etc,etc

tu n'as besoin que d'un seul pointeur et une seule variable auxiliaire.
Messages postés
13
Date d'inscription
jeudi 13 mars 2003
Statut
Membre
Dernière intervention
23 novembre 2005

OK!!!
Merci, cette fois c 'est très clair!!!
Merci beaucoup à toi...
Messages postés
1606
Date d'inscription
samedi 10 juillet 2004
Statut
Membre
Dernière intervention
25 juillet 2014
10
note simplement que la variable pointeur peut être d'un type pointer
quelconque. En effet elle ne sert qu'à recuperer l'adresse de la
variable initiale tu peux donc la declarer : pointeur:pointer; le type pointer est un type générique compatible avec tout les autres pointeurs.

bonne prog.
Messages postés
199
Date d'inscription
dimanche 2 mars 2003
Statut
Membre
Dernière intervention
10 octobre 2006
1
perso j'aurais fait : IntToStr(Integer(@Pointer))
je ne vois vraiment pas le problème... Un simple cast...

Tout problème a sa solution mais en général c'est jamais la bonne...
Messages postés
1606
Date d'inscription
samedi 10 juillet 2004
Statut
Membre
Dernière intervention
25 juillet 2014
10
--> c'est effectivement plus simple je n'y avais pas pensé quoique qu'il faille écrire @pointeur et non @pointer puisque pointer est un type de pointeur generique ce qui provoque une erreur de compilation
Messages postés
4
Date d'inscription
vendredi 5 septembre 2003
Statut
Membre
Dernière intervention
11 novembre 2005

Effectivement, il suffit de caster un pointer en integer pour l'afficher.
Cependant, ça n'a pas beaucoup de sens, sauf dans de rare cas pour debugger.

Dans tous les cas, on preferera un pointer sous sa forme hexa: IntToHex(Integer(@p),8);
C'est plus... "clair" ;)

Pour plusweb: Je trouve deplorable que l'on enseigne les pointers aussi tard. Ils font partis des bases essentielles de la programmation. Leur maitrise n'est pas un "plus", c'est... comment dire... essentiel.
Il font partie des mecanismes basiques, que leur utilisation soit implicite (comme c'est le cas en java) ou explicite (comme ici par exemple), au même titre que les simples operations arithmetiques.
En maitrisant les pointers, tu eviteras nombres d'erreurs qui leur sont liés.

Dans tous les cas, bon courage pour la suite ;)
Messages postés
4
Date d'inscription
vendredi 5 septembre 2003
Statut
Membre
Dernière intervention
11 novembre 2005

Avis aux Webmasters: Vous devrier regarder du coté d'Opera, il semble que tous mes CRLF du post precedent soient partis dans la stratosphere ^^
Messages postés
1606
Date d'inscription
samedi 10 juillet 2004
Statut
Membre
Dernière intervention
25 juillet 2014
10
effectivement afficher un pointeur ne presente que peu d'interet si ce n'est pedagogique.

le but de l'exercice étant surtout de manipuler les pointeurs et de
comprendre leur fonctionnement et la je te rejoins ils sont à la base
du fonctionnement de tous les programmes informatique et ce quelque
soit le langage employé. Ainsi le simple fait de faire un add dans une
liste cree plusieurs pointeurs (meme si c'est transparent pour le
programmeur).