【问题标题】:const - Shouldn't it not changeconst - 它不应该改变吗
【发布时间】:2011-01-28 10:52:50
【问题描述】:

在运行这个 C++ 代码时,我希望输出是 Abc,但是,它是 FFF,这是为什么呢? name不是指向常量char吗?

#include <iostream>
int main()
{
    const char* name = "Abc";
    name = "FFF";
    std::cout<<name<<std::endl;
    return 0;
}

【问题讨论】:

  • 我建议你阅读这篇关于const的帖子

标签: c++ pointers constants


【解决方案1】:

是的,正如您所说,它指向const char,但它不是一个常量指针。您正在更改您所指向的内容,而不是您所指向的内容。换句话说,在你重新分配指针后,保存“Abc”的内存仍然保存着字符“Abc”。

对于常量指针,您需要const char* const name = "Abc";。在这种情况下,它不会编译,因为您无法更改指针指向的内容。

一般来说,使用 C++ 中的 const 和指针,您可以从右到左读取类型名称以了解正在发生的事情。例如,在const char* const 的情况下,您可以将其读作“指向字符常量的常量指针”。有点奇怪,但它有效。

【讨论】:

    【解决方案2】:

    const char* name = "Abc"; -> 非 const 指针-> 名称,但数据(Abc)是常量

    name = "FFF" -> 将指针(名称)更改为指向 FFF。

    char *p              = "Hello";          // non-const pointer,
                                             // non-const data
    const char *p        = "Hello";          // non-const pointer,
                                             // const data
    char * const p       = "Hello";          // const pointer,
                                             // non-const data
    const char * const p = "Hello";          // const pointer,
                                             // const data
    

    【讨论】:

    • 这就是(一个原因。另一个是 typdef 规则)为什么我更喜欢总是把 const 放在右边。它使这条规则更容易解析。 char const * const p。从右到左阅读:p is a "constant *" to "constant char"
    • 出于某种原因,我在正确阅读const char* 时从未遇到任何问题。一直很自然地觉得const属于char
    • @Mephane:当然。但是现在在其中粘贴一个 typedef 看看它的含义是什么(如果你不小心它会改变(当 const 是第一个时))但是当 const 放在对象的左侧时是一致的。
    • 我知道。这就是为什么我不 typedef 指针,除非绝对不可避免(我还没有遇到过这种情况)。指针上的 typedef 的问题在于,您只能使用 typedef 创建的别名使指针值 const,您需要一个单独的 typedef 用于指向 const 的指针。我更喜欢只使用 C++ 关键字。
    【解决方案3】:

    使用const char* name = "Abc";,您告诉编译器您不会使用name 更改“Abc”的内容。但是,您可以随意更改指针以指向不同的内存位置。有关详细信息,请参阅此FAQ

    【讨论】:

      【解决方案4】:

      这是const 和说英语的人的一个已知问题。

      语法允许两者:

      • const T
      • T const

      两者含义相同。

      然而,一旦你把指针扔进去,事情就变得复杂了:

      • const T* 应改为 (const T)*
      • T const* 应阅读 (T const)*
      • T* const 应改为 (T*) const

      因此,我总是在对象的右侧使用const。这更一致。

      请注意,typedef 可以找到相同的问题,让我们定义 typedef T* pointer

      • const pointer 表示 T* const,而不是 const T*(作为宏所暗示的)
      • pointer const 表示T* const,类似于文本替换

      如果你习惯把const放在名字后面,而不是像英文形容词一样放在前面,那么你就不会落入那些陷阱。

      【讨论】:

      • 不会将T* const 读作T(* const) 读作constant pointer to T
      【解决方案5】:

      实际上最正确的语法是

      char const * pName;
      

      因为const关键字即适用于左侧部分。

      如果你想要一个 const poitner 到一个 const char 你会写它:

      char const * const pName;
      

      和一个指向 int 的 const 指针;

      int * const pInt;
      

      PS:但我仍然尽可能在行首写 const,这是一个固定的习惯 ;-)

      【讨论】:

        【解决方案6】:
        const char* name = "Abc";
        

        实际上这意味着,name 是一个指向 const 数据的指针。意味着,数据是 const,而不是指针本身。所以如果你写它是完全有效的:

        name = "FFF"; //ok : changing the pointer
        

        但是,以下内容不会编译:

         char * const name = "Abc"; //const pointer to the non-const data!
         name = "FFF"; //error: trying to change the pointer itself!
        

        查看编译错误:

        prog.cpp:5:错误:分配 只读变量“名称”

        在这里看到你自己:http://www.ideone.com/KyNXx

        【讨论】:

          【解决方案7】:

          当你声明一个变量时

          const T* ptr = /*...*/
          

          您正在声明一个指针,表示被指向的对象,而不是指针,不能改变。换句话说,它是一个“指向 const 的 T 的指针”。

          如果想让指针无法重新赋值,可以写

          T* const ptr = /*...*/
          

          现在这是一个指向 T 的不可变指针,可以修改。

          您可以像这样将它们组合在一起:

          const T* const ptr = /*...*/
          

          获取指向不可变 T 的不可变指针。

          作为一个有趣的提示,您通常可以通过从右到左读取类型来确定指针/指向对的哪些部分可以修改。在上面尝试一下,看看你会得到什么。

          【讨论】:

            【解决方案8】:

            首先,const 仅在编译时检查。如果编译成功,所有操作都会在运行时正常完成。

            在您的示例中,const 适用于name 指向的内容。因此,您可以更改指针,但不能更改内容。

            strcpy(name, "FFF");
            

            会被拒绝,但不会像你那样更改指针。

            【讨论】:

              【解决方案9】:

              文字字符串“Abc”和“FFF”常量,但name 是一个变量(指向常量数据的指针)。您只需将变量更改为指向不同的常量数据。

              此外,虽然在这种情况下数据必须是常量,但指向常量数据的指针仅意味着不能通过取消引用该指针来修改数据,也可以直接修改数据或通过不同的指针修改数据。例如

              int i = 0 ;
              const int* p = &i ;
              i++ ; // valid
              (*p)++ // error.
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2014-05-28
                • 1970-01-01
                • 2012-11-24
                • 2012-03-02
                • 1970-01-01
                • 2012-08-22
                • 2018-07-20
                相关资源
                最近更新 更多