执行这两个选项有什么区别,为什么在C ++中不推荐使用第二种类型?
char hello[] = {'h', 'e', 'l', 'l', 'o', '\0'};
char *hello = "hello";
但在正确的c ++中,第二个应该是:
const char *hello = "hello";
在大多数情况下,我猜你永远不会改变“你好”,但为什么你不能改变这段记忆呢?
答案 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
的古老代码。在任何一种情况下,尝试修改文字都会产生未定义的行为。
为什么你不能改变这段记忆?
因为字符串文字是常量。如果你想要一些你可以改变的记忆,你就必须创建自己的阵列。