我对const char *
和char *
感到困惑。
我知道在char *
我们想要修改内容时,我们需要做这样的事情
const char * temp = "Hello world";
char * str = new char[strlen(temp) + 1];
memcpy(str, temp, strlen(temp));
str[strlen(temp) + 1] = '\0';
如果我们想要使用这样的东西
char * str = "xxx";
char * str2 = "xts";
str = str2;
我们收到编译器警告。没关系我知道什么时候我想要改变char *
我必须使用一些内存副本。但关于const char *
我真的很困惑。在const char *
我可以使用此
const char * str = "Hello";
const char * str2 = "World";
str = str2; // and now str is Hello
我没有编译错误!为什么?为什么我们在不是const时使用内存复制而在const中我们只使用相等的运算符!并完成了!...怎么可能? 在const中使用equ可以吗?以后没问题?
答案 0 :(得分:1)
从C早期开始这是一个令人困惑的宿醉。早期的C没有const,所以字符串文字是" char *"。它们仍然是char *以避免破坏旧代码,但它们变得不可修改,所以const char *除了名称之外的所有内容。因此,当省略const时,现代C ++会发出警告或给出错误(严格遵守)。
顺便说一句,你的memcpy错过了尾随的字节。使用strcpy()复制字符串,这是正确的函数和正确的名称。您可以使用
在读/写内存中创建一个字符串char rwstring[] = "I am writeable";
语法。
答案 1 :(得分:0)
这是因为你的变量只是一个指针*
。你并没有修改他们的内容,而是他们指向的地方。
char * a = "asd";
char * b = "qwe";
a = b;
现在你丢掉了一个内容。现在a和b指向同一个地方。如果修改一个,则两者都被修改。
换句话说。 指针永远不会是常量(主要是)。指针变量中的const
谓词对指针没有任何意义。
真正的区别在于指针(不是const
)指向const
变量。当你改变指针时,它将指向另一个新的const
变量。这就是const
对简单指针没有影响的原因。
注意:您可以使用指针和const实现不同的行为,以及更复杂的场景。但简单的说,它几乎没有效果。
答案 2 :(得分:0)
正如其他答案所说,你应该区分它们指向的指针和字节。
两种类型的指针char *
和const char *
都可以更改,即"重定向"指向不同的字节。但是,如果要更改字符串的字节(字符),则无法使用const char *
。
所以,如果你有字符串文字"你好"和"世界"在你的程序中,你可以将它们分配给指针,打印指针将打印相应的文字。但是,要做任何非平凡的事情(例如将Hello
更改为HELLO
),您将需要非const
指针。
另一个例子:通过一些指针操作,您可以从字符串文字中删除前导字节:
const char* str = "Hello";
std::cout << str; // Hello
str = str + 2;
std::cout << str; // llo
但是,如果要提取子字符串,或对字符串执行任何其他转换,则应重新分配它,为此需要非const
指针。
BTW因为您使用的是C ++,所以可以使用std::string
,这样可以更轻松地处理字符串。它在没有您干预的情况下重新分配字符串:
#include <string>
std::string str("Hello");
str = str.substr(1, 3);
std::cout << str; // ell
答案 3 :(得分:0)
引用Malcolm McLean:
这是从C早期的混乱宿醉。早期C没有const,所以字符串文字是“char *”。它们仍然是char *以避免破坏旧代码,但它们变得不可修改,所以const char *除了名称之外都有。
实际上,字符串文字不是指针,而是数组,这就是为什么sizeof("hello world")
作为一个魅力(产生12,包含终止空字符,与strlen相反)的原因。除了这个小细节之外,即使在这些日子里,上述陈述对于好的旧 C 也是正确的。
在 C ++ 中,字符串文字从一开始就是常量字符数组(char const[]
):
C ++标准,5.13.5.8:
普通字符串文字和UTF-8字符串文字也称为窄字符串文字。窄字符串文字的类型为“n const char”的数组,其中n是下面定义的字符串的大小,并且具有静态存储持续时间。
(由我强调。)通常,不允许将指向const的指针指定给指向非const的指针:
char const* s = "hello";
char ss = s;
这将无法编译。将字符串文字分配给指向非const 的指针通常也会失败,正如标准在C.1.1中明确说明的,子条款5.13.5:
更改:字符串文字使const。 字符串文字的类型从“char of char”更改为“const char数组”。 [...]
char* p = "abc"; // valid in C, invalid in C++
仍然,编译器通常接受对非const的指针的字符串文字分配(作为扩展名!),可能保留与C的兼容性。因为根据标准,这是无效的,编译器会产生警告,至少......