web-dev-qa-db-fra.com

Qu'est-ce qu'un terme moderne pour "équivalence tableau/pointeur"?

À peu près tout le monde qui lit ceci connaît probablement ces trois faits essentiels sur C:

  1. Lorsque vous mentionnez le nom d'un tableau dans une expression, elle évalue (la plupart du temps) un pointeur sur le premier élément du tableau.
  2. L'opérateur "array subscripting" [] fonctionne aussi bien pour les pointeurs que pour les tableaux.
  3. Un paramètre de fonction qui semble être un tableau déclare en fait un pointeur.

Ces trois faits sont absolument essentiels pour la manipulation des tableaux et des pointeurs en C. Ils ne sont même pas trois faits distincts; Ce sont des facettes liées entre elles d'un même concept central. Il est impossible de programmer correctement, même assez basique, le C sans une bonne compréhension de ce concept.

Ma question aujourd’hui est simplement: Quel est le nom de ce concept?

Je pensais être démodé, mais je l'ai toujours appelé "L'équivalence entre les tableaux et les pointeurs en C" ou "équivalence tableau/pointeur" en abrégé. Mais j'ai appris que vous ne pouvez presque pas dire ces mots sur SO; ils sont à peu près tabous. 

Cela peut sembler être une question abstraite ou philosophique, alors pour l’encadrer plus concrètement, ce que je cherche, c’est un nom simple ou une expression nominale que je pourrais utiliser dans la phrase "Oui, en raison de _____, on peut penser à un indice de tableau comme sucre syntaxique pour arithmétique de pointeur ", en réponse à, disons, cette question .

(Mais notez s'il vous plaît que je suis pas chercher des réponses à cette question ou des réponses à la question "Qu'est-ce qui ne va pas avec l'équivalence de la Parole?" les tableaux et les pointeurs sont en quelque sorte les mêmes. J'avais cette confusion à l'esprit lorsque j'ai écrit cette entrée de liste FAQ .)

38
Steve Summit
  1. L'opérateur "array subscripting" [] fonctionne aussi bien pour les pointeurs que pour les tableaux.

Non, en fait, cela ne fonctionne que pour les pointeurs. Chaque fois que vous tapez [] dans une expression, vous obtenez toujours un pointeur sur le premier élément. Cela est garanti car arr[i] doit être équivalent à *(arr + i). Le premier est "sucre syntaxique" pour le second. 

  1. Un paramètre de fonction qui semble être un tableau déclare en fait un pointeur.

Il s'agit en réalité d'un cas particulier, appelé "ajustement de tableau", dans lequel le compilateur modifie implicitement la déclaration d'un paramètre de fonction de type tableau en un pointeur sur le premier élément. La logique est sûrement de rendre les fonctions compatibles avec la "décomposition de tableau" d'expressions, mais le standard C garde les termes séparés.

Les deux cas, expressions et paramètres de fonction, sont souvent appelés de manière informelle "matrice de décomposition". Bien que parfois cela ne soit utilisé que pour les expressions et non pour les paramètres de fonction. Je ne pense pas qu'il existe une utilisation unique et cohérente du terme. "Array decay" est le meilleur que je pense, bien que la norme C n'utilise ce terme nulle part.


(Je n'aime pas le terme «équivalence», car un tableau peut se transformer en pointeur, mais pas l'inverse. En effet, il y a toujours d'innombrables débutants qui arrivent avec des croyances confuses telles que «les tableaux et les pointeurs sont identiques». "équivalent" n'aide pas exactement.)

26
Lundin

La norme C n'a pas un seul mot pour cela. Il utilise le mot "conversion" pour définir le comportement (1) dans 6.3.2.1p3, "équivalent" pour définir le comportement (2) dans 6.5.2.1p2 et "ajustement" pour définir le comportement (3) dans 6.7.6.3p7.

Je suis démodé et je ne pense pas qu'il y ait quelque chose qui cloche dans l'appel de cette "équivalence tableau/pointeur", à condition que le contexte indique clairement que vous parlez d'expressions où (1) se produit ou de déclarations de fonction où (3) se produit. Cependant, un terme plus acceptable pour les personnes qui n'aiment pas "l'équivalence" serait peut-être "conversion de tableau à pointeur", car cela déroute le plus souvent les gens quand c'est (1), je pense.

