IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

Utilisation de pointeurs


Sujet :

Delphi

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 4
    Points : 3
    Points
    3
    Par défaut Utilisation de pointeurs
    : je suis débutant et les pointeurs me posent quelques problèmes. Je vourais pouvoir definir une adresse varaible de la facon suivante:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    var a1,a2, a3 , nom : string;
    pnom : ^string;
    pointeur : ^string;
    i : byte;
     
    begin
      for i := 1 to 3 do
      begin
        nom := 'a'+IntToStr(i);
        pnom := @nom;
        pointeur := @pnom^;
        pointeur := 'ok'+ IntToStr(i);
      end;
    end;
    l'instruction pointeur:=@pnom^ ne pointe pas sur l'adresse du nom contenu dans pnom, et je ne sais pas comment faire. je voulais ecrire ok1 dans a1, ok2 dans a2 et ok3 dans a3.

  2. #2
    Rédacteur
    Avatar de Pedro
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    5 411
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 5 411
    Points : 8 078
    Points
    8 078
    Par défaut
    Salut
    Lorsque tu déclares une variable pnom:^string, tu ne dois pas mettre le @ devant... C'est déjà un pointeur...
    en mettant @Nom^, tu as un pointer d'un pointer d'un type string
    Pedro
    Aucune réponse aux sollicitations techniques par MP

    Faut pas attendre d'en avoir besoin pour s'en servir... (Lucien Stéphane)

    Les pages Source C'est bon. Mangez-en!
    Le défi Delphi
    Règles du forum - FAQ Delphi - Pensez au chtit
    Aéroclub Bastia Saint-Exupéry

  3. #3
    Expert éminent sénior

    Avatar de Nono40
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2002
    Messages
    8 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Industrie

    Informations forums :
    Inscription : Mai 2002
    Messages : 8 640
    Points : 19 101
    Points
    19 101
    Par défaut
    Ce que tu veux faire ne fonctionnera jamais.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    nom := 'a'+IntToStr(i); 
    pnom := @nom;
    "Nom" va contenir une chaine "Ax"
    "pnom" va contenir l'adresse de la variable "nom" et non pas l'adresse de la variable "Ax".

    Il n'est pas possible de faire ce que tu veux.
    Delphi :
    La F.A.Q. , 877 réponses à vos questions !
    264 sources à consulter/télécharger !

  4. #4
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Je te propose une explication, qui, je l'espère te permettra de comprendre ce que sont des pointeurs, les variables, les adresses, etc...

    La mémoire :
    Tout d'abord, tu as la mémoire de l'ordinateur, tu peux te la représenter comme un nombre très important de cases d'une certaine taille que l'on appelle un octet. Tes cases, pour que ton ordinateur puisse y acceder, il faut qu'il puisse les repérer par un numéro : son Adresse.

    Donc, en gros, la mémoire d'un ordinateur est un gros tableau de cases numérotées de 0 à beaucoup, ces cases contenant chacune un octet.

    Les variables :

    Le gros tableau qu'est la mémoire est remplis par des données, qui des fois, ont besoin d'un octet, de deux, de quatre ou plus pour pouvoir être représentées : ces données sont appelées variables, celà peuvent être des caractères, des nombres.....
    Imaginons que tu aies une variable déclarée dans ton code delphi :
    UnNombre, qui a besoin de 32bits pour être stocké, va donc utiliser dans ton grand tableau, quatre cases contigues (quatre octets). Par exemple les case n° 205, 206, 207 et 208.
    pour obtenir le numéro de la case (donc l'Adresse) dans lequel elle se trouve tu as deux possibilités : @UnNombre ou bien Addr(UnNombre)

    L'adresse de UnNombre, sera le numéro de la première case qu'il occupe, c'est a dire 205.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    var UneAdresse:Pointer;
          UnNombre:cardinal;
    begin
      UneAdresse:=@UnNombre;
      //ou bien
      UneAdresse:=Addr(UnNombre);
    end;
    Donc,@Xsignifie "Donnes moi l'adresse de X"


    Les Pointeurs
    Déjà, un pointeur est une variable, un peu similaire à un entier (c'est criant en C++, pas en Delphi).
    C'est une variable, sur 32bits (4 octets), qui contient l'Adresse d'une case de la memoire.
    Comme c'est similaire à un nombre entier, on peut tout à fait imaginer (pour l'instant, on imagine, hein...) des additions et des soustractions et même afficher son contenu (ça marche très bien en c++, mais pas en Delphi qui "protège" ce genre de chose pour éviter des "accidents").

    Un pointeur, contenant en général l'adresse d'une autre variable, on dit que ce dernier "pointe" sur cette autre variable.

    Quand la valeur de l'adresse contenu dans le pointeur est égale à zéro, alors ça ce traduit en Delphi par UnPointeur=nil (bref, nil, c'est zéro).

    Maintenant, il peut être intéressant, connaissant une Adresse, de pouvoir acceder à son contenu.
    En supposant que UnPointeur=205, UnPointeur^ nous donnera le contenu de ce qui se trouve à la case n°205, c'est à dire la valeur de UnNombre.

    Donc,X^signifie "Donnes moi la valeur de ce qui se trouve en X"

    J'espère avoir été clair.

    Variables avancees :
    Normalement, une Variable d'un certain type (un byte par exemple, qui prend un octet, donc une case), ne peut cohabiter avec une variable d'un autre type (un char, qui tient lui aussi sur un octet).
    Celà peut pourtant être pratique pour transformer, sans faire de calculs, une variable UnByte contenant 65, directement en caractère UnChar qui vaudrait 'A'.

    Delphi le permet, tout comme le C++ le permet avec son instruction Union.
    La méthode, mal expliquée dans l'aide Delphi, est de déclarer un enregistrement avec une partie variable, comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Type 
        TSuperVariable=record
                                      case b:boolean of
                                      true:(UnByte:byte);
                                      false:(UneChar:Char);
                                  end;
    Après, on peu travailler "avec la memoire" comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    var SuperVariablebis:TSuperVariable
         UnMessage:string;
    begin
       SuperVariable.AByte:=65;
      //est equivalent à
      //SuperVariable.AChar:='A';
      UnMessage:='Valeur de AByte au format caractère :'+SuperVariable.AChar);
      ShowMessage(UnMessage);
    end;
    Rien n'empêche de faire des SuperVariables plus complexes, comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Type
         TSuperVariable1=record
                                      case i:smallint of
                                      1:(UnPetitReel:single);
                                      2:(UnEntierSigne:Integer);
                                      3:(UnEntierNonSigne:cardinal);
                                      4:(UnPointeur:Pointer);
                                      5:(UnPointeurSurUnEntier:^integer);
                                   end;
    On remarquera juste, que les cinq types (single,intzeger,cardinal,pointer,^înteger), proposent tous des variables de 4 octets. De là, les possibilités sont multiples (et dangereuses, donc attention, hein...)


    Addition sur des Pointeurs :
    Pour ce qui est additions et soustractions avec des pointeurs, c'est possible en déclarant un enregistrement avec une partie variable (sorte de UNION du c++) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    Type 
        TAccesMemoire=record
                                      case i:smallint of
                                      1:(UnPointeur:Pointer);
                                      2:(UneAdresse:Cardinal);
                                      3:(UnPointeurSurCaractere:^char);
                                      4:(UnPointeurSurByte:^byte);
                                  end;
     
    var Acces:TAccesMemoire;
         UneChaine:string;
         i:integer;
         UnMessageBizarre:string;
    begin
       //Initialisation des données
       UneChaine:='bonjour les Delphinautes, comment ça va ? :)';
       i:=66;
       UnMessageBizarre:=''; 
     
       //on se place, sur le premier caractère de la chaîne :
       Acces.UnPointeurSurCharactère:=@UneChaine[1];
     
       //on remplace le b minuscule par l'équivalent ASCII de ce qu'il y a dans i;
       Acces.UnPointeurSurByte^:=i;
     
       //Affichage
       ShowMessage(UneChaine);
       //deux pas en avant, un pas en arrièreu.... (5 fois)  
      for i:=1 to 5 do
      begin
         //2 pas en avant
         Acces.UneAdresse:=Acces.UneAdresse+2;
         //on récupère le caractère pointé
         UnMessageBizarre:=UnMessageBizarre
                                      +Acces.UnPointeurSurCaractere^;
         //1 pas en arrière
         Acces.UneAdresse:=Acces.UneAdresse-1;
         //on récupère le caractère pointé
         UnMessageBizarre:=UnMessageBizarre
                                      +Acces.UnPointeurSurCaractere^;
      end;
     
      ShowMessage(UnMessageBizarre);
     
    end;
    Bidouilleuse Delphi

  5. #5
    Membre averti
    Avatar de Hauwke
    Inscrit en
    Septembre 2005
    Messages
    329
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 329
    Points : 400
    Points
    400
    Par défaut
    Bonjour,
    Chapeau pour la concision et la clarté du post, Waskol. Je me suis cogné, comme beaucoup je pense, la majorité des tutos et autres faq sur les pointeurs sans avoir pu en retirer une essence aussi nette.
    Juste un commentaire au sujet de cette phrase:
    Citation Envoyé par Waskol
    Quand la valeur de l'adresse contenu dans le pointeur est égale à zéro, alors ça ce traduit en Delphi par UnPointeur=nil (bref, nil, c'est zéro).
    Puisque zéro est une adresse comme une autre, ça te dérangerait beaucoup si pour ma compréhension personnelle je modifiais un peu ta phrase de cette manière:
    Lorsque le pointeur ne contient aucune adresse, c'est à dire qu'il ne pointe sur aucune case alors on dit qu'il pointe "nil" (rien, le néant). De fait, en Delphi lorsque l'on lit "Unpointeur=nil" celà signifie que le développeur réserve un espace mémoire pour un pointeur, en l'occurence 4 octets, mais que pour l'instant il ne lui assigne la garde d'aucune adresse.(ca viendra sans doute aprés dans son code...Enfin, normalement ça devrait!)
    Cordialement,
    Hauwke

  6. #6
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Merci Hawke pour tes remerciements.

    Ta phrase est effectivement mieux étayée que la mienne et beaucoup plus compréhensible.

    Celà dit je n'ai pas choisi le terme zéro par hazard,
    Si tu utilises mon histoire de super variable :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Type
        TSuperPointeur=record
                     case b:boolean of
                     true:(UnPointeur:Pointer);
                     false:(UneAdresse:Cardinal);
                 end;
    hé bien tu t'apercevras qu'en écrivant ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    var SuperPointeur:TSuperPointeur;
    begin
      SuperPointeur.UnPointeur:=nil;
      ShowMessage(IntToStr(SuperPointeur.UneAdresse));
    end;
    Delphi t'affiche un joli zéro


    Edit vachement important : Donc zéro n'est pas une Adresse comme les autres !!!
    Bidouilleuse Delphi

  7. #7
    Membre averti
    Avatar de Hauwke
    Inscrit en
    Septembre 2005
    Messages
    329
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 329
    Points : 400
    Points
    400
    Par défaut
    Juste un petit peu de dialectique...
    Citation Envoyé par Waskol
    Quand la valeur de l'adresse contenu dans le pointeur est égale à zéro, alors ça ce traduit en Delphi par UnPointeur=nil (bref, nil, c'est zéro).
    Dans cette phrase zéro est une adresse... Le pointeur contient une adresse. C'est pour cette raison que j'ai pris la liberté de reformuler ta phrase
    Citation Envoyé par Waskol
    [...]hé bien tu t'apercevras qu'en écrivant ceci :
    Code:
    var SuperPointeur:TSuperPointeur;
    begin
    SuperPointeur.UnPointeur:=nil;
    ShowMessage(IntToStr(SuperPointeur.UneAdresse));
    end;[...]
    Dans celle ci tu affectes d'abord nil! Ce qui n'est pas du tout pareil, tu en conviendras. Ici c'est la machine qui a besoin d'un repére n'ayant aucune capacité d'abstraction. Le cpu te signale qu'il a compris ta symbolique et il a traduit de manière à te la restituer. c'est une convention dûe au premier fabricant de microprocesseur reprise par les constructeurs de langage. Le zéro est bien une adresse comme les autres, celle qui dans la logique binaire de la machine représente le "rien" puisque nos chères têtes à octets n'ont, en réalité, aucune notion de rien, de tout, d'ensemble et ou d'infinité. Toutes ces choses qui de toutes les façons n'éxistent que dans nos esprits aux capacités cognitives.
    Pour l'instant, le résultat est le même, j'en conviens.Mais pendant combien de temps encore? En fait, il ne s'agit que d'une convention dûe à la base de codage du système. Changes le 0,1 en carrotes, choux, navets et la théorie du "nil" reste valide mais le pointeur renverra non plus 0 mais choux par exemple. Dans la première phrase c'est toi qui parle le langage de l'ordinateur, dans la seconde c'est lui qui te répond dans le tien. Aujourd'hui grand nombre d'entre nous se tournent vers le Dotnet. ce langage n'admet plus ou peu les pointeurs, je le déplore! Au début, j'ai eu du mal avec les pointeurs mais aujourd'hui je ne saurai que difficilement m'en passer. C'est un domaine fabuleux de la prog, il permet la réalisation de prouesses avec une économie de ressources sans pareille. Avec 20 ko de Ram tu réalises des opérations sur des fichiers de centaines de giga...
    Voilà j'espére t'avoir convaincu de la nécessité de distinguer la théorie de la pratique. je le répéte, ton post est brillant, une huile limpide, mais je pense qu'il ne faut pas faire l'amalgame avec une convention d'utilisation.
    Cordialement,
    Hauwke

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Novembre 2005
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2005
    Messages : 4
    Points : 3
    Points
    3
    Par défaut
    merci à tous pour ces explications, je vais pouvoir continuer de faire joujou avec delphi.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. utilisation des pointeur
    Par nixonne dans le forum Langage
    Réponses: 2
    Dernier message: 25/08/2006, 09h19
  2. Réponses: 14
    Dernier message: 22/04/2006, 21h59
  3. Optimiser l'utilisation des pointeurs
    Par progfou dans le forum C
    Réponses: 65
    Dernier message: 10/03/2006, 11h49
  4. Réponses: 6
    Dernier message: 21/02/2006, 16h47
  5. Utilisation de Pointeurs dans API windows
    Par Drooxy dans le forum API, COM et SDKs
    Réponses: 4
    Dernier message: 13/03/2003, 22h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo