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

Langage Pascal Discussion :

[LG]Introduction aux pointeurs


Sujet :

Langage Pascal

  1. #1
    Futur Membre du Club
    [LG]Introduction aux pointeurs
    Bonjour

    Je voudrais modifie une variable pdt l'éxecution d'un programme...

    Je n'ai pas trop saisie le principe des pointeurs et j'aurai voulu avoir un peu d'aide pour comprendre :-D.



    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
     
    uses crt ;
    type entier = integer ; {type entier}
         PEntier = ^entier ; {pointe sur le type entier}
     
    var p : PEntier ; {ze pointeur}
    Begin
        clrscr ;
        p := NIL ;
        new (p) ;
        readln (p^) ; 
        writeln (p^) ;
        p^ := 6 ;
        dispose (p) ;
        readkey ;
    End.


    J'appuye par exemple sur 4, ça m'affiche 4 mais je voudrai que ça passe à 6 et ça ne le fait pas

    Je ne sais pas pourquoi ça ne fonctionne pas, ce que j'ai compris des pointeurs : c'est que ce sont des variables dynamiques, qui peuvent etre modifie pendant l'execution d'un programme, c ça ou j'ai tous faux ?

    Merci

  2. #2
    Responsable Pascal, Lazarus et Assembleur

    Bonjour !

    Quand tu dis : "je voudrais que ça passe à 6 et ça ne le fait pas", comment sais-tu que ça ne le fait pas ? Si c'est lors de l'affichage à l'écran, c'est normal que cela ne se voie pas car tu assignes 6 à ta variable dynamique juste après !

    Quant à la définition des pointeurs, il serait plus clair de dire que ce sont des adresses de variables dynamiques. En fait, lorsque tu exécutes New(p), le système d'exploitation alloue une variable de la taille voulue (dans ton cas, 2 octets puisqu'il s'agit d'un Integer) n'importe où dans la mémoire réservée à ton programme (le "tas") et il te renvoie l'adresse de la variable dans p.

    Et si tu modifies p, tu cours à la catastrophe : l'adresse de ta variable dynamique est perdue et si tu fais référence à celle-ci, ton programme va aller chercher autre chose ailleurs en mémoire.

    Donc, tu peux modifier ta variable dynamique (p^) à volonté, mais il vaut mieux ne pas modifier son adresse (p).
    Règles du forum
    Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
    Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
    Mes tutoriels et sources Pascal

    Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]

  3. #3
    Membre du Club
    ok
    John_win a écrit:

    J'appuye par exemple sur 4, ça m'affiche 4 mais je voudrai que ça passe à 6 et ça ne le fait pas


    Si je comprend bien ton pobleme tu veux afficher la valeur de ^P apres l'afectation : Donc tu n'as qu'a faire un write(^P) apres ^P := 6;

  4. #4
    Membre du Club
    ok
    John_win a écrit:

    J'appuye par exemple sur 4, ça m'affiche 4 mais je voudrai que ça passe à 6 et ça ne le fait pas


    Si je comprend bien ton pobleme tu veux afficher la valeur de P^ apres l'afectation : Donc tu n'as qu'a faire un write(P^) apres P^ := 6;

  5. #5
    Rédacteur

    Je voulais juste ajouter que lorsque tu crée la variable pointeur, par exemple sur un type entier, 2 octetc son alloués pour la valeur et un certain nombre (en général 4 octetc) pour stocker l'adresse en mémoire.

    De plus, est-ce que c'est si nécessaire de donner la valeur NIL au pointeur avant de l'initialiser avec new()?

  6. #6
    Membre du Club
    kik
    Oui
    Car avant le La variable peut pointer sur une autre adresse memoire

    Alors la les les lacune commencent

    Je te donne par exemple un exemple


    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     
    Var 
        str : ^string;
     
    BEGIN
      new(str);
      str := 'lol';
      Writeln(str);
      Readln;
    End.


    Alors t'as remarqué la difference
    Je te decris le resultat sur ma becane a cote (80806)
    Lol s'affiche suivi d'une phrase de caractere comme (11##7erpæÆÑA¾rô☼?)♥4444↓gÌ!Ü««\5│¯)
    Alors l'amigos t'as compris

    Un conseil de l'ecole (initialse toujours la variable avant utilisation)

    a+

  7. #7
    Rédacteur/Modérateur

    Ah ben, le code de Macluvitch est sûr de ne pas marcher !!
    Déjà, je conseillerais quand on utilise des pointeurs, de faire des types nouveaux :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    type PString=^string;

    Ici, on définit le type "Pointeur sur String".
    Ensuite new alloue une zone mémoire de la taille du type PString ( dans notre cas, 256 octets... ). Après cette allocation, on peut donc ranger une valeur dans la variable pointée par le pointeur sur string
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
     
    str^:='salut';
    writeln(str^);

    Surtout ne pas oublier le chapeau, sinon ca risque de ne pas bien marcher !!
    Et aussi, ne pas oublier le dispose, sinon ca risque de provoquer des erreurs !
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    dispose(str);

    Avec tout ça, tu es paré pour les pointeurs :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    type PString=^String;
    var str:PString;
    begin
    new(str); { ou str:=new(PString) --> syntaxe utilisée pour les objets plutôt }
    str^:='salut';
    writeln(str^);
    dispose(str);
    readln;
    end.


    a+
    M.Dlb - Modérateur z/OS - Rédacteur et Modérateur Pascal

  8. #8
    Responsable Pascal, Lazarus et Assembleur

    Citation Envoyé par King Kaiser
    De plus, est-ce que c'est si nécessaire de donner la valeur NIL au pointeur avant de l'initialiser avec new()?
    Sûrement pas : c'est une instruction inutile.

    Juste une dernière précision après la démonstration magistrale de Wormful_Sickfoot : tu peux forcer la fonction New à renvoyer Nil en cas d'erreur, au lieu de provoquer une runtime error bête et méchante.

    Pour ce faire, il suffit d'écrire une petite fonction comme celle-ci :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    {$F+}
    Function ERREUR_ALLOCATION (Taille : Word) : Integer;
    Begin
      ERREUR_ALLOCATION:=1;
    End;
    {$F-}

    (ne surtout pas oublier les appels far)

    Ensuite, il faut affecter l'adresse de cette fonction à la variable HeapError (de l'unité System), au début de ton programme principal :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    HeapError:=@ERREUR_ALLOCATION;

    Ainsi, après chaque allocation, tu testes la valeur du pointeur renvoyé avant de continuer. Cela alourdit un peu l'écriture de ton programme, mais ça fait nettement plus "pro".

    Exemple :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    New(p);
    if p <> Nil
       then
         { traitement }
       else
         WriteLn('Mémoire insuffisante');

    Dernier détail : la fonction doit renvoyer la valeur 1 avec BPW, mais je me demande si ce n'est pas -1 avec TP7. A vérifier.
    Règles du forum
    Cours et tutoriels Pascal, Delphi, Lazarus et Assembleur
    Avant de poser une question, consultez les FAQ Pascal, Delphi, Lazarus et Assembleur
    Mes tutoriels et sources Pascal

    Le problème en ce bas monde est que les imbéciles sont sûrs d'eux et fiers comme des coqs de basse cour, alors que les gens intelligents sont emplis de doute. [Bertrand Russell]

###raw>template_hook.ano_emploi###