web-dev-qa-db-fra.com

const char * et char const * - sont-ils les mêmes?

De ma compréhension, les modificateurs const devraient être lus de droite à gauche. J'en déduis que:

const char*

est un pointeur dont les éléments char ne peuvent pas être modifiés, mais le pointeur lui-même peut, et

char const*

est un pointeur constant sur mutable chars.

Mais j'obtiens les erreurs suivantes pour le code suivant:

const char* x = new char[20];
x = new char[30];   //this works, as expected
x[0] = 'a';         //gives an error as expected

char const* y = new char[20];
y = new char[20];   //this works, although the pointer should be const (right?)
y[0] = 'a';         //this doesn't although I expect it to work

C'est lequel alors? Est-ce que ma compréhension ou mon compilateur (VS 2005) est faux?

78
Luchian Grigore

En fait, selon la norme, const modifie l'élément directement en sa gauche . L’utilisation de const au début d’une déclaration n’est qu’un raccourci mental pratique. Donc, les deux déclarations suivantes sont équivalentes:

char const * pointerToConstantContent1;
const char * pointerToConstantContent2;

Afin de s'assurer que le pointeur lui-même n'est pas modifié, const doit être placé après l'astérisque:

char * const constantPointerToMutableContent;

Pour protéger à la fois le pointeur et le contenu sur lequel il pointe, utilisez deux const.

char const * const constantPointerToConstantContent;

J'ai personnellement adopté toujours mettre le const après la partie que je ne souhaite pas modifier de sorte que je maintienne la cohérence même lorsque le pointeur est la partie que je souhaite garder constante.

126
Greyson

Cela fonctionne parce que les deux sont identiques. Peut-être que vous êtes confus en cela,

const char*  // both are same
char const*

et

char* const  // unmutable pointer to "char"

et

const char* const  // unmutable pointer to "const char"

[Pour s'en souvenir, voici une règle simple, '*' affecte tout son LHS en premier ]

29
iammilind

C'est parce que la règle est la suivante:

RÈGLE: const lie à gauche, à moins qu'il n'y ait rien à gauche, alors il se lie à droite :)

alors, regardez ces comme:

(const --->> char)*
(char <<--- const)*

les deux mêmes! oh, et --->> et <<--- ne sont PAS des opérateurs, ils montrent simplement à quoi la const se lie.

24
Akanksh

(de 2 question d'initialisation de variable simple )

Une très bonne règle de base concernant const

Déclarations de lecture de droite à gauche.

(voir Vandevoorde/Josutiss "Modèles C++: le guide complet")

Par exemple.: 

int const x; // x is a constant int
const int x; // x is an int which is const

// easy. the rule becomes really useful in the following:
int const * const p; // p is const-pointer to const-int
int const &p;        // p is a reference to const-int
int * const * p;     // p is a pointer to const-pointer to int.

Depuis que je suis cette règle empirique, je n'ai plus jamais mal interprété de telles déclarations.

(: sisab retcarahc-rep a ton ton

11
Sebastian Mach

Voici comment j'essaie toujours d'interpréter:

char *p

     |_____ start from the asterisk. The above declaration is read as: "content of `p` is a `char`".

char * const p

     |_____ again start from the asterisk. "content of constant (since we have the `const` 
            modifier in the front) `p` is a `char`".

char const *p

           |_____ again start from the asterisk. "content of `p` is a constant `char`".

J'espère que ça aide!

5
yasouser

Dans les deux cas, vous indiquez un caractère constant.

const char * x  //(1) a variable pointer to a constant char
char const * x  //(2) a variable pointer to a constant char
char * const x  //(3) a constant pointer to a variable char
char const * const x //(4) a constant pointer to a constant char
char const * const * x //(5) a variable pointer to a constant pointer to a constant char
char const * const * const x //(6) can you guess this one?

Par défaut, const s'applique à ce qui est immédiatement à gauche, mais peut s'appliquer à ce qui est immédiatement à sa droite si rien ne le précède, comme dans (1).

0
Lino Mediavilla