Différence entre les types ssortingng et char en C ++

Je connais un peu C et maintenant je regarde C ++. Je suis habitué à utiliser des tableaux pour traiter les chaînes C, mais lorsque je regarde le code C ++, je vois des exemples utilisant à la fois des tableaux de type chaîne et des tableaux de caractères:

#include  #include  using namespace std; int main () { ssortingng mystr; cout << "What's your name? "; getline (cin, mystr); cout << "Hello " << mystr << ".\n"; cout << "What is your favorite team? "; getline (cin, mystr); cout << "I like " << mystr << " too!\n"; return 0; } 

et

 #include  using namespace std; int main () { char name[256], title[256]; cout << "Enter your name: "; cin.getline (name,256); cout << "Enter your favourite movie: "; cin.getline (title,256); cout << name << "'s favourite movie is " << title; return 0; } 

(les deux exemples de http://www.cplusplus.com )

Je suppose que c’est une question très souvent posée et évidente (évidente?), Mais ce serait bien si quelqu’un pouvait me dire quelle est exactement la différence entre les deux manières de traiter les chaînes en C ++ (performance, intégration de l’API). meilleur, …).

Je vous remercie.

Un tableau de caractères est juste cela – un tableau de caractères:

  • S’il est alloué sur la stack (comme dans votre exemple), il occupera toujours par exemple. 256 octets, quelle que soit la longueur du texte qu’il contient
  • S’il est alloué sur le tas (en utilisant malloc () ou new char []), vous êtes responsable de la libération de la mémoire par la suite et vous aurez toujours la surcharge d’une allocation de tas.
  • Si vous copiez un texte de plus de 256 caractères dans le tableau, il risque de tomber en panne, de produire des messages d’assertion malsains ou de provoquer un comportement inexplicable ailleurs dans votre programme.
  • Pour déterminer la longueur du texte, le tableau doit être analysé, caractère par caractère, pour un caractère \ 0.

Une chaîne est une classe qui contient un tableau de caractères, mais la gère automatiquement pour vous. La plupart des implémentations de chaînes ont un tableau intégré de 16 caractères (si bien que les chaînes courtes ne fragmentent pas le tas) et utilisent le tas pour les chaînes plus longues.

Vous pouvez accéder au tableau de caractères d’une chaîne comme ceci:

 std::ssortingng mySsortingng = "Hello World"; const char *mySsortingngChars = mySsortingng.c_str(); 

Les chaînes C ++ peuvent contenir des caractères incorporés \ 0, connaître leur longueur sans compter, sont plus rapides que les tableaux de caractères alloués au tas pour les textes courts et vous protègent des dépassements de mémoire tampon. De plus, ils sont plus lisibles et plus faciles à utiliser.

Cependant, les chaînes C ++ ne conviennent pas (très) à l’utilisation des limites de DLL, car cela exigerait que tout utilisateur d’une telle fonction s’assure d’utiliser exactement le même compilateur et l’exécution C ++, sans risquer que sa classe se comporte différemment.

Normalement, une classe de chaînes libère également sa mémoire de tas sur le segment de mémoire appelant, elle ne pourra donc libérer de la mémoire que si vous utilisez une version partagée (.dll ou .so) du moteur d’exécution.

En bref: utilisez les chaînes C ++ dans toutes vos fonctions et méthodes internes. Si vous écrivez un fichier .dll ou .so, utilisez des chaînes C dans vos fonctions publiques (dll / so -posé).

Eh bien, le type de chaîne est une classe complètement gérée pour les chaînes de caractères, tandis que char [] est toujours ce qu’il était en C, un tableau d’octets représentant une chaîne de caractères pour vous.

En ce qui concerne les API et les bibliothèques standard, tout est implémenté en termes de chaînes et non de char [], mais il y a encore beaucoup de fonctions de la libc qui reçoivent des char []. toujours utiliser std :: ssortingng.

En termes d’efficacité bien sûr, un tampon brut de mémoire non gérée sera presque toujours plus rapide pour beaucoup de choses, mais prenez en compte la comparaison de chaînes, std :: ssortingng a toujours la taille pour le vérifier en premier, tandis que pour char [] vous besoin de comparer caractère par caractère.

