web-dev-qa-db-fra.com

Qu'est-ce qu'une belle explication pour les pointeurs?

Dans vos propres études (seul ou en classe), avez-vous eu un moment "ah ha" où vous avez finalement vraiment compris les pointeurs? Avez-vous une explication que vous utilisez pour les programmeurs débutants qui semble particulièrement efficace?

Par exemple, lorsque les débutants rencontrent pour la première fois des pointeurs en C, ils peuvent simplement ajouter &le sable *s jusqu'à ce qu'il compile (comme je l'ai fait moi-même une fois). Peut-être que c'était une image, ou un exemple vraiment bien motivé, qui a fait "cliquer" les pointeurs pour vous ou votre élève. Qu'est-ce que c'était et qu'avez-vous essayé avant qui ne semble pas fonctionner? Des sujets étaient-ils prérequis (par exemple, des structures ou des tableaux)?

En d'autres termes, ce qui était nécessaire pour comprendre le sens de &le sable *, quand pouvez-vous les utiliser en toute confiance? Apprendre la syntaxe et la terminologie ou les cas d'utilisation ne suffit pas, à un moment donné l'idée doit être internalisée.


Mise à jour: J'aime vraiment les réponses jusqu'à présent; veuillez les faire venir. Il y a beaucoup de grandes perspectives ici, mais je pense que beaucoup sont de bonnes explications/slogans pour nous-mêmes après nous avons internalisé le concept. Je cherche les contextes et circonstances détaillés quand cela vous est apparu.

Par exemple:

Je n'ai que quelque peu compris les pointeurs syntaxiquement en C. J'ai entendu deux de mes amis expliquer des pointeurs à un autre ami, qui m'a demandé pourquoi un struct était passé avec un pointeur. Le premier ami a parlé de la façon dont il devait être référencé et modifié, mais ce n'était qu'un bref commentaire de l'autre ami où il m'a frappé: "C'est aussi plus efficace." Passer 4 octets au lieu de 16 octets était le dernier changement conceptuel dont j'avais besoin.

72
Macneil

Diagramme de la mémoire en tant que grille

Habituellement, ce que je fais est de représenter la mémoire comme une "grille", afin de pouvoir créer des adresses, mettre en évidence différents espaces mémoire et écrire dans les cellules des valeurs (ou même plus loin, leurs représentations binaires) et lier les pointeurs en mémoire aux valeurs qu'ils pointer vers. (Et puis mentionnez toujours que c'est une simplification).

Habituellement, c'est un moment "ohhhh" pour la plupart de mes élèves.

Jonglerie de symboles

Ensuite, quand il s'agit de les faire cesser d'oublier comment utiliser & et *, c'est très simple: présentez-le de la même manière qu'ils font les calculs mathématiques ou physiques. Si vous divisez une distance en km par une heure, vous obtenez une vitesse en km/h. Ce qui est dedans doit être sorti. Facile.

printf à la rescousse

Faire juste quelques exemples de base qui représentent visuellement ce que vous avez expliqué avec ceux-ci les réconfortera dans ce qu'ils pensent avoir compris, ou leur donnera l'occasion de dire "ah, je ne comprends pas celui-ci".

Soyez extensif

Couvrez les pointeurs pour les types simples et assurez-vous qu'ils comprennent la différence entre l'adressage et la taille d'un type de données, puis les structures, puis les tableaux et les niveaux multiples.

Commencez ensuite l'arithmétique du pointeur.


Addendum: récursivité

J'explique généralement la récursivité de la même manière, en utilisant une représentation visuelle. Demandez-leur d'imprimer l'alphabet à l'aide d'une fonction prédéfinie qui écrit un seul caractère, puis demandez-leur de l'imprimer dans l'ordre inverse en changeant simplement deux lignes.

Il y a généralement un "qu'est-ce que ...?" moment, et lorsque vous ajoutez juste un autre paramètre à votre printf pour imprimer des valeurs numériques et indenter les étapes, cela devient un soupir de soulagement.


Alternatives: le modèle Play-Doh et les gobelets à eau

