Question rapide:
int testfunc1 (const int a)
{
return a;
}
int testfunc2 (int const a)
{
return a;
}
Ces deux fonctions sont-elles les mêmes dans tous les aspects ou y a-t-il une différence? Je voudrais une réponse pour le langage C, mais s'il y a quelque chose d'intéressant dans le langage C++, j'aimerais le savoir aussi.
const T
et T const
sont identiques. Avec les types de pointeur, cela devient plus compliqué:
const char*
est un pointeur sur une constante char
char const*
est un pointeur sur une constante char
char* const
est un pointeur constant sur un (mutable) char
En d'autres termes, (1) et (2) sont identiques. Le seul moyen de créer le pointeur (plutôt que la pointee) const
consiste à utiliser un suffixe -const
.
C’est la raison pour laquelle beaucoup de gens préfèrent toujours mettre const
à droite du type (style "East const"): son emplacement par rapport au type est cohérent et facile à mémoriser (cela semble également rendre anecdotique il est plus facile d’enseigner aux débutants).
L'astuce consiste à lire la déclaration à l'envers (de droite à gauche):
const int a = 1; // read as "a is an integer which is constant"
int const a = 1; // read as "a is a constant integer"
Les deux sont la même chose. Par conséquent:
a = 2; // Can't do because a is constant
La lecture en arrière est particulièrement utile lorsque vous traitez avec des déclarations plus complexes telles que:
const char *s; // read as "s is a pointer to a char that is constant"
char c;
char *const t = &c; // read as "t is a constant pointer to a char"
*s = 'A'; // Can't do because the char is constant
s++; // Can do because the pointer isn't constant
*t = 'A'; // Can do because the char isn't constant
t++; // Can't do because the pointer is constant
Il n'y a pas de différence. Ils déclarent tous les deux que "a" est un entier ne pouvant pas être modifié.
Les différences commencent à apparaître lorsque vous utilisez des pointeurs.
Ces deux:
const int *a
int const *a
déclarer "a" pour être un pointeur sur un entier qui ne change pas. "a" peut être assigné à, mais "* a" ne le peut pas.
int * const a
déclare que "a" est un pointeur constant sur un entier. "* a" peut être attribué à, mais "a" ne peut pas.
const int * const a
déclare que "a" est un pointeur constant sur un entier constant. Ni "a" ni "* a" ne peuvent être attribués.
static int one = 1;
int testfunc3 (const int *a)
{
*a = 1; /* Error */
a = &one;
return *a;
}
int testfunc4 (int * const a)
{
*a = 1;
a = &one; /* Error */
return *a;
}
int testfunc5 (const int * const a)
{
*a = 1; /* Error */
a = &one; /* Error */
return *a;
}
Prakash a raison de dire que les déclarations sont les mêmes, bien qu'une explication un peu plus détaillée du cas du pointeur puisse être utile.
"const int * p" est un pointeur sur un int qui n'autorise pas sa modification via ce pointeur. "int * const p" est un pointeur sur un int qui ne peut pas être changé pour pointer sur un autre int.
Voir http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.5 .
const int
est identique à int const
, comme tous les types scalaires de C. En général, il n'est pas nécessaire de déclarer un paramètre de fonction scalaire sous la forme const
, car la sémantique de C-call-value signifie que les modifications apportées à la variable sont locales. sa fonction englobante.
Ce sont les mêmes, mais en C++, il y a une bonne raison de toujours utiliser const à droite. Vous serez cohérent partout car les fonctions membres const doivent être déclarées de cette façon:
int getInt() const;
Cela change le pointeur this
dans la fonction de Foo * const
à Foo const * const
. Voir ici.
Ce n'est pas une réponse directe, mais un conseil connexe. Pour garder les choses droites, j'utilise toujours la convection "put const
à l'extérieur", où par "à l'extérieur" j'entends l'extrême gauche ou l'extrême droite. De cette façon, il n’ya pas de confusion - le const s’applique à la chose la plus proche (soit le type, soit le *
). Par exemple.,
int * const foo = ...; // Pointer cannot change, pointed to value can change
const int * bar = ...; // Pointer can change, pointed to value cannot change
int * baz = ...; // Pointer can change, pointed to value can change
const int * const qux = ...; // Pointer cannot change, pointed to value cannot change
Oui, ils sont identiques pour seulement int
et différent pour int*
Je pense que dans ce cas, ils sont les mêmes, mais voici un exemple où l'ordre est important:
const int* cantChangeTheData;
int* const cantChangeTheAddress;