【问题标题】:const int pointer errorconst int 指针错误
【发布时间】:2014-10-05 07:07:18
【问题描述】:

我正在学习常量指针,我正在尝试这个

#include<iostream>
using namespace std ;
int main(){
    int a = 10 ; 
    const int *cp  = &a ;               // my constant pointer variable
    cout<<"\nAddress stored in cp = "<<cp ;
    ++cp;
    cout<<"\nAddress stored in cp = "<<cp   ;
}

它增加了存储在cp中的地址 但是根据我到现在的理解,++cp不应该报错,因为它是一个常量指针,总是指向同一个地址,这个地址是不能修改的。

但是当我更换时

const int *cp = &amp;a ;int *const cp = &amp;a ;

它给了我这个

请原谅我的无知,但是,他们不应该是同一个意思吗?

【问题讨论】:

  • 我个人不喜欢 spiral 方法来读取类型,我建议您将 const 放在 right(正确)的位置,这样位于const 类型的right(相对于left),在上面的代码中:int const *int * const。然后从右向左阅读。
  • @chris:螺旋规则是错误的。听大卫罗德里格斯的声音
  • @kotlomoy,螺旋规则在阅读类型时并没有让我失望过。唯一的例外是这个 cv 限定符被允许放在左边。如果我可以重命名它,我更喜欢交替左右规则之类的东西,但是一旦你理解了这项技术,你就会很难找到你看不懂的东西。
  • @chris:“你很难找到你看不懂的东西。” -int a[2][3]。信息:我根本没有受到压力

标签: c++ pointers constants


【解决方案1】:

当你在做int *const cp = &amp;a;时,它意味着一个指向常量cp的整数指针,所以cp不能改变。但是,在您之前的版本中,const int *cp 表示指向 cp 的常量 int 指针,因此 cp 指向的值不能更改,但指针本身可以。

通常,人们喜欢从右到左阅读:

const int *cpcp 是一个指向 int 常量的指针,所以整数不能改变。

int *const cp = &amp;a;cp是一个指向int的常量指针,所以指针不能改变。

【讨论】:

    【解决方案2】:
    const int *cp  = &a ; 
    

    cp 指向的地址内容是只读的,而指针cp 不是

    所以,

    *cp = value ; //Illegal
    ++cp ; // Legal
    

    int *const cp = &a ;
    

    指针是只读的,但cp指向的地址内容不是

    所以,

    *cp = value ; //Legal
    ++cp ; // Illegal
    

    还有,

    const int *const cp  = &a ;
    

    cp指向的指针和地址内容都是只读的

    *cp = value ; //Illegal
    ++cp ; // Illegal
    

    对于简单的声明从右到左阅读

    【讨论】:

      【解决方案3】:
      const int *cp1  = &a ; // pointer is variable, pointed to is constant
      int *const cp2  = &a ; // pointer is constant, pointed to is variable
      const int *const cp3  = &a ; // pointer is constant, pointed to is constant
      

      因此,

      cp1++; // possible
      *cp1++; // not possible
      cp2++; // not possible
      *cp2++; // possible
      cp3++; // not possible
      *cp3++; // not possible
      

      【讨论】:

        【解决方案4】:

        如果它有帮助(而且可能没有),以下是同义词,利用允许打开类型有const 出现在紧靠左侧的语言细节 类型的右侧,但在任何其他限定符(如指针或引用)之前:

        const int * p; // does NOT require initialization
        int const * q; // same as above
        

        两者都声明指向常量int数据的指针,并且在语法上可以互换。

        而这个:

        int * const p = &a; // requires initialization.
        

        声明一个指向int数据的常量指针; 不是指向常量int 数据的指针。

        进一步扩展(实际上合并两者),我们得到:

        const int * const p = &a;
        int const * const p = &a;
        

        这些是同义词。两者都声明了一个指向常量 int 数据的常量指针。指针和它指向的东西都是不可修改的,都需要初始化。


        无耻地抄袭图表

        以下内容是从一个轻微相关的question 我自己(好吧,没那么丢脸)无耻地扯掉的。我希望它有助于进一步解释当您将 const* 放置在声明的不同位置时会发生什么差异:

        单间接

        char *p;               // p is mutable, *p is mutable
        const char *p;         // p is mutable, *p is const
        char const *p;         // same as above.
        char *const p;         // p is const, *p is mutable, must be initialized.
        char const *const p;   // p is const, *p is const, must be initialized.
        

        双重间接

        char **p;        // ptr-to-ptr-to-char
                         // p, *p, and **p are ALL mutable
        
        const char **p;  // ptr-to-ptr-to-const-char
                         // p and *p are mutable, **p is const
        
        char const **p;  // same as above
        
        char *const *p;  // ptr-to-const-ptr-to-char
                         // p is mutable, *p is const, **p is mutable.
        
        char **const p;  // const-ptr-to-ptr-to-char
                         // p is const, *p is mutable, **p is mutable.
                         // must be initialized.
        
        const char **const p;  // const-ptr-to-ptr-to-const-char
                               // p is const, *p is mutable, **p is const.
                               // must be initialized.
        
        char const **const p;  // same as above
        
        char const *const *p;  // ptr-to-const-ptr-to-const-char
                               // p is mutable, *p is const, **p is const.
        
        const char *const *p;  // same as above.
        
        char *const *const p;  // const-ptr-to-const-ptr-to-char
                               // p is const, *p is const, **p is mutable.
                               // must be initialized.
        

        还有我个人最喜欢的:

        char const *const *const p;   // const-ptr-to-const-ptr-to-const-char
                                      // everything is const.
                                      // must be initialized.
        
        const char *const *const p;   // same as above
        

        【讨论】:

          【解决方案5】:

          这是我始终建议将const 放在int 右侧而不是左侧的原因之一。如:

          int const *cp;
          

          而不是:

          const int *cp;
          

          这样做的好处是,const 的项目在 const 关键字的右侧,它的类型在左侧。

          在上面,*cp(即cp的内容)是const,它的类型是int。如果你写

          int * const cp = &foo;
          

          并应用相同的规则,cpconstconst 项目的类型为 int *。当有多个间接级别时,使用此规则可以更容易理解正在发生的事情。

          int const ** cpp1;
          int * const *cpp2;
          int ** const cpp3 = &bar;
          int const ** const cpp4 = &xyz;
          

          最后一个是一个const 指针,指向一个指向const int 的可变指针。一个const 项目的类型为int,而另一个项目的类型为int **。简单易懂,只要你永远不要把const这个词放在int的左边。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-09-10
            • 1970-01-01
            • 2021-05-10
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-12-04
            相关资源
            最近更新 更多