Ce qu'est une variable
Une variable est une zone de mémoire nommée qui contient une valeur. En C++, chaque variable possède un type fixe - choisi lors de sa déclaration - et ce type ne change jamais. C'est ce qui rend C++ à typage statique : le compilateur connaît le type de chaque variable avant l'exécution du programme et refuse de compiler du code qui stocke une valeur du mauvais type.
Une déclaration comporte trois parties : le type, le nom et (presque toujours) une valeur initiale.
Lisez int age = 30; comme « crée un int appelé age et mets-y 30 ». Le point-virgule termine l'instruction, exactement comme la page sur les commentaires l'a montré pour chaque instruction. Remarquez que isActive s'est affiché 1 : un bool apparaît par défaut sous la forme 1/0, ce sur quoi s'appuie la page sur les types de données.
Initialisation vs. affectation
Ces deux notions se ressemblent mais sont des opérations différentes, et cette différence est l'une des idées les plus importantes de cette page.
L'initialisation donne à une variable sa première valeur dans le cadre de la déclaration. L'affectation modifie la valeur d'une variable qui existe déjà.
Vous pouvez déclarer sans initialiser puis affecter plus tard, mais soyez prudent :
Cela fonctionne parce que nous avons affecté score avant de le lire. La version dangereuse consiste à le lire d'abord - abordée juste après.
Le piège de la variable non initialisée
C'est le piège classique de C++ qui n'existe pas dans beaucoup d'autres langages. Lire une variable locale qui a été déclarée mais à laquelle on n'a jamais donné de valeur est un comportement indéfini : la variable contient les octets qui se trouvaient par hasard à cet emplacement mémoire.
int score; // non initialisée
std::cout << score; // comportement indéfini - affiche des données poubelles, ou « fonctionne », ou plante
Le compilateur construira cela sans broncher. Il peut afficher 0, il peut afficher 32766, et il peut se comporter différemment à chaque exécution ou sur chaque machine - ce qui rend ces bogues atroces à traquer. Deux parades :
- Initialisez toujours à la déclaration.
int score = 0;ne coûte rien et supprime tout le problème. - Activez les avertissements. Compiler avec
-Wall -Wextraamène le compilateur à signaler de nombreuses lectures non initialisées avant qu'elles ne vous mordent.
Préférez la première option pour chaque variable locale : donnez-lui une valeur de départ raisonnable au moment même où vous la créez.
Styles d'initialisation : =, () et {}
C++ propose plusieurs façons d'écrire une valeur initiale. Elles font pour la plupart la même chose, mais l'initialisation par accolades possède une sécurité supplémentaire qui mérite d'être connue.
La raison de recourir à {} est qu'elle rejette les conversions avec rétrécissement (narrowing) : les affectations qui perdraient silencieusement des données. Avec =, une valeur fractionnaire est tronquée sans bruit ; avec {}, le compilateur vous arrête :
int x = 3.9; // compile - x devient silencieusement 3 (le .9 est jeté)
int y{3.9}; // erreur de compilation - le rétrécissement de double vers int n'est pas autorisé
Détecter cela à la compilation est exactement ce que vous voulez. Une habitude moderne courante consiste à utiliser {} par défaut pour cette vérification supplémentaire, et à se rabattre sur = uniquement lorsque l'initialisation par copie se lit plus naturellement.
Règles et conventions de nommage
C++ impose quelques règles strictes, puis chacun ajoute des conventions par-dessus. Les règles : un nom peut contenir des lettres, des chiffres et _ ; il ne peut pas commencer par un chiffre ; il ne peut pas être un mot-clé réservé (comme int ou return) ; et il est sensible à la casse (age et Age sont deux variables différentes). Évitez les noms qui commencent par un underscore suivi d'une majuscule, ou qui contiennent deux underscores à la suite : ils sont réservés à l'implémentation.
Les conventions que suit la plupart du code C++ :
- Les variables utilisent
snake_caseoucamelCase- choisissez-en une et restez cohérent :item_countouitemCount. - Les noms doivent décrire la valeur :
count, pasc;user_email, pasx.
Des noms clairs ne sont pas de la décoration : c'est ainsi que votre futur vous relira le code. total_price = item_count * price_per_item se comprend tout seul d'une manière que t = c * p n'atteindra jamais.
Portée des variables
Une variable n'existe qu'à l'intérieur du bloc - les { ... } - où elle est déclarée, et elle est détruite à l'accolade fermante. C'est sa portée (scope). Une variable déclarée dans une boucle ou un bloc if est invisible en dehors :
i et square appartiennent tous deux à la boucle et disparaissent à sa fin ; total est déclaré dans le bloc extérieur, donc il survit. Un bloc interne peut aussi masquer (shadow) un nom d'un bloc externe : une nouvelle variable du même nom cache temporairement l'externe jusqu'à la fermeture du bloc interne, ce qui est une source fréquente de confusion ; évitez donc de réutiliser des noms entre portées imbriquées.
L'enseignement pratique : déclarez chaque variable dans le plus petit bloc qui en a besoin, et initialisez-la là. Une portée étroite signifie moins de noms qui se disputent votre attention et moins de risques de lire une valeur loin de l'endroit où elle a été définie.
Ensuite : Les types de données
Chaque variable de cette page a commencé par un type - int, double, string, bool. La page suivante détaille les types de données de C++ : les types fondamentaux et leurs tailles, les entiers signés et non signés, float vs. double, char, et comment choisir le bon type pour la tâche.
Questions fréquentes
Comment déclare-t-on une variable en C++ ?
Écrivez le type, puis un nom, et donnez-lui éventuellement une valeur : int age = 30;. Le type (int) est fixé pour toute la durée de vie de la variable ; le nom (age) est la façon dont vous y faites référence. Vous pouvez déclarer sans valeur - int age; -, mais pour une variable locale cela la laisse avec des données poubelles jusqu'à ce que vous lui en affectiez une ; initialisez-la donc toujours au point de déclaration.
Quelle est la différence entre initialisation et affectation en C++ ?
L'initialisation donne à une variable sa première valeur dans le cadre de sa déclaration : int x = 5; ou int x{5};. L'affectation modifie la valeur d'une variable qui existe déjà : x = 7;. La distinction compte, car lire une variable locale qui a été déclarée mais jamais initialisée est un comportement indéfini.
Que se passe-t-il si vous utilisez une variable non initialisée en C++ ?
Lire la valeur d'une variable locale non initialisée est un comportement indéfini : la variable contient les octets qui se trouvaient déjà à cet emplacement mémoire, donc votre programme peut afficher un nombre aléatoire, fonctionner par chance ou planter. Le compilateur ne vous arrêtera pas (même si beaucoup avertissent avec -Wall) ; la solution est donc de toujours donner une valeur aux variables locales au moment de leur déclaration.