以简单的方式修改常量字符 * 与字符 * 内容



我真的对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] = '';

如果我们想使用这样的东西

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

而且我没有编译器错误! 为什么? 为什么我们使用内存复制时不是常量,而在常量中我们只使用相等的运算符! 并完成...怎么可能?在常量中只使用相等可以吗? 以后没有问题发生?

正如其他答案所说,您应该区分它们指向的指针和字节。

两种类型的指针,char *const char *,都可以更改,即"重定向"以指向不同的字节。但是,如果要更改字符串的字节(字符),则不能使用const char *

因此,如果您的程序中有字符串文字"Hello"和"World",则可以将它们分配给指针,打印指针将打印相应的文字。但是,要做任何非平凡的事情(例如,将Hello更改为HELLO),您将需要非const指针。

另一个示例:通过一些指针操作,您可以从字符串文本中删除前导字节:

const char* str = "Hello";
std::cout << str; // Hello
str = str + 2;
std::cout << str; // llo

但是,如果要提取子字符串或对字符串执行任何其他转换,则应重新分配它,为此,您需要一个非const指针。


顺便说一句,由于您使用的是C++,因此您可以使用std::string,这使得使用字符串变得更加容易。它会在没有您干预的情况下重新分配字符串:

#include <string>
std::string str("Hello");
str = str.substr(1, 3);
std::cout << str; // ell

这是早期C时代的令人困惑的宿醉。早期的 C 没有 const,所以字符串文字是"char *"。它们仍然是 char * 以避免破坏旧代码,但它们变得不可修改,因此除了名称之外的所有 const char *。因此,现代C++在省略常量时发出警告或给出错误(严格符合)。

顺便说一下,你的memcpy错过了尾随的nul字节。使用 strcpy() 复制一个字符串,这是具有正确名称的正确函数。您可以使用

char rwstring[] = "I am writeable";

语法。

这是因为您的变量只是一个指针*。你不是在修改它们的内容,而是在修改它们指向的位置。

char * a = "asd";
char * b = "qwe";
a = b; 

现在你扔掉了 A 的内容。现在 a 和 b 指向同一个地方。如果修改一个,则会同时修改两个。

换句话说。指针从来都不是常量(大多数情况下)。指针变量中的const谓词对指针没有任何意义。

真正的区别在于指针(不是const)指向一个const变量。 当你改变指针时,它将指向另一个新的const变量。这就是为什么const对简单的指针没有影响。

注意:您可以使用指针实现不同的行为,并在更复杂的场景中实现 const 行为。但简单来说,它大多没有效果。

引用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 字符串文本也称为窄字符串文本。窄字符串文本的类型为"nconst char 数组">,其中 n 是下面定义的字符串大小,并具有静态存储持续时间。

(我强调。通常,不允许将指向 const 的指针分配给指向非 const 的指针:

char const* s = "hello";
char ss = s;

这将无法编译。将字符串文字分配给指向非 const 的指针通常也应该失败,正如标准在 C.1.1 子句 5.13.5 中明确指出的那样:

更改:字符串文字变为常量。 字符串文本的类型从"字符数组"更改为"常量字符数组"。 [...]

char* p = "abc";//在 C 中有效,在 C++ 中无效

尽管如此,编译器通常接受字符串文字赋值到指向非常量的指针(作为扩展!),可能是为了保持与 C 的兼容性。由于根据标准,这是无效的,编译器会产生警告,至少......

最新更新