30

为什么 C 中的以下代码有效?

const char* str = NULL;
str = "test";
str = "test2";

既然 str 是一个指向常量字符的指针,为什么我们可以给它分配不同的字符串字面量呢?此外,我们如何保护 str 不被修改?例如,如果我们后来将 str 分配给一个更长的字符串,该字符串最终覆盖了另一部分内存,这似乎是一个问题。

我应该在我的测试中补充一点,我在每次分配之前和之后打印出 str 的内存地址,它从未改变过。因此,尽管 str 是一个指向 const char 的指针,但实际上内存正在被修改。我想知道这是否可能是 C 的遗留问题?

4

6 回答 6

44

您正在更改不是 const 的指针(它指向的是 const)。

如果您希望指针本身为 const,则声明如下所示:

char * const str = "something";

或者

char const * const str = "something";  // a const pointer to const char
const char * const str = "something";  //    same thing

指向非常量数据的 const 指针通常不如指向 const 的指针有用。

于 2009-01-13T19:13:08.277 回答
14

此外,我们如何保护 str 不被修改?

char * const str1; // str1 cannot be modified, but the character pointed to can
const char * str2; // str2 can be modified, but the character pointed to cannot
const char * const str3 // neither str3 nor the character pointed to can be modified.

最简单的阅读方法是从变量名开始向左阅读:

  • str1是一个指向字符const ant指针
  • str2指向字符const ant的指针
  • str3是一个const ant指针,指向一个字符const ant

注意:从右到左的阅读在一般情况下不起作用,但对于简单的声明,这是一种简单的方法。我发现了一个基于“The C Programming Language”中的代码的java 小程序,它可以破译声明并完整解释如何做到这一点。

于 2009-01-13T19:21:28.477 回答
2

在相关说明中,请务必查看“ const 指针与指向 const 的指针”。它有助于一些人所说的const 正确性。我把它放在我的书签里,这样我可以不时地参考它。

于 2009-01-13T22:02:21.743 回答
1

字符串文字的内存是在堆栈上分配的,您所做的所有分配都是将str指针更改为指向这些内存地址。它最初指向的常量字符根本没有改变。

于 2009-01-13T19:12:01.413 回答
1

您正在寻找的可能是语法...

const char* const str = NULL;
str = "test";
str = "test2";

请注意 char* 后面的“const”,它在尝试编译/构建时会产生编译器错误。

于 2009-01-13T19:18:06.863 回答
1

此外,将变量声明为 const 意味着该变量是只读的;这并不意味着该值是恒定的!

于 2009-01-13T19:41:51.323 回答