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

时间:2014-01-20 02:09:19

标签: c++

执行这两个选项有什么区别,为什么在C ++中不推荐使用第二种类型?

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

char *hello = "hello";

但在正确的c ++中,第二个应该是:

const char *hello = "hello";

在大多数情况下,我猜你永远不会改变“你好”,但为什么你不能改变这段记忆呢?

4 个答案:

答案 0 :(得分:4)

  

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

这会在可写内存中创建一个包含6个字节的数组(如果在函数内部,在数据段中,如果直接在全局范围内或在命名空间内),则在堆栈中创建一个数组,使用每个字符串的ASCII代码进行初始化字符依次。

  

char * hello =“hello”;

"hello"字符串文字通常表示:

  • 将程序加载到内存并开始运行的OS加载程序代码会将可执行映像中的文本“hello \ 0”复制到某个内存中,然后将其设置为只读,并且< / p>

  • 一个名为“hello”的单独变量 - 它是程序中任何大小的指针(例如,32位应用程序为4个字节,64位为8个) - 将存在于堆栈中(如果是上面出现在函数内部或可写内存段中(如果该行在全局或命名空间范围内),并且前一个文本数据的地址将被复制到hello指针中。

  • 您可以将hello更改为指向其他位置(例如,更改为其他语言的等效文本),但通常不应尝试更改上述代码指向{1}}的字符串文字。 ..见下文。

  

但在正确的c ++中,第二个应该是:

     

const char * hello =“hello”;

是的 - 那好多了。为了向后兼容,C ++历史上允许非hello指向字符串文字,但实际上不能保证修改它们。有些编译器总是或者可以选择(当命令行参数询问时)将字符串文字放在可写内存中。但是,即使它们是可写的,改变它们也会导致很多错误。假设你有这样的代码和编译器标志,以允许它编译:

const

然后一些完全无关的代码执行此操作......

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

...如果“end”的所有提及都共享相同的内存,则可能会开始打印“End” - 这是一种常见且理想的优化。关闭它可能非常浪费,虽然它允许这个hackery对文本的不相关使用产生较少的意外副作用,但是当std::cout << "this is the " << (x ? "start": "end"); 可能实际上没有比较时,仍然很难推断代码和调试if (s == "end")s

答案 1 :(得分:1)

当你使用[]时,你创建一个数组,这是一个项目的集合,在这种情况下是字符。

正如您可能知道的那样,使用*会创建一个可能看起来相同但只是单个值(内存地址)的指针。

本质上,数组创建一个与数据一样大的变量,而指针只是创建一个包含字符串常量的内存位置的8字节变量。

答案 2 :(得分:0)

如果您想要更改字符串,请使用

char hello[] = "Hello";

这是合法的,与第一份陈述完全相同。您还可以保留额外的空间,因为您在写作时可能希望以后存储更大的字符串:

char hello[100] = "Hello";

答案 3 :(得分:0)

  

执行这两个选项有什么区别

第一个声明包含这些字符的数组。第二个声明了一个指向字符串文字的指针:一个包含相同字符的静态常量数组。或者如果你被允许那样做的话。

  

为什么在C ++中不推荐使用第二种类型?

不是:它被禁止,因为字符串文字是不变的。在C ++ 11之前,它被允许但不推荐使用,以避免破坏未使用const的古老代码。在任何一种情况下,尝试修改文字都会产生未定义的行为。

  

为什么你不能改变这段记忆?

因为字符串文字是常量。如果你想要一些你可以改变的记忆,你就必须创建自己的阵列。