web-dev-qa-db-fra.com

const int vs int const comme paramètre de fonction en C ++ et C

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.

109
Nils Pipenbrinck

const T et T const sont identiques. Avec les types de pointeur, cela devient plus compliqué:

  1. const char* est un pointeur sur une constante char
  2. char const* est un pointeur sur une constante char
  3. 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).

168
Konrad Rudolph

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
323
Ates Goral

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;
}
13
Andru Luvisi

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 .

7
Fred Larson

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.

5
Emerick Rogul

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.

4
Nick Westgate

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
4
Pat Notz

Oui, ils sont identiques pour seulement int

et différent pour int*

3
prakash

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;
3
user7545