qualificateur const pour les pointeurs vers les pointeurs

J’ai un peu de mal à déterminer ce qui est constant, appliqué aux pointeurs, etc. C’est-à-dire ce qui est constant quand vous avez

const Foo **foo; 

Puis-je changer quelque chose dans ** foo? comme dans foo[0]->bar = 12;

Qu’en est-il de:

  const Foo ***foo; Foo **const foo; 

Vous pouvez utiliser cdecl pour comprendre la signification d’une déclaration en C.

 const int **foo; declare foo as pointer to pointer to const int 

ainsi, vous pouvez modifier les pointeurs, mais pas la valeur qu’ils indiquent.

 int * const * const foo; declare foo as const pointer to const pointer to int 

il s’agit plutôt d’un pointeur cosnt, pointant vers un pointeur const, vers un int non const: vous ne pouvez pas modifier la valeur pointée, mais elle peut être modifiée.


C utilise la règle Clockwise / Spiral , dans le cas où vous n’avez que des modificateurs à gauche de la variable (de foo), vous lisez des éléments allant de droite à gauche:

 int(5) *(4) const(3) *(2) const(1) foo; 

foo est un pointeur constant (1) (2) à une constante (3) pointeur (4) à un entier (5).

 int(6) const(5) *(4) const(3) *(2) const(1) foo; const(6) int(5) *(4) const(3) *(2) const(1) foo; // [same as above] 

Dans ce cas, foo est un pointeur constant (1) (2) à constante (3) pointeur (4) sur un entier constant (5) (6) [ou sur un entier (5) qui est constant (6)].

Le const s’applique à l’expression **foo ; ainsi, foo et *foo sont accessibles en écriture, mais **foo ne l’est pas.

Quelques autres exemples:

 const Foo * const *foo; // foo is writable, *foo and **foo are not Foo * const * foo; // foo and **foo are writable, *foo is not Foo * const * const foo; // **foo is writable, foo and *foo are not const Foo * const * const foo; // none of the expressions are writable 

const Foo * * foo (ou Foo const * * foo ) est un pointeur sur un pointeur sur un const Foo.

Foo * const * foo est un pointeur sur un const. Pointeur sur un Foo.

Foo * * const foo est un pointeur const sur un pointeur sur Foo.

Je pense que la meilleure façon d’écrire de telles expressions de type est d’appliquer toujours le const à gauche. Celui que vous avez donné peut aussi être écrit:

 Foo const**foo; 

Ici le const ne s’applique qu’à ce qui rest, donc Foo .

 Foo *const* foo; 

Ici à gauche est Foo*

 Foo const*const* foo; 

est alors ((Foo const)*const)* .

Lorsque vous souhaitez à son tour lire une telle expression, échangez le type const et le type nu si nécessaire pour que le const à droite.

Dans const Foo **foo , c’est l’object Foo réel qui est const. Vous pouvez donc changer foo , et *foo , mais vous ne pouvez pas changer **foo .

Pour const Foo ***foo , vous pouvez changer foo , *foo et **foo , mais pas ***foo .

Pour Foo **const foo , vous pouvez changer *foo et **foo , mais pas foo lui-même.

Lire les types de l’intérieur. À partir de foo , const Foo **foo; lit * (pointeur) sur un * (pointeur) sur const Foo (un object Foo que vous n’êtes pas autorisé à modifier). Foo **const foo; lit const (non modifiable) * (pointeur) sur * (pointeur) sur Foo (un object Foo).