7
votes

Pourquoi Strrchr () renvoie `Char *` au lieu de `const Char *`?

La fonction Char * Strrchr (const Char * Str, int ch) renvoie un pointeur ( char * ) dans STR ( const char * ) où la dernière occurrence de ch est situé.

Nous pouvons donc écrire le code suivant sans aucun casting: xxx

Quel est l'avantage de retourner * au lieu de const char * ?

EDIT:

Comme un Shafik Yaghmour a souligné, il y a de très bonnes réponses à Comment fonctionne la mise en œuvre Strchr?

Comme mon code est en C ++, je vais utiliser au lieu de < string.h> . Merci pour vos réponses; -)

Cependant, le La réponse de Mike Seymour convient mieux à la question. J'ai même ajouté une réponse plus détaillée ci-dessous pour dire clairement comme strrchr () est une Fonction (surcharge non autorisée), la déclaration correspond à la fois const et cordes non-const . Parce que strrchr () peut être appelé avec une chaîne non-const , la chaîne renvoyée doit également être non-const . < / p>


9 commentaires

Remarque, comme vous avez ce marquage c ++ et non c , vous devez vraiment utiliser cstring , plutôt que string.h .


Cette réponse est plutôt bonne: Stackoverflow.com/a/14368141/1708801


duplicaté possible de Comment fonctionne la mise en œuvre Strchr


@Bobtfish: Pourquoi voudriez-vous infester votre programme avec STD :: Prefix Sois? Autorisez-vous la réutilisation des noms apparaissant dans String.h en-tête à un but? Je ne le fais sûrement pas. Donc, ils vont bien dans le monde où string.h les met.


@Balogpal: Comme vous le verrez de la ou des réponses ci-dessous, c'est en fait la clé de la résolution de cet énigme.


@Balogpal sauf, les en-têtes de style C ne font pas partie de la norme C ++. Et ils ne sont pas garantis de contenir les surcharges spécifiques C ++.


@Bobtfish: En réalité, la distinction n'est pas purement pédante ici. fournit les surcharges de const-bonnes impossibles à fournir en C.


@Angew: la norme C ++ inclut la norme C par référence afin de pouvoir en fait partie. En ce qui concerne les différences C vs. C ++, mon interprétation était que celles s'appliquent aux deux formes, et ne diffèrent que dans les noms obligatoires de la note de bas de page 177 en C ++ 11. Mais cela va mériter de demander.


@Olicharlesworth: Je vois mais n'est pas correct. Malgré la tonne des votes.


5 Réponses :


3
votes

const char * str signifie strrchr ne garantit pas de modifier str .

retour const char * signifie strrchr interdit de modifier la valeur renvoyée.


5 commentaires

Je suis d'accord avec toi. Mais pourquoi strrchr () retourne char * ? Pourquoi pas const char * ?


Sa réponse vous a dit que @olibre. Lisez-le à nouveau.


@crush pas vraiment. Comme le démontre l'OP, ce type de retour est dangereux. Notez que la version C ++ a les bonnes surcharges.


Ok je viens de comprendre tout en écrivant ce commentaire ... donc la réponse est la suivante: strrchr () ne veut pas modifier le contenu du pointeur retourné pointant sur la chaîne contectrice transmise sous forme de paramètre car La chaîne transmise peut être non constituée. Je suis correct?


@Olibre c'est ce que je veux dire. Surtout quand y compris un en-tête C.



13
votes

Vous envisagez la fonction héritée de la bibliothèque standard C ( ). La bibliothèque C ++ ( ) présente approprié const et non- const surcharge , vous devez donc l'utiliser dans la mesure du possible.


3 commentaires

L'annexe D.5P2 indique que "chaque en-tête C, chacun ayant un nom de nom de formulaire.h, se comporte comme si chaque nom placé dans l'espace de noms de la bibliothèque standard par l'en-tête CName correspondant est placé dans la portée des espaces de noms globaux. .. . "La surcharge mentionnée doit donc être dans Sting.h aussi, et aucune raison d'utiliser la version C pour cette raison seulement.


@Balogpal vous confondez "Nom" et "Déclaration". Le nom nom strrchr est placé dans l'espace de noms global par et dans l'espace de noms std par < Code> . Néanmoins, (étant un en-tête C) ne peut pas contenir des surcharges, il ne fournit donc qu'une seule signification pour le nom strrchr . est un en-tête C ++, il fournit donc deux déclarations (surchargées) pour le nom strrchr .


@andrew: Vous dites donc, y compris ivenir à une version NULL telle que définie dans la norme C au lieu de la manière dont C ++ l'exige qu'elle soit remplacée, interdisant (nul *) 0? Juste pour choisir un delta au hasard qui rendrait un zillion Les projets existants ne compilent pas. Désolé, je garde avec mon interprétation qui "se comporte comme" signifie "se comporter comme".



0
votes

Pourquoi voudriez-vous interdire au code de modifier une variable renvoyée? L'esprit que const char * n'est pas char * cons , vous seriez autorisé à modifier le caractère dans tous les cas, mais vous n'aurez pas de contrôle sur la valeur renvoyée elle-même, Ce qui n'a pas beaucoup de sens puisque vous pouvez vouloir le changer et éditer la chaîne sous-jacente dans une position différente de votre objectif.


1 commentaires

Je ne comprends pas vraiment ce que tu veux dire. Où est votre Char * Const ? Est-ce à propos de constStr ? Je pense que const Char Constr [] = "x" est comme const char * consonstr = "x" sauf pour Tailleof (Constron) .



7
votes

en C, la fonction doit être soit comme celle-ci, soit forcer l'utilisateur à utiliser des moulages dotés dans de nombreuses situations:

  • S'il a fallu un pointeur non const , vous ne pouvez pas rechercher un const chaîne;
  • S'il est renvoyé un pointeur Const , vous ne pouvez pas l'utiliser pour modifier une chaîne de Const Const .

    en C ++, vous devez inclure plutôt que l'en-tête C-C-seulement. Cela vous donnera deux surcharges de const-bonnes, ce qui ne pouvait pas être fait en C: xxx


1 commentaires

J'ai accepté votre réponse, mais j'ai fourni un plus détaillé. Acclamations



2
votes

strrchr () code> de code> est une fonction C. Comme c ne permet pas la surcharge de fonction, strrchr () code> a été conçu pour concevoir à la fois const fort> et cordes non-const fores>. xxx

strrchr () code> peut être appelé avec une chaîne non-const forge>, et donc la chaîne renvoyée doit également être non-const forte > Comme expliqué dans les exemples suivants. p>

Const strong> Contexte sans erreur de compilation: p> xxx pré>

non-const contexte sans erreur de compilation: p> xxx pré>

mauvaise utilisation également sans erreur de compilation: p> xxx pré>

en C ++, il y a deux fonctions surchargées : H2>
#include <cstring>
int main()
{
    const char CONSTSTR[] = "foo/bar/foobar.txt";

    char *nonconst = std::strrchr (CONSTSTR, '/');
// Visual C++ v10 (2010)
// error C2440: 'initializing' : cannot convert from 'const char *' to 'char *'

    *nonconst++ = 'B';
    *nonconst++ = 'A';
    *nonconst++ = 'D';
}


0 commentaires