13
zwol

Je voudrais aller avec le terme de tableau decay . Ce terme va bien avec ce qu'il suggère. La norme C ne dit pas cela dans ce contexte et oui, le premier jour où j'ai entendu le terme, je suis allé le chercher dans la norme mais je ne pouvais pas le trouver (c'est donc un peu déroutant de savoir qui a inventé le terme, etc.). De même, on peut écrire en raison de"le tableau de la plupart des scénarios est converti en pointeur" ...- Non, ce n'est pas un nom unique. Mais cela ne laisse aucune mauvaise interprétation se produire. Le standard lui-même dit que c'est la "conversion". 

La plupart du temps, j'essaie de dire le long chemin, puis de mettre le mot ("tableau en décomposition") entre crochets. En fait, il y a des réponses pour lesquelles je ne l'ai même pas mentionné et que je me suis contenté de reprendre les mots standard deconversion en pointeur

9
coderredoc

Je suggère que "la désintégration d'un point à un autre" soit un raccourci raisonnable, car "de désintégration" Est un jargon banal pour désigner la conversion de type, avec un précédent Ailleurs dans la FAQ C: Question 6.12 :

Q: Puisque les références de tableau se décomposent en pointeurs, si arr est un tableau, Quelle est la difference entre arr et & arr?

Une signification technique élargie de "décomposition" incluant celle-ci a été adoptée dans la nomenclature de la bibliothèque de normes C++ depuis C++ 11: std::decay

5
Mike Kinghan

Il n’ya pas de nom unique donné aux trois concepts mentionnés, mais je pense que les décrire comme impliquant une sorte «d’équivalence» est contre-productif, du moins pour décrire le C «moderne». Tandis que les résultats de la décomposition en matrice se comportent généralement comme des pointeurs, C99 spécifie qu'il n'est pas nécessaire que les pointeurs générés par l'affaiblissement d'un tableau se comportent de la même manière que les pointeurs obtenus par d'autres moyens. Donné:

char fetch_byte_at(void *p, int x) { return ((char*)p)[x]; }

struct {char arr[5][7];} s;
char test1(int x) { return s.arr[0][x]; }
char test2(int x) { return fetch_byte_at(&s, x); }

la norme ne précise pas directement pourquoi la valeur du pointeur s.arr[0] utilisée dans test1 ne doit pas être équivalente à la valeur du pointeur ((char*)(void*)s) utilisée lorsque fetch_byte_at est appelé à partir de test2. Cependant, cela implique simultanément que test2 devrait être capable de lire tous les octets de s [impliquant que cela devrait fonctionner de manière prévisible avec des valeurs de x jusqu'à au moins 34] tout en disant que s.arr[0][x] n’a de sens que pour les valeurs de x 6.

Tandis que rien dans la norme ne contredirait l'un ou l'autre de vos deux premiers points individuellement, il est impossible pour les deux de tenir. Soit le résultat d'une dégradation du tableau est autre chose qu'un pointeur "ordinaire" sur le premier élément du tableau, soit l'application de l'opérateur [] à un tableau a une sémantique différente de celle appliquée à un pointeur. Bien qu'il soit difficile de savoir lequel des n ° 1 et n ° 2 a été invalidé par C99, ils ne forment plus ensemble une quelconque "équivalence" dans le C moderne.

Si vous reconnaissez une distinction entre le C traditionnel et le C "moderne", il pourrait être utile de définir les termes qui rendent le premier utile. De telles choses vont toutefois au-delà des points que vous mentionnez. Malheureusement, je ne connais pas de termes standard pour de telles choses et je n’aimerais pas que la norme fournisse une telle terminologie quand elle ne prend plus en charge les concepts en question.

5
supercat

Merci à tous. J'utilise cette "réponse" pour résumer les réponses données par les gens et mon évaluation, et non pas comme une réponse correcte. J'attends de tout le monde un vote supérieur ou précédent.

Beaucoup de gens ont sérieusement réfléchi à cette question et je l’apprécie. Mais à ce stade, la seule chose que je puisse conclure est qu’il n’ya pas de réponse, du moins aujourd’hui, à la question à laquelle je pensais.

Un bon nombre de personnes ont suggéré une "décomposition de matrice", et c'est un très beau coup, mais cela ne fonctionne pas pour moi. Il fait principalement référence aux faits 1 et peut-être 3 énumérés dans la question initiale, mais pas vraiment au fait 2. Vous ne pouvez pas dire "Oui, en raison de la décomposition d'un tableau, l'indexation d'un tableau peut être considérée comme un sucre syntaxique pour l'arithmétique de pointeur". (Ou du moins, vous ne pouvez pas dire cela si votre intention est d'être clair et instructif.) Il vous faudrait dire quelque chose comme: "Oui, en raison de la décomposition d'un tableau et du fait que la manière dont l'arithmétique de pointeur est définie est cohérente avec cela, tableau indice peut être considéré comme un sucre syntaxique pour arithmétique de pointeur ", qui est, eh bien, une bouilloire différente de poisson entièrement.

Bien que je ne l'aie pas dit explicitement, je recherchais un terme commun, un usage largement répandu et accepté, bien qu'il n'y ait aucune obligation d'impliquer des mots réellement utilisés dans la norme. Et étant donné que personne n’avait craché un tel terme, étant donné que tout le monde s’engageait dans une certaine quantité de spéculations et "qu’en est-il de ...?", J’en conclus qu’il n’existe pas de terme unique largement utilisé pour le concept derrière le trio faits. (Autre que "l'équivalence", qui est exclue.)

Un certain nombre de répondeurs et de commentateurs ont dit ceci (qu'il n'y a pas de réponse unique) de différentes manières. Je vais aller de l'avant et accepter la réponse de Lundin sur cette base, et parce que d'autres semblent l'avoir préférée.

Moi, à l'avenir, j'essaierais peut-être d'utiliser "La correspondance entre les tableaux et les pointeurs en C" et de voir si elle a du succès. Les tableaux et les pointeurs sont aussi différents que les hommes et les femmes et ils sont en fait assez éloignés les uns des autres, mais ils échangent souvent des lettres. :-)

2
Steve Summit

Cela peut sembler une question abstraite ou philosophique, alors pour le cadrer plus concrètement, ce que je cherche, c’est un nom simple ou une expression nominale que je pourrais utiliser comme suit: "Oui, en raison de _____, l’abonnement à un tableau peut être considéré comme sucre syntaxique pour arithmétique de pointeur ", en réponse à, disons, cette question.

La phrase que vous recherchez est "Oui, étant donné que l’abonnement à un tableau est une arithmétique de pointeur sous le capot, l’abonnement à un tableau peut être considéré comme un sucre syntaxique pour l’arithmétique de pointeur."

Ce qui est bien sûr stupide, parce que la raison de dire que l’abonnement à un tableau est un sucre syntaxique pour l’arithmétique de pointeur est que c’est exactement ce que c’est, cela n’exige aucune explication supplémentaire, à moins que la personne à qui vous le dites ne sache pas quoi. tableau s'abonner ',' arithmétique de pointeur 'ou' sucre syntaxique 'signifie. Cela ne veut pas dire que le compilateur ne connaisse pas la différence entre les deux (c'est parce que c'est lui qui est responsable de tout le sucre syntaxique que vous obtenez à la suite de cela).

Cette même question pourrait être posée à propos de tout ce que n'importe quelle langue fait pour nous, ce que nous pourrions faire nous-mêmes en utilisant un nombre plus élevé d'instructions de niveau inférieur et en tant que tel, pouvant y faire référence en utilisant plusieurs termes qui ne font que changer la quantité de sucre syntaxique utilisée. L’important n’est pas de prétendre qu’elles sont différentes (elles le sont toujours, mais ce n’est pas l’objet), mais de faciliter la programmation (pensez à écrire du code sans avoir l’opérateur [] comme sucre syntaxique pour l’arithmétique de pointeur, et vous réalisez rapidement la raison de son existence - ce n'est pas parce que c'est différent , c'est parce que c'est plus facile écrire, lire et gérer).

(Mais notez bien que je ne cherche pas de réponses à cette question, ni à la question "Qu'est-ce qui ne va pas avec le mot" équivalence "?". Oui, je sais, cela peut induire les apprenants en erreur en leur faisant croire que les tableaux et les pointeurs sont en quelque sorte Je l'avais en tête lorsque j'ai écrit cette entrée de liste FAQ.)

Votre question semble être "Qu'est-ce qu'un terme moderne pour l'équivalence de pointeur de matrice en ce sens que l'abonnement à une matrice n'est qu'un sucre syntaxique pour l'arithmétique de pointeur?"

La réponse est:

  1. "Abonnement à un tableau" lorsque vous utilisez l'opérateur [] pour indexer un tableau.
  2. "Arithmétique de pointeur" lorsque vous déplacez manuellement un pointeur (au lieu d'utiliser l'opérateur []). Vous pourriez aussi vouloir utiliser ce terme pour tout calcul mathématique que vous faites sur la valeur que vous donnez à l'opérateur [], mais vous ne faites pas vraiment de l'arithmétique de pointeur, mais plutôt "calculer un index", qui est le terme utilisé pour la syntaxe. sucre d'avoir automatiquement pris en compte pour vous la taille des objets en mémoire (ce qui encore n'est pas différent, mais plus facile à écrire, à lire et à gérer, donc: sucre syntaxique).
