2011-01-28 107 views
11

如果我有一个指向一个字符串变量array of chars的指针,有没有打字之间的差异:C++ - 的char *与字符串*

char *name = "name"; 

而且,

string name = "name"; 
+0

什么类型在这个例子中“字符串”? – Nick 2011-01-28 09:09:51

+12

`string * name =“name”;`不会编译。 – Naveen 2011-01-28 09:09:53

+1

Dupe of:http://stackoverflow.com/questions/801209/c-char-vs-stdstring(一旦语法错误被修复)? – Flexo 2011-01-28 09:10:34

回答

28

是的,有一个区别。主要是因为你可以修改你的字符串,但你不能修改你的第一个版本 - 但C++编译器甚至不会警告你,如果你尝试这是禁止的。

所以总是使用第二个版本。

如果你需要使用一个字符指针,无论出于何种原因,使其const

char const* str = "name"; 

现在,如果你尝试修改的str内容,编译器将禁止这个(正确)。您还应该将编译器的警告级别提高一级:然后它会警告您的第一个代码(即char* str = "name")是合法的,但不推荐使用。

+2

@Konrad鲁道夫。当你说“你的字符串变量不应该是一个指针”时,为什么?谢谢 – Simplicity 2011-01-28 09:19:23

+2

@ user588855:因为`std :: string`已经在内部管理`char *`指针了,所以你只需要将它作为普通对象来使用。尽管如此,为了避免昂贵的副本,如果将它用作函数参数,并且不需要在函数内部修改,请记住通过`const`引用(`const string&`)传递它。 – 2011-01-28 09:24:58

0

是的,char*是指向一个字符数组的指针,它是一个字符串。 string *是指向std::string(这是很少使用)的数组的指针。

string *name = "name"; 

“名”是一个const char*,它永远不会被转换为std::string*。这将导致编译错误。

有效声明:

string name = "name"; 

const char* name = "name"; // char* name = "name" is valid, but deprecated 
8

是的,第二个是无效的C++! (它不会编译)。

您可以创建一个在许多方面string,但一个方法如下:

string name = "name"; 

注意,没有必要为*,因为我们并不需要把它声明为一个指针。

-1
string *name = "name"; 

在GCC中不编译。

8

对于初学者来说,你可能想改变

string *name = "name"; 

阅读

string name = "name"; 

第一个版本将无法编译,因为string*char*是完全不同的类型。

stringchar*之间的区别在于char*只是指向序列的指针。这种操作字符串的方法基于C编程语言,并且是以C++编码字符串的本地方式。 C字符串的工作有点棘手 - 您需要确保为它们正确分配空间,以避免走出它们占用的缓冲区的末端,将它们放入可变内存以避免出现分段错误等。主要功能操纵他们在<cstring>。大多数C++程序员建议不要使用C风格的字符串,因为它们本质上难以使用,但是它们仍然支持向后兼容性和作为低级API可以构建的“最低公分母”。

C++风格string是封装字符串的对象。其内存管理的细节对用户不可见(尽管可以保证所有的内存都是连续的)。它使用运算符重载来使像串联这样的常用操作更易于使用,并且还支持设计用于执行诸如搜索,替换,子串等高级操作的若干成员函数。它们也被设计为与STL算法交互操作,尽管C风格的字符串也可以做到这一点。

总之,作为一名C++程序员,您最好使用string类型。它更安全,更易于使用。了解C风格的字符串还是很好的,因为在你的编程生涯中你肯定会遇到它们,但是最好不要在你的程序中使用它们,除非有令人信服的理由才能使用string

4

char* name = "name"应该是无效的,但是在大多数系统上进行编译,以便在没有const的情况下向后兼容旧版本,并且如果没有编译,会破坏大量遗留代码。它通常会收到警告。

危险是你得到一个指向可写入数据的指针(根据C++的规则可写),但是如果你真的试图写入它,你会调用Undefined Behavior,并且语言规则应该试图保护你尽可能合理。

正确的结构是

const char * name = "name"; 

这没有什么错以上,即使在C++中。使用字符串并不总是更正确。

你的第二个说法确实应该

std::string name = "name"; 

串因此std下在标准库中定义的类(实际上是一个的basic_string<char,char_traits<char>,allocator<char>的typedef)(如在basic_string的,char_traits和分配器)

有很多使用字符串比使用char数组更好的场景。举个例子,你可以修改它。所以

name[0] = 'N'; 

(转换的第一个字母为大写)是字符串,而不是用的char *(未定义行为)或为const char *(不会编译)有效。你可以修改字符串,如果你有char name[] = "name";

但是,如果想要追加一个字符到字符串,std :: string结构是唯一一个可以让你做到这一点干净。使用旧的C API,你将不得不使用strcat(),但除非你已经分配足够的内存来做这件事,否则这将是无效的。

std :: string为你管理内存,所以你不必调用malloc()等。实际上,allocator是第三个模板参数,它管理着下面的内存 - basic_string提出了它需要多少内存的请求,但是与实际使用的内存分配技术分离,所以你可以使用内存池等来提高效率,即使使用std ::串。

另外的basic_string实际上并不执行很多都是做,而不是通过char_traits字符串操作。 (这使得它可以使用专业的C函数,在其下进行优化)。因此

的std :: string是当你正在处理构造和在运行时(而不仅仅是文字)传来传动态字符串来管理你的字符串的最佳方式。

你很少会使用字符串*(一个指向字符串)。如果你这样做,它将是一个指向对象的指针,就像任何其他指针一样。你不能像你那样分配它。

1

C++串类封装炭类C的字符串组成。这是一个更方便(http://www.cplusplus.com/reference/string/string/)。

遗留你总是可以“提取”从字符串变量字符指针来处理它作为字符指针:

char * cstr; 
    string str ("Please split this phrase into tokens"); 
    cstr = new char [str.size()+1]; 
    strcpy (cstr, str.c_str()); //here str.c_str() generate null terminated char* pointer 
    //str.data() is equivalent, but without null on end