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

 C Discussion :

Comprendre les pointeurs


Sujet :

C

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 6
    Points : 0
    Points
    0
    Par défaut Comprendre les pointeurs
    Bonjour bonsoir a toutes et a tous

    Avant tout, Pardonnez mon orthographe, j'ai un clavier QWERTY

    Je suis un étudiant en informatique 2eme année, j'ai validé tout mes modules sauf les modules de langage C.

    Le plus grand problème c'est les pointeurs, en effet j'ai du mal a les utiliser dans ma tête sa sature, j'ai lu tout les tutos proposés par notre cher ami Google y compris ceux de site mais toujours a la case départ.

    je sais que nombreux d'entre vous maîtrisez ca parfaitement, je demande a ceux qui maîtrisent les pointeurs qu'ils m'expliquent a leurs facon avec des exemple pour illustrer la chose.

    j'espere que ce n'ai pas trop demander pour vous

    Tres cordialement

  2. #2
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2013
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2013
    Messages : 105
    Points : 49
    Points
    49
    Par défaut
    un pointeur renvoie vers un numéro de case mémoire, et non le contenu de cette case
    il suffit de mettre un "p" au début du nom du pointeur pour s'en rappeler

    c'est utile pour se déplacer dans un tableau (ensemble de cases) en s'aidant du pointeur

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 6
    Points : 0
    Points
    0
    Par défaut
    Bonsoir

    Pour la définition, on va dire que je l'ai connais par coeur, j'essaye de m'en servir, mais il suffit de voir un %d et un %p avec des variable qui commencent par des étoiles sachant que je sais même pas dans quel but sont faits ses pointeurs, a part voir une variable se faire appeler de deux manières différentes...

    Cordialement

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut
    Jusqu'à preuve du contraire, le clavier qwerty excuse les fautes d'accents et les manques de cédilles, mais certainement pas les fautes d'orthographe ou de grammaire...

    Ta question est extrêmement vaste, on ne sait pas où commencer. Le plus important est d'avoir une définition claire et précise de ce qu'est un pointeur. Je trouve celle de ShinobiX1 trop vague par exemple, surtout quand ça attaque la partie tableau. Pointeurs et tableaux sont proches mais c'est un débat d'un niveau supérieur.

    Ce qu'il faut retenir, c'est qu'un pointeur est une variable qui contient une adresse (= dont la valeur est une adresse), et normalement cette adresse est celle d'une autre variable. Comme une adresse seule ne permet pas de savoir quel type de données on doit lire, le pointeur est typé : il porte donc en lui-même le type supposé de la donnée qui se trouve à l'adresse donnée par sa valeur.

    Voilà pour la définition d'un pointeur. Il y a ensuite les opérateurs & et * que tu dois connaitre, à relier aux notions d'indirection et de déréférencement. Il y a ensuite les concepts de pointeurs contenant l'adresse du début d'un bloc (fonctions malloc, calloc, realloc et free) de données du même type. Pour finir, tu pourras voir le lien entre tableau et pointeur (http://gradot.wordpress.com/2012/08/...ointeurs-en-c/ mais ça commence déjà à être avancé, il faut déjà bien comprendre le pointeur en lui-même). On ne va pas tout détailler ici car il faudrait plusieurs heures pour tout écrire. Le plus simple et constructif est sans doute que tu poses des questions précises sur les points qui te causent soucis.

  5. #5
    Rédacteur
    Avatar de Franck.H
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2004
    Messages
    6 951
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Haut Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2004
    Messages : 6 951
    Points : 12 462
    Points
    12 462
    Par défaut
    Moi je dis tout simplement, pose tes questions par rapport à ce que tu ne comprends pas et alors nous pourrons t'aider avec des exemples à la clé si nécessaire
    Mon Site
    Ma bibliothèque de gestion des chaînes de caractères en C

    L'imagination est plus importante que le savoir. A. Einstein

    Je ne répond à aucune question technique par MP, merci d'avance !

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    L'exemple le plus simple pour montrer les pointeurs et leur utilité, c'est la fonction qui inverse deux entiers.

    Si on le fait naïvement avec des paramètres reçus par valeur, ça ne marche pas:
    Code C : 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
    #include <stdio.h>
     
    /*La fonction reçoit des copies des entiers*/
    void inverser(int gauche, int droite)
    {
    	/*On inverse les entiers reçus*/
    	int tmp = gauche;
    	gauche = droite;
    	droite = tmp;
    }
     
    int main(void)
    {
    	int a = 10;
    	int b = 42;
    	printf("Avant appel: a = %d, b = %d\n", a, b);
    	inverser(a, b);
    	printf("Après appel: a = %d, b = %d\n", a, b);
    	return 0;
    }

    Par contre, si les entiers étaient dans un tableau, ça marcherait:
    Code C : 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
    #include <stdio.h>
     
    int g_tableau[10];
     
    /*La fonction reçoit les indexes des entiers dans le tableau*/
    void inverser(int indexGauche, int indexDroite)
    {
    	/*On inverse les entiers aux indexes indiqués*/
    	int tmp = g_tableau[indexGauche];
    	g_tableau[indexGauche] = g_tableau[indexDroite];
    	g_tableau[indexDroite] = tmp;
    }
     
    int main(void)
    {
    	g_tableau[3] = 10;
    	g_tableau[4] = 42;
    	printf("Avant appel: a = %d, b = %d\n", g_tableau[3], g_tableau[4]);
    	inverser(3, 4); /*On passe les indexes où se trouvent les entiers*/
    	printf("Après appel: a = %d, b = %d\n", g_tableau[3], g_tableau[4]);
    	return 0;
    }

    Hé bien les pointeurs, ça comme si toutes les variables du programme étaient dans un grand tableau.
    Code C : 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
    #include <stdio.h>
     
    /*La fonction reçoit les pointeurs vers les entiers (type *ptr dans une déclaration signifie "ptr est un pointeur vers variable de type type")*/
    void inverser(int *pGauche, int *pDroite)
    {
    	/*On inverse les entiers pointés (*ptr hors d'une déclaration signifie "valeur pointée par ptr")*/
    	int tmp = *pGauche;
    	*pGauche = *pDroite;
    	*pDroite = tmp;
    }
     
    int main(void)
    {
    	int a = 10;
    	int b = 42;
    	printf("Avant appel: a = %d, b = %d\n", a, b);
    	inverser(&a, &b); /*On passe les adresses où se trouvent les entiers ( &a signifiant "adresse de a")*/
    	printf("Après appel: a = %d, b = %d\n", a, b);
    	return 0;
    }
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 6
    Points : 0
    Points
    0
    Par défaut
    Citation Envoyé par Franck.H Voir le message
    Moi je dis tout simplement, pose tes questions par rapport à ce que tu ne comprends pas et alors nous pourrons t'aider avec des exemples à la clé si nécessaire
    Bonjour

    ca vous sert à quoi les pointeurs, en temps que programmeurs ?

    Pour se déplacer, l'homme à besoin de ses deux jambes, il court pour aller vite, ensuite on à eu les inventions comme le vélo jusqu'à la Ferrari de Alonso . Les différents inventions qui ont été faites ont pris en comptes 3 arguments : gain de temps, moins d'effort et aussi sur la masse déplacée (déménagement avec des camions par exemple)... et pour les pointeurs?

    Cordialement

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Pour se déplacer, l'homme a besoin d'une adresse où aller, surtout.
    Le pointeur, c'est ça: Une adresse.

    Informatiquement, les pointeurs sont indispensables pour tout tableau dont on ne connaît pas la taille lors de l'écriture du programme (le cas facile, c'est quand on connaît la taille durant l'exécution du programme lors de la création du tableau; le cas difficile c'est quand le tableau doit s'agrandir au fur et à mesure que l'utilisateur tape des choses).

    Quant au C, tu vois les pointeurs dès que tu fais un simple puts() ou printf(): En effet, tu passes à la fonction un pointeur vers le premier caractère à afficher!
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut
    Comme l'a dit Médinoc, tu te déplaces, mais pour aller où ?

    Un pointeur, c'est comme un post-it : dessus, il y a écrit l'adresse et ce qu'il y a à cette adresse (un plombier, une restaurant, un marchant de tapis).

    En C, tu as très souvent besoin des pointeurs car les paramètres sont passés par copie. Cela veut dire que tu ne reçois pas la variable elle-même mais une copie de cette variable. Encore une fois, Médinoc l'a déjà dit Essaye un code comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #include <stdio.h>
     
    void f(int a)
    {
        a = 0;
    }
     
    int main(void)
    {
        int a = 50;
        f(a);
        printf("%d\n", a);
        return a;
    }
    Ce code affiche 50 et non 0. Pourquoi ? Parce que dans f(), a n'est pas le même a que dans main(), c'est une copie de ce a. Si tu veux pouvoir modifier, il faut donner à f() un pointeur vers a, pour retrouver a et le modifier directement. Pour reprendre l'analogie au post-it, tu donnes un f() un post-it avec l'adresse de a et le fait que a est de type int (c'est un pointeur sur int : int*), f() fait une copie de ce post-it et utilise à l'intérieur cette copie. Mais la copie d'un post-it te donne un post-it qui contient les informations qu'il te faut pour retrouver a et donc modifier a.
    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
    #include <stdio.h>
     
    void f(int *pa)
    {
        *pa = 0;
    }
     
    int main(void)
    {
        int a = 50;
        int *pa = &a;
        f(pa);
        printf("%d\n", a);
        return a;
    }
    Ce code-ci affiche 0.

    Si tu as compris cet exemple, alors tu as compris à quoi sert un pointeur. Il sert à retrouver une variable qui est quelque part dans la mémoire. Si tu ne l'as pas compris, recommence la lecture de ce message.

  10. #10
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 6
    Points : 0
    Points
    0
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Si tu as compris cet exemple, alors tu as compris à quoi sert un pointeur. Il sert à retrouver une variable qui est quelque part dans la mémoire. Si tu ne l'as pas compris, recommence la lecture de ce message.
    Ca je l'ai bien compris mais, a quoi sa sert? plus précisément c'est quoi la suite?

    La pour moi c'est comme si je suis à table avec une personne et qui me démontre qu'il es capable de manger ou d'écrire avec les deux mains sans contraintes. On peut déduire que si il se blesse d'une main il aura toujours l'autre pour combler les difficultés (L'utilité ).

    Cordialement

  11. #11
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Eh bien, as-tu lu mon dernier message?
    Comment répliquerais-tu les différents exemples (tableau de longueur déterminée à l'exécution, ou simple affichage d'une chaîne de caractères) sans pointeur?

    Tout ce qui n'est pas absolument trivial (comme de simples fonctions mathématiques) en C nécessite qu'une fonction sache où se trouve quelque chose, ce que seuls les pointeurs peuvent apporter.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  12. #12
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 826
    Points : 218 287
    Points
    218 287
    Billets dans le blog
    117
    Par défaut
    Bonjour,

    Moi, je pense qu'il ne faut pas faire comme vous le faites et essayer de comparer avec tous les éléments qui nous entourent. La machine ne marche nécessairement pas de la même façon.
    Il y a plusieurs mécanismes qu'il faut garder en tête :

    La mémoire

    Tout ce qui existe dans un programme correspond à des emplacements en mémoire. La mémoire n'est autre qu'un grand tableau où l'on peut placer des nombres. Voici une mémoire de cinq cases :
    Ça veut dire que je peux mettre cinq nombres dedans.
    À un moment, je déclare une variable :
    Dans la mémoire d'un ordinateur, cela correspond à :
    42
    (Actuellement, mon nombre '42' peut être n'importe où, c'est géré par le système d'exploitation, et peut importe où mon nombre est stocké (tant qu'il est stocké cela suffira).
    Pour une raison ou une autre, nous avons besoin de savoir où, dans la mémoire, est stocké notre nombre. En code C, on peut faire :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    int* pFoo = &foo; // Récupération de l'emplacement mémoire de foo
    En français, pFoo, est équivalent à "case numéro 2".
    En informatique, déjà, l'ordinateur ne gère pas des nombres décimaux, mais des hexa décimaux, mais en plus, il compte à partir de 0, il va me dire :
    0x00000001
    On ajoute 0x devant le nombre, pour indiquer que c'est de l'hexadécimal. Pour l'ordinateur, c'est la case 1, car il existe une case 0. Et cette représentation d'exemple n'est valide que sur les architectures 32 bits, en effet, le nombre 0x00000001 est un nombre sur 32 bits.

    Voilà, cette variable pFoo, qui définit l'emplacement d'une chose en mémoire, s'appelle un pointeur, car ce n'est pas une variable comme les autres.
    Toutefois, même si le langage ne considère pas un pointeur comme une variable de type int/double ou autre (pour de multiples raisons), un pointeur est un nombre. Cela veut dire que si je fais :
    J'accède à la case suivante.


    ---

    Les pointeurs

    Ok, tout cela est bien cool, je pense maintenant que l'on sait ce qu'est un pointeur. Mais, qu'elle est l'utilité ?
    Un secret que l'on ne dit peut être pas assez tôt, c'est que les variables que vous passez en arguments à une fonction comme ici :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void bar(int foo)
    {
        // Affiche foo
        // Ici, foo est une copie du foo présent dans la fonction main
    }
     
    int main(void)
    {
        int fooMain = 42;
        bar(fooMain);
    }
    sont des copies.
    Cela veut dire que lorsque le programme se trouve dans la fonction bar(), dans mon tableau de cinq cases, je trouverai deux fois '42'.

    Maintenant, imaginons que nous souhaitons avoir une fonction bar, qui incrémente la variable. C'est cool, on pourrait faire ça :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void bar(int foo)
    {
        // Ici, foo est une copie du foo présent dans la fonction main
        foo = foo+1;
    }
     
    int main(void)
    {
        int fooMain = 42;
        bar(fooMain);
        // Ici, fooMain vaut toujours 42 ! Nous n'avons modifié que la copie de la variable et non la variable
    }
    Dans la fonction bar, je modifie la copie de la variable fooMain, du main(). Cette copie est une copie temporaire, présente uniquement lors de l'exécution de la fonction. Il n'y a pas de mécanisme où, la modification effectuée sur foo, serait répercutée sur fooMain, car cela apporterait bien trop de soucis (complexité de mise en place et des bogues supplémentaires).
    Du coup, comment pourrais-je faire pour que ce code marche ?

    Au lieu de passer ma variable fooMain, directement, je vais donner son adresse.
    Ainsi, la fonction bar() pourra lire l'adresse, aller dans la bonne case de mon tableau et modifier la variable.
    Pour rappel, une adresse, en C, c'est un pointeur. Du coup, on écrit ça :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    void bar(int* pFoo)
    {
        // Ici, pFoo est une copie de l'adresse de la variable, donc c'est bon, on peut toujours accéder la variable en lisant l'adresse
        *pFoo = *pFoo+1;
    }
     
    int main(void)
    {
        int fooMain = 42;
        bar(&fooMain);
        // Ici, fooMain vaut 43 ! Nous sommes super bons \ o /
    }

    Par contre, si on essaie de modifier pFoo, alors, la modification ne sera pas répercutée, car, on retombe dans le même cas problématique que précédemment.

    ---

    Les tableaux

    Maintenant, qu'en est t-il si nous voulons transférer un tableau à une fonction ? Ou même comment pouvons-nous spécifier un tableau dans un programme ?
    On ne va pas faire N variables, pour les N cases de notre tableau, c'est trop lourd à gérer, c'est trop pénible et on ne peut pas automatiser les traitements avec des boucles (for).
    Du coup, on va juste garder un pointeur sur le premier élément du tableau.
    En C, que ce soit l'écriture :
    ou
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    int* pTab; // Après cette ligne, il faut demander de la mémoire au système avec malloc
    Le principe est le même. Les deux variables sont des pointeurs, pointant sur la première case du tableau à gérer.
    On peut passer ce pointeur à une fonction, comme précédemment, si on veut utiliser le tableau dans une fonction.

    Lorsque l'on veut accéder à un élément d'un tableau, on écrit généralement :
    En réalité, le compilateur (ou l'ordinateur), que va t-il faire ? Il va prendre l'adresse pTab, puis se déplacer de 5 cases (on compte toujours à partir de zéro dans le monde de l'ordinateur).
    Comme je l'ai dit plus haut, un pointeur, ça reste un simple nombre, donc l'ordinateur va faire :
    Mais bon, cette écriture étant moins lisible, on ne la privilégie pas.



    Voilà, je pense avoir tout dit sur les pointeurs. Je pense avoir montré deux utilités flagrantes des pointeurs, même si j'ai été un peu rapide sur les tableaux.

    Pour les programmeurs un peu plus avancés, les pointeurs peuvent aussi éviter les copies des structures (optimisation). En effet, une structure peut contenir des éléments qui prendront 100 octets en mémoire (par exemple). Si on passe la structure à une fonction, on va copier ces 100 octets, comme je l'ai dit tout à l'heure. Par contre, si on ne donne qu'un pointeur à la fonction, pointant sur la structure, alors dans ce cas, on ne copie que le pointeur (4 octets en 32 bits). Le gain est conséquent (surtout si la fonction est appelée des milliers de fois).
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  13. #13
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Hulkabyl Voir le message
    Ca je l'ai bien compris mais, a quoi sa sert? plus précisément c'est quoi la suite?
    Ca ne sert à rien : c'est comme ça que ça fonctionne ! La suite ? Coder tes programmes bien sûr !


    Citation Envoyé par Hulkabyl Voir le message
    La pour moi c'est comme si je suis à table avec une personne et qui me démontre qu'il es capable de manger ou d'écrire avec les deux mains sans contraintes. On peut déduire que si il se blesse d'une main il aura toujours l'autre pour combler les difficultés (L'utilité ).
    Ce que tu ne comprends, c'est qu'il n'y pas d'utilité à utiliser un pointeur*, il y a obligation d'utiliser un pointeur ! Tu ne peux pas faire autrement. Essaye d'écrire f() qui remet une variable à zéro sans utiliser, essaye de coder les fonctions montrées par Médinoc sans pointeur : tu ne pourras pas.

    Ici, tu n'es pas à table avec quelqu'un qui te dit que savoir manger avec les deux mains, c'est formidable. Cette personne te dit que si tu veux manger, il faut mettre les aliments dans ta bouche. Tu n'as pas trop solution (bien que tu pourrais toujours essayer de te mettre les aliments dans le nez). Dans beaucoup de cas en C, les pointeurs ne sont pas utiles*, ils sont obligatoires. Tu ne peux pas faire autrement. Si tu veux utiliser la valeur d'une variable, tu n'en a pas besoin ; si tu veux modifier ou retrouver une variable, il te faut un pointeur. Et je dis bien "faut" pas "serait utile".

    *: Il existe en fait des cas où un pointeur est plus utile. Le plus simple est sans doute des pointeurs sur structures pour économiser la stack lors d'un appel à une fonction. Mais tu as encore des choses à comprendre avant d'en arriver là.
    EDIT : je vois que LittleWhite et moi sommes d'accord sur ce point ^^

  14. #14
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 6
    Points : 0
    Points
    0
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Eh bien, as-tu lu mon dernier message?
    Comment répliquerais-tu les différents exemples (tableau de longueur déterminée à l'exécution, ou simple affichage d'une chaîne de caractères) sans pointeur?
    il n'est pas si différent que l'exemple cité par Bktero

    Tout ce qui n'est pas absolument trivial (comme de simples fonctions mathématiques) en C nécessite qu'une fonction sache où se trouve quelque chose, ce que seuls les pointeurs peuvent apporter.
    La première fonction que j'ai apprise dans ma vie en informatique c'est la somme des n premiers entier en scheme , et qaund j'ai vraiment envie de comprendre quelque chose, je reviens a elle toujours.

    voici donc la fonction som qui calcule la somme des n premier entier jusqu'a n. Exemple: som(5) = 15.
    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
    #include<stdio.h>
    int som(int n){
    int i,somme=0;
     
    for(i = 0;i< n; i++){
    somme += i;
    }
    }
     
    int main(){
     
    int n = 5;
     
    printf(" %d \n",som(n));
     
    }
    Maintenant s je veux mettre le resultat des sommes de n premier entier jusqu'a n dans un tableau, on vas dire pour les 10 premiers:


    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
     
    #include<stdio.h>
     
    int som(int tab[20],int n){
     
      int i;
      int somme = 0;
     
     
        for (i = 0; i< n;i++){
          somme += i;
          tab[i]=somme;
          printf("la somme de %d== %d \n",i,tab[i]);
        }
     
    }
     
     
    int main(){
     
      int tab[20];
      int n = 10;
      som(tab,n);
     
    }
    en Pointeur?!

  15. #15
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Surprise: En C, ces trois déclarations sont* identiques et donneront à ta fonction le même code assembleur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int som(int tab[20], int n){
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int som(int tab[], int n){
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int som(int *tab, int n){
    Les tableaux sont passés par adresse en C, en tant que pointeurs vers leur premier élément. Comme Monsieur Jourdain faisait de la prose sans le savoir, tu utilises les pointeurs sans le savoir.

    Et ta fonction som(int n) fait partie de ce qui est "absolument trivial (comme de simples fonctions mathématiques)".

    *presque: La première aura un effet légèrement différent pour les opérateurs sizeof et &, qui ne sont pas utilisés dans ta fonction.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  16. #16
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2014
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2014
    Messages : 6
    Points : 0
    Points
    0
    Par défaut
    Comme Monsieur Jourdain faisait de la prose sans le savoir, tu utilises les pointeurs sans le savoir.
    je ne peux qu'esquisser un sourire en lisant ca

    mis a part la syntaxe qui diffère entre tableau et pointeur, qu'est que le programmeur gagne en utilisant les pointeur d'un point de vue optimale? je sais qu'avec les pointeurs on peut faire un tableau dynamique et ca va me servir beaucoup, j'espère que sa sera la prochaine étape, j'entendais mon prof parler de malloc et sizeof.

    Grace a vous, cette discussion sera presque résolu et je remercie a tous ce qui ont contribué

    Très cordialement

  17. #17
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    D'un point de vue vitesse tu veux dire? Ça permet d'économiser en copie d'objets encombrants, mais à par cela les pointeurs introduisent une indirection qui a un coût en performance. Comme dit plus haut, on utilise les pointeurs parce qu'on en a besoin, pas parce qu'on en a envie.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  18. #18
    Membre éclairé
    Profil pro
    Ingénieur sécurité
    Inscrit en
    Février 2007
    Messages
    574
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 574
    Points : 751
    Points
    751
    Par défaut
    Citation Envoyé par Hulkabyl Voir le message
    qu'est que le programmeur gagne en utilisant les pointeur d'un point de vue optimale?
    Je reprends l'example de LittleWhite, ou tu as le chiffre 42 a l'addresse 0x00000001.

    Imagine que tu as 10 fonctions qui travaillent sur ton chiffre 42. Comment tu fais pour leur passer ce chiffre? Admettont que tu le copie de fonction en fonction, tu as maintenant 10 variations de ton chiffre 42 en memoire.
    Si tu passes un pointeur vers ton chiffre a tes 10 fonctions, tu n'as qu'un endroit en memoire sur lequel tu travailles. Toutes tes fonctions travaillent sur la meme zone memoire (0x00000001).

    Maintenant imaginons que tes 10 fonctions ne travaillent pas sur un nombre, mais sur un element en memoire qui fait 100Mo. C'est pas tres efficace de travailler sur une copie de cet element, car tu occuperas 100Mo * 10 = 1Go de memoire. Si tes 10 fonctions travaillent sur la zone memoire de ton element (via son pointeur), tu n'utilise que 100Mo de memoire.

  19. #19
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut
    *presque: La première aura un effet légèrement différent pour les opérateurs sizeof et &, qui ne sont pas utilisés dans ta fonction.
    Non, d'après ce que je sais. Une fois dans la fonction, on ne sait pas si le paramètre réel était un tableau (un vrai tableau) ou un pointeur (sur zone malloquée ou non). Dans la fonction, sizeof renverra la taille d'un pointeur. Les 3 prototypes sont donc complètement similaires une fois dans la fonction. Un compilateur malin pourra par contre peut-être mettre des warnings si les paramètres réels ne sont pas du type du paramètre formel, il faudrait tester.

    Comme Monsieur Jourdain faisait de la prose sans le savoir, tu utilises les pointeurs sans le savoir.
    Les pointeurs sont partout en C

  20. #20
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 518
    Points
    41 518
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Non, d'après ce que je sais. Une fois dans la fonction, on ne sait pas si le paramètre réel était un tableau (un vrai tableau) ou un pointeur (sur zone malloquée ou non). Dans la fonction, sizeof renverra la taille d'un pointeur. Les 3 prototypes sont donc complètement similaires une fois dans la fonction. Un compilateur malin pourra par contre peut-être mettre des warnings si les paramètres réels ne sont pas du type du paramètre formel, il faudrait tester.
    Tu as raison, je viens de tester sous VS 2010:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void TestArrayC(int arr[20])
    {
    	int (*pArr)[20];
    	pArr = &arr;
    }
    Visual me dit TestArrayC.c(4): warning C4047: '=' : 'int (*)[20]' differs in levels of indirection from 'int **', la taille passée entre crochets est donc purement décorative et n'a aucun effet.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

Discussions similaires

  1. Je n'arrive pas à comprendre les "pointeurs"
    Par andrianiaina dans le forum Débuter
    Réponses: 7
    Dernier message: 26/03/2012, 15h35
  2. Réponses: 4
    Dernier message: 13/08/2004, 19h39
  3. [TTreeView] Problème avec les pointeurs d'objet
    Par BlackWood dans le forum Composants VCL
    Réponses: 2
    Dernier message: 02/07/2004, 15h31
  4. pointeurs, toujours les pointeurs :/
    Par giviz dans le forum C
    Réponses: 16
    Dernier message: 08/10/2003, 16h02
  5. Pb de débutant sur les pointeurs!!!
    Par benji17c dans le forum C
    Réponses: 6
    Dernier message: 30/09/2003, 18h50

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