1
pie

C'est une question subtile. En parcourant un dictionnaire des synonymes et un dictionnaire anglais, je suis arrivé à la conclusion que le terme similitude pourrait convenir à votre contexte.

Selon la définition du dictionnaire en ligne d’Oxford, Word Similar est défini comme suit:

avoir une ressemblance en apparence, caractère ou quantité, sans être identique.

et le mot Similitude comme:

la qualité ou l'état d'être semblable à quelque chose.

Comme les tableaux et les pointeurs ne sont pas identiques, mais sont parfois traités de la même manière, on pourrait dire:

Oui, en raison de Array/Pointer similitude , l’indice de tableau peut être considéré comme un sucre syntaxique pour l’arithmétique de pointeur "

1
machine_1

Je conviens que des termes tels que "équivalence de pointeur/tableau" ou "décomposition de tableau" (en un pointeur) sont inexacts et peuvent être très trompeurs.

Je propose ce qui suit:

Accès à un tableau en utilisant l'opérateur [] avec un index a une expression arithmétique de pointeur équivalente. Cependant, il n'y a pas d'équivalence entre un pointeur et un tableau: je peux modifier avec joie la valeur (le contenu) d'un pointeur, peut-être pour enregistrer un compteur d'itération séparé, mais je ne peux pas le faire avec le tableau "décomposé"; il est immuable et présente, à certains égards, un comportement similaire aux références C++.

Les deux verbes "to decay" et "to convert" en anglais indiquent invariablement que l'original est modifié au cours du processus. L'utilisation du nom d'un tableau ou de l'opérateur unaire '&' ne modifie pas leur opérande.

Par conséquent, une expression comme "renvoie un pointeur" ou "crée un pointeur" serait plus précise. Cela se reflète dans le fait que, dans les deux cas, le pointeur résultant est temporaire, assis (généralement) dans un registre GP de la CPU. et ne peut pas être attribué à.

C'est du moins ce que je comprends, mais regarder les désassemblages semble le confirmer.

0
GermanNerd

Standard utilise le terme converti en. L'équivalence de tableau et de pointeur est toujours meilleure sur tableau decay aux pointeurs. Standard ne mentionne ce terme nulle part, mais il s'agit simplement d'une compréhension mutuelle entre les programmeurs que lorsqu'il apparaît dans le contexte des tableaux et des pointeurs, il est considéré comme une équivalence de tableau et de pointeur. Et ce que signifie équivalence de pointeur et de tableau est: arithmétique de pointeur et indexation de tableau [qui] sont équivalentes en C, les pointeurs et les tableaux sont différents.

0
haccks