2014-10-05 2 views
3

Я учусь о постоянных указателей, и я пытался этоConst ошибка ИНТ указатель

#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 = &a ; с int *const cp = &a ;

Это дает мне эту enter image description here

Простите мое невежество, но они не предполагают, чтобы означать то же самое?

+0

http://c-faq.com/decl/spiral.anderson.html – chris

+1

Лично мне не нравится * спиральный подход к типу чтения, я бы порекомендовал вам поместить 'const' в * right * (правильный) место, которое соответствует * right * (в отличие от * left *) типа 'const', в коде выше:' int const * 'и' int * const'. Затем читайте справа налево. –

+0

@chris: Спиральное правило НЕПРАВИЛЬНО. Слушайте Дэвида Родригеса – kotlomoy

ответ

2

Когда вы делаете int *const cp = &a;, это означает целочисленный указатель на константу cp, поэтому cp не может измениться. Однако в вашей предыдущей версии const int *cp означает постоянный указатель на cp, поэтому значение, в котором точки cp не могут измениться, но сам указатель может.

Обычно люди любят читать это справа налево:

const int *cp ср является указателем на INT константа, поэтому целое число не может измениться.

int *const cp = &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 

Для простого объявления справа налево

1
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 
1

Если это помогает на всех (и про bably нет), следующие синонимы, используя преимущества языка, которые позволяют открывать тип, который имеет вид 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 и * в разных местах декларации:

Single-Косвенность:

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 
0

Это одна из причин, по которым я всегда рекомендую разместить const справа от int не слева. Как и в:

int const *cp; 

и нет:

const int *cp; 

Это имеет то преимущество, что элемент, который сделан const является то, что на правой части const ключевого слова, и его тип находится на левой стороне.

В приведенном выше примере * cp (т. Е. Содержимое cp) является константой, а тип - int. Если вы пишете

int * const cp = &foo; 

и применять те же правила, cp является const и const элемент имеет тип int *. Когда есть несколько уровней косвенности, использование этого правила значительно облегчает понимание происходящего.

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

Это последний из которых является const указатель на изменяемый указатель на const int. И один номер const имеет тип int, а другой - тип int **. Тривиально понять, если вы никогда не ставите слово const слева от int.

Смежные вопросы