Arkaitz a raison de dire que la ssortingng est un type géré. Cela signifie pour vous que vous n’avez jamais à vous soucier de la longueur de la chaîne, et que vous n’avez pas à vous soucier de la libérer ou de la réallouer.

En revanche, la notation char[] dans le cas ci-dessus a limité le tampon de caractères à exactement 256 caractères. Si vous avez essayé d’écrire plus de 256 caractères dans ce tampon, vous écraserez au mieux les autres mémoires que votre programme “possède”. Au pire, vous allez essayer d’écraser la mémoire que vous ne possédez pas et votre système d’exploitation va tuer votre programme sur le champ.

Bottom line? Les chaînes sont plus conviviales pour les programmeurs, les char [] sont beaucoup plus efficaces pour l’ordinateur.

Personnellement, je ne vois aucune raison pour laquelle on aimerait utiliser char * ou char [] sauf pour la compatibilité avec l’ancien code. std :: ssortingng n’est pas plus lent que l’utilisation d’une chaîne de caractères, sauf qu’il va gérer la ré-allocation pour vous. Vous pouvez définir sa taille lorsque vous le créez et éviter ainsi une nouvelle répartition si vous le souhaitez. Son opérateur d’indexation ([]) fournit un access à temps constant (et est dans tous les sens du mot exactement la même chose que l’utilisation d’un indexeur c-ssortingng). L’utilisation de la méthode at vous permet également de vérifier la sécurité des bornes, ce que vous n’obtenez pas avec les chaînes de caractères, à moins que vous ne l’écriviez. Votre compilateur optimisera le plus souvent l’utilisation de l’indexeur en mode release. Il est facile de perdre son temps avec des cordes en c des choses telles que supprimer vs supprimer [], la sécurité des exceptions, même comment réaffecter une chaîne de caractères.

Et lorsque vous devez gérer des concepts avancés, tels que les chaînes COW et non-COW pour MT, vous aurez besoin de std :: ssortingng.

Si vous vous inquiétez des copies, tant que vous utilisez des références et des références const où vous le pouvez, vous ne risquez pas d’avoir de copie à cause des copies, et c’est la même chose avec la chaîne de caractères.

Les chaînes ont des fonctions d’assistance et gèrent les tableaux de caractères automatiquement. Vous pouvez concaténer des chaînes, pour un tableau de caractères vous devez le copier dans un nouveau tableau, les chaînes peuvent changer de longueur à l’exécution. Un tableau de caractères est plus difficile à gérer qu’une chaîne et certaines fonctions peuvent uniquement accepter une chaîne en entrée, ce qui vous oblige à convertir le tableau en chaîne. Il est préférable d’utiliser des chaînes de caractères, elles ont été créées pour que vous n’ayez pas à utiliser de tableaux. Si les tableaux étaient objectivement meilleurs, nous n’aurions pas de chaînes.

Pensez à (char *) en tant que ssortingng.begin (). La différence essentielle est que (char *) est un iterator et std :: ssortingng est un conteneur. Si vous vous en tenez à des chaînes de base, un (char *) vous donnera ce que fait std :: ssortingng :: iterator. Vous pouvez utiliser (char *) lorsque vous voulez bénéficier d’un iterator et aussi de la compatibilité avec C, mais c’est l’exception et non la règle. Comme toujours, faites attention à l’invalidation de l’iterator. Lorsque les gens disent (char *) n’est pas sûr, c’est ce qu’ils veulent dire. C’est aussi sûr que n’importe quel autre iterator C ++.

Une des différences est la terminaison Null (\ 0).

En C et C ++, char * ou char [] prendra un pointeur sur un seul caractère comme paramètre et suivra la mémoire jusqu’à ce qu’une valeur de 0 soit atteinte (souvent appelée le terminateur nul).

Les chaînes C ++ peuvent contenir des caractères incorporés \ 0, connaître leur longueur sans compter.

 #include #include #include using namespace std; void NullTerminatedSsortingng(ssortingng str){ int NUll_term = 3; str[NUll_term] = '\0'; // specific character is kept as NULL in ssortingng cout << str << endl < 

Sortie:

 strlen = 11 size = 11 sizeof = 32 Fee s Happy strlen = 11 sizeof = 12 Fee