C ++ - char * vs. string *

时间:2011-01-28 09:05:51

标签: c++ string pointers char

如果我有一个指向字符串变量array of chars的指针,那么输入之间是否存在差异:

char *name = "name";

string name = "name";

7 个答案:

答案 0 :(得分:29)

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

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

如果您出于某种原因需要使用char指针,请将其设为const

char const* str = "name";

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

答案 1 :(得分:9)

对于初学者,您可能想要更改

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也可以使用它们,除非有令人信服的理由这样做

答案 2 :(得分:8)

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

您可以通过多种方式创建string,但有一种方法如下:

string name = "name";

请注意,不需要*,因为我们不需要将其声明为指针。

答案 3 :(得分:4)

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

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

正确的构造是

const char * name = "name";

上述内容没有任何问题,即使在C ++中也是如此。使用字符串并不总是更正确。

你的第二个陈述应该是

std::string name = "name";

string是标准库中定义的类(实际上是basic_string<char,char_traits<char>,allocator<char>的typedef),因此在命名空间std中(如basic_string,char_traits和allocator)

在各种情况下,使用字符串比使用char数组要好得多。例如,在您的情况下,您可以修改它。所以

name[0] = 'N';

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

,则可以修改字符串

但是如果想在字符串中附加一个字符,那么std :: string结构是唯一一个允许你干净利落的结构。使用旧的C API,您必须使用strcat(),但除非您已经分配了足够的内存来执行此操作,否则这将无效。

std :: string为你管理内存,所以你不必调用malloc()等。实际上,第三个模板参数allocator管理下面的内存 - basic_string生成需要多少内存的请求但是被解耦从使用的实际内存分配技术来看,即使使用std :: string也可以使用内存池等来提高效率。

此外,basic_string实际上并不执行许多字符串操作,而是通过char_traits完成。 (这允许它使用下面的专业C函数进行了很好的优化)。

因此,当您处理在运行时构造和传递的动态字符串时(而不仅仅是文字),

std :: string是管理字符串的最佳方式。

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

答案 4 :(得分:1)

C ++字符串类封装了类似char C的字符串。它更方便(http://www.cplusplus.com/reference/string/string/)。

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

    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

答案 5 :(得分:0)

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

string *name = "name"; 

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

有效声明:

string name = "name";

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

答案 6 :(得分:-1)

string *name = "name";

不在GCC中编译。