En fait, j'avais des collègues dans une université qui ont montré aux étudiants une vidéo expliquant les pointeurs et les accès à la mémoire à l'aide de pâte play-doh. C'était incroyablement intelligent et bien fait, même si je n'ai jamais vraiment utilisé cette technique moi-même, sauf pour les très jeunes apprenants intéressés à saisir la programmation (mais généralement ceux que je ne les conduirais pas vers une langue utilisant des pointeurs trop tôt). Fondamentalement, en utilisant de minuscules boules de play-doh que vous pouvez attacher à d'autres boules de play-doh plus grandes représentant des espaces mémoire, et que vous pouvez combiner ensemble pour les lier (comme dans une structure de données liée) ou fusionner ensemble (comme dans un contigu espace mémoire). L'utilisation de couleurs différentes pour les espaces mémoire pointés et les pointeurs aident également. Mais je pense toujours que la fonction Memory-as-a-Grid fonctionne mieux, car vous pouvez clairement montrer que le pointage est vraiment une question d '"adressage", comme sur une "carte/grille". Alors que le mode Play-doh les confond encore en pensant que les choses se "touchent" vraiment en mémoire.

La chose Water Cup a également été utilisée directement par une collègue, mais je ne sais pas si elle l'a inventée. C'était une approche intéressante, mais j'ai remarqué que de nombreux étudiants étaient déconcertés par l'explication. Quelque chose de semblable à technique de la tasse à café de DevSolo . Mais je pense que c'est en fait trompeur car vous faites confondre les conteneurs, les structures de données, les pointeurs et les tableaux. Cela pourrait être une approche intéressante pour expliquer les tableaux au début, je suppose, mais je ne m'en tiendrai pas très longtemps.

25
haylem

Quelqu'un de bien plus sage que je l'ai déjà dit:

La religieuse Wu Jincang a demandé au sixième patriarche Huineng: "J'ai étudié le sutra Mahaparinirvana pendant de nombreuses années, mais il y a de nombreux domaines que je ne comprends pas très bien. S'il vous plaît, éclairez-moi."

Le patriach a répondu: "Je suis analphabète. Veuillez me lire les caractères et je pourrai peut-être en expliquer le sens."

Elle a dit: "Vous ne pouvez même pas reconnaître les personnages. Comment pouvez-vous alors comprendre le sens?"

"La vérité n'a rien à voir avec les mots. La vérité peut être comparée à la lune brillante dans le ciel. Les mots, dans ce cas, peuvent être comparés à un doigt. Le doigt peut pointer vers l'emplacement de la lune. Cependant, le doigt n'est pas le lune. Pour regarder la lune, il faut regarder au-delà du doigt, non? "

80
Frank Shearar

J'ai trouvé que les diagrammes étaient très utiles. Exemple:

pointer diagram


Ce type de diagramme m'a aidé à voir que les pointeurs étaient leur propre variable, mais contenaient une valeur qui était l'emplacement d'un autre objet, c'est-à-dire un tableau ou une chaîne. De plus, lorsque je l'ai fait au crayon, je pouvais l'utiliser pour tracer mon programme sur papier ou sur un tableau noir/blanc.

46
Michael K

Quand j'ai "appris" pour la première fois les pointeurs, j'ai été en quelque sorte poussé dedans. Mon université avait pris la décision longtemps avant de m'inscrire pour centrer le programme autour de Java, alors quand mon professeur Data Structures a donné une conférence sur C et nous a demandé de mettre en œuvre une liste XOR avec des pointeurs, j'ai eu l'impression de me lancer dans quelque chose façon au-dessus de ma tête.

J'ai compris la définition:

Un pointeur est une variable qui contient l'adresse d'une variable

Mais je ne comprenais toujours pas une grande partie du concept. Avec le recul, je pense que cela était centré sur trois choses:

  1. Quel est exactement un emplacement mémoire? (À l'époque, je n'ai pas pris de cours d'organisation informatique)

  2. La syntaxe maladroite (alors euh ... pourquoi exactement est-elle définie comme "int * ip" mais ensuite je me réfère à la variable comme "ip"?)

  3. En quoi est-il avantageux de stocker l'adresse d'une variable plutôt que de simplement utiliser la variable?

Ce n'est que lorsque j'ai acheté le livre K&R et terminé tous les problèmes que j'ai vraiment compris les pointeurs. Outre le fait que j'avais longtemps suivi le cours d'organisation informatique (qui, je pense, devrait être requis avant d'apprendre le C), cela était dû en partie au fait que je me suis rendu compte que les pointeurs peuvent être utilisés pour des fonctions, des tableaux, des structures ... pour faire des choses utiles et pas seulement comme stockage pour les adresses de variables ordinaires.

