Quelle est la différence entre une variable et un emplacement de mémoire? [fermé]


38

Récemment, j'ai essayé d'expliquer les pointeurs de manière visuelle, sous forme de cartes mémoire.

Question 001: Ceci est le dessin d'un emplacement dans la mémoire de l'ordinateur. Est-il vrai que son adresse est 0x23452? Pourquoi?

entrez la description de l'image ici

Réponse: Oui, car 0x23452décrit où l’ordinateur peut trouver cet emplacement.


Question 002: Est-il vrai que le caractère best stocké dans l'emplacement de mémoire 0x23452? Pourquoi?

entrez la description de l'image ici

Réponse: Non, car le personnage aest réellement stocké à l'intérieur.


Question 003: Est-il vrai qu'un pointeur est stocké dans l'emplacement de mémoire 0x23452? Pourquoi?

entrez la description de l'image ici

Réponse: Oui, parce que l'adresse de l'emplacement de la mémoire 0x34501est stockée à l'intérieur.


Question 004: Est-il vrai qu'un pointeur est stocké dans l'emplacement de mémoire 0x23452? Pourquoi?

entrez la description de l'image ici

Réponse: Oui, parce que l'adresse d'un autre emplacement de mémoire est stockée à l'intérieur.


Maintenant pour la partie qui m'a inquiété. Un ingénieur en logiciel m'a expliqué les pointeurs comme ceci:

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

Sur la base des quatre cartes mémoire que je vous ai montrées à tous, je définirais les pointeurs d'une manière légèrement différente:

Un pointeur est un emplacement de mémoire dont la valeur est l'adresse de la mémoire d'un autre emplacement de mémoire.

Est-il prudent de dire qu'une variable est la même chose qu'un emplacement de mémoire?

Si non, alors qui a raison? Quelle est la différence entre une variable et un emplacement de mémoire?


37
Il y a une hypothèse implicite ici que tout le monde la lecture de ces images saura votre intention que le nombre hexadécimal dans la zone est une adresse de mémoire, et que le a, 0x23453. niletc. les choses à l'intérieur sont les valeurs. Cela peut sembler évident pour vous, mais je ne serais pas à l'aise de donner des réponses décisives à ces questions sans voir comment ces domaines sont définis. Il n'y a vraiment aucun moyen de savoir si adans la seconde image est un caractère, une chaîne (si elles sont différentes) ou le nom d'une variable. Si c'est une chaîne, alors c'est nilaussi une chaîne? Ou une valeur "nulle"?
ilkkachu

39
La question 1 est une mauvaise question. C’est quelque chose que vous devez dire aux lecteurs avant de pouvoir répondre aux autres questions. Au lieu d'une question, il convient que le lecteur reçoive des informations: "Dans les questions suivantes, les zones sont des emplacements de mémoire et les numéros hexadécimaux situés en dessous sont leurs adresses".
17 du 26

15
La question 3 est impossible à répondre compte tenu du contexte. Il n'y a aucun moyen de savoir au niveau des octets comment la valeur stockée en mémoire est interprétée / utilisée au niveau de l'application.
17 du 26

