à propos de “int const * p” et “const int * p”

#include  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; } 

Le code peut être compilé avec VC6.0 et VC2010. Mais j’ai des questions comme coup:

const int * p = & i1;

Cela signifie que les points “p” ne peuvent pas être modifiés, mais que p ne peut pas être modifié, n’est-ce pas? alors

p = & i2;

cette ligne peut être respectée, oui?

Cette ligne:

 int const *p2 = &i1; 

Dans mon esprit, cela signifie que p2 ne peut pas être modifié alors que quels points p2 peuvent être modifiés, ai-je raison? Pourquoi le

p2 = & i2;

peut être compilé?

A propos de cette ligne:

const int const * p3 = & i1;

p3 = & i2;

Oh, mon dieu … je suis fou. Je n’ai aucune idée pourquoi cette ligne peut être compilée sans erreur … Tout organisme peut-il m’aider?

Un autre code qui m’a confondu est ici:

 class Coo2 { public: Coo2() : p(new int(0)) {} ~Coo2() {delete p;} int const * getP() const { *p = 1; return this->p; } private: int* p; }; 

pourquoi ce code peut être compilé? Dans

int const * getP () const

J’ai changer la valeur ou * p!

Avec l’aide du pointeur, vous pouvez réellement faire deux choses.

  1. Vous pouvez modifier les données pointées, mais ne pouvez pas pointer vers un autre emplacement de mémoire.
  2. Vous pouvez le diriger vers un emplacement de mémoire différent, mais vous ne pouvez pas modifier les données pointées.

Maintenant, quand vous dites, int const * ptr ou int const * ptr, il entre dans la première catégorie. C’est pareil que –

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

Pour que vous ne puissiez pas réellement changer d’emplacement, c’est-à-dire que vous pointiez sur un emplacement constant mais que vous puissiez modifier les données, la sémantique devrait être int* const . Puisque le contenu du pointeur est une constante, il devrait être initialisé pendant la déclaration.

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

Cependant, il existe un troisième type. Pointeur constant sur un emplacement constant, qui ne peut ni pointer vers un autre emplacement de mémoire ni modifier les données pointées. (c’est-à-dire, const int * const)

Et maintenant, pour répondre aux questions , les deux premières peuvent être compilées car elles ne désignent pas des emplacements constants. Ils peuvent donc être modifiés ultérieurement.

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

Dans l’extrait de p3 ci-dessus, p3 est un pointeur constant sur un emplacement constant. Donc, il ne peut pas être modifié.

const à la fin d’une fonction membre dit qu’il ne va pas changer l’état de l’object. Quand vous dites *p = 1; , vous ne modifiez pas l’état de l’object. p pointe toujours sur le même emplacement mémoire. Ce n’est pas autorisé à faire –

 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; } 

J’espère que maintenant vous comprenez pourquoi le programme comstack 🙂

Nous considérons ici 4 types de déclarations de pointeurs:

  1. int * w; Cela signifie que w est un pointeur sur une valeur de type entier. Nous pouvons modifier le pointeur et son contenu. Si nous initialisons la déclaration w tant que ci-dessous: int * w = &a;
    Ensuite, les deux opérations ci-dessous sont viables:
    w = &b; (vrai)
    *w = 1; (vrai)

  2. int * const x;
    Cela signifie que x est un pointeur constant qui pointe vers une valeur de type entier. Si nous initialisons la déclaration x while comme ci-dessous:
    int * const x = &a;
    Ensuite, nous ne pouvons pas faire: x = &b;(wrong) car x est un pointeur constant et ne peut pas être modifié.
    Cependant, il est possible de faire: *x = 1;(true) , car le contenu de x n’est pas constant.

  3. int const * y; // les deux signifient la même chose
    const int * y;
    Cela signifie que y est un pointeur qui pointe vers une valeur entière constante. Si nous initialisons la déclaration y while comme ci-dessous:
    int const * y = &a;
    Ensuite, il est possible de faire: y=&b;(true) car y est un pointeur non constant pouvant pointer n’importe où.
    Cependant, nous ne pouvons pas faire: *y=1;(wrong) car la variable pointée vers y est une variable constante et ne peut pas être modifiée.

  4. int const * const z; // les deux signifient la même chose
    const int * const z;
    Cela signifie que z est un pointeur constant qui pointe vers une valeur entière constante. Si nous initialisons z en tant que déclaration comme ci-dessous:
    int const * const z = &a;
    Par conséquent, les opérations non en aval sont viables:
    z = &b;(wrong)
    *z = 1;(wrong)

int const * p; et const int * p sont les mêmes. C’est lorsque le const vient après le * que la sémantique de l’expression change.

Je sais, c’est fou.

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

Ces deux déclarent des pointeurs non const à des données const.

C’est-à-dire qu’en utilisant p , vous ne pouvez pas modifier les données sur lesquelles il pointe. Toutefois, vous pouvez modifier le pointeur lui-même, par exemple, en atsortingbuant à p = &i2 légale. Mais *p = 87987 est illégal, car les données *p = 87987 par p sont const!

 int * const p = &i1; 

Ceci déclare le pointeur const sur des données non constantes. Autrement dit, p=&i2 est illégal, mais *p = 98789 est légal.

 const int * const p = &i1; 

Ceci déclare le pointeur const aux données const. C’est-à-dire que p=&i2 et *p=87897 sont *p=87897 illégaux.

Les deux sont exactement les mêmes. Ce qui compte, c’est la position du qualificatif par rapport à l’astérisque ( * ):

 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 

Non, le mot-clé const précédant le * signifie que la variable à laquelle vous faites référence est une variable “const” et qu’elle ne peut pas être modifiée.

  1. Si vous voulez un pointeur qui ne peut pas être réaffecté, vous devez le déclarer comme Foo* const p = &bar;
  2. Si vous voulez un pointeur qui pointe sur un object “const” qui ne peut pas être réaffecté, déclarez-le en tant que const Foo* const p = &bar

Il est parfaitement correct d’avoir un pointeur de const int* foo assigné à un pointeur de const int* const bar tout comme il est bien d’avoir la valeur d’un const int assignée à un const int . Pensez-y de la même manière.

int const * est identique à const int *

Succinctement; chaque combinaison de lecture / écriture 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 }