为什么可以分配一个const char *为char *?(Why is it possible t

2019-06-23 20:29发布

我知道,例如"hello"是类型const char* 。 所以我的问题是:

  1. 我们怎样才能一个字符串像分配"hello" ,以非const char*这样的:

     char* s = "hello"; // "hello" is type of const char* and s is char* // and we know that conversion from const char* to // char* is invalid 
  2. 是字符串像"hello" ,这将需要记忆在我所有的程序,或者它就像当语句结束,这将被摧毁临时变量?

Answer 1:

事实上, "hello"的类型是char const[6]

但问题的要点仍然是正确的-为什么C ++允许我们一个只读存储器位置分配给非const类型?

这样做的唯一原因是向后兼容旧的C代码,这不知道const 。 如果C ++一直严格在这里它会打破很多现有的代码。

这就是说,大多数编译器可配置警告这样的代码为过时,甚至在默认情况下做到这一点。 此外,C ++ 11完全不允许此,而是编译器可能不能执行它。


对于Standerdese球迷:
[参考文献1] C ++ 03标准:§4.2/ 2

字符串文字(2.13.4),其不是一个宽字符串文字可以转换为类型“字符指针”的右值; 一个宽字符串文字可以转换为类型“指针wchar_t的”的右值。 在任一情况下,结果是一个指针数组的第一个元素。 这种转换被认为是只有在有明确的相应指针目标类型,而不是当人们普遍需要从一个左值转换为右值。 [ 注:该转换已被弃用 。 见附录D.对于在重载解析(13.3.3.1.1)排名的目的,这种转换被认为是一个阵列到指针转换随后资格转换(4.4)。 [实施例:“ABC”转换为“指针为const char”作为阵列到指针转换,然后以“字符指针”作为资格转换。 ]

C ++ 11简单地移除上述引文这意味着它是在C ++ 11非法代码。

[参考文献2] C99标准6.4.5 / 5 “字符串文字-语义”:

在转换阶段7,字节或值为零的代码被附加到从字符串文字或文字产生每个多字节字符序列。 然后,将多字节字符序列用于初始化静态存储持续时间和长度刚好足以包含序列的阵列。 为字符串文字,阵列元素具有char类型,以及与多字节字符序列的各个字节被初始化; 对于宽字符串文字,阵列元素具有wchar_t类型,并与宽字符序列被初始化...

这些阵列是否是不同的条件是它们的元件具有相应的值是不确定的。 如果程序试图修改这样的阵列,该行为是未定义。



Answer 2:

就像我所有的节目“你好”将内存中的所有这就像当语句结束,这将被摧毁一个临时变量文本字符串。

它被保存在数据PROGRAMM,所以它是PROGRAMM的寿命内awaiable。 您可以从当前范围返回指针和引用这些数据。

为什么唯一的理由const char*被强制转换为char*是comatiblity与C,就像WINAPI系统调用。 而这一投是由不同于其他任何常量铸造unexplicit。



Answer 3:

只需使用一个string

std::string s("hello");

这将是C ++的方式。 如果你真的必须使用char ,你需要创建一个数组,其内容在复制。



Answer 4:

回答你的第二个问题是变量s存储在RAM类型指针到字符。 如果是全球性的或静态的,它是在堆中分配,并在那里保留正在运行的程序的生命。 如果它是一个地方(“自动”)变量,它在栈中分配并保持直到当前函数返回。 在任一情况下,它占用的内存来保存一个指针所需的量。

字符串"Hello"是一个常数,它存储程序本身的一部分,与其他所有的常量和初始化一起。 如果你建立你的程序在设备上运行,那么该字符串存储在ROM中。

需要注意的是,因为字符串是恒定的, s是一个指针,没有拷贝是必要的。 指针s仅指向哪里字符串存储。



Answer 5:

在你的榜样,你是不是分配的,但建设。 的std :: string,例如,确实有一个std::string(const char *)构造函数(实际上它更复杂,但它并不重要)。 并且,类似地,字符*(如果它是一个类型,而不是一个指针型)可以有一个const char *构造函数,这是复制内存。

我真的不知道如何编译器确实有效这里,但我认为这可能是类似于我上面描述:副本"Hello"的堆构造和s与此副本的地址进行初始化。



文章来源: Why is it possible to assign a const char* to a char*?