简体   繁体   English

C ++ - char * vs. string *

[英]C++ - char* vs. string*

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";

Yes, there's a difference. 是的,有区别。 Mainly because you can modify your string but you cannot modify 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. 所以总是使用第二个版本。

If you need to use a char pointer for whatever reason, make it const : 如果由于某种原因需要使用char指针,请将其设为const

char const* str = "name";

Now, if you try to modify the contents of str , the compiler will forbid this (correctly). 现在,如果您尝试修改str的内容,编译器将禁止此(正确)。 You should also push the warning level of your compiler up a notch: then it will warn that your first code (ie char* str = "name" ) is legal but deprecated. 您还应该将编译器的警告级别提升一级:然后它会警告您的第一个代码(即char* str = "name" )是合法的但不推荐使用。

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. 第一个版本不会编译,因为string*char*基本上是不同的类型。

The difference between a string and a char* is that the char* is just a pointer to the sequence. stringchar*之间的区别在于char*只是指向序列的指针。 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编程语言,是字符串在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> . 使用C字符串有点棘手 - 你需要确保为它们正确分配空间,避免走出它们占用的缓冲区的末尾,将它们放在可变内存中以避免分段错误等。主要功能用于操作它们在<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. 大多数C ++程序员建议不要使用C风格的字符串,因为它们本身就更难以使用,但它们仍然支持向后兼容性和低级API可以构建的“最低公分母”。

A C++-style string is an object encapsulating a string. C ++样式的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. 它使用运算符重载来使串联等常见操作更容易使用,并且还支持几个用于执行高级操作(如搜索,替换,子串等)的成员函数。它们还可以与STL算法进行互操作,尽管C风格的字符串也可以做到这一点。

In short, as a C++ programmer you are probably better off using the string type. 简而言之,作为C ++程序员,您最好使用string类型。 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 string can also be used unless there's a compelling reason to do so. 了解C风格的字符串仍然很好,因为你在编程生涯中肯定会遇到它们,但最好不要在你的程序中使用它们,除非有令人信服的理由,否则也可以使用string

Yes, the second one isn't valid C++! 是的,第二个是无效的C ++! (It won't compile). (它不会编译)。

You can create a string in many ways, but one way is as follows: 您可以通过多种方式创建string ,但有一种方法如下:

string name = "name";

Note that there's no need for the * , as we don't need to declare it as a pointer. 请注意,不需要* ,因为我们不需要将其声明为指针。

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. char* name = "name"应该是无效的,但是在大多数系统上进行编译,以便在没有const的情况下向后兼容,并且如果它没有编译就会破坏大量遗留代码。 It usually gets a warning though. 它通常会收到警告。

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 ++的规则可写),但如果你真的尝试写入它,你会调用未定义的行为,而语言规则应该尽可能地合理地保护你。可能。

The correct construct is 正确的结构是

const char * name = "name";

There is nothing wrong with the above, even in C++. 即使在C ++中,上面也没有错。 Using string is not always more correct. 使用字符串并不总是更正确。

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和allocator)

There are various scenarios where using string is far preferable to using arrays of char. 在各种情况下,使用字符串比使用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). (将第一个字母转换为大写字母)对于字符串有效,而不是char *(未定义的行为)或const char *(不会编译)。 You would be allowed to modify the string if you had char name[] = "name"; 如果你有char name[] = "name";你可以修改字符串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. 但是,如果要将字符附加到字符串,则std :: string构造是唯一允许您干净地执行此操作的构造。 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. 使用旧的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. 另外,basic_string实际上并不执行许多字符串操作,而是通过char_traits完成。 (This allows it to use specialist C-functions underneath which are well optimised). (这允许它使用下面的专业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. 你将无法像你那样分配它。

C++ string class is encapsulating of char C-like string. C ++字符串类封装了类似char C的字符串。 It is a much more convenient (http://www.cplusplus.com/reference/string/string/). 它更方便(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指针来处理它作为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

Yes, char* is the pointer to an array of character, which is a string. 是的, char*是指向字符数组的指针,这是一个字符串。 string * is the pointer to an array of std::string (which is very rarely used). string *是指向std::string数组的指针(很少使用)。

string *name = "name"; 

"name" is a const char* , and it would never been converted to a std::string* . “name”是一个const char* ,它永远不会转换为std::string* This will results compile error. 这将导致编译错误。

The valid declaration: 有效声明:

string name = "name";

or 要么

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

不在GCC中编译。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM