138 votes

Différence entre string et char[] types en C++

Je connais un peu le C et maintenant, je prends un coup d'oeil sur le C++. Je suis habitué à des tableaux de char pour traiter les chaînes C, mais si je regarde le code C++ je vois il y a des exemples à l'aide de deux type de chaîne et des tableaux de char:

#include <iostream>
#include <string>
using namespace std;

int main () {
  string 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 <iostream>
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 un très demandé et répondu (évident, non?) question, mais ce serait sympa si quelqu'un pouvait me dire quelle est exactement la différence entre les deux façons de traiter avec des chaînes de caractères en C++ (rendement, l'intégration de l'API, la manière dont chacun est le meilleur, ...).

Je vous remercie.

202voto

Cygon Points 3790

Un char tableau est un tableau de caractères:

  • Si alloué sur la pile (comme dans votre exemple), il sera toujours occuper par exemple. 256 octets peu importe combien de temps le texte qu'il contient est
  • Si alloué sur le tas (à l'aide de malloc() ou new char[]) vous êtes responsable pour 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 peut tomber en panne, produire laid affirmation de messages ou de cause inexplicable (mal)le comportement quelque part d'autre dans votre programme.
  • Pour déterminer le texte de la longueur, le tableau doit être scannée, caractère par caractère, par un \0 caractères.

Une chaîne est une classe qui contient un tableau de char, mais gère automatiquement pour vous. La plupart chaîne implémentations ont intégré dans le tableau de 16 caractères (donc des chaînes courtes de ne pas fragmenter le tas) et d'utiliser le segment de mémoire pour des chaînes plus longues.

Vous pouvez accéder à une chaîne de caractères char tableau comme ceci:

std::string myString = "Hello World";
const char *myStringChars = myString.c_str();

Les chaînes C++ peut contenir incorporé \0 caractères, connaître leur longueur sans compter, sont plus rapides que allouées sur la pile des tableaux de char pour des textes courts et de vous protéger des dépassements de mémoire tampon. En Plus d'être plus lisible et plus facile à utiliser.

-

Cependant, les chaînes C++ ne sont pas (très) adapté pour une utilisation sur les limites de la DLL, car il faudrait pour cela n'importe quel utilisateur d'une telle fonction de DLL pour s'assurer qu'il est en utilisant exactement les mêmes et d'un compilateur C++ runtime mise en œuvre, de peur qu'il risque sa classe string se comporter différemment.

Normalement, une chaîne de classe permettrait également de libérer son segment de mémoire sur l'appel d'un segment, alors il va seulement être en mesure de libérer de l'espace mémoire si vous utilisez partagé (.dll ou .si la version du moteur d'exécution.

En bref: utiliser les chaînes C++ dans toutes vos fonctions internes et des méthodes. Si jamais vous en écrire un .dll ou .ainsi, l'utilisation de chaînes C dans votre public (dll/so-exposés).

15voto

Mark Rushakoff Points 97350

Arkaitz est juste qu' string est un type géré. Ce que cela signifie pour vous est que vous n'aurez jamais à vous soucier de combien de temps la chaîne est, ni ne vous avoir à vous soucier de libérer ou de la réaffectation de la mémoire de la chaîne.

D'autre part, l' char[] de la notation dans le cas ci-dessus a restreint le tampon de caractères exactement à 256 caractères. Si vous avez essayé d'écrire plus de 256 caractères dans la mémoire tampon, au mieux, vous permettra de remplacer la mémoire d'autres que votre programme est "propriétaire". Au pire, on va essayer d'écraser la mémoire que vous ne possédez pas, et votre système d'exploitation va tuer votre programme sur place.

Ligne de fond? Les chaînes sont beaucoup plus sympathique programmeur, char[]s sont beaucoup plus efficace pour l'ordinateur.

7voto

Arkaitz Jimenez Points 10651

Eh bien, type de chaîne est entièrement géré classe pour les chaînes de caractères, tandis que les char[] est encore ce qu'il était en C, un tableau d'octets représentant une chaîne de caractères pour vous.

En termes d'API et de la bibliothèque standard, tout est mis en œuvre en termes de chaînes de caractères et pas char[], mais il y a encore beaucoup de fonctions de la libc qui reçoivent des char[] de sorte que vous devrez peut-être l'utiliser pour ceux qui, en dehors de cela, je serais toujours utiliser std::string.

En termes d'efficacité, bien sûr, une crue de la mémoire tampon de mémoire non managée sera presque toujours plus rapide pour beaucoup de choses, mais de prendre en compte la comparaison de chaînes de caractères par exemple, std::string a toujours la taille de la vérifier en premier, tandis qu'avec des char[] vous avez besoin de comparer, caractère par caractère.

5voto

Abhay Points 4268

Personnellement, je ne vois aucune raison pour laquelle on aimerait utiliser char* ou char[] à l'exception de la compatibilité avec l'ancien code. std::string est pas plus lent qu'un c-string, sauf qu'il va traiter de ré-allocation pour vous. Vous pouvez définir la taille que vous créez, et ainsi éviter la ré-allocation si vous le souhaitez. Il indexation de l'opérateur ([]) fournit à constante de temps d'accès (et dans tous les sens du mot exactement la même chose qu'à l'aide d'un c-string indexeur). À l'aide de la méthode vous donne limites vérifié la sécurité, ainsi, quelque chose que vous n'avez pas avec c-strings, à moins que vous l'écrivez. Votre compilateur le plus souvent d'optimiser l'indexation de l'utilisation en mode release. Il est facile de s'amuser avec c-strings; des choses telles que la suppression vs delete[], à l'exception de la sécurité, de même que la façon de redistribuer une c-string.

Et lorsque vous avez à traiter avec des concepts avancés comme avoir de la VACHE chaînes, et non de la VACHE pour MT etc, vous aurez besoin de std::string.

Si vous êtes inquiet au sujet de copies, aussi longtemps que vous utilisez des références, et const références partout où vous le pouvez, vous n'aurez pas de frais généraux en raison de copies, et c'est la même chose que vous feriez avec le c-string.

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