informatique (MP2I/MPI) · Chapitre 8 · Application directe du cours
Portée et durée de vie ne sont pas la même chose
Mémoire, fichiers et entrées-sorties · niveau 2
Énoncé
Qu'affiche ce programme ? Combien de variables nommées n existe-t-il ?
int n = 100; /* globale */
void compteur(void) {
int local = 0;
static int persistant = 0;
local = local + 1;
persistant = persistant + 1;
printf("local = %d, persistant = %d\n", local, persistant);
}
int main(void) {
int n = 1;
printf("dans main, n = %d\n", n);
{ int n = 2; printf("dans le bloc, n = %d\n", n); }
printf("apres le bloc, n = %d\n", n);
for (int i = 0; i < 3; i = i + 1) { compteur(); }
return 0;
}Corrigé
La sortie mesurée est :
dans main, n = 1
dans le bloc, n = 2
apres le bloc, n = 1
local = 1, persistant = 1
local = 1, persistant = 2
local = 1, persistant = 3
Il existe trois variables nommées n, et elles coexistent : la globale à , la locale de main à , celle du bloc à . Aucune n'écrase l'autre — le bloc masque le nom, il ne modifie pas la case. À la sortie du bloc, la locale de main vaut toujours , et la globale vaut toujours : elle est simplement devenue inaccessible par son nom dès la ligne int n = 1;.
C'est la définition même de la portée : elle est syntaxique. Elle se lit sur le texte du programme, en fermant les accolades du regard, sans rien exécuter.
Les trois dernières lignes séparent les deux notions. local et persistant ont la même portée — le corps de compteur — et des durées de vie opposées : local naît et meurt à chaque appel, donc revaut trois fois ; persistant est allouée une fois pour toutes dans la zone des globales et compte .
Le tableau à retenir :
| Portée | Durée de vie | |
|---|---|---|
int n globale | tout le fichier, sauf masquage | le programme |
int n locale | le bloc | l'appel |
static int persistant | le bloc | le programme |
bloc malloc | (aucune : il n'a pas de nom) | jusqu'au free |
La ligne static est celle qui prouve que les deux colonnes sont indépendantes.