о "int const *p" и " const int *p "
#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 = & i1;
это означает, что точки " p " не могут быть изменены,но p не может быть изменен,я прав? так что
p = &i2;
эту строку можно выполнить, да?
эта строка:
int const *p2 = &i1;
на мой взгляд, это означает, что p2 не может быть изменен, а какие точки p2 могут быть изменился, верно? Почему
p2 = &i2;
можно скомпилировать?
об этом строки:
const int const *p3 = & i1;
p3 = &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 !
8 ответов
С помощью указателя, вы можете сделать две вещи.
- вы можете изменить данные, которые он указывает, но не может указывать на другую область памяти.
- вы можете указать его в другое место памяти, но не можете изменить данные, на которые он указывает.
теперь, когда вы говорите, int const * ptr или int const * ptr, он подпадает под первую категорию. Это то же самое, что ... --10-->
const int num = 5; // Both mean the same.
int const num = 5;
To, на самом деле не в состоянии изменить на другое местоположение, т. е. указатель на постоянное местоположение, но иметь возможность изменять данные, семантика должна быть int* const
. Поскольку содержимое указателя является константой, его следует инициализировать во время объявления.
int num = 5;
int* const ptr; // Wrong
ptr = # // Wrong
int* const ptr = #
*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;
}
надеюсь, теперь вы понимаете, почему программа компилируется :)
здесь мы рассмотрим 4 типа указателей объявления:
int * w;
Это означает, что w является указателем на значение целочисленного типа. Мы можем изменить как указатель, так и его содержимое. Если мы инициализируем Вт при объявлении, как показано ниже:int * w = &a;
Тогда обе операции ниже жизнеспособны:w = &b;
(true)*w = 1;
(правда)int * const x;
Это означает, что x-это постоянный указатель, указывающий на значение целочисленного типа. Если мы инициализируйте X при объявлении, как показано ниже:int * const x = &a;
Тогда мы не можем сделать:x = &b;(wrong)
потому что x является постоянным указателем и не может быть изменен.
Тем не менее, это можно сделать:*x = 1;(true)
, потому что содержание x не является постоянным.int const * y;
//оба означают одно и то жеconst int * y;
Это означает, что y-указатель, указывающий на постоянное целое значение. Если мы инициализируем y во время объявления, как показано ниже:int const * y = &a;
Тогда это можно сделать:y=&b;(true)
потому что y-это непостоянный указатель, который может указывать в любом месте.
Однако, мы не можем сделать:*y=1;(wrong)
потому что переменная, на которую указывает y, является постоянной переменной и не может быть изменена.int const * const z;
//оба означают одно и то жеconst int * const z;
Это означает, что Z является постоянный указатель на постоянное целое значение. Если мы инициализируем Z при объявлении, как показано ниже:int const * const z = &a;
Таким образом, не ниже операций жизнеспособны:z = &b;(wrong)
*z = 1;(wrong)
int const * p;
и const int * p
то же самое. Это когда const
после *
что
семантика выражения меняется.
Я знаю, это безумие.
const int *p = &i1;
int const *p2 = &i1;
эти оба заявляют, что не константный указатель на константные данные.
то есть, используя p
, вы не можете изменить данные, которые он указывает. Однако вы можете изменить сам указатель, например, назначив as p = &i2
, которое является законным. Но!--5--> является незаконным, так как данные p
указывает на const!
--
int * const p = &i1;
это объявляет константный указатель на неконстантные данные. То есть, p=&i2
незаконно, но *p = 98789
is законный.
--
const int * const p = &i1;
это объявляет указатель const на данные const. То есть теперь оба!--7--> и *p=87897
являются незаконными.
эти два точно такие же. Имеет значение положение классификатора относительно звездочки (*
):
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
нет,const
ключевое слово перед * означает, что переменная, на которую вы указываете, является переменной "const", и только она не может быть изменена.
- если вы хотите указатель, который не может быть переназначен, то вам нужно объявить его как
Foo* const p = &bar;
- если вы хотите указатель, который указывает на объект" const", который не может быть переназначен, объявите его как
const Foo* const p = &bar
совершенно нормально иметь указатель const int* foo
присваивается указателю const int* const bar
так же, как хорошо иметь int
's значение, присвоенное const int
. Думайте об этом так же.
кратко; каждая комбинация чтения / записи int & pointer;
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
}