C ++中string和char types的区别

我知道一点C,现在我正在看C ++。 我习惯字符数组处理Cstring,但是当我看着C + +代码,我看到有一些使用stringtypes和字符数组的例子:

#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; } 

 #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; } 

(这两个例子来自http://www.cplusplus.com )

我认为这是一个广泛的问题和回答(显而易见的问题),但是如果有人能告诉我在C ++中处理string的两种方式之间的区别是什么(性能,API集成,每种方式更好,…)。

谢谢。

字符数组就是这样一个字符数组:

  • 如果在堆栈中分配(如你的例子),它将永远占用例如。 无论它包含的文本有多长,都是256字节
  • 如果在堆上分配(使用malloc()或new char []),则负责释放内存,并且总是会有堆分配的开销。
  • 如果将超过256个字符的文本复制到数组中,它可能会崩溃,产生丑陋的断言消息或导致程序中其他位置出现无法解释的(错误)行为。
  • 要确定文本的长度,必须逐个字符地扫描数组,以获得\ 0字符。

string是一个包含char数组的类,但会自动为您进行pipe理。 大多数string实现都有一个由16个字符组成的内置数组(所以短的string不会将堆分段),并使用堆来存储更长的string。

你可以像这样访问一个string的char数组:

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

C ++string可以包含embedded的\ 0字符,知道它们的长度而不需要计数,比用短文本的堆分配字符数组更快,并且保护你免于缓冲区溢出。 另外他们更可读,更易于使用。

但是,C ++string不适合跨越DLL边界的用法,因为这需要这样一个DLL函数的任何用户来确保他使用完全相同的编译器和C ++运行时实现,以免冒着他的string类行为不同的风险。

通常情况下,一个string类也会在调用堆中释放它的堆内存,所以如果你使用的是运行时的共享(.dll或.so)版本,它将只能再次释放内存。

简而言之:在你所有的内部函数和方法中使用C ++string。 如果您曾经写过.dll或.so,请在公共(dll / so-exposed)函数中使用Cstring。

那么,stringtypes是一个完全托pipe的string类,而char []仍然是C中的一个字节数组,它代表了一个string。

在API和标准库方面,一切都是以string而不是char []来实现的,但是libc中仍然有很多函数接收char [],所以你可能需要使用它,除此之外,总是使用std :: string。

从效率的angular度来看,非托pipe内存的原始缓冲区对于很多事情来说几乎总是会更快,但是考虑到比较string,例如std :: string总是要检查它的大小,而使用char []需要按字符比较字符。

Arkaitz是正确的, string是一个托pipetypes。 这对来说意味着你不必担心string的长度,也不必担心释放或重新分配string的内存。

另一方面,上述情况下的char[]表示法将字符缓冲区限制为256个字符。 如果您尝试将超过256个字符写入该缓冲区,则至多会覆盖程序“拥有”的其他内存。 在最坏的情况下,你会尝试覆盖你不拥有的内存,而你的操作系统将在现场杀死你的程序。

底线? string对程序员更友好,char []对计算机来说效率更高。

我个人看不出有什么理由为什么要使用char *或char [],除了与旧代码的兼容性。 std :: string不会比使用c-string慢,只是它会为你处理重新分配。 您可以在创build时设置它的大小,从而避免重新分配。 它是索引操作符([])提供了持续的时间访问(在每一个单词中,与使用c-string索引器完全一样)。 使用at方法也可以使得你的边界检查安全,除非你写了,否则你不会用c-string得到。 您的编译器通常会优化索引器在发布模式下的使用。 用C字串很容易, 如删除vs删除[],exception安全,甚至如何重新分配一个Cstring。

而当你不得不处理像COWstring这样的高级概念和MT的非COW等时,你需要std :: string。

如果你担心副本,只要你使用引用和const引用,你就不会因为副本而产生任何开销,而且和使用cstring一样。

string具有帮助函数并自动pipe理字符数组。 您可以连接string,对于需要将字符数组复制到新数组的string,string可以在运行时更改其长度。 字符数组比string更难pipe理,某些函数只能接受string作为input,要求将数组转换为string。 最好使用string,这样做是为了不必使用数组。 如果数组客观上更好,我们不会有string。

把(char *)看作string.begin()。 本质区别是(char *)是一个迭代器,std :: string是一个容器。 如果你坚持基本的string(char *)会给你什么std :: string :: iterator。 你可以使用(char *)当你想要一个迭代器的好处,也可以与C兼容,但这是例外,而不是规则。 一如既往,小心迭代器失效。 当人们说(char *)不安全时,这就是他们的意思。 它和其他C ++迭代器一样安全。

其中一个区别是空终止(\ 0)。

在C和C ++中,char *或char []会将指向单个字符的指针作为参数,并沿着内存进行跟踪,直到达到0的内存值(通常称为空终止符)。

C ++string可以包含embedded的\ 0字符,知道它们的长度而不计算。

 #include<stdio.h> #include<string.h> #include<iostream> using namespace std; void NullTerminatedString(string str){ int NUll_term = 3; str[NUll_term] = '\0'; // specific character is kept as NULL in string cout << str << endl <<endl <<endl; } void NullTerminatedChar(char *str){ int NUll_term = 3; str[NUll_term] = 0; // from specific, all the character are removed cout << str << endl; } int main(){ string str = "Feels Happy"; printf("string = %s\n", str.c_str()); printf("strlen = %d\n", strlen(str.c_str())); printf("size = %d\n", str.size()); printf("sizeof = %d\n", sizeof(str)); // sizeof std::string class and compiler dependent NullTerminatedString(str); char str1[12] = "Feels Happy"; printf("char[] = %s\n", str1); printf("strlen = %d\n", strlen(str1)); printf("sizeof = %d\n", sizeof(str1)); // sizeof char array NullTerminatedChar(str1); return 0; } 

输出:

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