C++ - 字符* 与字符串*

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4826481/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:40:07  来源:igfitidea点击:

C++ - char* vs. string*

c++stringpointerschar

提问by Simplicity

If I have a pointer that points to a string variable array of chars, is there a difference between typing:

如果我有一个指向字符串变量的指针,array of chars键入以下内容是否有区别:

char *name = "name";

And,

和,

string name = "name";

回答by Konrad Rudolph

Yes, there's a difference. Mainly because you can modify your string but you cannotmodify your first version – but the C++ compiler won't even warn you that this is forbidden if you try.

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

So always use the second version.

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

Ifyou need to use a char pointer for whatever reason, make it const:

如果出于某种原因需要使用字符指针,请使用它const

char const* str = "name";

Now, if you try to modify the contents of str, the compiler will forbid this (correctly). You should also push the warning level of your compiler up a notch: then it will warn that your first code (i.e. char* str = "name") is legal but deprecated.

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

回答by templatetypedef

For starters, you probably want to change

首先,你可能想要改变

string *name = "name";

to read

阅读

string name = "name";

The first version won't compile, because a string*and a char*are fundamentally different types.

第一个版本不会编译,因为 astring*和 achar*是根本不同的类型。

The difference between a stringand a char*is that the char*is just a pointer to the sequence. This approach of manipulating strings is based on the C programming language and is the native way in which strings are encoded in C++. C strings are a bit tricky to work with - you need to be sure to allocate space for them properly, to avoid walking off the end of the buffer they occupy, to put them in mutable memory to avoid segmentation faults, etc. The main functions for manipulating them are in <cstring>. Most C++ programmers advise against the use of C-style strings, as they are inherently harder to work with, but they are still supported both for backwards compatibility and as a "lowest common denominator" to which low-level APIs can build off of.

一个之间的差string和一个char*是,char*仅仅是一个指针序列。这种处理字符串的方法基于 C 编程语言,是在 C++ 中对字符串进行编码的原生方式。C 字符串使用起来有点棘手 - 您需要确保为它们正确分配空间,避免离开它们占用的缓冲区的末尾,将它们放在可变内存中以避免分段错误等。 主要功能操纵它们在<cstring>. 大多数 C++ 程序员建议不要使用 C 风格的字符串,因为它们本质上更难使用,但仍然支持它们向后兼容性和作为低级 API 可以建立的“最低公分母”。

A C++-style stringis an object encapsulating a string. The details of its memory management are not visible to the user (though you can be guaranteed that all the memory is contiguous). It uses operator overloading to make some common operations like concatenation easier to use, and also supports several member functions designed to do high-level operations like searching, replacing, substrings, etc. They also are designed to interoperate with the STL algorithms, though C-style strings can do this as well.

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

In short, as a C++ programmer you are probably better off using the stringtype. It's safer and a bit easier to use. It's still good to know about C-style strings because you will certainly encounter them in your programming career, but it's probably best not to use them in your programs where stringcan also be used unless there's a compelling reason to do so.

简而言之,作为 C++ 程序员,您最好使用该string类型。它更安全,更容易使用。了解 C 样式字符串仍然很好,因为您肯定会在您的编程生涯中遇到它们,但最好不要在您的程序中使用它们,string除非有令人信服的理由这样做。

回答by Oliver Charlesworth

Yes, the second one isn't valid C++! (It won't compile).

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

You can create a stringin many ways, but one way is as follows:

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

string name = "name";

Note that there's no need for the *, as we don't need to declare it as a pointer.

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

回答by CashCow

char* name = "name"should be invalid but compiles on most systems for backward compatibility to the old days when there was no const and that it would break large amounts of legacy code if it did not compile. It usually gets a warning though.

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

The danger is that you get a pointer to writable data (writable according to the rules of C++) but if you actually tried writing to it you would invoke Undefined Behaviour, and the language rules should attempt to protect you from that as much as is reasonably possible.

危险在于你得到一个指向可写数据的指针(根据 C++ 的规则可写),但如果你真的尝试写入它,你会调用 Undefined Behaviour,并且语言规则应该尽可能地保护你免受这种情况的影响可能的。

The correct construct is

正确的构造是

const char * name = "name";

There is nothing wrong with the above, even in C++. Using string is not always more correct.

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

Your second statement should really be

你的第二个陈述真的应该是

std::string name = "name";

string is a class (actually a typedef of basic_string<char,char_traits<char>,allocator<char>) defined in the standard library therefore in namespace std (as are basic_string, char_traits and allocator)

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

There are various scenarios where using string is far preferable to using arrays of char. In your immediate case, for example, you CAN modify it. So

在各种情况下,使用字符串比使用字符数组更可取。例如,在您的直接情况下,您可以修改它。所以

name[0] = 'N';

(convert the first letter to upper-case) is valid with string and not with the char* (undefined behaviour) or const char * (won't compile). You would be allowed to modify the string if you had char name[] = "name";

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

However if want to append a character to the string, the std::string construct is the only one that will allow you to do that cleanly. With the old C API you would have to use strcat() but that would not be valid unless you had allocated enough memory to do that.

但是,如果想在字符串中附加一个字符,std::string 构造是唯一可以让您干净利落地执行此操作的构造。使用旧的 C API,您将不得不使用 strcat() ,但除非您分配了足够的内存来执行此操作,否则这将无效。

std::string manages the memory for you so you do not have to call malloc() etc. Actually allocator, the 3rd template parameter, manages the memory underneath - basic_string makes the requests for how much memory it needs but is decoupled from the actual memory allocation technique used, so you can use memory pools, etc. for efficiency even with std::string.

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

In addition basic_string does not actually perform many of the string operations which are done instead through char_traits. (This allows it to use specialist C-functions underneath which are well optimised).

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

std::string therefore is the best way to manage your strings when you are handling dynamic strings constructed and passed around at run-time (rather than just literals).

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

You will rarely use a string* (a pointer to a string). If you do so it would be a pointer to an object, like any other pointer. You would not be able to allocate it the way you did.

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

回答by udjin

C++ string class is encapsulating of char C-like string. It is a much more convenient (http://www.cplusplus.com/reference/string/string/).

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

for legacy you always can "extract" char pointer from string variable to deal with it as char pointer:

对于传统,您始终可以从字符串变量中“提取”字符指针以将其作为字符指针处理:

    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

回答by Hoàng Long

Yes, char*is the pointer to an array of character, which is a string. string *is the pointer to an array of std::string(which is very rarely used).

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

string *name = "name"; 

"name" is a const char*, and it would never been converted to a std::string*. This will results compile error.

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

The valid declaration:

有效声明:

string name = "name";

or

或者

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

回答by Shamim Hafiz

string *name = "name";

Does not compile in GCC.

不能在 GCC 中编译。