简体   繁体   English

char array []和char * array有什么区别?

[英]What is the difference between char array[] and char *array?

What is the difference between doing these two options, and why is the second type deprecated in C++? 这两个选项之间有什么区别?为什么C ++中不推荐使用第二种类型?

char hello[] = {'h', 'e', 'l', 'l', 'o', '\0'};

char *hello = "hello";

But in correct c++ the second should be: 但是在正确的c ++中,第二个应该是:

const char *hello = "hello";

For the most part I guess you are never going to change "hello", but why can't you change this memory if you wanted to? 在大多数情况下,我想您永远都不会更改“ hello”,但是如果您愿意,为什么不能更改此内存呢?

char hello[] = {'h', 'e', 'l', 'l', 'o', '\\0'};

This creates an array of 6 bytes in writable memory (on the stack if this is inside a function, in a data segment if directly at global scope or inside a namespace), to be initialised with the ASCII codes for each of those characters in turn. 这将在可写内存中创建一个6字节的数组(如果在函数内,则在堆栈上;如果在全局范围内或在名称空间内,则在数据段中)在堆栈中依次使用每个字符的ASCII码进行初始化。

char *hello = "hello"; char * hello =“ hello”;

"hello" is a string literal , which typically means: "hello"字符串文字通常表示:

  • the OS loader code that loads your program into memory and starts it running will have copied the text "hello\\0" from your executable image into some memory that will then have been set to be read only, and 用于将程序加载到内存中并开始运行的OS加载程序代码将已将文本“ hello \\ 0”从可执行映像复制到某些内存中,然后将其设置为只读。

  • a separate variable named "hello" - which is of whatever size pointers are in your program (eg 4 bytes for 32-bit applications, 8 for 64-bit) - will exist on the stack (if the line above appears inside a function) or in writable memory segment (if the line is at global or namespace scope), and the address of the former textual data will be copied into the hello pointer. 堆栈中将存在一个单独的变量“ hello”-大小与程序中指针的大小无关(例如,对于32位应用程序为4字节,对于64位为8字节)(如果上面的行出现在函数内)或在可写内存段中(如果该行位于全局或命名空间范围内),则以前的文本数据的地址将被复制到hello指针中。

  • you can change hello to point somewhere else (eg to another language's equivalent text), but normally shouldn't try to change the string literal to which the above code points hello ... see below. 您可以将hello更改为指向其他位置(例如,另一种语言的等效文本),但通常不应该尝试更改上述代码所指向的字符串文字hello ...参见下文。

But in correct c++ the second should be: 但是在正确的c ++中,第二个应该是:

const char *hello = "hello"; const char * hello =“ hello”;

Yes - that's much better. 是的-更好。 For backwards compatibility, C++ has historically allowed non- const pointers to string literals, but actually modifying them wasn't guaranteed to be possible. 为了向后兼容,C ++历来允许使用非const指针指向字符串文字,但是实际上并不能保证对它们进行修改。 Some compilers always, or can optionally (when asked by command line arguments), put string literals in writable memory. 有些编译器总是或可以选择(在命令行参数要求时)将字符串文字放入可写内存中。 But, even if they are writable, changing them leads to lots of potential for errors. 但是,即使它们可写,更改它们也会导致很多潜在的错误。 Say you have code like this and compiler flags to allow it to compile: 假设您具有这样的代码和编译器标志,以使其能够进行编译:

char* end = "end";
if (mixed_case_mode) end[0] = 'E';
if (s == "end") ...;

Then some completely unrelated code that does this... 然后是一些完全不相关的代码可以执行此操作...

std::cout << "this is the " << (x ? "start": "end");

...might start printing "End" if all mentions of "end" shared the same memory - a common and desirable optimisation. ...如果所有提及“结束”的人都共享相同的记忆,则可以开始打印“结束”,这是常见且理想的优化方式。 Turning this off can be quite wasteful, and while it allows this hackery to work with less unintended side effects to unrelated uses of the text, it's still very hard to reason about the code and debug when if (s == "end") might not actually be comparing s to "end" . 禁用此功能可能会非常浪费,并且虽然可以使这种黑客程序对与文本无关的使用产生较少的意外副作用,但是仍然很难对代码进行推理并调试何时if (s == "end")实际上不是将s"end"进行比较。

When you use [] you create an array which is a collection of items, chars in this case. 使用[]时,将创建一个数组,该数组是项目的集合,在这种情况下为char。

As you probably are aware, using * creates a pointer which might appear to be the same thing but is simply a single value (a memory address). 如您所知,使用*创建一个指针,该指针看似相同,但仅仅是一个值(内存地址)。

In essence the array creates a variable as large as the data where as the pointer just creates a 8 byte variable which contains the memory location of the string constant. 本质上,数组创建的变量与数据一样大,而指针仅创建一个8字节的变量,其中包含字符串常量的存储位置。

If you want a string you can change, just use 如果您想更改字符串,只需使用

char hello[] = "Hello";

This is legal and means exactly the same as your first statement. 这是合法的,并且与您的第一句话完全相同。 You can also reserve extra space, since you're writing you might want to store a bigger string later: 您还可以保留额外的空间,因为您正在编写,所以以后可能需要存储更大的字符串:

char hello[100] = "Hello";

What is the difference between doing these two options 这两个选项有什么区别

The first declares an array containing those characters. 第一个声明包含这些字符的数组。 The second declares a pointer to a string literal: a static constant array containing the same characters. 第二个声明一个指向字符串文字的指针:一个包含相同字符的静态常量数组。 Or it would, if you were allowed to do that. 否则,如果允许您这样做。

why is the second type deprecated in C++? 为什么在C ++中不推荐使用第二种类型?

It isn't: it's forbidden, since the string literal is constant. 不是:因为字符串文字是常量,所以它是被禁止的。 Before C++11, it was allowed, but deprecated, to avoid breaking ancient code that didn't use const . 在C ++ 11之前,为了避免破坏不使用const古老代码,允许但不建议使用它。 In either case, attempting to modify the literal gives undefined behaviour. 无论哪种情况,尝试修改文字都会产生未定义的行为。

why can't you change this memory if you wanted to? 如果需要,为什么不能更改此内存?

Because string literals are constant. 因为字符串文字是常量。 If you want some memory that you can change, you'll have to create your own array. 如果您想要一些可以更改的内存,则必须创建自己的数组。

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

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