Ce qu'il faut retenir, c'est que const
et "constante" signifient deux choses bien différentes.
El const
signifie en réalité "lecture seule". A constant est un littéral numérique, tel que 42
o 1.5
(ou une énumération ou une constante de caractère). A expression constante est un type particulier d'expression qui peut être évalué au moment de la compilation, tel que 2 + 2
.
Ainsi, une déclaration a été faite :
const int n = 5;
l'expression n
fait référence à la valeur de la objet et elle n'est pas traitée comme une expression constante. Un compilateur typique optimisera une référence à n
en le remplaçant par le même code qu'il utiliserait pour un littéral 5
mais ce n'est pas obligatoire - et les règles pour savoir si une expression est constant sont déterminées par le langage, et non par l'ingéniosité du compilateur actuel.
Un exemple de la différence entre const
(en lecture seule) et constant (évalué au moment de la compilation) est :
const size_t now = time(NULL);
El const
signifie que vous n'êtes pas autorisé à modifier la valeur de l'élément now
après son initialisation, mais la valeur de time(NULL)
ne peuvent clairement pas être calculés avant le moment de l'exécution.
Alors ça :
const int n = 5;
int x[n];
n'est pas plus valable en C qu'elle ne le serait sans l'élément const
mot-clé.
La langue pourrait (et IMHO probablement devrait) évaluer n
comme une expression constante ; elle n'est simplement pas définie de cette façon. (Le C++ a une telle règle ; voir la norme C++ ou une référence décente pour les détails sanglants).
Si vous voulez une constante nommée avec la valeur 5
La méthode la plus courante consiste à définir une macro :
#define N 5
int x[N];
Une autre approche consiste à définir une constante d'énumération :
enum { n = 5 };
int x[n];
Les constantes d'énumération sont des expressions constantes, et sont toujours de type int
(ce qui signifie que cette méthode ne fonctionnera pas pour les types autres que int
). Et on peut dire que c'est un abus de l'autorité de la enum
mécanisme.
À partir de la norme 1999, un tableau peut être défini avec une taille non constante ; c'est un VLA, ou tableau à longueur variable. Ces tableaux ne sont autorisés qu'à l'échelle du bloc et ne peuvent pas avoir d'initialisateur (puisque le compilateur n'est pas en mesure de vérifier que l'initialisateur a le nombre correct d'éléments).
Mais étant donné votre code original :
const int n = 5;
int x[n] = { 1,1,3,4,5 };
vous pouvez laisser le compilateur déduire la longueur à partir de l'initialisateur :
int x[] = { 1,1,3,4,5 };
Et vous pouvez alors calculer la longueur à partir de la taille du tableau :
const int x_len = sizeof x / sizeof x[0];