Juste pour le plaisir, j'avais un Selon le Documentation de Oublier sur la liste un instant, ma question actuelle est la suivante: comment ces opérateurs (>, <,> =, <=) fonctionnent sur des pointeurs de C ++ et C? Comparent-ils simplement les adresses de mémoire réelles? P> E.g. Sur un système de 32 bits, Les tests semblent confirmer cela, mais je pensais qu'il serait bon de le mettre sur Stackoverflow pour une référence future. C et C ++ font les deux Des choses étranges aux pointeurs, de sorte que vous ne connaissez jamais vraiment ... p> p> std :: Liste Code> de
Const Char * Code>, chaque élément pointant vers une chaîne de texte NULL terminée et a exécuté un
STD :: Liste :: Trier () Code> dessus. Comme cela se produit, il ne tient pas (aucun jeu de mots destiné) n'a pas trié les cordes. Considérant que cela travaillait sur des pointeurs, cela a du sens.
std :: list :: Trier () code>, il utilise (par défaut) utilise l'opérateur
<< / code> entre les éléments à comparer. p>
p1 code>>
p2 code> car
0xdab0bc47 code>>
0xbabec475 code>? P >
3 Réponses :
Oui, ils comparent simplement l'adresse mémoire. P>
en C ++, vous ne pouvez pas comparer à tous les indicateurs utilisant les opérateurs relationnels. Vous ne pouvez comparer que deux pointeurs qui pointent sur des éléments dans le même tableau ou deux pointeurs qui pointent vers des membres du même objet. (Vous pouvez également comparer un pointeur avec lui-même, bien sûr.) P>
Vous pouvez toutefois utiliser Si vous avez un espace d'adressage plat, il est probable que les comparaisons du pointeur comparent simplement des adresses comme si elles sont des entiers. P>
(Je pense que les règles sont les mêmes en C, sans les objets de la fonction de comparaison, mais que quelqu'un devra confirmer cela; je ne suis pas aussi familier avec C comme je suis avec C ++.) P> std :: moins code> et les autres objets de comparaison relationnels pour comparer deux pointeurs. Les résultats sont définis par la mise en œuvre, mais il est garanti qu'il existe une commande totale. P>
La comparaison de 2 pointeurs compare toujours les adresses sous forme d'entiers.
@ZAC: Un pointeur n'est pas un entier, et vous ne pouvez pas le comparer en tant que tel.
C'est un entier représentant un emplacement d'adresse. Et vous pouvez (cependant, la comparaison de 2 adresses d'entités complètement séparées semble un peu stupide) les comparer. En fait, chaque fois que vous faites si (p! = Null) code>, c'est exactement ce que vous faites.
@Fredoverflow, ouais - n'est-ce pas assez vieux pour me souvenir des pointeurs près des pointeurs?
@ZAC, NULL est un cas particulier garanti par le compilateur. Toutes les autres comparaisons aux entiers seraient inquiétantes. Je ne suis pas assez d'un avocat de langue pour dire à quel point Worrisome.
@ZAC: Pouvez-vous fournir une source standard pour "comparer 2 pointeurs compare toujours les adresses comme entiers".
@Mark: vous pouvez écrire char * p1 = nouveau caractère; Char * p2 = nouveau caractère; Si (p1 == p2) {// fait quelque chose} code> et il effectue une comparaison entière sur les adresses 2. Faire
char * p1 = nouveau caractère; Si (P1 == 4) {// fait quelque chose} code> est légal et compile ... même si ce n'est pas très utile. La comparaison des pointeurs ne fait rien de plus que de comparer les adresses de mémoire à l'aide d'entier des adresses.
@James: est std :: Moins code> spécialisé pour les pointeurs ou comment montrerait-il une différence d'utiliser
std :: moins code> au lieu de bon vieux
Opérateur << / code>?
@ZAC: Ce n'est pas légal, vous ne pouvez pas comparer un pointeur à un entier. Vous êtes tout simplement faux, les pointeurs ne sont pas nécessairement entiers, ils sont leur propre type avec une représentation définie par la mise en œuvre.
@Fredoverflow: oui; STD :: Moins Code> fournit une commande totale pour les pointeurs.
@Gman: Désolé, la deuxième liste était censée dire si (p1 == (char *) 4) code>. Voir la section 5.4.7 du langage de programmation C pour référence.
@ZAC: (1) Vous n'êtes pas garanti (char *) 4 code> est une valeur valide. (2) C'est un livre, pas une norme. (3) C n'a pas
nouveau code>, mais vos échantillons de code font.
@ZAC: Pour un cas spécifique (si hypothétique) où les pointeurs sont pas i> juste comparé à titre d'entiers, envisagez une implémentation avec deux espaces de mémoire complètement séparés, «rouge» et «bleu». Supposons qu'un bit indique l'espace de l'adresse: un pointeur "rouge", converti en entier, a le bit supérieur, alors que le pointeur "bleu" ne le fait pas. Il n'y a rien dans la norme pour dire si des pointeurs "rouges" se comparent moins ou supérieurs à ceux "bleus" utilisant std: moins code> ou s'ils sont mélangés ensemble. Donc, ils n'ont pas besoin d'être comparés "comme des entiers". Ils sont comparés comme des pointeurs, de manière spécifique à la mise en œuvre.
@ZAC: Juste parce que cela compile ne signifie pas que c'est correct ou même légal. N'utilisez pas votre compilateur pour vous dire ce qui est et n'est pas correct ou vrai sur C ++. Utilisez la norme.
... Donc, la qualification de James "c'est probablement" est correcte. Il n'y a aucune garantie que je ne peux voir dans la norme que la comparaison de pointeur, la comparaison entière et la conversion de pointeur-integer, sont constamment cohérentes. Cependant, vous devez vous attendre à i> un agent de mise en œuvre pour les rendre cohérents, en particulier sur une architecture de mémoire plate, en utilisant des opcodes sensibles pour l'architecture. S'ils sont cohérents, c'est ce que j'appellerais "les comparer comme s'ils sont des entiers". Il y a toujours une différence entre les comparer comme des entiers signés vs non signés et la norme ne se soucie que si un objet couvre un +/- Cutoff.
@John: Je n'ai jamais dit que c'était d'accord; J'ai dit que c'est ainsi que cela fonctionne. J'ai même dit que ce n'est pas très utile de le faire. La question de l'OP est: "Les opérateurs travaillent sur des pointeurs en C ++ et C? Comparent-ils simplement les adresses de mémoire réelles?" Pas "Qu'est-ce que std :: moins code> faire?".
@ZAC: Vous avez dit que "la comparaison de 2 pointeurs compare toujours les adresses en tant qu'ibètes". C'est faux.
Comme les autres mentionnaient précédemment, les opérations du pointeur <> sont significatives dans un tableau. Supposons x [5]. x [i] est le même que * (x + i). x [i + 1] est également * (x + i +1). Le 2e élément a clairement une valeur de pointeur supérieure.
@ZAC: STD :: Moins Code> Quel que soit ce qu'il faut pour fournir une commande sur des pointeurs. Sur les systèmes avec un modèle de mémoire plate simple, il suffit de «comparer les pointeurs comme s'il s'agissait d'entiers», mais sur d'autres systèmes, cela peut avoir à faire quelque chose de plus complexe.
opérateur << / code> compare les positions dans une matrice, en fonction de la spécification, et qui est garantie de fonctionner dans le cas particulier des tableaux (garantie d'être contiguës), mais sur certains systèmes, il peut céder "bizarre "Résultats si utilisés sur des pointeurs arbitraires.
Ceci est juste un supplément. P>
C ++ 20.3.3 / 8: p>
Pour les modèles plus, moins, greater_equal et less_equal, la spécialisations pour tout type de pointeur donner un ordre total, même si la opérateurs intégrés <,>, <=,> = do pas. p> blockQuote>
C 6.5.8 / 5: p>
Si deux pointeurs vers objet ou types incomplets tant de points à la même objet, ou à la fois un point passé le dernier élément de la même baie objet, ils comparent l'égalité. Si la les objets mis en évidence sont membres du même objet global, des pointeurs vers les membres de la structure déclarée plus tard comparer plus de pointeurs vers membres déclarés plus tôt dans la la structure, et des pointeurs vers réseau des éléments avec des valeurs plus grandes en indice comparer plus de pointeurs vers les éléments de la même matrice inférieure avec valeurs indice. Tous les pointeurs vers membres du même objet syndical comparer l'égalité. Si l'expression P des points à un élément d'un tableau l'objet et le point Q d'expression pour le dernier élément de la même baie objet, l'expression de pointeur Q + 1 compare supérieure à P. Dans tous les autres cas, le comportement est indéfini strong>. p> blockQuote>
Alors, je pense que la comparaison
char const * code> qui appartiennent à deux « \-0'-chaîne terminée comme dans la question est un comportement non défini (en C). P>
Oui, ils comparent simplement des adresses de mémoire.
L'endiénation n'est pas pertinente ici. p1> p2 si gros / bas Endian.
Ouais, j'ai remarqué, mais c'était amusant d'écrire Dabobcat et des babecats avec des chars hexagonaux, alors j'ai ignoré le non-si-grandeur de l'exemple ...
Il est intéressant de noter que tous les algorithmes de tri de code> et
std :: list :: trit code> utilisent
opérateur << / code> Par défaut (je viens d'avoir Pour regarder ça; j'aurais pensé qu'ils utiliseraient
std :: moins code> par défaut).