2008-11-13 7 views
8

Je me demandais toujours pourquoi une opération aussi simple et basique comme l'échange du contenu de deux variables n'est pas intégrée pour de nombreuses langues.Pourquoi un opérateur swap/exchange n'existe-t-il pas dans les langages impératifs ou OO comme C/C++/C#/Java ...?

C'est l'un des exercices de programmation les plus élémentaires dans les cours d'informatique; il est fortement utilisé dans de nombreux algorithmes (par exemple, le tri); de temps en temps on en a besoin et on doit utiliser une variable temporaire ou utiliser une fonction template/générique.

Il s'agit même d'une instruction machine de base sur de nombreux processeurs, de sorte que le schéma standard avec une variable temporaire sera optimisé.

De nombreux opérateurs moins évidents ont été créés, comme les opérateurs d'affectation (par exemple + =, qui a probablement été créé pour refléter les instructions machine cumulatives, par exemple ajouter ax, bx), ou le? opérateur en C#.

Alors, quelle est la raison? Ou existe-t-il réellement, et je l'ai toujours manqué?

+0

Bonnes questions. Je me suis aussi interrogé à ce sujet, bien que les réponses aient du sens. – pro3carp3

+1

L'instruction SWAP * existe * dans QBasic. – dan04

+0

Plus intéressant qu'une macro "swap two variables", il y aurait quelque chose qui se comporterait comme l'opérateur virgule, mais dont la valeur était celle du premier opérande. Imaginez que l'opérateur ait été écrit "=:" (je ne sais vraiment pas quelle notation serait bonne). Alors "x = (y =: y = x)" permuterait x et y. D'autres utilisations seraient, par exemple. "return (y =: y + = 4)" serait conceptuellement similaire à l'opérateur post-incrément, mais incrémenté de 4 au lieu d'un. – supercat

Répondre

11

Dans mon expérience, il est généralement pas nécessaire dans les applications réelles, en dehors des algorithmes de tri déjà mentionnés et parfois dans À mon avis, c'est un peu trop spécial pour avoir un langage généraliste.

Comme cela a également été mentionné, tous les processeurs ne le supportent pas comme une instruction (et beaucoup ne le supportent pas pour les objets plus gros qu'un mot). Donc, s'il était supporté avec une sémantique supplémentaire utile (par exemple, une opération atomique), il serait difficile de supporter certains processeurs, et s'il n'avait pas la sémantique supplémentaire, il serait juste (rarement utilisé) du sucre synatatique. Les opérateurs d'assigment (+ = etc) ont été supportés parce qu'ils sont beaucoup plus communs dans les programmes du monde réel - et donc le sucre syntacique qu'ils fournissent était plus utile, et aussi comme une optimisation - rappelez-vous que les dates C remontent à la fin des années 60. http://www.youtube.com/watch/début des années 70, et l'optimisation du compilateur n'était pas aussi avancée (et les machines moins performantes, donc vous ne vouliez pas de longues passes d'optimisation de toute façon).

Paul

+0

Bonne réponse. Mais il y a plus d'algorithmes dans lesquels il est utilisé: algorithme de Fisher-Yales (version moderne), algorithme de Steinhaus-Johnson-Trotter, matrice-transposition. Et dans les plus spécialisés, où il est utilisé comme argument pour réduire la complexité de l'espace. J'admets que ce sont des cas spécialisés. –

+1

"Ce sont des cas spécialisés" Exactement. –

+0

Un compilateur d'optimisation peut toujours utiliser des instructions d'échange natif lorsqu'il repère le motif, il n'est donc même pas nécessaire pour les cas spécialisés cités. –

0

Vous avez le XOR operator qui fait une substitution variable type primitif ...

+0

Cela peut provoquer une erreur si les deux choses que vous échangez ont le même emplacement de stockage. Ça va les éliminer. On m'a également dit que sur les processeurs modernes, c'est moins efficace que d'utiliser une variable temporaire. –

3

Il est un exemple largement utilisé dans les cours de sciences informatiques, mais je presque jamais me surprends besoin dans le code réel - alors que j'utilise + = très fréquemment. Oui, dans le tri, cela serait utile - mais vous n'avez pas besoin d'implémenter le tri vous-même, donc le nombre d'utilisations réelles dans le code source serait encore assez bas.

+0

L'échange de deux valeurs n'est pas courant, mais il est assez courant de vouloir stocker et lire simultanément une valeur lvalue. Dans un sens, c'est ce que les opérateurs postfix ++ et - font (ils stockent une valeur modifiée, mais la valeur propagée au reste de l'expression est la valeur de pré-mise à jour). – supercat

-1

Je pense qu'ils ont juste oublié de l'ajouter :-) Oui, pas tous les processeurs ont ce genre d'instructions, et alors? Nous avons beaucoup d'autres choses que la plupart des processeurs n'ont pas d'instructions à calculer. Ce serait beaucoup plus facile/clair et aussi plus rapide (par intrinsèque) si nous l'avions !!!

+0

Ne serait pas nécessairement plus rapide - le compilateur pourrait aligner l'appel à échanger (et j'imagine que certains le font déjà) si c'est vraiment la performance critique. –

+0

Qu'en est-il du matériel sous-jacent, s'il avait XCHG ou une instruction similaire, swap serait fait sans avoir besoin d'une variable temporaire et il s'exécuterait plus rapidement. Il y a plus à intrinsèque qu'inline! – Malkocoglu

+0

... et l'optimisation est plus importante que l'inline. Les compilateurs sont capables de déterminer quand un échange est en cours (ce n'est pas * difficile * d'identifier une variable temp et d'utiliser XCHG à la place). – Imagist

4

C++ est-ce que a un échange. En outre, vous pouvez également spécialiser swap pour les types personnalisés!

+2

Ceci est juste une fonction définie. Ce que je voulais dire, c'est pourquoi ce n'est pas directement intégré. –

Questions connexes