Portée des variables : variables locales et globales#
Nous avons vu dans les cours précédents que l’on pouvait déclarer des variables à différents endroits :
Directement dans une cellule Jupyter ou l’entête d’un programme :
int a = 1;
Dans une boucle
for
:for ( int a = 0; i <= 5; i ++ ) { ... }
Comme paramètre d’une fonction :
int f(int a) { ... }
Dans le corps d’une fonction :
int f() { int a; ... }
Et en fait, plus généralement, dans un bloc :
{ int a; ... }
Objectif pédagogique
Formaliser les cas précédents en introduisant la notion de portée d’une variable.
Quelques exemples#
Dans un programme, le même nom peut être utilisé pour plusieurs variables, ce qui peut amener des ambiguïtés.
Exercice
Devinez le résultat des commandes suivantes.
int i = 1;
{
i = 2;
i = i + 1;
}
i
int i = 1;
{
int i = 2;
i = i + 1;
}
i
int i = 1;
for ( int i = 1; i < 10; i++ ) {
int i;
}
i
#include <iostream>
using namespace std;
int a = 0, b = 0;
void f(int b) {
int c = 5;
cout << "1: " << a << " " << b << " " << c << endl;
}
void g() {
int a = 2, c = 2;
cout << "2: " << a << " " << b << " " << c << endl;
{
long a = 3, c = 3;
cout << "3: " << a << " " << b << " " << c << endl;
}
cout << "4: " << a << " " << b << " " << c << endl;
f(4);
}
g()
Attention
La réponse pourrait en fait dépendre du langage!
Pour prédire rigoureusement le comportement du programme, il faut préciser la sémantique des variables et notamment leur portée.
La portée des variables#
En C++
, comme dans la plupart des langages modernes, la portée d’une
variable (où elle est définie) est déterminée par le contexte
lexical (comment le code est écrit) sans avoir à considérer le
contexte d’exécution (comment le code s’exécute). Cela permet en effet
de raisonner localement à une fonction, à un fichier, sans se préocuper
du reste du programme.
Sémantique#
Définition : Portée des variables
Une variable est visible depuis sa déclaration jusqu’à la fin du
bloc { ... }
où elle est déclarée.
Attention
Cas particuliers
Dans le cas d’une boucle for
, on considère l’entête comme étant dans
le bloc for (int i ...) { ... }
.
Définition : Variables locales, paramètres formels et variables globales
Une variable locale (local variable) est définie dans un bloc (par exemple d’une fonction).
Un paramètre formel (formal parameter) est défini dans l’entête d’une fonction; il se comporte comme une variable locale du bloc de la fonction.
Une variable globale (global variable) est définie ailleurs (cellule Jupyter, entête de programme)
Attention
Une variable peut masquer des variables issues des contextes englobants!
Exercice
Reprenez l’exemple ci-dessus, et annotez chaque déclaration et chaque utilisation de variable : quelles variables y sont locales, globales, … Puis exécutez le pas-à-pas en dessinant la pile d’exécution pour prédire à nouveau l’affichage. Vérifiez.
Solution
int a = 0, b = 0; // Variables globales
void f(int b) { // Paramètre (donc local à f)
int c = 5; // Variable locale de f
// a: globale; b: paramètre de f; c: local à f
cout << "1: " << a << " " << b << " " << c << endl;
}
void g() {
int a = 2, c = 2; // Variables locales à g
// a, c: locales à g; b: globale
cout << "2: " << a << " " << b << " " << c << endl;
{
long a = 3, c = 3; // Variables locales au bloc
// a, c: locales au bloc; b: globale
cout << "3: " << a << " " << b << " " << c << endl;
}
// a, c: locales à g; b: globale
cout << "4: " << a << " " << b << " " << c << endl;
f(4);
}
g()
Rappels#
Une variable locale à une fonction n’existe que le temps d’exécution de la fonction
La valeur de cette variable d’un appel à la fonction est perdue lors du retour au programme appelant et ne peut pas être récupérée lors d’un appel ultérieur
Variables globales : bonnes pratiques#
Accessible à l’intérieur de toutes les fonctions
On peut modifier la valeur d’une variable globale
Ceci est déconseillé (effet de bord)Une variable locale masque une variable globale du même nom
Ceci est déconseillé (ambiguïté à la lecture rapide)On évitera ces pratiques dans le cadre de ce cours
Résumé: portée des variables#
Une variable est définie depuis sa déclaration jusqu’à la fin du bloc la contenant
(en considérant l’entête d’une fonction ou d’une bouclefor
comme faisant partie du bloc)
Une variable hors de tout bloc est dite globale En général, on évite les variables globales
Sinon elle est locale