Partage
  • Partager sur Facebook
  • Partager sur Twitter

Pointeur

    13 septembre 2020 à 11:37:28

    Bonjour, 

    Je commence à apprendre le language C, je suis dans le chapitre sur les pointeurs, cependant j'ai une question, le pointeur est défini comme une variable qui contient l'adresse d'une autre variable. Mais est ce que un pointeur peut pointer vers un type de variable, par exemple, un pointeur peut-il contenir plusieurs adresses de toutes les variables qui sont des flottants, ainsi si une fonction ne demande que des flottants on peut lui donner facilement l'adresse de cet unique pointeur !

    J'espère que ma question n'est pas trop embrouillante ^^" 

    Merci d'avance 

    • Partager sur Facebook
    • Partager sur Twitter
      13 septembre 2020 à 12:02:49

      Martin3338526 a écrit:

      le pointeur est défini comme une variable qui contient l'adresse d'une autre variable. 

      Tout à fait !

      Un pointeur peut pointer sur une variable de type flottant, il suffit qu'il soit de type pointeur sur flottant (double ou float en C),(éventuellement pointeur sur void, mais ça tu verras plus tard). Mais il ne peut pointer que sur une seule variable à la fois ! Si tu veux pointer plusieurs variables, il te faut un tableau de pointeurs ! 

      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        13 septembre 2020 à 14:00:46

        Salut,

        Tu peux feinter la limite d'une adresse par pointeur en utilisant un tableau de pointeurs :

        float *tab_ptr[SIZE] = {NULL};

        lors de l'envoie de cette variable à une fonction tu vas lui envoyer un pointeur sur un tableau de pointeurs de float. Par contre fait attention avec le C et les tableaux de pointeurs, c'est très mal fait au niveau typage et on s'y perd très rapidement. Par exemple en double tableau est un tableau de pointeur sur des tableaux mais ça ne fonctionne pas pareil :

        int tab[2][2] = {{1,2},{3,4}}; // ici on a 2 lignes
        int *ptr_tab[2] = {{1,2},{3,4}}; // ici aussi
        
        // avec tab on est obligé de définir la taille des colonnes
        // et elles sont toutes de même taille
        // avec ptr_tab on n'est pas obligé de préciser la taille
        // et on peut y ranger des éléments de taille différent

        Et on peut aller jusqu'aux pointeur sur pointeur qui représentant aussi un tableau de pointeurs et un double tableau mais fonctionne différemment. Il faut bien comprendre toutes ces subtilisées car c'est un point où tu y ferras souvent des erreurs ou te bloquera.

        Par exemple pour faire un tableau de string tu faire un double tableau mais il y a mieux :

        char *str_tab[] = {
           "bonjour",
           "je suis content",
           "toutes ces chaines n'ont pas la meme taille",
           "et ca fonctionne quand meme"
        }

        utiliser le double tableau nous forcerait à avoir des chaines de taille identiques ce qui implique des problèmes de taille ou alors de l'espace mémoire perdu. L'autre solution sera d'utiliser un pointeur sur pointeur mais on ne pourrait pas initialiser aussi facilement (malloc / free);

        -
        Edité par Anonyme 13 septembre 2020 à 14:06:29

        • Partager sur Facebook
        • Partager sur Twitter
          13 septembre 2020 à 16:03:44

          Salut,

          Le fait  est qu'il n'y  a jamais qu'une variable bien précise à chaque adresse mémoire susceptible d'être représentée.

          Par contre, les pointeurs ont "cela de bien" que, représentant l'adresse à laquelle on devrait trouver une donnée d'un type particulier, il est tout à fait possible d'aller à "l'adresse suivante" et d'y trouver une autre donnée du même type.

          C'est, d'ailleurs, ce que l'on fait avec les tableaux, par exemple.

          Donc, pour répondre à ta question: non un pointeur ne peut représenter qu'une adresse mémoire à la fois, et nous ne pourrons trouver qu'une seule donnée d'un type bien particulier à cette adresse.

          Par contre, il est possible d'organiser les données en mémoire de manière à ce que toutes les données d'un même type soient regroupées et qu'elles apparaissent à des adresses mémoire successives.

          Et comme on doit indiquer le type de la donnée que l'on s'attend (que l'on espère) trouver à l'adresse mémoire représentée par le pointeur et que, de plus, chaque type de donnée va nécessiter "une certaine quantité" de mémoire pour être entièrement représenté, il sera effectivement possible (dans certaines conditions) de partir de l'adresse mémoire (connue) à laquelle se trouve une donnée, et de "faire un bond" vers une autre adresse mémoire, à laquelle se trouvera (on l'espère du moins) une autre donnée de même type ;)

          • Partager sur Facebook
          • Partager sur Twitter
          Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
            14 septembre 2020 à 7:27:25

            > Le fait  est qu'il n'y  a jamais qu'une variable bien précise à chaque adresse mémoire susceptible d'être représentée.
            Pas certain de la comprendre celle-là ...
            Tu peux avoir plusieurs variables qui pointent vers la même position. C'est rare que c'est utile.
            On a parlé de pointeurs vers des tableaux et des tableaux de pointeurs. Il ne faut pas confondre.
            Un pointeur vers un tableau est l'adresse du premier élément du tableau.
            Sachant le type du pointeur (et du tableau) on pourra accéder aux autres  éléments du tableau.
            Un tableau de pointeurs est un tableau qui contient plusieurs pointeurs de même type (en général, sauf les void).
            Chaque pointeur du tableau pointe vers un élément différent, possiblement un tableau également (mais pas forcément).
            Et pour en rajouter, on peut avoir un pointeur vers l'adresse d'un autre pointeur.
                int n = 42;
                int *p = &n;
                int *q = &p;
            • Partager sur Facebook
            • Partager sur Twitter

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

              14 septembre 2020 à 9:30:56

              PierrotLeFou a écrit:

              > Le fait  est qu'il n'y  a jamais qu'une variable bien précise à chaque adresse mémoire susceptible d'être représentée.
              Pas certain de la comprendre celle-là ...
              Tu peux avoir plusieurs variables qui pointent vers la même position. C'est rare que c'est utile.

              Si tu as un code aussi simple que

              int i=15;
              int j=18;
              int * ptr = &i;

              ptr contient l'adresse mémoire de ... i.  Et si tu regarde "ce qui est pointé" par ptr, tu ne pourras y trouver ... que i.

              Si tu veux accéder à la valeur de j, tu devras aller voir ce qui se trouve en ... ptr++.

              De même si tu as un code à peine plus compliqué prenant la forme de

              int tab[3]={15, 18, 20};

              En tab[0], tu ne pourra trouver que la valeur 15.  Si tu veux accéder à la valeur 18, tu devras aller voir ce qui se trouve en tab[1] et si tu veux accéder à la valeur 20, il faudra que tu aille voir en ... tab[2].

              On pourrait encore aller plus loin, avec un code proche de

              typedef struct point_{
                  int x;
                  int y;
                  struct point* suivant;
              }point;
              point p1;
              point p2;
              p1.x = 15;
              p1.y = 18:
              p1.suivant = &p2;
              p2.x = 20;
              p2.z = 24;
              p2.suivant = nullptr;
              

              Si l'adresse de p1 regroupe, effectivement, trois données (x,y et adresse de p2), ces trois données sont chacune à une adresse différente (adresse de p1 pour p1.x, adresse de p1+sizeof(int) pour p1.y et adresse de p1 + 2*sizeof(int) pour suivant, qui représente l'adresse de p2.

              Donc, à un instant T de ton exécution, si tu observe une adresse particulière de ton programme, tu ne pourras jamais y trouver qu'une seule donnée bien précise. et ce, quel que soit le nombre de pointeurs qui pointent vers cette adresse bien précise.

              Si tu veux accéder à "une autre" donnée, qu'il s'agisse d'une autre donnée de même type ou de la donnée suivante contenue par la structure permettant de représenter le concept "complexe" que tu manipule,  tu devras aller regarder à une adresse différente pour le faire.

              C'est pour cela que j'ai dit qu'il n'y aura jamais qu'une seule variable (j'aurais du parler de donnée ou de valeur, cela aurait été plus juste) à chaque adresse susceptible d'être représentée.  Car on se fout du nombre de pointeur qui fournissent l'adresse mémoire en question ;)

              -
              Edité par koala01 14 septembre 2020 à 9:33:35

              • Partager sur Facebook
              • Partager sur Twitter
              Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                14 septembre 2020 à 9:50:12

                koala01 a écrit:

                Si tu as un code aussi simple que

                int i=15;
                int j=18;
                int * ptr = &i;

                ptr contient l'adresse mémoire de ... i.  Et si tu regarde "ce qui est pointé" par ptr, tu ne pourras y trouver ... que i.

                Si tu veux accéder à la valeur de j, tu devras aller voir ce qui se trouve en ... ptr++.

                Pour les tableau ok, mais là c'est beaucoup moins sûr !

                • Partager sur Facebook
                • Partager sur Twitter
                  14 septembre 2020 à 9:58:08

                  rouloude a écrit:

                  Pour les tableau ok, mais là c'est beaucoup moins sûr !

                  Oui, de fait... j'avais pourtant prévu de préciser "à priori, et encore", mais... ca m'est sorti de la tête :p

                  Merci pour la précision ;)

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                    14 septembre 2020 à 14:59:34

                    rouloude a écrit:

                    koala01 a écrit:

                    Si tu as un code aussi simple que

                    int i=15;
                    int j=18;
                    int * ptr = &i;

                    ptr contient l'adresse mémoire de ... i.  Et si tu regarde "ce qui est pointé" par ptr, tu ne pourras y trouver ... que i.

                    Si tu veux accéder à la valeur de j, tu devras aller voir ce qui se trouve en ... ptr++.

                    Pour les tableau ok, mais là c'est beaucoup moins sûr !


                    Il n'est absolument pas dit que la variable i sera représentée par une zone en mémoire située après celle de i. Elle a très bien pu être représentée ailleurs, par un registre, ou rien du tout.

                    $ cat a.c
                    #include <stdio.h>
                    
                    int main() {
                       int i = 12;
                       int j = 34;
                       int *p = & i;
                       printf("%d\n", *(p+1));
                    }
                    
                    $ gcc a.c
                    $ ./a.out 
                    1275787468
                    $ ./a.out 
                    129405788
                    $ ./a.out
                    1387327484


                    nawak, et pas le même à chaque fois.

                    -
                    Edité par michelbillaud 14 septembre 2020 à 15:00:25

                    • Partager sur Facebook
                    • Partager sur Twitter
                      14 septembre 2020 à 17:46:20

                      Ce que je voulais dire est ceci:
                          int n = 42;
                          int *p = &n;
                          int *q = &n;
                      Alors *p == *q
                      J'ai déjà vu ça dans un algorithme d'arbre binaire représentant une expression arithmétique.
                      L'auteur voulait implémenter la distributivité de la multiplication sur l'addition:
                      (a+b)*(c+d) = a*c+a*d+b*c+b*d, certains termes étant répétés.
                      • Partager sur Facebook
                      • Partager sur Twitter

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

                      Pointeur

                      × 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