Partage
  • Partager sur Facebook
  • Partager sur Twitter

Question sur les pointeurs

    26 mars 2022 à 16:40:49

    Bonjour,

    je commence maintenant le chapitre que les pointeurs.

    Je ne comprends pas pourquoi il fait mettre l'étoile * avant la variable pointeur.

    J'ai essayé de ne pas mettre l'étoile et ça donne le même résultat.

    Voici le code:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int age = 10;
        int *pointeurSurAge = &age;
        printf("pointeurSurAge vaut %p\n", pointeurSurAge);
        int pointeurSurAge2 = &age;
        printf("pointeurSurAge2 vaut %p\n", pointeurSurAge2);
        return 0;
    }
    


    Vous verrez, que pointeurSurAge 2 donne le même résultat que pointeurSurAge.

    Alors à quoi sert l'étoile * ?

    Merci pour votre aide

    -
    Edité par ATGC 26 mars 2022 à 16:59:13

    • Partager sur Facebook
    • Partager sur Twitter
      26 mars 2022 à 17:28:31

      Actives les warning -Wextra et -Wall
      Essaies d'afficher: *pointeurSurAge1 et *pointeurSurAge2
      • Partager sur Facebook
      • Partager sur Twitter

      Le Tout est souvent plus grand que la somme de ses parties.

        26 mars 2022 à 17:37:51

        Dans le code que tu nous montres l'étoile sert à déclarer la variable pointeurSurAge comme étant un pointeur (sur int dans ton code).

        Dans ton code la variable pointeurSurAge2 est déclarée comme étant un entier (int). 

        A cet entier, tu lui affectes une adresse, comme une adresse est un entier, il l'accepte, mais le compilateur émet un Warning comme quoi la variable n'est pas adapter pour recevoir une adresse. (Les tailles ne sont pas forcement compatible).

        Seule les pointeurs peuvent être affecté avec des adresses ! 

        • Partager sur Facebook
        • Partager sur Twitter
        ...
          26 mars 2022 à 17:38:18

          PierrotLeFou a écrit:

          Actives les warning -Wextra et -Wall
          Essaies d'afficher: *pointeurSurAge1 et *pointeurSurAge2


          D'accord, ça me met une erreur, même si je ne comprends pas très bien pourquoi

          error: invalid type argument of unary '*' (have 'int')|

          • Partager sur Facebook
          • Partager sur Twitter
            26 mars 2022 à 17:50:37

            rouIoude vient de t'expliquer que tu veux mettre une adresse dans un int. Ça risque de ne pas marcher, d'où ton warning.
            Faire *pointeurSurAge ne peut pas marcher car tu ne l'as pas déclaré comme pointeur.
            • Partager sur Facebook
            • Partager sur Twitter

            Le Tout est souvent plus grand que la somme de ses parties.

              26 mars 2022 à 17:50:42

              rouIoude a écrit:

              Dans le code que tu nous montres l'étoile sert à déclarer la variable pointeurSurAge comme étant un pointeur (sur int dans ton code).

              Dans ton code la variable pointeurSurAge2 est déclarée comme étant un entier (int). 

              A cet entier, tu lui affectes une adresse, comme une adresse est un entier, il l'accepte, mais le compilateur émet un Warning comme quoi la variable n'est pas adapter pour recevoir une adresse. (Les tailles ne sont pas forcement compatible).

              Seule les pointeurs peuvent être affecté avec des adresses ! 

              D'accord, je comprends un peu mieux, même si je pense que je devrai m'attarder un peu plus là dessus.

              Merci



              • Partager sur Facebook
              • Partager sur Twitter
                26 mars 2022 à 17:56:01

                Essaies d'afficher  sizeof(pointeurSurAge) et sizeof(pointeurSurAge2)

                ou sizeof(int) et sizeof(int*)

                -
                Edité par PierrotLeFou 26 mars 2022 à 17:58:50

                • Partager sur Facebook
                • Partager sur Twitter

                Le Tout est souvent plus grand que la somme de ses parties.

                  26 mars 2022 à 19:56:32

                  Hello,

                  Essaye de compiler ce code, qui affiche la valeur pointée

                  #include <stdio.h>
                   
                  int main(void)
                  {
                      int age = 10;
                      int *pointeurSurAge = &age;
                      printf("*pointeurSurAge vaut %d\n", *pointeurSurAge);
                      int pointeurSurAge2 = &age;
                      printf("*pointeurSurAge2 vaut %d\n", *pointeurSurAge2);
                      return 0;
                  }

                  -
                  Edité par edgarjacobs 26 mars 2022 à 19:56:46

                  • Partager sur Facebook
                  • Partager sur Twitter

                  On écrit "j'ai tort", pas "tord" qui est le verbe "tordre" à la 3ème personne de l'indicatif présent

                    26 mars 2022 à 20:12:27

                    L'exemple de ce cours de qualité fort discutable est artificiel, il est là pour montrer comment on utilise un pointeur. Pas pourquoi on l'utilise.

                    Comme il n'y a pas d'objectif, il n'y a pas vraiment de raison d'employer un pointeur, et donc de "mettre des étoiles" ou pas. Ça fait des programmes qui - quand le compilateur en veut - affichent un truc, et voilà.

                    ---

                    Prenons un exemple connu, scanf. Dans 

                    int age;
                    printf("votre age ?");
                    scanf("%d", &age);

                    On est bien d'accord qu'on met & dans le scanf, parce que scanf attend qu'on lui dise à quel endroit il faut ranger la valeur tapée par l'utilisateur. 

                    On donne donc à scanf, comme 2ieme paramètre, l'adresse  (et pas la valeur) d'une variable entière. Age est une variable entière, &age est son adresse.

                    Maintenant si on veut passer par une variable intermédiaire

                    scanf("%d", adr_entier);

                    Il faut que adr_entier contienne cette adresse, donc avoir fait

                    adr_entier = &age;

                    Et pour ça avoir déclaré adr_entier du type qui va bien.

                    int *adr_entier;

                    Il y a une étoile parce que ce n'est pas une variable qui contient un int,  mais l'ADRESSE d'un int. Un pointeur d'entier.

                    Que peut on faire avec cette variable adr_entier, maintenant qu'elle est déclarée ?

                    • Y affecter l'adresse d'un entier. C'est ce qu'on a fait avec adr_entier = &age;
                    • Se servir de sa valeur (Qui est une adresse), c'est ce qu'on a fait dans scanf("%d", adr_entier);
                    • On peut aussi la déréferencer, c'est à dire se servir de l'entier designé par l'adresse contenue dans le pointeur (l'entier pointé)
                    Exemple 
                    printf("vous avez %d ans\n", *adr_entier);
                    La notation *, ca dit qu'on fait afficher la valeur de l'entier pointé, pas la valeur du pointeur.

                     ---

                    Donc deux usages de l'étoile

                    •  Dans la déclaration du pointeur
                    • Lors de son déréférencement.

                    Ce n'est pas un hasard. Un des principes de conception de C, c'est que la déclaration d'une variable ressemble à  son utilisation.

                    Ici, 

                    int *adr_entier;

                    Ca raconte que *adr_entier s'utilise comme un int.

                    Si on déclarait 

                    int *p[10];

                    Ça raconterait que p est un tableau de 10 pointeurs d'entier. Pour manipuler un de ces entiers on ferait

                    *p[3] = 45;
                    printf("résultat = %d\n",  *p[i]);

                    Ça ressemble, non ?

                    -
                    Edité par michelbillaud 26 mars 2022 à 21:01:11

                    • Partager sur Facebook
                    • Partager sur Twitter
                      27 mars 2022 à 1:25:42

                      En espérant que ceci va éclairer et non assombrir ...
                      -
                      #include <stdio.h>
                      int main(void) {
                          int age = 42;
                          int *ptr = &age;
                          printf("%d\n", age);   // valeur de age directement
                          printf("%d\n", *ptr);   // Valeur de age par le pointeur.
                          printf("%p\n", ptr);   // Valeur de ptr = adresse de age.
                          printf("%p\n", &ptr);   // Adresse du pointeur ptr.
                      }
                      -
                      42                                                                                                                      
                      42                                                                                                                      
                      000000000061fdec                                                                                                        
                      000000000061fde0
                      • Partager sur Facebook
                      • Partager sur Twitter

                      Le Tout est souvent plus grand que la somme de ses parties.

                        27 mars 2022 à 7:20:29

                        Au fait, pourquoi utiliser un pointeur ? Quel besoin ?

                        Bon, par exemple, à plusieurs endroits on voudrait demander un entier, et vérifier qu'il est entre deux valeurs (sinon on repose la question).

                        Par exemple avec un appel de ce genre

                        int age;
                        
                        demander_entier("quel age ?", &age, 1, 140);

                        Ou

                        int nb_places;
                        
                        demander_entier("combien de passagers ?", 
                                        & nb_places,
                                        1, 4); 

                        La fonction aura comme second parametre une adresse, celle de l'entier à remplir.  Il est donc déclaré comme pointeur d'entier

                        void demander_entier(char question[],
                                             int *adr_nombre,   // pointeur
                                             int min,
                                             int max)
                        {
                             while(true) {
                                printf("%s ", question);
                                scanf("%d", adr_nombre);
                                if (  (min  <= *adr_nombre)
                                    &&(*adr_nombre <= max)) break;
                                printf("invalide\n");
                             }
                        }





                        -
                        Edité par michelbillaud 27 mars 2022 à 7:21:32

                        • Partager sur Facebook
                        • Partager sur Twitter
                          27 mars 2022 à 14:43:22

                          michelbillaud a écrit:

                          Au fait, pourquoi utiliser un pointeur ? Quel besoin ?

                          Bon, par exemple, à plusieurs endroits on voudrait demander un entier, et vérifier qu'il est entre deux valeurs (sinon on repose la question).

                          Par exemple avec un appel de ce genre

                          int age;
                          
                          demander_entier("quel age ?", &age, 1, 140);

                          Ou

                          int nb_places;
                          
                          demander_entier("combien de passagers ?", 
                                          & nb_places,
                                          1, 4); 

                          La fonction aura comme second parametre une adresse, celle de l'entier à remplir.  Il est donc déclaré comme pointeur d'entier

                          void demander_entier(char question[],
                                               int *adr_nombre,   // pointeur
                                               int min,
                                               int max)
                          {
                               while(true) {
                                  printf("%s ", question);
                                  scanf("%d", adr_nombre);
                                  if (  (min  <= *adr_nombre)
                                      &&(*adr_nombre <= max)) break;
                                  printf("invalide\n");
                               }
                          }





                          -
                          Edité par michelbillaud il y a environ 7 heures

                          Merci pour ces exemples, je comprends un peu mieux.

                          • Partager sur Facebook
                          • Partager sur Twitter
                            27 mars 2022 à 14:47:12

                            Un pointeur, c'est fait pour pointer. Tu as affiché l'adresse du pointeur, mais pas l'éventuelle valeur pointée. C'est là où il y a vraiment une différence.

                            Si je fais ça :

                            #include <stdio.h>
                            int main(void)
                            {
                                int x = 34 ;
                                // 1) D'abord un vrai pointeur
                                int *p1 ;
                                p1 = &x ;       // on le fait pointer sur x
                                printf("Valeur du pointeur : %p\n", p1) ;
                                printf("Valeur pointée     : %d\n", *p1) ;
                                // 2) Ensuite un faux pointeur
                                int p2 ;
                                p2 = &x ;       // on le fait pointer sur x
                                printf("Valeur du pointeur : %p\n", p2) ;
                                printf("Valeur pointée     : %d\n", *p2) ;
                            }

                            ça ne compile pas : il refuse la dernière ligne.

                            Ainsi, même s'il peut servir (aux warnings près) à stocker une adresse, un entier ne peut pas servir à pointer.

                            (Chez moi ça ne donne pas la même chose : 0x7ffced5b0218 puis 0xed5b0218. Apparemment le pointeur a plus de chiffres.)

                            -
                            Edité par robun 27 mars 2022 à 14:49:08

                            • Partager sur Facebook
                            • Partager sur Twitter

                            Question sur les pointeurs

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown