Variables statiques et dynamiques

Revenons aux variables. En premier lieu, on distingue les variables statiques et les variables dynamiques. Les premières existent aussi longtemps que le programme, et sont initialisées (éventuellement) en même temps que lui. Les secondes sont créées (et initialisées éventuellement) à un certain moment dans le programme, puis détruites ultérieurement ; ce processus peut se produire plusieurs fois pour une même variable.

Il existe trois sortes de variables statiques. Les variables globales sont déclarées en dehors de toute fonction, souvent au début du fichier. Dans le schéma de programme ci-après, c’est le cas des variables glob1 et glob2. Ces variables sont automatiquement initialisées, même si aucune initialisation n’est explicitée par le programmeur : dans ce cas, elles sont mises à zéro (c’est ce qui arrive à glob1 dans notre exemple, et glob2 prend évidemment la valeur indiquée 10).

Ces variables globales sont visibles (c’est-à-dire utilisables) de toutes les fonctions qui les suivent dans le fichier, comme des fonctions f et g dans notre exemple. Il en résulte parfois des effets pervers si l’on utilise n’importe quoi comme variable globale, car une fonction peut modifier une telle variable, provoquant alors des effets inattendus dans les autres fonctions. Ainsi g modifie glob1.

// schéma de programme montrant les différents// types de variables				#include <iostream.h>				int glob1, glob2 = 10; // statiques globales			void f(int arg1, int &arg2){     static int stat = 1;  // statique explicite     arg2 = ++arg1 * stat++;}			void g(void){     int loc = 0;   // locale     for (int i = 1; i <= glob2; i++)   // i est locale          cout << i << '\t' << glob1++ * loc++ << '\n';}			main(){     int mloc1, mloc2 = 7; // statique de main     f(mloc2, mloc1);     if (mloc1 > 0) {        for (int k = 1; k <= 3; k++) f(0,0);        mloc1 = 0;        }     g();     return 0;}

Deuxième type de variables statiques, celles qui sont explicitement déclarées ainsi avec le mot réservé static dans une fonction (pour l’intérêt de cette déclaration, voir précédemment). C’est le cas, dans notre exemple, de la variable stat dans la fonction f. Une telle variable est également initialisée à zéro si aucune initialisation explicite n’est indiquée. Dans notre exemple, la variable stat est augmentée dans f, il en résulte que lors des appels successifs de cette fonction, on aura des résultats différents en général.

Une telle variable n’est visible que dans le bloc où elle est déclarée. Il en résulte que par exemple g et main ne peuvent avoir accès à stat. Il s’agit d’un processus beaucoup plus sûr que l’utilisation de globales.

Troisième type de variables statiques, celles qui sont déclarées dans le bloc principal de la fonction main, comme mloc1 et mloc2. Ces variables sont en fait des variables locales de main (voir ci-après), mais comme la durée de parcours de main est celle du programme entier, elles existent tout au long du programme. De telles variables ne sont cependant visibles que dans la fonction main. De plus elles ne sont jamais initialisées automatiquement (la valeur de mloc1 au début du programme est donc aléatoire).

Toutes les variables statiques sont créées dans le segment de données à la compilation.

Il existe deux sortes de variables dynamiques. Les variables dynamiques du programmeur sont celles qu’il crée explicitement dans le tas à l’aide de malloc ou de new, et qu’il détruit quand bon lui semble. Ces variables ne sont pas prises en compte par le compilateur, ce n’est pas lui qui s’en occupe.

Les autres variables dynamiques sont dites automatiques, parce qu’elles sont automatiquement créées et détruites par le programme de façon transparente pour le programmeur. Elles sont placées dans la pile. Il en existe différentes espèces.

Les variables locales sont celles qui sont déclarées à l’intérieur d’un bloc, et qui sont détruites à la fin de ce bloc. C’est le cas des variables loc et i dans g (dont le bloc est celui de la fonction, elles sont donc détruites avec elle), mloc1 et mloc2 dans main, dont nous avons déjà parlé, et k dans main (dont le bloc est celui du if). Aucune de ces variables n’est initialisée automatiquement, il est donc préférable de toujours préciser une valeur initiale.

Les arguments d’une fonction sont des variables automatiques dont la durée de vie est celle de la fonction ; ces variables sont toujours initialisées lors de l’appel de la fonction, avec les paramètres réels passés à celle-ci, ou les valeurs par défaut s’il y a lieu. C’est le cas de arg1 et de la référence arg2 dans f.

Enfin, les variables cachées sont celles qui ne sont jamais nommées. Il s’agit en particulier des variables temporaires créées par le programme lorsqu’on initialise une référence sur une constante. Dans ce cas, une variable provisoire est créée et initialisée, dont la durée de vie est celle de la référence afférente. Ainsi, lors de l’appel de f(0,0), une variable temporaire de valeur zéro est créée dont la durée de vie est celle de arg2, c’est-à-dire la durée de f.

On retiendra deux points importants. Primo, les variables globales sont dangereuses, car n’importe qui peut les modifier sans prévenir. Secundo, les variables automatiques ne sont jamais initialisées par le compilateur, il faut le faire explicitement.

Précédent Précédent Sommaire Sommaire Suivant Suivant