Chapitre 7 Expressions et affectations ISBN 0 321
Chapitre 7 Expressions et affectations ISBN 0 -321 -49362 -1
Chapitre 7: Sujets • • Introduction Expressions arithmétiques Surcharge des opérateurs Conversions de types Expressions relationelle et booléenne Évaluations court-circuitées Les affectations Affectation multi-types 2
Introduction • Expressions: Outil fondamental permettant de spécifier les calculs devant être effectués par un programme informatique. • Point crucial: Comprendre la syntaxe et la sémantique des expressions du langage. • Évaluation d'une expression: Le résultat dépend de l'odre d'évaluation des opérateurs et des opérandes. 3
Expressions arithmétiques • L'apparition des premiers langages était motivée par le besoin d'évaluer des expressions arithmétiques telles que celles que l'on retrouve en mathématique, en science et en génie. • Expressions arithmétiques: opérateurs, opérandes, parenthèses et appels de fonctions. 4
Expressions arithmétiques: Conception • Choix de conception – – – Règles de précédence des opérateurs Règles d'associativité des opérateurs Ordre d'évaluation des opérandes Effets de bord de l'évaluation des opérandes Surcharge des opérateurs Mélange de types dans les expressions 5
Expressions arithmétiques: Opérateurs • Opérateur unaire: 1 opérande – *ptr • Opérateur binaire: 2 opérandes – a+b • Opérateur ternaire: 3 opérandes –a ? b : c Dans la plupart des langages les opérateurs binaires sont infixes 6
Priorité des opérateurs arithmétiques • Les règles de priorité des opérateurs définissent l'ordre avec lequel sont évalués les opérateurs adjacents dans une expression. • Niveaux de priorité typique: – – – parenthèses opérateurs unaires ** (exponentiation, le cas échéant) *, / +, - 7
Règles d'associativité des opérateurs • Les règles d'associativité des opérateurs définissent l'ordre avec lequel les opérateurs adjacents de même priorité sont évalués. • Règles d'associativité typiques: – De gauche à droite, excepté pour l'exponentiation qui est de droite à gauche – Les opérateurs unaires sont quelquefois évalué de droite à gauche (par exemple en FORTRAN) • APL est différent: tous les opérateurs ont la même priorité et sont évalués de droite à gauche. • Bien sûr, les règles de priorité et d'associativité peuvent être outrepassées en utilisant des parenthèses. 8
Expressions conditionnelles • Utilisé dans les langages de type C • Exemple: moyenne = (nbre == 0)? 0 : somme / nbre • Équivalent à if (nbre == 0) moyenne = 0 else moyenne = somme /nbre 9
Ordre d'évaluation des opérandes – Type d'opérandes: 1. Variables: évaluées en récupérant la valeur en mémoire 2. Constantes: Souvent évaluées de la même façon que les variables. Quelque fois la variable fait partie de l'instruction machine. 3. Expressions avec parenthèses: Évaluer tous les opérateurs avant d'utiliser la valeur comme opérande. – L'ordre d'évaluation des opérandes est important pour l'efficacité et lorsqu'il y a effet de bord. 10
Effet de bord des fonctions • Lorsqu'une fonction change la valeur d'un paramètre ou d'une variable non locale. • Principal problème: – Lorsqu'un des opérandes d'une expression est une fonction qui modifie la valeur d'une variable présente dans une autre opérande. – Exemple: int f(int& a){a++; return 1; } b = a / f(a); 11
Effet de bord des fonctions • Deux solutions possibles au problème: 1. Définir le langage afin de proscrire les effets de bord. • • Pas de paramètre pouvant être modifié Aucune variable non locale Avantage: C'est possible et cela fonctionne! Désavantage: Manque de flexibilité 2. Définir le langage afin que l'ordre d'évaluation des opérandes soit fixe. • Désavantage: limite l'optimisation effectuée par le compilateur. 12
Surcharge des opérateurs • Utilisation d'un opérateur pour plus d'un usage. • Quelques cas sont communs – + pour int et float – En Java: + pour la concaténation • Quelques uns sont problématiques (e. g. , & en C et C++) – Plus difficile de détecter les erreurs car l'omission d'une opérande peut ne pas être détectée: • si on écrit &b plutôt que a&b – Peut être évité (en Pascal on écrit div pour la division entière) 13
Surcharge des opérateurs (suite) • C++, Ada, Fortran 95 et C# permettent aux usager de surcharger les opérateurs. – addition et produit sur les matrices: A*B+C*D • Problèmes potentiels: – L'usage d'un symbole peut être injustifié – Les programmes peuvent être moins lisibles même si l'usage est justifié • par exemple si on doit vérifier le type de tous les paramètres pour déterminer la sémantique. 14
Conversion de types • Une conversion réductrice (narrowing conversion) est une converstion vers un type plus restreint. – Exemple: float vers int • Une conversion expensive (widening conversion) est une conversion vers un type plus général – Exemple: int vers float 15
Conversion implicite (Coercition) • Une coercition est une conversion de type implicite • désavantages: – Elles diminuent la capacité du compilateur de détecter les erreurs de types. • La plupart des langages utilisent la coercition expensive pour tous les types numériques dans les expressions • En Ada il n'y a pratiquement aucune coercition dans les expressions. 16
Conversion explicite • Possible dans la plupart des langages • cast en C • Exemples – C: (int) angle – Ada: Float (sum) • Note: La syntaxe de Ada est similaire aux appels de fonctions. • Ada possède aussi une fonction unchecked_Conversion qui change le type sans changer la représentation. 17
Erreurs dans les expressions • Causes – Limitations Inhérentes de l'arithmétique: • e. g. , division par zéro – Limitations de l'ordinateur • e. g. débordement • Certains langages offrent des outils pour traiter ce type d'erreurs (exceptions) 18
Expressions booléennes et relationelles • Expression relationelle – Utilise des opérateurs relationels et des opérandes de types variés – S'évalue à une représentation d'une valeur booléenne – Les symboles représentant les opérateurs varient en fonction des langages != (C), /= (Ada), . NE. (Fortran), <> (Fortran), ~= (Lua), !== (PHP) 19
Expressions booléennes et relationelles • Expressions booléennes – Les opérandes sont des booléens et le résultat est un booléen – Exemples d'opérateurs FORTRAN 77 FORTRAN 90 . AND. . OR. . NOT. and or not C && || ! Ada and or not xor 20
Pas de type booléen en C • Le C utilise le type int pour représenter les booléens (0=faux et les autres valeurs valent • Chose curieuse en C: a < b < c est une expression légale mais le résultat n'est pas ce que vous espérez: – Que vaux 1 < 0 < 1 ? 21
Précédence des opérateurs • Opérateurs relationels dans les langages de type C: ++ et -- postfixes + et - unaires, ++ et -- préfixes, ! *, /, % + et - binaires <, >, <=, >= =, != && || 22
Évaluations court-circuitées • Lorsque le résultat d'une expression est déterminé sans évaluer toutes les opérandes et/ou opérateurs. • Exemple: (13*a) * (b/13– 1) Si a est zéro, inutile d'évaluer (b/13 -1) • Problème avec les évaluations non court-circuitées index = 0; while ((index < length) && (LIST[index] != value)) index++; – Lorsque index=length alors LIST [index] n'est pas valide (en C) 23
Évaluations court-circuitées (suite) • C, C++, et Java: utilisent l'évaluation courtcircuitée pour les opérateurs booléens usuels (&& and ||), mais ils fournissent aussi des opérateurs sur les bits qui ne sont pas court-circuités(& and |) • Ada: on peut spécifier si les opérateurs AND et OR doivent être court-circuités en utilisant and-then et or-else: I : = 1; while (I<=N) and then (tab(I) /= K) loop I: =I+1; end loop; 24
Évaluations court-circuitées (suite) • Ruby, Perl, Python: Tous les opérateurs logiques sont court-circuités. • L'évaluation court-circuitée expose le problème potentiel de l'effet de bord dans les expressions: e. g. (a > b) || (b++ / 3) 25
Les affectations • Syntaxe générale: <var_cible> <operator_affectation> <expression> • L'opérateur d'affectation = FORTRAN, BASIC, PL/I, C, C++, Java : = ALGOLs, Pascal, Ada • = peut être problématique lorsqu'il est surchargé par l'opérateur relationel d'égalité 26
Cible conditionnelle • En C, C++, et Java: (flag)? total : subtotal = 0 Ce qui est équivalent à: if (flag) total = 0 else subtotal = 0 • Note: Cela illustre la différence entre les l-valeurs et les r-valeurs. 27
Opérateurs composés • Raccourci permettant de spécifier une forme particulière • Introduit dans ALGOL; adopté par C • Exemple a = a + b peut s'écrire a += b 28
Opérateurs d'affectation unaires • Dans les langages de type C • Combine l'incrémentation (ou la décrémentation) avec l'affectation • Exemples count++ --count sum = ++count sum = count++ 29
L'affectation comme expression • En C, C++, et Java, l'affectation produit un résultat et peut être utilisé comme opérande. • Exemple: while ((ch = getchar())!= EOF){…} ch = getchar() est évalué et le résultat (mis dans ch) est utilisé comme valeur de comparaison avec EOF. 30
Affectation multi-types • L'affectation peut aussi être multi-type: int a, b; float c; c = a / b; • Fortran, C, C++ et Perl utilisent des règles de coercition pour l'affectation similaire à celle utilisée dans les expressions. 31
Affectation multi-types (suite) • En Java et C#, seule la coercition expensive est effectuée. • En Ada, il n'y a aucune coercition pour l'affectation. • Les langages utilisant le typage dynamique n'ont pas besoin d'effectuer de coercition. 32
Sommaire • • • Expressions Associativité et priorité des opérateurs Évaluations court-circuitées Surcharge des opérateurs Expressions multi-types Formes variées d'affectations. 33
- Slides: 33