40 votes

Quel est le terme moderne pour "équivalence tableau/pointeur" ?

Tous ceux qui lisent ces lignes connaissent probablement ces trois faits essentiels sur le C :

  1. Lorsque vous mentionnez le nom d'un tableau dans une expression, celle-ci est évaluée (la plupart du temps) comme un pointeur vers le premier élément du tableau.
  2. L'opérateur de "souscripting de tableau". [] 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 centraux pour la gestion des tableaux et des pointeurs en C. Ce ne sont même pas trois faits distincts ; ce sont des facettes liées entre elles d'un concept central. Il n'est pas possible d'effectuer correctement une programmation C, même relativement basique, sans une bonne compréhension de ce concept.

Ma question aujourd'hui est simple, Quel est le nom de ce concept ?

Je suppose que je suis vieux jeu, mais j'ai toujours appelé cela "L'équivalence entre les tableaux et les pointeurs en C", ou "équivalence tableau/pointeur" pour faire court. Mais j'ai appris que l'on ne peut presque pas prononcer ces mots sur l'OS ; ils sont plutôt tabous.

Cela peut sembler être une question abstraite ou philosophique, donc pour la formuler plus concrètement, ce que je cherche est un nom ou une expression simple que je pourrais utiliser dans la phrase "Oui, en raison de _____, l'inscription des tableaux peut être considérée comme un sucre syntaxique pour l'arithmétique des pointeurs", en réponse à, disons, cette question .

(Mais veuillez noter que je suis no à la recherche de réponses à cette question, ou de réponses à la question "Qu'est-ce qui ne va pas avec le mot 'équivalence' ?". Oui, je sais, il peut induire les apprenants en erreur en leur faisant croire que les tableaux et les pointeurs sont en quelque sorte identiques. J'avais cette confusion en tête lorsque j'ai écrit cette entrée de liste FAQ .)

21 votes

Peut-être "array decay" ?

4 votes

L'équivalence est d'environ expressions en utilisant soit le [] ou le (unaire) * opérateurs. De nos jours, la plupart des gens semblent penser en termes de tableaux et de pointeurs. objets ce qui cause la confusion. (car ces objets ne sont pas équivalents) IMHO, IANALL.

0 votes

Si l'expression "promotion implicite d'un entier" est quelque chose à voir, je pense que l'expression "conversion implicite d'un tableau" devrait être compréhensible par la plupart.

32voto

Lundin Points 21616
  1. L'opérateur de "souscripting de tableau" [] 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. Ceci est garanti puisque arr[i] doit être équivalent à *(arr + i) . Le premier est un "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 fait d'un cas particulier, appelé "ajustement de tableau", où le compilateur transforme implicitement la déclaration d'un paramètre de fonction de type tableau en un pointeur vers le premier élément. La raison en est sûrement de rendre les fonctions compatibles avec la "désintégration de tableau" des expressions, mais la norme C maintient les termes séparés.

Dans les deux cas, expressions et paramètres de fonction, on parle souvent de manière informelle de "décomposition de tableau". Bien que ce terme ne soit parfois 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 de ce terme. "Array decay" est le meilleur 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 la même chose". Les appeler "équivalents" n'aide pas vraiment).

1 votes

" Lorsque vous tapez [] dans une expression, vous obtenez toujours un pointeur sur le premier élément. "est, je pense, mal formulé. Le résultat de l'utilisation de [] sur un T* n'est pas un T* c'est un T . Je ne suis pas sûr que cela puisse être mieux formulé, cependant.

1 votes

@NicHartley Le résultat d'utiliser [i] sur un T* est un *(T + i) . Le résultat de l'expression sera en effet une lvalue de type T .

1 votes

J'aurais dû dire quelque chose comme "L'opérateur 'array subscripting'". [] fonctionne aussi bien pour les pointeurs que pour les tableaux". Non, [] ne voit jamais un tableau, toujours un pointeur, mais je pense qu'il est sûr de dire que pour la plupart des programmeurs, la plupart du temps, [] est au moins imaginé pour être un opérateur d'inscription de tableau, agissant sur un tableau si c'est ce que l'opérande est déclaré.

13voto

Zack Points 44583

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

Je suis vieux jeu et je pense qu'il n'y a rien de mal à appeler cela "équivalence tableau/pointeur", à condition qu'il soit clair dans le contexte que vous parlez d'expressions où (1) se produit ou de déclarations de fonctions où (3) se produit. Cependant, un terme plus acceptable pour les personnes qui n'aiment pas le terme "équivalence" serait peut-être "conversion tableau/pointeur", puisque cela perturbe les gens le plus souvent quand il s'agit de (1), je pense.

0 votes

Je ne pense pas qu'il y ait beaucoup de mal à l'appeler "équivalence tableau/pointeur", mais sérieusement, n'essayez pas de dire ça dans une réponse sur SO ! La dernière fois que j'ai essayé, j'ai été downvoted jusqu'à l'oubli, et j'ai dû supprimer la réponse (par ailleurs très bien, IMO) juste pour arrêter le carnage.

9voto

coderredoc Points 27302