6
A noter: tout ce que vous écrivez ici est vrai pour C ou C ++, mais faux pour pratiquement tout langage ne disposant pas de référence / déréférencement de pointeur explicite. Toute la métaphore des variables correspondant aux emplacements dans lesquels les valeurs sont réparties pour un langage (comme Python, Java, C #, Ruby, JavaScript ou bien d’autres) où l’affectation ne fait que pointer une variable vers un objet sans le copier. , et les mutations de l’objet sont visibles à travers toutes les variables pointant vers lui. Pour cette raison, la documentation de Python utilise la métaphore alternative des variables sous forme d'étiquettes d'identification accrochées aux objets.
Mark Amery

19
BTW, et pardonnez-moi si vous comprenez déjà cela, mais il semble que cela puisse prêter à confusion - cette notation "0x23452" est juste un moyen de désigner un nombre au format hexadécimal, et ce, pour plus de commodité. Mais il s’agit simplement d’un nombre - le préfixe 0x ne signifie en aucun cas qu’il s’agit d’un pointeur; ce qui est stocké en mémoire est littéralement un nombre sans signification (vous pouvez étiqueter les emplacements de mémoire avec des entiers décimaux ordinaires). La signification (c.-à-d. Comment le nombre doit être interprété) vient du langage - du type de la variable et de la manière dont elle est utilisée.
Filip Milovanović

Réponses:


69

Une variable est une construction logique qui correspond à l'intention d'un algorithme, tandis qu'un emplacement mémoire est une construction physique qui décrit le fonctionnement d'un ordinateur. De manière générale, pour exécuter un programme, il existe un mappage (généré par le compilateur) entre la notion logique de variable et le stockage de l'ordinateur.

(Même en langage assembleur, nous avons une notion de variables (logiques) allant à l'algorithme et à l'intention, ainsi que des emplacements mémoire (physiques), bien qu'ils soient plus regroupés dans l'assembly.)

Une variable est un concept de niveau élevé (er). Une variable représente soit un inconnu (comme en mathématiques ou une tâche de programmation), soit un paramètre fictif pouvant être remplacé par une valeur (comme dans la programmation: paramètres).

Un emplacement de mémoire est un concept de bas niveau. Un emplacement de mémoire peut être utilisé pour stocker une valeur, parfois pour stocker la valeur d'une variable. Cependant, un registre de CPU est un autre moyen de stocker la valeur de certaines variables. Les registres de la CPU sont également des emplacements de stockage de bas niveau, mais ils ne sont pas des emplacements de mémoire car ils ne possèdent pas d’adresses, mais juste des noms.

Dans un certain sens, une variable est un mécanisme d'abstraction permettant d'exprimer l'intention du programme, tandis qu'un emplacement mémoire est une entité physique de l'environnement de traitement qui fournit le stockage et la récupération.

Question 003: Est-il vrai qu'un pointeur est stocké dans l'emplacement de mémoire 0x23452? Pourquoi?

Nous ne pouvons pas dire d'avance. Ce n’est pas parce qu’il existe une valeur qui fonctionnerait comme une adresse que cela pourrait être l’adresse, il pourrait s’agir de l’entier (décimal) 144466. Nous ne pouvons pas émettre d'hypothèses sur l'interprétation des valeurs simplement en fonction de la façon dont elles apparaissent numériquement.

Question 004: Est-il vrai qu'un pointeur est stocké dans l'emplacement de mémoire 0x23452? Pourquoi?

C'est en effet une question étrange. Ils s'attendent à des hypothèses basées sur les cases, cependant, notons que les adresses augmentent de 1 pour chaque case. Sur n'importe quel ordinateur moderne, cela signifierait que chaque boîte peut contenir un adressage sur un octet, qui est la norme depuis des décennies. Cependant, un octet ne contient que 8 bits et peut aller de 0 à 255 (pour les valeurs non signées); pourtant, ils affichent une valeur beaucoup plus grande stockée dans l'une de ces adresses, donc très suspecte. (Cela pourrait fonctionner s'il s'agissait d'une machine adressée à un mot, mais ce n'est pas ce qui est dit et, aujourd'hui, peu de machines le sont, bien que certaines machines éducatives le soient aussi.)

Sur la base des quatre cartes mémoire que je vous ai montrées à tous, je définirais les pointeurs d'une manière légèrement différente:

Un pointeur est un emplacement de mémoire dont la valeur est l'adresse de la mémoire d'un autre emplacement de mémoire.

Bien qu'il existe des situations où cette pensée est correcte, vous mélangez des métaphores ici. La notion de variable concerne l’algorithme et son objectif - il n’est pas nécessaire de supposer que toutes les variables ont des emplacements de mémoire. Certaines variables (notamment les tableaux) ont des emplacements de mémoire car ceux-ci prennent en charge l’adressage (alors que les registres de CPU ne peuvent être nommés que non indexés).

Pour l'exécution, il existe un mappage logique entre les variables et les instructions, les emplacements mémoire du processeur et les séquences d'instructions du processeur. Une variable dont la valeur ne change jamais (par exemple une constante) ne nécessite même pas nécessairement un emplacement de mémoire, car la valeur peut être reproduite à volonté (par exemple si nécessaire pour les séquences de code générées par le compilateur).


4
Et même les octets de 8 bits ne sont toujours pas universels.
Déduplicateur

14
@JimmyJames Prenons le cas d'un forindex de boucle lorsque le compilateur décide de dérouler complètement la boucle. Nulle part dans le code de sortie produit (qu'il s'agisse d'un code d'assemblage, d'un code machine ou d'un code d'octet), il n'y a un emplacement de mémoire dans lequel le compteur de boucles est stocké. Mais c'est toujours une variable.
dmckee

4
@JimmyJames, dans le cas du pointeur en boucle déroulée, alors oui, si votre code utilise réellement la valeur du compteur, il doit être chargé quelque part , mais (a) cet endroit pourrait être un registre, et (b) il n'y a aucune raison de principe pour que ce soit le même emplacement à chaque itération de la boucle déroulée.
Salomon Slow

3
Si la boucle effectue quelque chose comme copier un tableau de longueur fixe sourcedans un tableau de longueur égale, destune boucle codée for (int i=0; i<8; ++i) dest[i] = source[i];pourrait bien être compilée jusqu'à obtenir quelque chose d'équivalent à la répétition du dest++ = source++;nombre de fois approprié. Avec le compteur de boucles lui-même n’est nulle part en évidence (pas même dans le registre), et seul le nombre de répétitions vous renseigne sur la condition de la boucle.
dmckee

2
La distinction est un peu confuse par les langages tels que C dont la sémantique s'appuie étroitement sur une abstraction d'une machine dont la mémoire est constituée d'emplacements numérotés.
Michael Kay

20

Est-il prudent de dire qu'une variable est la même chose qu'un emplacement de mémoire?

La variable et l'emplacement mémoire sont deux abstractions à deux niveaux d'abstraction différents. Les variables et les pointeurs sont un concept de niveau supérieur au niveau du code / langue, la mémoire est un concept de niveau inférieur au niveau de la machine. Une fois qu'un code a été compilé dans un exécutable, il n'y a plus aucune variable. Essayer de parler de l'emplacement de la mémoire et des variables de cette manière est une erreur catégorique.

Une variable peut être implémentée en utilisant la mémoire, mais pas toujours comme un compilateur peut optimiser un calcul et faire tous les calculs relatifs à une variable entièrement dans des registres, ou il peut mettre une seule variable dans plusieurs emplacements de mémoire, ou utiliser une seule mémoire. emplacement pour plusieurs variables.

Un pointeur est un emplacement de mémoire dont la valeur est l'adresse de la mémoire d'un autre emplacement de mémoire.

Cette série de cartes mémoire est tellement confuse qu’elles ne sont pas simplement mauvaises, mais elles ne sont même pas mauvaises.


1
Once a code had been compiled into an executable, there's no longer any variables.C'est quelque chose avec lequel je suis en désaccord. Il est exact que votre variable telle que vous la connaissez (c'est-à-dire sous ce nom) n'existe plus, mais votre phrasé semble suggérer que l'exécutable compilé utilise uniquement des adresses de mémoire. Ce n'est pas correct Votre exécutable compilé mais non exécutable n'a aucune idée des adresses de mémoire qu'il utilisera lors de son exécution. Le concept de variable (c'est-à-dire une référence réutilisable à l'adresse de mémoire affectée au moment de l'exécution) existe toujours à l'intérieur de l'exécutable compilé.
Flater

2
Ou encore, le compilateur pourrait optimiser la variable de manière totalement distante, de différentes manières. Pré-calculer quelque chose, élaguer des variables inutiles. Si la variable est une constante, le compilateur pourrait alors utiliser des instructions de la CPU utilisant des constantes, ce qui ne serait plus le cas si la variable était nulle part.
kutschkem

16

Les variables sont des constructions de langage . Ils ont un nom, résident dans une portée, peuvent être référencés par d'autres parties du code, etc. Ils constituent une entité logique . Le compilateur est libre d'implémenter cette construction de langage comme bon lui semble, à condition que le comportement observable soit celui prescrit par le standard de langage. En tant que telle, la variable n'a même pas besoin d'être stockée n'importe où si le compilateur peut prouver que cela n'est pas nécessaire.

Les emplacements de mémoire sont un concept matériel . Ils signifient une place dans la mémoire virtuelle / physique. Chaque emplacement de mémoire a exactement une adresse physique et une quantité d'adresses virtuelles pouvant être utilisées pour le manipuler. Mais il y a toujours exactement un octet stocké dans chaque emplacement de mémoire.

Les pointeurs sont un type particulier de valeurs . Dire quelque chose est un pointeur revient à dire que quelque chose est de type double. Cela signifie combien de bits sont utilisés pour la valeur et comment ces bits sont interprétés, mais cela ne signifie pas que cette valeur est stockée dans une variable, ni que cette valeur est stockée en mémoire.


Pour donner un exemple en C: quand j’ai un tableau 2D int foo[6][7];et que j’accède à un élément de celui-ci avec foo[1][2], fooc’est une variable qui contient un tableau. Lorsque fooest utilisé dans ce contexte, il est transformé en un pointeur sur le premier élément du tableau. Ce pointeur n'est stocké dans aucune variable, ni en mémoire, sa valeur est uniquement générée dans un registre de la CPU, utilisé puis oublié. De même, l'expression foo[1]est transformée en un autre pointeur dans ce contexte, qui, là encore, n'est pas dans une variable, n'est pas stocké en mémoire, mais calculé dans la CPU, utilisé et oublié. Les trois concepts de variable , l' emplacement de la mémoire et le pointeur sont en réalité trois concepts différents.


Btw, je voulais vraiment dire "il y a toujours exactement un octet stocké à chaque emplacement de mémoire". Ce n'était pas le cas à l'âge de pierre de l'informatique il y a une cinquantaine d'années, mais c'est vrai pour pratiquement tout le matériel utilisé aujourd'hui. Chaque fois que vous stockez une valeur en mémoire supérieure à un octet, vous utilisez en réalité un certain nombre d'emplacements de mémoire consécutifs. C'est-à-dire (en supposant que l'ordre des octets big endian), le nombre 0x01234567 est stocké en mémoire

+------+------+------+------+
| 0x01 | 0x23 | 0x45 | 0x67 |
+------+------+------+------+
    ^      ^      ^      ^
    |      |      |      |
 0x4242 0x4243 0x4244 0x4245

(Les petites machines comme l’architecture X86 stockent les octets dans l’ordre inverse.) Cela vaut également pour les pointeurs: un pointeur sur une machine 64 bits est stocké sur huit octets consécutifs, chacun avec sa propre adresse de mémoire. Vous ne pouvez pas regarder une cellule mémoire et dire: "Oh, c'est un pointeur!" Vous ne voyez toujours que des octets lorsque vous examinez la mémoire .


Comment l'ordinateur sait-il qu'un groupe d'emplacements mémoire consécutifs commence et se termine?
Progner

6
@progner Ce n'est pas le cas. Il interprète les octets en mémoire en fonction des instructions qu'il obtient. Ces instructions ne sont également stockées que dans une séquence d'octets eux-mêmes. Pour la CPU, la seule différence entre un octet contenant une instruction, un octet contenant un caractère et un octet contenant des bits à virgule flottante est la manière dont il a été chargé d’utiliser cet octet. Si l'octet est récupéré parce que le compteur de programme y pointe, il est utilisé comme une instruction. S'il est récupéré parce qu'une instruction dit de le charger dans un registre flottant, il est utilisé comme donnée à virgule flottante.
cmaster

7
@progner C’était en fait l’innovation clé de l’architecture de von-Neuman: stocker les instructions et les données dans la même mémoire, ce qui permet aux instructions de modifier des données qui seront exécutées ultérieurement sous la forme de plusieurs instructions. Cela autorisait le code à auto-modification, mais permettait également au noyau d'un système de charger un programme en mémoire, puis d'indiquer à la CPU d'exécuter ce programme. Avant von-Neuman, les ordinateurs tels que les machines Zuse recevaient leurs instructions via un canal totalement indépendant des données sur lesquelles ils opéraient.
cmaster

5

Laissez-moi me concentrer sur votre question actuelle - "qui a raison?" en comparant ces deux affirmations:

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

La réponse à cette question est non . La première parle d'une "adresse mémoire d'une autre variable", mais les variables n'ont pas nécessairement d'adresses de mémoire, comme les autres réponses l'ont déjà expliqué. Le second indique "un pointeur est un emplacement de mémoire", mais un pointeur est littéralement un nombre, qui peut être stocké dans une variable, mais comme auparavant, une variable n'a pas nécessairement d'adresse de mémoire.

Quelques exemples d’énoncés plus précis:

  • "Un pointeur est un nombre représentant l'adresse de la mémoire d'un emplacement de mémoire", ou

  • "Une variable de pointeur est une variable dont la valeur est l'adresse de la mémoire d'un emplacement de mémoire."

  • "Une adresse mémoire peut contenir un pointeur représentant l’adresse mémoire d’un emplacement mémoire."

Notez parfois que le terme "pointeur" est utilisé comme raccourci pour "variable de pointeur", ce qui est correct tant qu'il ne crée pas de confusion.


Vous pouvez changer "un autre" en "a" car un pointeur peut pointer sur lui-même.
Pieter B

@PieterB: nitty, nitty ;-) Je ne sais pas si cela rend les choses plus claires, car je voulais seulement changer le libellé original au degré requis pour le rendre plus sensé. Mais hélas, j'ai fait le montage.
Doc Brown

Pour être honnête, si vous obtenez cette énigme "mais un pointeur est littéralement juste un nombre", ce n'est pas correct non plus, en fait, un pointeur est un identifiant représentant un nombre;) Ou du moins nous devions connaître les spécificités linguistiques pour entrer dans ces détails.
Zaibis

2
Un pointeur est une valeur (le numéro est déjà trop spécifique pour certaines implémentations) faisant potentiellement référence à un objet. Potentiellement, car il y a aussi des pointeurs nuls, des pointeurs sauvages et des pointeurs pendants, bien que certains (ou même tous!) D'entre eux puissent être écartés par le langage utilisé.
Déduplicateur

2
@Déduplicateur: vous avez raison, mais je pense que le modèle mental d'un pointeur en tant que nombre est suffisant pour les besoins de cette question. Alors gardons les choses simples.
Doc Brown

5

Je ne dirais certainement pas qu'un pointeur est un emplacement de mémoire contenant une adresse. D'une part, je ne suis pas au courant d'une architecture où 0x23453un seul octet pourrait tenir. :) Même si vous supprimez la distinction octets / mots, vous avez toujours le problème que chaque emplacement de mémoire contient une adresse. Les adresses ne sont que des chiffres et le contenu de la mémoire ne sont que des chiffres.

Je pense que le truc ici est que "le pointeur" décrit l'intention humaine , pas une caractéristique particulière de l'architecture. Cela ressemble à la façon dont un "caractère" ou une "chaîne" n'est pas une chose concrète que vous pouvez voir en mémoire - ce ne sont que des chiffres, mais ils fonctionnent comme des chaînes car ils sont traités de la sorte. "Pointeur" signifie simplement une valeur destinée à être utilisée comme adresse.

Honnêtement, si votre objectif est d’enseigner une langue particulière (Objective C?), Je ne suis pas sûr que tirer la cassette mémoire classique soit utile. Vous dites déjà des mensonges blancs en affichant des valeurs dactylographiées et des valeurs trop grandes pour un octet. Enseignez la sémantique et non la mécanique - la principale idée sur les pointeurs est qu'ils fournissent l' indirection , ce qui est un outil extrêmement utile à comprendre.

Je pense qu'une bonne comparaison pourrait être une URL, qui vous indique trouver des données, mais pas les données elles-mêmes. Écoutez-moi:

  • Vous vous souciez rarement de ce que l'URL est réellement ; la grande majorité d'entre eux sont liés par des noms. Beaucoup de gens utilisent Internet sans savoir exactement comment une URL aboutit à une page; Certaines personnes sont complètement inconscientes des URL.

  • Toutes les chaînes ne constituent pas une URL ou ne sont pas destinées à être utilisées comme URL.

  • Si vous essayez de visiter une URL fictive ou une page qui existait auparavant mais qui a été supprimée depuis, vous obtenez une erreur.

  • Une URL peut pointer vers une image, du texte, de la musique ou un certain nombre d’autres éléments individuels, ou sur une page contenant divers éléments. Il est très courant d'avoir un tas de pages avec des dispositions similaires mais des données différentes.

  • Si vous créez une page Web et que vous souhaitez faire référence à des données figurant sur une autre page Web, vous n'avez pas besoin de tout copier / coller. vous pouvez simplement faire un lien vers elle.

  • N'importe quel nombre d'autres pages peut créer un lien vers la même URL.

  • Si vous avez une collection de pages similaires, vous pouvez créer une page d'index qui répertorie tous les liens, ou simplement un lien "Suivant" au bas de la page 1 qui vous mène à la page 2, etc. Les avantages et les inconvénients des deux approches sont immédiatement évidents, en particulier si vous envisagez ce que le webmaster doit faire pour ajouter ou supprimer des pages à différents endroits.

Cette analogie, il est clair très ce que les pointeurs sont pour , ce qui est essentiel pour les comprendre - sinon ils semblent arbitraires, compliqué et inutile. Comprendre comment quelque chose fonctionne est beaucoup plus facile si vous comprenez déjà ce que cela fait et pourquoi c'est utile. Si vous avez déjà compris qu'un pointeur est une boîte noire qui vous indique où quelque chose d' autre est, et puis vous en apprendre davantage sur les subtilités du modèle de mémoire, représentant alors des pointeurs comme des adresses est assez évidente. De plus, la sémantique de l'enseignement mettra vos étudiants dans un endroit bien meilleur pour comprendre et inventer d'autres formes d'indirection - ce qui est bien quand la plupart des langues principales n'ont pas de pointeur!


every memory location contains an address- Chaque emplacement de mémoire a une adresse. Ce n'est contenu nulle part, sauf peut-être dans une variable de pointeur.
Robert Harvey

@ RobertHarvey chaque emplacement de mémoire (mot, au moins) contient un nombre, qui pourrait être interprété de manière triviale comme une adresse. le fait était que rien dans le matériel ne distingue réellement les adresses des non-adresses
Eevee

2

Je sais que vous avez déjà accepté une réponse, et cette question a déjà cinq réponses, mais il y a un point qu'ils ne mentionnent pas, un qui, je pense, vous a fait trébucher. Les manuels CS tentent souvent d’être agnostiques quant au choix du langage de programmation, ce qui laisse supposer implicitement que la terminologie utilisée pour décrire les choses est universelle. Ce n'est pas.

En C, l'opérateur unary esperluette s'appelle l'opérateur "address-of". Les programmeurs C n'hésiteraient pas à dire que l'expression est &xévaluée à l'adresse de la variable x. Bien sûr, ils signifient "l'adresse mémoire dans laquelle est stockée la valeur de la variable x", mais personne n'est aussi pédant dans une conversation informelle. En C, le mot "pointeur" fait généralement référence au type de données d'une variable destinée à avoir une adresse mémoire comme valeur. Ou équivalent le type de données de la valeur. Mais certaines personnes utiliseraient "pointeur" comme valeur elle-même.

En Java, toutes les variables de type objet ou tableau se comportent beaucoup comme des pointeurs C (à l’exception de l’arithmétique de pointeur), mais les programmeurs Java les appellent des références et non des pointeurs.

C ++ considère que les références et les pointeurs sont des concepts différents. Ils sont liés, mais pas tout à fait la même chose, donc les programmeurs C ++ doivent faire la distinction dans la conversation. L'esperluette est lue comme "adresse-de" dans certains contextes et "référence-à" dans d'autres.

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

Voilà comment un programmeur C pourrait le décrire, en utilisant "un pointeur" dans le même sens que "un int." (Comme dans "un pointeur contient une adresse mémoire, alors qu'un int contient un entier compris dans une certaine plage".)

Un pointeur est un emplacement de mémoire dont la valeur est l'adresse de la mémoire d'un autre emplacement de mémoire.

C'est une façon étrange de le dire, car cela nécessite une définition très vague et informelle de «est».

Est-il prudent de dire qu'une variable est la même chose qu'un emplacement de mémoire?

Il serait plus clair de dire qu'une adresse mémoire est l'emplacement dans la mémoire où la valeur d'une variable est stockée. (Accordée, toutes les variables ne sont pas stockées en mémoire, à cause des optimisations du compilateur, mais toutes les variables dont l'adresse est prise le &xseront.)


En pédant: adresse à laquelle quelque chose est stocké. Mis à part une adresse ne pouvant rien stocker, les objets sont souvent stockés dans plusieurs emplacements adjacents. Un seul d'entre eux (généralement sélectionné par une règle relativement cohérente) est adressé (et n'utilise qu'une adresse sur un nombre potentiellement important).
Déduplicateur

@ Déduplicateur, je ne cherche pas à être pédant.
Gatkin

La norme C distingue même, formellement, les variables qui doivent suivre strictement les étapes de la machine abstraite à chaque «point de séquence» - pour des raisons de sécurité du thread et certaines opérations de bas niveau sur du matériel mappé en mémoire - et celles qui ne le sont pas. t, qui sont libres d’être déplacés dans un registre ou optimisés complètement.
Davislor

@Davislor: le standard C utilise le terme "objet" là où d'autres spécifications de langage utilisent "variable", ainsi que pour décrire d'autres éléments qui ne sont pas des variables. Certaines discussions peuvent utiliser le terme "variable", indépendant du langage, mais pour une raison quelconque, il manque un terme dans la norme permettant de distinguer les allocations disjointes nommées (variables) des autres types d'objets tels que les allocations imbriquées (membres struct / union) ou les objets non nommés générés. par déréférencement des pointeurs. De manière informelle, "variable" est un excellent terme, mais le Standard ne l’utilise pas.
Supercat

@ supercat Ce n'est pas correct. La norme C11 utilise le terme «variable» plus de cent fois, dont plusieurs dizaines sont des noms, par exemple, «L'accès simultané à la variable en cours d'initialisation, même via une opération atomique, constitue une course de données."
Davislor

1

L'instruction Un pointeur est une variable dont la valeur est l'adresse mémoire d'une autre variable est simplifiée à l'excès. Mais au moment où un lecteur comprendra ce qu'est exactement un emplacement mémoire et comment il diffère d'une variable, il comprendra déjà ce qu'est exactement un pointeur et n'aura donc plus besoin de s'appuyer sur cette explication inexacte.

L'instruction Un pointeur est un emplacement mémoire dont la valeur est l'adresse de la mémoire d'un autre emplacement mémoire incorrect. Il n'est pas nécessaire que la valeur d'un pointeur soit stockée dans un emplacement de mémoire. Si un pointeur doit pointer sur un emplacement de mémoire, cela peut faire l'objet d'un débat, en fonction de la définition souhaitée de "mémoire".

Quelle est la différence entre une variable et un emplacement de mémoire

Un emplacement de mémoire est l'un des multiples emplacements possibles où les données peuvent être stockées. Ces données peuvent être une variable ou une partie d’une variable. Les variables sont un moyen d'étiquetage des données.


0

Cette réponse se concentre sur C et C ++; cela semble approprié puisque votre question concerne les pointeurs qui font plus partie intégrante de C / C ++ que d’autres langages. La plupart de cet article s'appliquera à la plupart des langages compilés sans une exécution complexe (comme Pascal ou Ada, mais pas comme Java ou C #).

Les bonnes réponses déjà données soulignent qu'une variable est une construction de langage à un niveau plus abstrait que la mémoire physique. Je voudrais cependant souligner que cette abstraction a une certaine logique et un certain système:

L'abstraction consiste principalement à utiliser un nom au lieu d'une adresse littérale.

L'idée principale est qu'une variable est un handle nommé pour un objet typé; les objets en C / C ++ sont généralement en mémoire. Les langues ajoutent ensuite quelques détails concernant la gestion de la durée de vie et le marshaling des données pour les conversions de types. Le concept de variable est plus abstrait que les adresses physiques, car nous ne nous soucions pas de la valeur numérique des adresses ni de l'emplacement exact des fonctions en mémoire. Nous les nommons simplement et nous les adressons ensuite par leur nom, et le compilateur, l’éditeur de liens et le système d’exécution s’occupent des détails.

Et ne prétendez pas que C / C ++ n’est pas agnostique en mémoire: il existe, après tout, l’opérateur d’adresse universellement applicable. Oui, vous ne pouvez pas prendre l'adresse d'une variable C dans la classe de stockage de registre; mais quand en as-tu utilisé un dernier? Il s’agit d’une exception spéciale au concept général et non d’un rejet complet de l’argument. La règle générale est au contraire que prendre une adresse de variable oblige en fait le compilateur à créer un objet en mémoire, même s'il ne le ferait pas autrement (par exemple avec des constantes). Le concept de "poignée nommée" est également un bon paradigme pour les références C ++: une référence est simplement un autre nom du même objet.

Quand j’ai écrit inline assembler pour 68k, c’était bien de voir comment utiliser les noms de variables comme décalages pour les registres d’adresses (et les noms de variables déclarées à la registerplace des noms de registres à nu!). Pour le compilateur, une variable est un décalage d'adresse constant. Pour réitérer: Les variables sont des descripteurs nommés, généralement des objets en mémoire.


Les pointeurs constituent également une partie fondamentale des langages C #, Java, JS et d’autres langages. Les appeler différemment ne change rien à cela, même si ce sont de bonnes relations publiques.
Déduplicateur

@Deduplicator :-) Bon vieux Tony ...
Peter - Réintégrer Monica

0

On dirait que la question s'adresse à un langage populaire formé en augmentant la norme C avec la garantie supplémentaire "Dans les cas où certaines parties de la norme ou la documentation d'une implémentation décrivent le comportement de certaines actions, et d'autres les catégorisent comme non définies , la première partie domine. ", ainsi qu’une définition de" variable "cohérente avec l’utilisation du terme dans d’autres langues.

Dans cette langue, chaque emplacement de mémoire peut être considéré comme une boîte aux lettres numérotée contenant toujours un certain nombre (généralement huit) de bits, chacun pouvant être indépendamment zéro ou un. Les emplacements de mémoire sont généralement organisés en rangées de deux, quatre ou huit. et certaines opérations traitent simultanément sur plusieurs emplacements de mémoire. En fonction de la machine, certaines opérations opérant sur des groupes de deux, quatre ou huit emplacements de mémoire peuvent être limitées à des emplacements situés sur une seule ligne. En outre, alors que certaines machines peuvent avoir une seule pièce de boîtes aux lettres numérotées consécutivement, d’autres peuvent avoir plusieurs groupes de boîtes aux lettres numérotées et disjointes.

Une variable identifie une plage d'emplacements de mémoire qui lui sont associés exclusivement et un type en tant que ces emplacements de mémoire doivent être interprétés. La lecture d'une variable entraîne l'interprétation des bits situés dans ses emplacements de stockage associés d'une manière appropriée au type de la variable, et l'écriture d'une variable entraîne la définition des bits associés d'une manière appropriée à son type et à sa valeur.

Une adresse encapsule toutes les informations nécessaires pour identifier une boîte aux lettres. Cela peut être stocké sous la forme d'un numéro simple ou d'une sorte d'indicateur de groupe avec le numéro d'une boîte aux lettres de ce groupe.

L'application de l' &opérateur à une variable produira un pointeur qui encapsule l'adresse et le type de celle-ci. L’application du unaire *ou de l’ []opérateur à un pointeur entraîne l’interprétation ou la définition des bits des boîtes aux lettres commençant à une adresse encapsulée, d’une manière appropriée au type encapsulé.


On dirait que vous réfléchissez trop à la question.
Robert Harvey

0

J'arrive en retard à cette soirée mais je ne peux pas m'empêcher de mettre mes 2 centimes dedans.

À ces moments, quelle est la différence entre les valeurs stockées dans ces emplacements de mémoire?

Temps 1

entrez la description de l'image ici

Temps 2

entrez la description de l'image ici

Bonne réponse: rien. Ce sont toutes des valeurs identiques présentées avec des interprétations différentes de leur signification.

Comment je sais ça? Parce que c'est moi qui ai inventé ça. Vous ne le savez pas vraiment encore.

Vous rencontrez quelque chose que j'appelle le problème hors bande . Comment interpréter correctement la signification de ces valeurs n'est pas stocké ici. Cette connaissance est stockée ailleurs. Pourtant, lorsque vous présentez ces valeurs sur papier, vous mettez cette interprétation. Cela signifie que vous avez ajouté des informations qui n'existent tout simplement pas dans ces emplacements de mémoire.

Par exemple, les valeurs ici sont identiques, mais vous savez que cela n’est vrai que si vous avez raison lorsque vous supposez qu’un encodage de caractères ASCII / UTF-8 correspond à la façon dont j’ai obtenu le premier, plutôt que de dire EBCDIC . Et vous devez également supposer que la deuxième expression est une expression hexadécimale des valeurs numériques stockées dans ces emplacements de mémoire, qui pourraient toutes être des pointeurs vers d'autres adresses, plutôt que de dire des références à des chaînes qui commencent toutes par "0x". : P

Rien stocké dans ces emplacements de mémoire ne vous dit que ces hypothèses sont correctes. Cette information peut être stockée. Mais il serait stocké ailleurs.

C'est le problème de présentation . Vous ne pouvez exprimer aucun chiffre sans d'abord vous mettre d'accord sur la manière de le présenter. Vous pouvez vous appuyer sur des hypothèses, des conventions et du contexte, mais si vous y réfléchissez profondément, lorsque la présentation n'est pas explicitement définie, la seule réponse vraiment correcte est "pas assez d'informations".


C'est encore plus amusant quand la même mémoire est utilisée pour différentes choses constantes en même temps.
Déduplicateur

@Duplicator True. Cela me fait toujours penser à la distribution de réinterprétation de c ++ . Mêmes bits vus d'une manière différente.
candied_orange

@Deduplicator ou, à bien y penser, union in c
candied_orange
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.