Question Quelle est la différence entre const int *, const int * const et int const *?


Je gâche toujours comment utiliser const int*, const int * const, et int const * correctement. Existe-t-il un ensemble de règles définissant ce que vous pouvez et ne pouvez pas faire?

Je veux connaître toutes les choses à faire et à ne pas faire en termes d'affectations, de passage aux fonctions, etc.


992
2017-07-17 13:28


origine


Réponses:


Lire à l'envers (comme conduit par Règle dans le sens horaire / en spirale):

  • int* - pointeur vers int
  • int const * - pointeur vers const int
  • int * const - pointeur const vers int
  • int const * const - pointeur const vers const int

Maintenant le premier const peut être de chaque côté du type:

  • const int * == int const *
  • const int * const == int const * const

Si vous voulez vraiment devenir fou, vous pouvez faire des choses comme ça:

  • int ** - pointeur vers le pointeur vers int
  • int ** const - un pointeur const vers un pointeur vers un int
  • int * const * - un pointeur vers un pointeur const vers un int
  • int const ** - un pointeur vers un pointeur vers un const int
  • int * const * const - un pointeur const vers un pointeur const vers un int
  • ...

Et pour s'assurer que nous sommes clair sur la signification de const

const int* foo;
int *const bar; //note, you actually need to set the pointer 
                //here because you can't change it later ;)

foo est un pointeur variable vers un entier constant. Cela vous permet de changer ce que vous pointez mais pas la valeur que vous pointez. Le plus souvent cela est vu avec des chaînes de style C où vous avez un pointeur vers un const char. Vous pouvez changer la chaîne que vous pointez mais vous ne pouvez pas changer le contenu de ces chaînes. Ceci est important lorsque la chaîne se trouve dans le segment de données d'un programme et ne doit pas être modifiée.

bar est un pointeur fixe ou fixe vers une valeur qui peut être modifiée. C'est comme une référence sans le sucre syntaxique supplémentaire. En raison de ce fait, habituellement vous utiliseriez une référence où vous utiliseriez un T* const pointeur sauf si vous devez autoriser NULL pointeurs.


1740
2017-07-17 13:29



Pour ceux qui ne connaissent pas la règle dans le sens des aiguilles d'une montre Commencez par le nom de la variable, déplacez-vous dans le sens des aiguilles d'une montre (dans ce cas, reculez) jusqu'à la prochaine aiguille ou type. Répétez jusqu'à ce que l'expression se termine.

voici une démo:

pointer to int

const pointer to int const

pointer to int const

pointer to const int

const pointer to int


232
2017-07-10 02:15



Je pense que tout est déjà répondu ici, mais je veux juste ajouter que vous devriez vous méfier de typedefs! Ils ne sont pas seulement des remplacements de texte.

Par exemple:

typedef char *ASTRING;
const ASTRING astring;

Le type de astring est char * const, ne pas const char *. C'est une raison que j'ai toujours tendance à mettre const à droite du type, et jamais au début.


123
2017-07-17 13:39



Comme à peu près tout le monde a souligné:

Quelle est la différence entre const X* p, X* const p et const X* const p?

Vous devez lire les déclarations de pointeur   de droite à gauche.

  • const X* p signifie "p pointe sur un X qui est const": l'objet X ne peut pas être modifié via p.

  • X* const p signifie que "p est un pointeur const vers un X qui n'est pas const": vous ne pouvez pas changer le pointeur p lui-même, mais vous pouvez changer l'objet X via p.

  • const X* const p signifie "p est un pointeur const sur un X qui est const": vous ne pouvez pas changer le pointeur p lui-même, ni changer l'objet X via p.