J'opterais pour le terme de désintégration des réseaux . Ce terme va bien avec ce qu'il suggère. La norme C n'en parle pas dans ce contexte et oui, le premier jour où j'ai entendu le terme, je l'ai cherché dans la norme mais je ne l'ai pas trouvé (donc c'est un peu confus de savoir qui a inventé le terme, etc). Alternativement, on peut aussi écrire due to "la plupart des scénarios de tableau sont convertis en pointeur"... - Non, il ne s'agit pas d'un nom unique, mais cela ne permet pas de faire des erreurs d'interprétation. La norme elle-même dit que c'est la "conversion".

La plupart du temps, j'essaie de le dire de la manière la plus longue possible, puis je mets le mot ("array decaying") entre parenthèses. En fait, il y a des réponses où je ne l'ai même pas mentionné et où j'ai simplement suivi les mots de la norme, à savoir : "array decaying". conversion en pointeur .

1 votes

@bolov. : Ah oui... mais désintégration des réseaux qui a inventé ce terme ? La norme C utilise le terme "decay" à un seul endroit et c'est vraiment hors contexte par rapport à la question qui nous est posée. Je suis sûr qu'aucune des normes n'utilise la décroissance pour désigner cette chose.

3 votes

J'ai fait une recherche rapide et il semble que "decay" n'ait pas été utilisé non plus dans "The C programming Language" de Kernighan et Ritchie. C'est donc une question intéressante que de savoir d'où vient ce terme.

1 votes

@bolov. : Et bolov vous avez commenté et c'est bien - mais avez-vous vu que c'est en tag C - c'est pourquoi je n'ai pas mentionné que je parlais de la norme C. :) Je cherche l'origine du terme.

5voto

Mike Kinghan Points 4567

Je suggère que "array-to-pointer decay" est un raccourci raisonnable, puisque "decay" est un jargon courant pour faire référence à la conversion de type, avec un précédent ailleurs dans la FAQ C : Question 6.12 :

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

Un sens technique étendu de "decay" qui inclut celui-ci a été adopté dans la nomenclature de la bibliothèque standard C++. adoptée dans la nomenclature de la bibliothèque standard C++ depuis C++11 : std::decay

0 votes

Je n'avais pas entendu parler de cette nouvelle syntaxe C++11 ! Merci pour le, er, pointeur.

5voto

supercat Points 25534

Il n'y a 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, au moins quand on décrit le C "moderne". Alors que les résultats de la désintégration des tableaux se comportent généralement comme des pointeurs, C99 spécifie que les pointeurs produits par la désintégration des tableaux ne sont pas tenus de se comporter de la même manière que les pointeurs obtenus par d'autres moyens. Étant 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 la raison pour laquelle la valeur du pointeur s.arr[0] utilisé dans test1 ne doit pas être équivalent à la valeur du pointeur ((char*)(void*)s) utilisé lorsque fetch_byte_at est appelé à partir de test2 . Il implique cependant simultanément que test2 devrait être capable de lire tous les octets de s [ce qui implique qu'il 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 jusqu'à 6.

Bien que rien dans la norme ne contredise l'un ou l'autre de vos deux premiers points individuellement, il n'est pas possible que les deux soient valables. Soit le résultat d'une désintégration de tableau est autre chose qu'un pointeur "ordinaire" vers le premier élément du tableau, soit l'application de la fonction [] à un tableau a une sémantique différente de celle de l'application à un pointeur. Alors qu'il n'est pas clair lequel des #1 et #2 a été invalidé par C99, ils ne forment plus ensemble aucune sorte d'"équivalence" dans le C moderne.

Si vous reconnaissez une distinction entre le C traditionnel et le C "moderne", il pourrait être utile d'établir des termes pour les choses qui rendent le premier utile. Ces éléments vont toutefois au-delà des points que vous mentionnez. Malheureusement, je ne connais pas de termes standard pour de telles choses, et je ne m'attendrais pas à ce que la norme fournisse une telle terminologie lorsqu'elle ne supportera plus les concepts impliqués.

0 votes

Votre exemple me laisse quelque peu perplexe ; son introduction de tableaux 2-D et d'une structure enveloppante, et fetch_byte_at L'utilisation de void * pour gratter la plupart des informations sur les types, rend les choses plutôt confuses.

0 votes

Si l'on s'en tient à des tableaux simples et uniques et à des pointeurs, je ne pense pas qu'il y ait de désaccord sur le fait que pour arr de type array-of-T, l'expression arr a le type pointeur-à-T, et que [] s'applique également. (Je ne pense pas que cela ait changé au cours des années, non plus. Il y a plus de clarté en termes de ce que vous pouvez et ne pouvez pas faire lorsque vous essayez d'"aplatir" un tableau multidimensionnel ou des pointeurs, mais ce sont des questions différentes).

0 votes

@SteveSummit : Je pensais que l'utilisation de & sur une lvalue de type tableau pourrait prêter à confusion. Je pensais que le fait d'envelopper un tableau dans une structure et de prendre l'adresse de la structure rendrait clair le fait que le code traite l'adresse de l'agrégat.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X