关于“int const * p”和“const int * p”

时间:2011-03-11 03:03:04

标签: c++ const

#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
    int i1 = 0;
    int i2 = 10;

    const int *p = &i1;
    int const *p2 = &i1;
    const int const *p3 = &i1;

    p = &i2;
    p2 = &i2;
    p3 = &i2;

    cout << *p << endl
        << *p2 <<endl
        << *p3 <<endl;
    return 0;
}

可以使用VC6.0和VC2010编译代码。 但我有一些问题:

  

const int * p =&amp; i1;

这意味着什么“p”点不能修改,但p不能修改,我是对的吗? 所以

  

p =&amp; i2;

这条线可以遵守,是吗?

这一行:

int const *p2 = &i1;

在我看来,这意味着p2无法修改,而p2点可以改变,我是对的吗? 为什么

  

p2 =&amp; i2;

可以编译吗?

关于这一行:

  

const int const * p3 =&amp; i1;

     

p3 =&amp; i2;

哦,上帝......我疯了。我不知道为什么这行可以编译没有错误... 任何人都可以帮助我吗?

困扰我的另一个代码在这里:

class Coo2    
{      
 public:     

 Coo2() : p(new int(0)) {}    

 ~Coo2() {delete p;}    


    int const * getP() const   
    {      
         *p = 1;         
         return this->p;      
    }      

 private:    
      int* p;    
};   

为什么要编译这段代码? 在

  

int const * getP()const

我已更改值或* p!

9 个答案:

答案 0 :(得分:8)

这里我们考虑4种类型的指针声明:

  1. int * w; 这意味着w是指向整数类型值的指针。我们可以修改指针及其内容。如果我们在声明时初始化w如下: int * w = &a;
    然后,以下两个操作都是可行的:
    w = &b;(真)
    *w = 1;(真)

  2. int * const x;
    这意味着x是一个指向整数类型值的常量指针。如果我们在声明时初始化x如下:
    int * const x = &a;
    然后,我们不能这样做:x = &b;(wrong)因为x是一个常量指针而且无法修改 但是,可以执行:*x = 1;(true),因为x的内容不是常量。

  3. int const * y; //两者的意思相同  const int * y;
    这意味着y是一个指向常量整数值的指针。如果我们在声明时初始化y如下:
    int const * y = &a;
    然后,可以执行:y=&b;(true)因为y是一个可以指向任何位置的非常量指针 但是,我们不能这样做:*y=1;(wrong)因为y指向的变量是一个常量变量而且无法修改。

  4. int const * const z; //两者的意思相同  const int * const z;
    这意味着z是一个指向常量整数值的常量指针。如果我们在声明时初始化z如下:
    int const * const z = &a;
    因此,以下操作不可行:
    z = &b;(wrong)
    *z = 1;(wrong)

答案 1 :(得分:5)

在指针的帮助下,你实际上可以做两件事。

  1. 您可以更改它指向的数据,但不能指向不同的内存位置。
  2. 您可以将其指向其他内存位置,但无法更改其指向的数据。
  3. 现在,当你说int const * ptr或int const * ptr时,它属于第一类。它与 -

    相同
    const int num = 5; // Both mean the same.
    int const num = 5; 
    

    To,实际上无法更改到其他位置,即指向常量位置但能够修改数据的指针,语义应为int* const。由于指针的内容是常量,因此应在声明时初始化。

    int num = 5;
    
    int* const ptr; // Wrong
    ptr = &num; // Wrong
    
    int* const ptr = &num;
    *ptr = 100;
    

    然而,还有第三种。指向常量位置的常量指针,既不能指向不同的内存位置,也不能更改它指向的数据。 (即const int * const)

    现在回答问题,前两个可以编译,因为它们没有指向常量位置。因此,它们也可以在后期修改。

    const int const *p3 = &i1;
    p3 = &i2;  // Wrong
    

    在上面的代码片段中,p3是指向常量位置的常量指针。所以,它无法修改。

    成员函数末尾的

    const表示它不会改变对象的状态。当您说*p = 1;时,您没有更改对象的状态。 p仍然指向相同的内存位置。这是不允许的 -

    int const * Coo2::getP() const   
    {      
         *p = 1;   // State of `p` is still not modified.
         p = new int ; // Error: Changing the memory location to which p points.
                       //        This is what changing the state of object mean and       
                       //        is not allowed because of `const` keyword at the end of function
         return this->p;      
    }
    

    希望,现在你明白为什么程序会编译:)

答案 2 :(得分:4)

int const * p;const int * p是相同的。当const出现在*之后时 表达式的语义改变。

我知道,这很疯狂。

答案 3 :(得分:2)

const int *p = &i1;
int const *p2 = &i1;

这两个都声明了对const数据的非常量指针。

也就是说,使用p,您无法更改它指向的数据。但是,您可以更改指针本身,例如,通过指定合法的p = &i2。但是*p = 87987是非法的,因为p指向的数据是const!

-

int * const p = &i1;

这声明了指向非const数据的const指针。也就是说,p=&i2是非法的,但*p = 98789是合法的。

-

const int * const p = &i1;

这声明了const数据的const指针。也就是说,现在p=&i2*p=87897都是非法的。

答案 4 :(得分:2)

两者完全一样。重要的是限定符相对于星号(*)的位置:

int const *p; // normal pointer to const int
const int *p; // ditto

int *const p; // const pointer to normal int (rarely useful)

int const * const p; // const pointer to const int

答案 5 :(得分:2)

这是一个指向常量的指针:

  const int* p;

以下语句是非法的,因为它试图改变 常量的值:

  *p = 3;

但是这个是合法的,因为指针本身不是一个常量:

  p = &x;

另一方面,这个声明显示了一个指向变量的常量指针。

  int* const p;

在这种情况下,以下语句是合法的,因为变量可以更改:

  *p = 3;

但这个不是,因为它试图改变一个常量的值。

  p = &x;

参考链接:http://faculty.cs.niu.edu/~freedman/241/const-ptrs.txt

答案 6 :(得分:1)

不,*之前的const关键字表示您指向的变量是“const”变量,只有它不能被修改。

  1. 如果您想要一个无法重新分配的指针,那么您需要将其声明为Foo* const p = &bar;
  2. 如果您想要一个指向无法重新分配的“const”对象的指针,请将其声明为const Foo* const p = &bar
  3. const int* foo的指针指定给const int* const bar的指针是完全正常的,就像将int的值分配给{{1}一样好}}。以同样的方式考虑它。

答案 7 :(得分:1)

int const *与const int *

相同

答案 8 :(得分:1)

简洁地;读/写int&amp;的每个组合指针;

int main() {

  int a,b;

  int* w;                       // read/write int, read/write pointer
  w= &b;                        // good
  *w= 1;                        // good

  int* const x = &a;            // read only pointer, read/write int 
  // x = &b;                    // compilation error
  *x = 0;                       // good

  int const * y;                // read/write ptr, read only int 
  const int * y2;               // "    "    "
  y = &a;                       // good
  // *y = 0;                    // compilation error
  y2 = &a;                      // good
  // *y2 = 0;                   // compilation error

  int const * const z = &a;     // read only ptr and read only int 
  const int * const z2 = &b;    // "    "   "   "   
  // *z = 0;                    // compilation error
  // z = &a;                    // compilation error
  // *z2 = 0;                   // compilation error
  // z2 = &a;                   // compilation error

}