Mais mon moment "aha" était de loin la façon dont K&R a expliqué la syntaxe maladroite de la définition d'un pointeur simple. J'ai pris des notes tout au long du livre (dans lesquelles je reformule les points soulevés par le livre dans mes propres mots afin d'approfondir ma compréhension), et c'est celui qui s'y rapporte:

Un pointeur est une variable qui contient une adresse vers une variable. Un pointeur est à la fois défini et déréférencé (donnant la valeur stockée à l'emplacement de mémoire vers lequel il pointe) avec l'opérateur '*'; l'expression est mnémonique.

Ex.: 
   int a;      /* Variable 'a' is an integer */

   int *ip;   /* Variable ip is a pointer and dereferencing it gives an integer.
                 In other words, the expression *ip is an int, so ip is a pointer
                 to an int */

J'avais toujours senti que je ne pouvais pas saisir pleinement les concepts plus avancés de pointeurs jusqu'à ce que j'aie quelque chose de si élémentaire enraciné dans ma tête. Cela m'avait dérangé indéfiniment après cette mission (ce que je n'ai pas trop bien fait d'ailleurs;)) pourquoi "* ip" n'existait pas juste après que j'ai (pensé avoir) défini "* ip". La maîtrise de ceci est essentielle pour des concepts plus avancés impliquant des pointeurs, comme les pointeurs de fonction et des définitions plus compliquées comme ceci:

char (*(x())[])()

Dans l'ensemble, je pense que le concept de pointeurs nécessite:

  1. Une compréhension de base de la façon dont la mémoire est disposée dans un ordinateur (et de ce qu'est la mémoire).

  2. Connaissance de la puissance des pointeurs (utilisation dans le monde réel, pas seulement un autre concept abstrait qu'ils apprennent pour le plaisir d'apprendre).

  3. Décrypter les hiéroglyphes familièrement connus comme "une définition d'un pointeur"

Donc, dans l'ensemble, je pense qu'il devrait y avoir au moins 3 moments "aha" lors de l'apprentissage des pointeurs. Je suis encore étudiant, donc j'ai pensé que vous apprécieriez le point de vue de quelqu'un qui est encore (relativement) à peine au courant de l'apprentissage du concept.

32
Kevin

Le pointeur est un peu comme les raccourcis des applications sur votre bureau. Supprimez le raccourci et la cible existe toujours. Démarrez le raccourci et la cible démarre.

J'explique toujours le fonctionnement de ceci en créant simplement un fichier txt sur mon bureau et deux raccourcis vers le fichier. Après avoir copié et supprimé les raccourcis, vous pouvez voir que les gens comprennent l'idée derrière les "références".

Une fois que le groupe a compris les bases des raccourcis, vous pouvez commencer à expliquer les pointeurs comme vous le souhaitez. Ils le comprendront probablement assez facilement.

19
Barfieldmv

Il y a 8 à 10 ans, j'ai donné un cours d'introduction "C" dans un collège communautaire. C'était toujours un sujet amusant à explorer. Ce qui semblait fonctionner le mieux, et c'était après avoir discuté avec un collègue à quelques reprises était d'utiliser une tasse de café et votre main.

J'ai utilisé l'analogie d'une tasse de café (ou d'une rangée d'entre eux pour les tableaux) comme variable (elle peut contenir quelque chose). J'ai ensuite utilisé ma main, qui pouvait aussi tenir quelque chose ou, en étendant mon index pour "pointer" vers une tasse de café.

Une main proche était nulle, un doigt pointé sur ma tête (comme un faux pistolet) était un pointeur qui pendait.

Puis avec quelques démonstrations et voyages à travers le débogueur, il a cliqué avec le plus.

14
DevSolo

Je suis vraiment très inquiet quand j'entends la question "comment avez-vous compris les pointeurs". J'ai toujours pensé que le concept était incroyablement simple, et une évolution logique des langages fournissant une grande puissance aux programmeurs.

Ce qui m'inquiète, c'est que je n'ai jamais eu de difficulté à comprendre le concept de pointeurs. Donc, quand vous êtes ici "quand avez-vous enfin compris" encore et encore, vous commencez à penser:

Est-ce que je l'obtiens réellement? Peut-être que je ne l'ai jamais fait?

Peut-être que la raison pour laquelle le concept semble être délicat, c'est parce que nous continuons à dire à tous ceux qui ne les ont pas encore rencontrés que les pointeurs sont si difficiles, et voici une centaine de façons d'apprendre.

Je lance juste cette idée là-bas, bien sûr, personnellement, j'aime un bon diagramme et Steve Gibson fait toujours un travail fantastique pour expliquer quoi que ce soit !

10
Marcus Whybrow

Je n'ai jamais eu beaucoup de problème avec les pointeurs en C, mais c'est peut-être parce que j'ai dû d'abord apprendre l'assembleur. C'était en fait un soulagement de ne plus avoir à gérer moi-même les adresses. Alors peut-être que la réponse (en supposant que c'est quelque chose que vous enseignez) est de donner aux étudiants un langage d'assemblage émulé avec lequel travailler. Ils le feront le découvriront en train d'écrire quelque chose de plus sophistiqué que "Hello, world".

7
Larry Coleman

Un pointeur est une variable dont la valeur est l'adresse mémoire d'une autre variable.

7
kirk.burleson

Comment j'ai vraiment appris les pointeurs? En écrivant un simple compilateur de première année de collège.

Comment expliquer les pointeurs en termes simples? J'aime l'analogie (datée?) D'un catalogue de bibliothèque stocké sur des fiches. Chaque carte ("pointeur") contient des informations sur l'emplacement de certains livres ("données"), mais ne contient pas réellement le livre lui-même. Si vous modifiez la carte ("arithmétique du pointeur"), tout ce qu'elle fait est de changer le livre vers lequel elle pointe et n'a aucun impact sur le livre lui-même - faites juste attention à ne pas bousiller l'adresse ou vous pourriez pointer vers un livre inexistant ou même la mauvaise bibliothèque. Cependant, si vous suivez "l'adresse" sur la carte et accédez à la partie appropriée de la bibliothèque ("déréférencer le pointeur"), vous pouvez voir/modifier le livre lui-même.

6
Yevgeniy Brikman

Modifié à l'appui de l'exigence révisée de la question

Mon chemin vers la compréhension "post-pointeur" (si je me souviens bien) s'est déroulé comme suit. J'avais une expérience simple de la programmation d'assemblage depuis que j'étais encore en train de nettoyer avec un micro BBC alors j'ai eu le concept de mémoire comme un tas de boîtes (voir ci-dessous pour cela). Cela a été renforcé par l'utilisation de tableaux. Cependant, j'allais dans le monde de C et je devais m'occuper des cordes et cela signifiait des pointeurs. En BASIC, c'était trivial, en assembleur, je n'ai jamais eu à travailler avec eux, et maintenant en C classique, ce sont tous des pointeurs et des trucs. Ah, mais je peux revenir aux tableaux avec des chaînes (terminées par null) comme ceci:

char s[] = "Hello, world!";
printf("%s",s);

Très bien, c'est juste un tableau de caractères (8 bits par caractère dans mon petit monde) avec un caractère zéro à la fin pour montrer où cela se termine. Le printf prend juste ce tableau et le parcourt en l'imprimant. Mais que faire si je veux passer cette chaîne dans une fonction?

void print_str(char* p) {
  printf("%s",p);
}

C'est ce que dit le manuel, mais de quoi s'agit-il *? Hmm, char * signifie "pointeur sur un caractère". OK ... m'a perdu. Ensuite, il m'est apparu que le char * rend p équivalent à s [0]. D'accord, je peux l'utiliser, mais je n'ai toujours pas défini les pointeurs. Je veux dire, comment puis-je définir certaines données avec l'une de ces choses? De nouveau au manuel ...

char* p = "Hello World!";

Pendant que j'écris ce qui précède, je me dis "déclare un pointeur sur un caractère et le mettre égal à ce tableau de caractères". D'une manière ou d'une autre, ce pointeur supprime le besoin d'un tableau. Je suppose que c'est le compilateur qui fait des trucs pour moi pour changer. Alors, comment puis-je changer le tableau avec ce pointeur? Je sais que je pourrais utiliser la version tableau

 s[2] = 'L'; 

mais quel est l'équivalent dans "pointer speak"? De nouveau à ce manuel ...

*(p+2) = 'L';

Je suppose que * signifie simplement "le contenu de l'adresse mémoire" et (p+2) est s[2]. Ce qui signifiait que le pointeur p était ... juste ... une ... adresse ... bong!

Qu'il y a le son des Lumières. J'ai soudainement branché des pointeurs (c'était il y a longtemps, nous, les anciens, nous ne "gémissions" que plus tard). C'était juste une indirection.


Original:

OK, mon 2c vaut:

Imaginez que la mémoire est un tas de boîtes. Chaque case a un numéro sur le côté (l'adresse). Chaque case contient un numéro (le contenu). Vous pouvez travailler avec ces boîtes de 2 façons: variables (je veux le contenu de la boîte N), pointeurs (je veux le contenu de la boîte tout ce qui se trouve dans la boîte N ). Les pointeurs sont simplement indirection.

Et pour la grande réponse qui couvre tout ce que vous aurez besoin de savoir - lire ceci .

5
Gary Rowe

Je suppose que quelqu'un qui va apprendre les pointeurs sait quelles sont les variables normales et comment elles fonctionnent en C. Maintenant, essayons de définir des pointeurs avec certains de ses attributs-

  • Ce sont aussi des variables, mais de nature différente. Supposons qu'il y ait deux couches dans l'espace variable. Les variables normales de différents types résident dans la couche supérieure et les pointeurs dans la couche inférieure. Comme cette figure-

    alt text

  • Comme son nom l'indique, les pointeurs peuvent pointer vers quelque chose. Comme notre doigt peut pointer vers un objet. Quelles sont les choses qu'ils indiquent? Ce sont les variables normales. En bref, "les pointeurs pointent vers des variables normales".

  • Comme les variables normales, les pointeurs sont également du même nombre de types comme int, char ou float. Et un pointeur d'un type spécifique peut pointer uniquement vers le même type de variables.
  • Un pointeur peut pointer vers une variable et plus tard, le même pointeur peut pointer vers une autre variable. Seul le type doit être le même. Ainsi, l'association d'un pointeur avec une variable n'est pas permanente et peut être modifiée.
  • Alors, comment un pointeur est-il déclaré? Presque comme des variables normales. Vous devez faire précéder le nom d'un astérisque (*). Comme-

    int *pointer;
    
  • Alors, comment un pointeur est-il associé à une variable? En utilisant le & opérateur avant la variable comme cette instruction-

    pointer = &variable;
    
  • Comment un pointeur est utilisé en pointant sur une variable? Cela se fait également en précédant le nom d'un astérisque (*). Ensuite, il peut être utilisé à la place de la variable qu'il pointe maintenant -

    *pointer = var1 + var2;
    

    au lieu de

    variable = var1 + var2;
    
  • Maintenant, jouez avec des pointeurs avec du code. Habituez-vous maintenant à ces caractéristiques des pointeurs. Jusqu'ici, nous parlons de ce que font les pointeurs. Une fois que vous êtes d'accord, commencez à étudier comment les pointeurs pointent vers une variable et comment ils réagissent si des opérations arithmétiques normales leur sont appliquées. Ensuite, optez pour la relation entre les pointeurs et les tableaux et les pointeurs aux pointeurs.

C'est tout ce que je proposerai sur l'apprentissage des pointeurs.

5
Gulshan

Obtenez quelques petits blocs de bois.

ajoutez des crochets métalliques à une extrémité et des yeux métalliques à l'autre.

vous pouvez maintenant faire une liste chaînée avec des choses avec lesquelles vous pouvez jouer.

Essayez d'expliquer avec cet accessoire physique. Je souhaitais souvent l'avoir quand j'enseignais des pointeurs aux étudiants de première année (étudiants de première année).

Le petit crochet en métal est le pointeur, le bloc de bois sur lequel la chose pointait.

JE DÉFIEZ quiconque de ne pas l'obtenir après avoir joué avec les blocs.

4
Tim Williscroft

J'ai rendu ma vie plus facile quand je viens de retirer tous les peluches et j'ai commencé à traiter le pointeur comme toute autre variable plutôt que comme une entité magique (il y a très longtemps en 11e année). Je sais juste 3 choses:

  1. Le pointeur est une variable qui stocke l'adresse d'une autre variable (ou n'importe quelle adresse).
  2. * est utilisé pour obtenir la valeur à l'emplacement mémoire qui est stocké dans la variable de pointeur.
  3. & L'opérateur donne l'adresse d'un emplacement mémoire.

Le reste est du sucre syntaxique et du bon sens. Il suffit d'écrire quelques programmes C simples (comme l'implémentation d'une bibliothèque de listes chaînées) en utilisant des pointeurs pour les comprendre.

4
Sridhar Iyer

L'explication que j'ai vraiment bafouée était:

Considérons une grille de ville avec différentes maisons construites sur des parcelles de terrain. Dans votre main, vous tenez un morceau de papier. Sur le papier que vous avez écrit:


La maison de David,

112 Telle et telle rue.


Le morceau de papier (variable de pointeur) contient une adresse qui pointe vers la maison de David. Lorsque vous voulez dire à un ami de jeter un coup d'œil à la maison cool de David, il est beaucoup plus facile d'utiliser le morceau de papier comme référence à la maison que d'envoyer le bâtiment réel de deux étages par la poste.

Comme pour les vrais pointeurs, vous pouvez avoir des problèmes lorsque vous suivez l'adresse sur votre feuille de papier. David aurait pu bouger et quand vous y êtes, vous trouvez juste un gros trou dans le sol. Dans ce cas, il aurait été préférable d'effacer l'adresse sur le papier lorsque David a déménagé ou au moins de la remplacer par la nouvelle. Vous pourriez également constater que vous vous rendez à l'adresse et entrez ce que vous pensez être le salon de votre ami David, mais cette fois, vous vous retrouvez dans une piscine complète d'étrangers. Quelqu'un d'autre a utilisé l'espace à l'adresse que vous aviez pour quelque chose de complètement différent.

2
Per Wiklander
  1. Le pointeur peut être considéré comme une généralisation d'un index dans un tableau.
    • Considérez qu'un grand tableau peut être découpé en un certain nombre de tableaux plus petits, sans chevauchement et de taille variable. Maintenant, ces petits tableaux sont ce que nous considérons généralement comme un tableau. Le plus grand est alors tout l'espace mémoire de l'ordinateur. Le processus de découpage de tableaux plus petits est appelé allocation de mémoire.
  2. Un ensemble de structures qui sont reliées entre elles par certains pointeurs peut être considéré comme un graphique orienté .
    • Chaque sommet est une variable qui peut contenir une certaine valeur.
    • Certaines variables sont des pointeurs, et chaque pointeur peut avoir exactement un Edge sortant vers quelque chose d'autre.
    • Les variables qui ne sont pas des pointeurs n'auront aucun Edge sortant. Ils pourraient avoir n'importe quel nombre de Edge entrant.
2
rwong

Si vous voulez expliquer des pointeurs, vous devez d'abord expliquer la mémoire. Je fais habituellement cela en utilisant du papier millimétré/du papier quadrillé avec des lignes et des colonnes. Si "l'élève" comprend la mémoire, elle peut comprendre ce qu'est une adresse. Si vous avez une adresse, vous avez des pointeurs.

Vous pouvez jouer avec cette abstraction. Par exemple. écrire l'adresse (nombre) d'un carré dans un autre carré. Tracez maintenant une flèche du carré du pointeur au carré de destination. Remplacez maintenant le pointeur (par exemple, augmentez-le) et ajustez la flèche. Écrivez une adresse dans un autre carré et laissez l'élève dessiner la flèche ...

Étape suivante: attribuez un nom à certains carrés (comme le pointeur). Vous pouvez maintenant expliquer le déréférencement. C'est ça.

2
EricSchaefer

Je ne me souviens pas vraiment des circonstances entourant mes pointeurs-aha-moment, mais j'ai réaménagé rétroactivement la mémoire autour de ma compréhension d'un tableau de style C. (c'est-à-dire que arr[3] est identique à *(arr+3))

Pour une raison quelconque, je trouve extrêmement utile de voir les pointeurs comme des tableaux chaque fois que je rencontre une situation de pointeur.

2
Zaz

Fondamentalement, @Gary Rowe a présenté le bon modèle. La mémoire sous forme d'un ensemble de cases avec des adresses (numéros) dessus. Chaque case stocke une valeur (nombre).

L'idée d'un pointeur est d'interpréter la valeur dans une case comme l'adresse d'une autre case. Cette valeur est utilisée pour se référer à une boîte spécifique, c'est pourquoi elle est appelée référence. Ainsi déréférencement est le processus d'ouverture de la boîte à laquelle il est fait référence.

si v est une variable (case), alors l'instruction

  • v signifie la valeur de v, c'est-à-dire donnez-moi ce qui est dans la boîte
  • *v signifie déréférencer la valeur de v, c.-à-d. donnez-moi ce qui se trouve dans la case désignée par la valeur de v
  • &v signifie référence v, c'est-à-dire donnez-moi l'adresse sur la case

Je pense que cela ne sert pas l'objectif d'introduire des pointeurs comme quelque chose de complètement différent. C'était un concept difficile à saisir pour moi quand j'étais enfant. Cela a toujours semblé être une magie noire que je n'ai jamais vraiment comprise, qui avait besoin de beaucoup de caractères spéciaux. La première fois que j'ai compris, c'est quand j'ai écrit un petit jeu utilisant la double indirection dans une langue qui n'a pas d'arithmétique de pointeur. Cela m'a éclairé.

Les pointeurs sont une question d'interprétation. Je pense que l'explication rend les choses beaucoup plus faciles. Et l'arithmétique des pointeurs sont des opérations extrêmement simples et intuitives si on leur montre un exemple simple avec une mémoire de 10 variables.

2
back2dos

C'est peut-être juste moi, mais je travaille bien avec des analogies. Disons que vous avez un ami (fonction/classe) "Foo", qui veut avoir quelqu'un d'autre (fonction/classe différente), "Bar", contactez-vous pour une raison quelconque. "Foo" pourrait vous amener à aller voir "Bar", mais ce n'est pas pratique, déplacer tous ces êtres (instances) autour. Cependant, "Foo" pourrait envoyer à "Bar" votre numéro de téléphone (pointeur). De cette façon, peu importe où vous êtes, "Foo" sait comment vous contacter sans avoir à vous trouver.

Et, disons que "Bar" a une connaissance, "Baz", qui veut aussi vous contacter. Mais vous protégez votre numéro de téléphone et vous ne voulez pas que tout le monde ait, "Baz" peut appeler "Bar" (téléphone comme pointeur), qui peut ensuite vous renvoyer l'appel (un autre pointeur). Et ainsi de suite dans la chaîne des amis de "Baz" et des amis d'amis.

2
Hugo

Les pointeurs font façon plus de sens si vous avez étudié le langage d'assemblage et/ou l'architecture informatique. Je pense que si j'enseigne une classe C, je commencerais par quelques semaines d'architecture pour expliquer le modèle de mémoire et les types d'instructions que le processeur exécute réellement.

2
Barry Brown

Mon "aha!" est venu dans ce tutoriel:

n tutoriel sur les pointeurs et les tableaux en C

Pour être exact, il est venu dans ce chapitre: Chapitre 3: Pointeurs et chaînes

Pour être encore plus précis, il est venu avec cette phrase:

Le paramètre passé à put () est un pointeur, c'est-à-dire la valeur d'un pointeur (puisque tous les paramètres de C sont passés par valeur), et la valeur d'un pointeur est l'adresse vers laquelle il pointe, ou, simplement, une adresse .

Quand j'ai lu cela, les nuages ​​se sont séparés et les anges ont sonné des fanfares de trompette.

Car, voyez-vous, chaque tutoriel ou livre C que j'avais lu auparavant avait affirmé que C pouvait passer par valeur ou par référence, un mensonge néfaste. La vérité est que C passe toujours par valeur, mais parfois la valeur passée se trouve être une adresse. Dans la méthode, une copie est faite de cette adresse, tout comme une copie serait faite d'un int passé. Une copie n'est pas faite du valeur vers laquelle pointe le pointeur. Ainsi, en utilisant le pointeur dans la méthode, vous pouvez accéder à la valeur d'origine et la modifier.

Je ne suis jamais devenu programmeur C, mais je suis devenu programmeur .NET, et les objets et les références d'objets fonctionnent de la même manière; la référence à l'objet est passée par valeur (et donc copiée), mais l'objet lui-même n'est pas copié. J'ai travaillé avec de nombreux programmeurs qui ne comprennent pas cela car ils n'ont jamais appris les pointeurs.

2
Kyralessa

Un pointeur est une note collante qui vous indique où se trouve quelque chose d'utile. Il contient l'emplacement de la chose et vous indique la taille de la chose (en C, de toute façon). Donc, un double pointeur est comme une note collante qui dit "Il y a un pack de six dans le réfrigérateur". Vous devez en fait aller chercher le pack de six pour savoir s'il s'agit de Coke ou de Budweiser.

1
philosodad

http://cslibrary.stanford.edu/

Ce site propose d'excellents didacticiels pour l'apprentissage des pointeurs et la gestion de la mémoire.

Je vous suggère de parcourir les bases des pointeurs, les pointeurs et la mémoire donnés sur le site. Vous pouvez également consulter les problèmes de listes chaînées indiqués sur le lien pour renforcer davantage les concepts de pointeur.

1
deovrat singh

Étant donné le code:

int v=42; // déclarer et initialiser une variable simple

int *p = &v; // création d'un point p vers la variable v

On peut dire ce qui suit sur le code ci-dessus:

int * p // "int pointer p" ... c'est ainsi que vous déclarez un pointeur sur une variable de type int

*p // "pointé par p" ... ce sont les données vers lesquelles p pointe, la même chose que v.

&v // "adresse de la variable v" ... ceci représente la valeur littérale de p

1
zener

La clé pour expliquer les pointeurs est de s'assurer que les personnes à qui vous expliquez ont déjà une compréhension du concept de mémoire. Bien que ce serait bien s'ils comprenaient vraiment le bas niveau, croire que la mémoire existe en tant que tableau massif et comprendre que vous pouvez accéder à n'importe quelle position dans le tableau par son emplacement d'index suffit.

L'étape suivante, avoir le concept de passer l'emplacement de l'index plutôt que de copier toute la mémoire est logique pour la plupart des gens. Et cela suffit pour permettre à la plupart des gens de comprendre pourquoi les pointeurs sont utiles.

la dernière étape pour comprendre les pointeurs consiste à expliquer comment vous pouvez passer en paramètre un emplacement d'index de mémoire pour la méthode de stockage de l'emplacement d'index pour l'emplacement où toutes les données sont stockées. J'ai trouvé que cela peut être un pas trop loin pour certaines personnes.

Une fois que quelqu'un a saisi ces étapes de base, il est facile pour lui de comprendre que vous pouvez chaîner des pointeurs indéfiniment, tant que vous gardez une trace du nombre de fois où vous devez consulter les adresses pour trouver l'objet de données réel.

Une fois que quelqu'un a saisi des pointeurs, la prochaine chose qu'ils doivent saisir rapidement est la différence entre la mémoire de tas et la mémoire de pile, et pourquoi les pointeurs pour empiler la mémoire sont dangereux lorsqu'ils sont passés en dehors de la méthode.

1
Michael Shaw

L'astuce consiste à expliquer que l'emplacement d'une chose et la chose elle-même ne sont pas les mêmes, tout comme une image d'un tuyau n'est pas un tuya . Lorsque vous déplacez une chose, son emplacement change. L'emplacement reste et quelque chose d'autre peut y être mis.

1
sal

En supposant que vous compreniez déjà les tableaux au moins à un niveau superficiel, ma meilleure explication pour les pointeurs serait la suivante:

Imaginez toute la mémoire de votre ordinateur (ou l'espace d'adressage de votre processus si vous voulez être plus précis) comme un tableau géant d'octets. Un pointeur n'est qu'un index dans ce tableau. Les pointeurs ne sont donc qu'un type particulier d'entier.

L'apprentissage de toutes les astuces que les codeurs C et Assembly pourraient faire en traitant les pointeurs comme des entiers, et comment la distinction est purement conventionnelle au niveau du langage Assembly, a aidé à consolider cette compréhension pour moi.

0
dsimcha

Quand j'étais à l'université, mon professeur avait des diapositives PowerPoint vraiment soignées représentant un point en tant que variable distincte avec une flèche vers un emplacement de mémoire (représenté comme un tableau) et quand nous faisions des listes liées, il le faisait étape par étape -par étape, montrant quand la flèche change, quand le pointeur est déréférencé etc ..., il n'y avait aucun moyen de ne pas le comprendre en quelques minutes. Le concept lui-même est vraiment facile, mais le faire correctement ou l'appliquer dans des programmes pratiques nécessite plus de pratique.

0
chiurox

Avant de faire cela, j'explique qu'en programmation "tout utilise de la mémoire" et l'allocation de variables (statiques) en mémoire. Je vais également expliquer ce qu'est une adresse mémoire et la relation entre l'espace mémoire, l'adresse mémoire et les variables.

Enfin, j'explique qu'il existe un type de données et des variables entières, un type de données de chaîne et des variables ... et ainsi de suite, jusqu'à expliquer qu'il existe un type de données spécial qui stocke les adresses mémoire, qui a une valeur vide comme 0 o "", appelé null.

Et, enfin, des variables allouées dynamiquement via l'utilisation de pointeurs.

0
umlcat

Je me souviens d'un livre "C puzzles" ou similaire, que j'ai lu uniquement parce que c'était l'un des rares livres de programmation/informatique disponibles dans la bibliothèque, ma compréhension de C était rudimentaire. Il vous a lancé une expression C et a demandé à l'expliquer, de plus en plus compliqué.

0
peterchen