Upload
yasmina-verger
View
107
Download
2
Embed Size (px)
Citation preview
1-1
Chapitre 5: Les variables
• Introduction • Les noms• Les variables• Les attributions (bindings)• Portée et durée de vie • L'environnement de référence• Les noms constants
1-2
Introduction
• Langages impératifs: abstraction de l'architecture de von Neumann – Mémoire– Processeur
• Rôle central des variables et de l'instruction d'affectation.
1-3
Le nom des variables
• Quelques considérations:– Longueur maximum?– Caractères permis (connecteurs)?– Distinction des majuscules et minuscules?– Mots spéciaux: réservés ou mots clefs?
1-4
Le nom des variables (suite)
• Longueur– Si trop court alors peu significatif– Exemples:
• FORTRAN I: maximum 6• COBOL: maximum 30• FORTRAN 90 and ANSI C: maximum 31• Ada and Java: pas de limite• C++: la limite provient de l'implémentation pas de
la définition.
1-5
Le nom des variables (suite)
• Connecteurs (caractère '_' )– Pascal, Modula-2, and FORTRAN 77: pas
permis – Autres: permis– En Fortran avant 1990 le caractère d'espace ' '
était ignoré: ma variable = mavariable.
• Moins populaire maintenant: On utilise souvent un mélange de lettres majuscules et minuscules (camel notation):– MaVariable plutôt que ma_variable
1-6
Le nom des variables (suite)
• Distinguer les majuscules des minuscules– Désavantage: lisibilité (des noms qui se
ressemblent sont en fait différents)• En C++ et en Java certains noms prédéfinies
contiennent les deux types de lettres (e.g. IndexOutOfBoundsException)
– C, C++, C# et Java (entre autres): distinguent les majuscules des minuscules
– En Java parseInt est une méthode pour convertir une chaîne de caractère en entier. Cela ne cause pas de problème de lisibilité mais rend plus difficile l'écriture du code.
1-7
Le nom des variables (suite)
• Mots spéciaux:
– Aident à la lisibilité: utilisés pour séparer ou délimiter des parties de programme.
– Un mot clé est un mot qui est spécial seulement dans certains contextes, e.g., en Fortran
– Real VarName (Real est un type de données)– Real = 3.4 (Real est une variable) –
– Un mot réservé est un mot spécial qui ne peut pas être utilisé comme nom défini par l'usager.
– COBOL possède plus de 500 mots réservés: LENGTH, BOTTOM, DESTINATION, COUNT, etc.
1-8
Variables et attributs
• Une variable est une abstraction représentant une zone mémoire.
• Une variable est caractérisée par ses attributs:– Nom– Addresse (l-valeur)– Valeur (r-valeur)– Type– Durée de vie– Portée
1-9
Attributs d'une variable
• Nom – Certaines variables n'en possède pas.• Addresse – Adresse mémoire à laquelle la
variable est associée– Possiblement différentes adresses à différents moments
de l'exécution (exemple: variables locales)– Plusieurs variables peuvent partager le même nom.– Il est possible pour plusieurs variables d'avoir la même
adresse: on dit que ce sont des pseudonymes (ou alias)
– Les pseudonymes sont créés à l'aide des pointeurs, des variables références et des unions (en C et C++).
– Les pseudonymes peuvent être un réel problème pour la lisibilité et la fiabilité.
1-10
Attributs d'une variable (suite)
• Type:– ensemble de valeurs– ensemble d'opérations
• Valeur – contenue de la case mémoire associée à la variable
1-11
Le concept d'attribution (binding)
• Une attribution est une association entre un objet et ses propriétés:– Entre une variable et ses attributs– Entre un symbole et une opération
• L'instant d'attribution (binding time) est le moment où l'association a lieu.
• Les différents attributs d'une variable ne sont pas tous données en même temps:– En C la déclaration
extern int n;
dans une fonction, associe un type et un nom à la variable x sans associer d'adresse.
1-12
Instants d'attribution possibles
• Lors de la conception -- Le symbole + est associé à l'opération d'addition
• Lors de l'implémentation-- On choisit la représentation des nombres en point flottant (float et double en C)
• Lors de la compilation -- On associe un type à une variable en C ou en Java.
• Lors du chargement en mémoire -- Une case mémoire est attribuée à une variable statique en C
• Lors de l'exécution -- Une case mémoire est attribuée à une variable locale non statique.
1-13
Attributions statique et dynamique• Une attribution est statique si elle se
produit avant l'exécution et demeure inchangée pendant toute la durée de l'exécution du programme.
• Une attribution est dynamique si elle se produit pendant l'exécution du programme.
1-14
Attribution de type
• Comment un type est-il spécifié?• À quel moment l'attribution a-t-elle lieu?• Si l'attribution de type est statique alors
celui-ci peut être spécifié de façon explicite (par une déclaration) ou être implicite.
1-15
Déclarations implicite et explicite
• Une déclaration explicite est un énoncé utilisé pour spécifier le type de variables.
• Une déclaration implicite est un mécanisme par défaut. La première apparition de la variable constitue sa déclaration implicite.
1-16
Déclarations implicite et explicite
• Certains langages comme FORTRAN, PL/I, BASIC et Perl utilisent des déclarations implicites de variables.
• En Fortran les variables dont le nom commence par une des lettres i,j,k,l,m,n (majuscules ou minuscules) sont des entiers; les autres sont des réels.– Avantage: facilité d'écriture– Inconvénient: fiabilité (il est facile de se tromper);
• En Perl: $var (scalaire), @var (tableau), %var (hash)
1-17
Attribution dynamique des types
• Exemple: JavaScript, Python et PHP• Le type est spécifié par une affectation e.g.,
JavaScript list = [2, 4.33, 6, 8];
list = 17.3;– Avantage: flexibilité (programmes génériques)– Inconvénient:
• Coût élevé d'implémentation ralentissant l'exécution (la mémoire doit être alloué dynamiquement et on doit mémoriser le type courant)
• Il est difficile de détecter les erreurs de types (la détection doit se faire en cours d'exécution)
1-18
Inférence de types
• ML, Miranda et Haskell– Types attribués dynamiquement– Le type est déterminé par le contexte plutôt
que par une affectation. – Exemple en ML:
• fun square(x) = x*x ;• x possède le type int car l'opérateur * indique que x est une valeur numérique
• En ML le type numérique par défaut est int
1-19
Attribution d'une case mémoire et d'une durée de vie
• Allocation – Attribuer à une variable une case mémoire en prevenance d'une collection de cases disponibles.
• Désallocation – Action de retourner la case mémoire, précédemment attribuée à une variable, à la collection de cases disponibles.
• La durée de vie d'une variable est le temps pendant lequel elle se voit attribuer une case mémoire.
1-20
Variables et durée de vie
• Quatre catégories:– Statiques– Dynamiques sur pile (stack dynamic)– Dynamiques sur tas (heap dynamic)
• Explicites• Implicites
1-21
Variables statiques
• Statique—Une case mémoire est attribuée avant le début de l'exécution et pour toute la durée de l'exécution.– e.g.: toutes les variables en FORTRAN 77 ainsi
que les variables globales et statiques en C– Avantages: efficacité (adressage direct),
permet d'implémenter des fonctions à mémoire.
– Désavantage: manque de flexibilité (absence de récursion)
1-22
Variables dynamiques sur pile
• Dynamique sur pile—L'attribution d'un espace mémoire se produit en cours d'exécution au moment de la déclaration. L'espace est pris sur la pile.
• Avantage: permet la récursion et la réutilisation de la mémoire.
• Désavantages: – Temps supplémentaire pour allouer et
désallouer la mémoire– Les sous-programmes sont sans mémoire– On doit utiliser l'adressage indirect
1-23
Variables explicites-dynamiques sur tas
• L'allocation et la désallocation doivent être effectuées explicitement par des directives spécifiées par le programmeur et prenant effet durant l'exécution.
• Implémentation:– pointeurs (objets dynamiques en C++ via new et delete), – références (tous les objets en Java: la désallocation est
faite automatiquement)
• Avantage: Permet d'implémenter des structures de données dynamiques: listes chaînées, arbres, etc.
• Désavantage: moins efficace et moins fiable.
1-24
Variables implicites-dynamiques sur tas
• Allocations et désallocations causées par les affectations– variables en JavaScript, Python, etc.– Dans ces langages les variables sont des noms
qui s'adaptent à l'usage qu'on en fait
• Avantage: flexibilité• Désavantages:
– Inefficace car tous les attibuts sont dynamiques
– La détection des erreurs est difficile
1-25
La portée d'une variable
• La portée d'une variable est la partie du programme où la variable est visible.
• Les variables non-locales d'une section de programme (fonction, classe, bloc d'instructions, etc) sont celles visibles mais déclarées ailleurs dans le programme.
• Les règles de portée d'un langage détermine comment la référence à un nom est associée à une variable.
1-26
Portée statique
• Déterminée uniquement par la syntaxe (avant l'exécution).
• Pour associer un nom à une variable, le compilateur doit d'abord trouver la déclaration.
• Processus de recherche: On regarde d'abord dans la portée locale, puis dans des portées de plus en plus larges, jusqu'à ce qu'on trouve une déclaration avec le même nom.
1-27
Portée statique (suite)
procedure Big is
x: Integer;
procedure Sub1 is
x: Integer;
begin -- Sub1
∶ end –- Sub1
procedure Sub2 is
begin –- Sub2
∶ end; -- Sub2
begin -- Big
∶ end; -- Big
• Exemple en Ada
• Remarque: En JavaScript, Python et PHP il est aussi possible d'avoir des fonctions imbriquées.
• La procédure Sub1 peut accéder à la variable x de Big en utilisant la notation Big.x
1-28
Portée statique (suite)
void sub(){
int count;
∶ while ( ... ){
int count;
count++;
∶ }
}
• Exemple en C++
• Remarque: Ce code n'est pas valide en Java et en C# (on ne peut pas réutiliser un nom de variable dans un bloc imbriqué)
• En C++ une variable globale X peut être redéfinie dans une fonction et on peut accéder à la définition originale avec l'opérateur de portée ::X
1-29
Les blocs d'instructions
– Provenant d'Algol 60, il s'agit d'une méthode pour créer des portées statiques à l'intérieur d'une section de programme.
– Exemples:
C
if (s>t) { int temp=s; s=t; t=temp;}
declare temp : Integer;begin temp=a; a=b; b=temp;end
Ada
1-30
Les blocs d'instructions (suite)
– Dans les premières version de C++, la variable count aurait été visible à l'extérieur du for.
– Ce code n'est plus valide.
void fun(){...for (int count = 0; count < 10; count++)
{ ... }cout<<count;}
C++, Java, C# possèdent une instruction for permettant de déclarer des variables dans la section d'initialisation.
1-31
Les blocs d'instructions (suite)
• Les classes des langages C++, Java et C# ont des règles de portée un peu différentes.
• Les variables d'instance et de classe sont visibles dans toutes les méthodes, peu importe l'endroit où elles sont définies.
• La portée d'une variable définie dans une méthode est locale à la méthode.
1-32
La portée des variables en Ruby
• La forme du nom indique la portée
• Un nom de variable locale commence par une lettre minuscule
• Une variable globale commence par le symbole $
• Une variable d'instance commence par le symbole @ suivit d'une lettre
• Une variable de classe commence par deux symboles @@ suivit d'une lettre
• Un nom constant commence par une lettre majuscule
1-33
Évaluation de la portée statique
• Considérons l'exemple suivant et supposons qu'il n'y a pas d'autre portées que celles définies par MAIN et ses procédures.
MAINMAIN
E
A
C
D
B
A B
C D E
1-34
Portée statique: Exemple
MAIN MAIN
A B
C D E
A
C
B
ED
• Un programmeur peut appeler une procédure qu'il n'aurait pas dû appeler• Il est impossible d'empêcher A ou B d'accéder aux variables de MAIN.
1-35
Portée statique (suite)
• Supposons qu'on veut faire un changement tel que D puisse accéder à la variable X définie dans B
• Solutions:– Mettre D dans B
• D ne peut plus appeler C • D ne peut plus accéder aux données de A
– Mettre X dans MAIN• Toutes les procédures peuvent maintenant y accéder
• Même problème pour l'accès aux procédures• Conclusion: La portée statique encourages
l'utilisation de variables globales et de procédures au même niveau (comme en C)
1-36
Portée dynamique
• Méthode utilisée dans APL, SNOBOL4 et premières versions de Lisp
• Optionel dans Common Lisp et Perl
• Utilise la séquence des appels de procédures plutôt que la position des variables (critères temporels plutôt que spatiaux)
• On recherche la déclaration d'une variable localement puis en regardant dans la chaîne des appels de procédures.
1-37
Portée dynamique: Exemple
Big appelle Sub1Sub1 appelle Sub2Sub2 utilise x
• Portée statique :Le x est celui de Big• Portée dynamique:Le x est celui de Sub1
procedure Big is
x: Integer;
procedure Sub1 is
x: Integer;
begin -- Sub1
∶ end –- Sub1
procedure Sub2 is
begin –- Sub2
∶ end; -- Sub2
begin -- Big
∶ end; -- Big
1-38
Portée dynamique: évaluation
• Avantages: – Moins de paramètres à passer aux procédures
• Désavantages: – lecture difficile– moins bonne fiabilité– Certaines erreurs de typage ne peuvent pas
être détecter statiquement– Ralenti l'exécution
1-39
Portée et durée de vie
• La portée et la durée de vie d'une variable sont des concepts différents qui semblent souvent liés.
• Exemple: Une variable locale X dans une fonction FCT ne faisant aucun appel de fonction.
• Si FCT fait un appel de fonction alors X est toujours définie (elle reste dans la pile) mais:– X n'est plus accessible si sa portée est statique– X est toujours accessible si sa portée est dynamique
• Mais si la variable locale est statique alors sa durée de vie ne dépend pas de sa portée.
1-40
L'environnement de référence
• L'environnement de référence d'un énoncé est la collection de tous les noms visibles dans l'énoncé.
• Dans un langage à portées statiques, c'est l'ensembles des variables locales ainsi que toutes les variables visibles définies dans les portée supérieures.
• Un sous-programme est actif si son exécution a commencée mais n'est pas encore terminée.
• Dans un langage à portées dynamiques, l'environnement de référence est l'ensemble des variables locales ainsi que toutes les variables visibles des sous-programmes actifs.
1-41
L'environnement de référence
procedure Main is A,B: Integer; procedure Sub1 is X,Y: Integer; begin ... end; procedure Sub2 is X: Integer;
procedure Sub3 is A,X: Integer; begin ... end; begin ... end; begin ... end;
X,Y de Sub1, A,B de Main
A,X de Sub3, B de Main
X de Sub2, A,B de Main
A,B de Main
Portée statique:
1-42
L'environnement de référence
procedure Example is A,B: Integer; procedure Sub1 is X,Y: Integer; begin ... end; procedure Sub2 is X: Integer;
procedure Sub3 is A,X: Integer; begin ... end; begin ... end; begin ... end;
X,Y de Sub1, A de Sub3, B de Main
A,X de Sub3, B de Main
X de Sub2, A,B de Main
A,B de Main
Portée dynamique(Main → Sub2 → Sub3 → Sub1):
1-43
Les noms constants
• Un nom constant est une variable à laquelle on attribut une valeur une seule fois: au moment de l'attribution de l'espace mémoire.
• Avantages: lisibilité et modification• Utilisés pour paramétriser les programmes
– Par exemple un programme qui traite MAX entrées.
• L'attribution d'une valeur peut être statique ou dynamique
• Langages: – FORTRAN 90: expressions constantes seulement– Ada, C++, and Java: N'importe quelles expressions– C++: const , Java : final– C#: const (statique) et readonly (dynamique)
1-44
Initialisation de variables
• Initialiser un variable consiste à lui attribuer une valeur au moment de l'attribution d'un espace mémoire.
• La valeur doit être constante pour les variables statiques mais peut être une expression évaluée en cours d'exécution pour les variables dynamiques.
• Dans la plupart des langages l'initialisation est faite lors de la déclaration:
int sum = 0; • Initialisation par défaut dans certains langages:
– Ex. En C les variables statiques sont initialisés à 0 lorsqu'il n'y a aucune autre instruction; l'initialisation des variables dynamiques est indéterminée.
1-45
Sommaire
• Les variables sont caractérisées par 6 attributs: nom, adresse, valeur, type, durée de vie et portée.
• Une attribution est une association entre un attribut et une entité du programme.
• On regroupe les variables scalaires en 4 catégories: statiques, dynamiques sur pile, explicites dynamiques sur tas et implicites dynamiques sur tas.
• La portée des variables est un attribut essentiel pour comprendre un programme.
• Un langage fortement typé s'il est possible de détecter toutes les erreurs de types.