44
2017-07-17 13:36



  1. Référence constante:

    Une référence à une variable (ici int), qui est constante. Nous passons la variable comme référence principalement, parce que les références sont de taille plus petite que la valeur réelle, mais il y a un effet secondaire et c'est parce que c'est comme un alias à la variable réelle. Nous pouvons accidentellement changer la variable principale grâce à notre accès complet à l'alias, donc nous le rendons constant pour éviter cet effet secondaire.

    int var0 = 0;
    const int &ptr1 = var0;
    ptr1 = 8; // Error
    var0 = 6; // OK
    
  2. Les pointeurs constants

    Une fois qu'un pointeur constant pointe vers une variable, il ne peut pointer vers aucune autre variable.

    int var1 = 1;
    int var2 = 0;
    
    int *const ptr2 = &var1;
    ptr2 = &var2; // Error
    
  3. Pointeur à constante

    Un pointeur à travers lequel on ne peut pas changer la valeur d'une variable pointée est connu sous le nom de pointeur vers la constante.

    int const * ptr3 = &var2;
    *ptr3 = 4; // Error
    
  4. Pointeur constant vers une constante

    Un pointeur constant vers une constante est un pointeur qui ne peut ni changer l'adresse vers laquelle il pointe, ni changer la valeur conservée à cette adresse.

    int var3 = 0;
    int var4 = 0;
    const int * const ptr4 = &var3;
    *ptr4 = 1;     // Error
     ptr4 = &var4; // Error
    

39
2018-05-17 20:21



Cette question montre précisément pourquoi j'aime faire les choses comme je l'ai mentionné dans ma question est const après le type id acceptable?

Bref, je trouve que la façon la plus simple de se souvenir de la règle est que le "const" va après la chose à laquelle il s'applique. Donc dans votre question, "int const *" signifie que int est constant, alors que "int * const" signifierait que le pointeur est constant.

Si quelqu'un décide de le mettre à l'avant même (par exemple: "const int *"), comme une exception spéciale dans ce cas, il s'applique à la chose après.

Beaucoup de gens aiment utiliser cette exception spéciale parce qu'ils pensent que c'est plus joli. Je ne l'aime pas, parce que c'est une exception, et donc confond les choses.


15
2017-07-17 13:52



La règle générale est que const mot-clé s'applique à ce qui le précède immédiatement. Exception, un départ const s'applique à ce qui suit.

  • const int* est le même que int const* et des moyens "pointeur vers constant int".
  • const int* const est le même que int const* const et des moyens "pointeur constant vers constant int".

Modifier: Pour les choses à faire et à ne pas faire, si cette réponse ne suffit pas, pourriez-vous être plus précis sur ce que vous voulez?


14
2017-07-17 13:30



Utilisation simple de 'const'

L'utilisation la plus simple consiste à déclarer une constante nommée. Pour ce faire, on déclare une constante comme si c'était une variable mais on ajoute 'const' avant elle. On doit l'initialiser immédiatement dans le constructeur car, bien sûr, on ne peut pas définir la valeur plus tard car cela la modifierait. Par exemple,

const int Constant1=96; 

va créer une constante entière, dénuée d'imagination 'Constant1', avec la valeur 96.

Ces constantes sont utiles pour les paramètres qui sont utilisés dans le programme mais n'ont pas besoin d'être modifiés après la compilation du programme. Il a un avantage pour les programmeurs sur la commande '#define' du préprocesseur C en ce qu'il est compris et utilisé par le compilateur lui-même, non seulement substitué dans le programme par le préprocesseur avant d'atteindre le compilateur principal, donc les messages d'erreur sont beaucoup plus utiles .

Il fonctionne également avec des pointeurs, mais il faut faire attention où 'const' pour déterminer si le pointeur ou ce qu'il pointe est constant ou les deux. Par exemple,

const int * Constant2 

déclare que Constant2 est un pointeur variable vers un entier constant et

int const * Constant2

est une syntaxe alternative qui fait la même chose, alors que

int * const Constant3

déclare que Constant3 est pointeur constant vers un entier variable et

int const * const Constant4

déclare que Constant4 est un pointeur constant vers un entier constant. Fondamentalement, 'const' s'applique à tout ce qui est sur sa gauche immédiate (autre que s'il n'y a rien, auquel cas il s'applique à ce qui est son droit immédiat).

ref: http://duramecho.com/ComputerInformation/WhyHowCppConst.html


12
2017-07-17 13:31