CSI3525: Concepts des Langages de Programmation Notes # 9: Expressions et Affectations ( Lire Chapitre 6 )
Expressions Arithmetiques: Precedence des Operateurs La precedence (ou puissance) des operateurs est l’ordre d’evaluation d’expressions contennant plus d’un operateurs [Lorsque des parentheses ne sont pas la pour determiner cet ordre explicitement]. Les operateurs sont groupes par types: Exposant: **. Operateurs unitaires: abs, + unitaire, - unitaire, ++, --, not. Operateurs multiplicatifs: *, /, div, mod, and. Operateurs additifs: + binaire, - binaire, or.
Ordre de Precedence dans Differents Langages Les regles de precedences peuvent etre differentes d’un langage a l’autre: Pascal: multiplicatifs > additifs C: unitaires > multiplicatifs > additifs Ada: exposants > multiplicatifs > unitaire +, - > additifs Fortran: ** > multiplicatifs > additifs APL: Tous les operateurs ont le meme niveau de precedence.
Expressions Arithmetique: Associativite Etant donne un operateur binaire, , on peut parle de: Associativite de gauche a droite: x y z = ( x y ) z Pascal, Ada, C (les operateurs “normaux”) Associativite de droite a gauche: x y z = x ( y z ) C (les operateurs de self-incrementation: ++, --) Non-Associativite: x y z est illegal: il faut specifier ou bien ( x y ) z ou alors x ( y z ) Ada (exposants): x ** y ** z est incorrect.
Expressions Arithmetique: Associativite (continue) Pas de Precedence, une regle d’Associativite: APL: toujours l’associativite de droite a gauche: x + y * z = x + ( y * z ) x * y + z = x * ( y + z ) Smalltalk: toujours l’associativite de gauche a droite x + y * z = ( x + y ) * z x * y + z = ( x * y ) + z
Expressions Arithmetique: Evaluation d’Arguments et Effets Secondaires Une fonction apparaissant dans une expression peut avoir des effets secondaires (un changement dans un objet non-local–ce qui veut dire que cet objet n’etait pas mentionne dans l’expression) Example: function twice (var x: real): real; begin x := x + x; twice := x end; Si on fait l’appel: z := twice(y); la valeur de y est changee secretement. L’ordre d’evaluation d’operateurs est tres important dans le cas d’effets secondaires
Expressions Arithmetique: Evaluation d’Arguments et Effets Secondaires (continue) Dans le programme suivant: y := 10; z := y + twice ( y ); Si le premier operande est evalue le premier, z aura la valeur30. Si, cependant, le deuxieme operande est evalue le premier, z aura la valeur 40. Le meme probleme arrive lorsque la valeur d’une variable globale est change a l’interieur d’une fonction ou d’une procedure.
Expressions Arithmetique: Evaluation d’Arguments et Effets Secondaires (continue) Solutions pour ce probleme: Interdiction d’effets secondaires de fonctions: 1) Pas une bonne idee pour les langages qui n’ont pas de procedures, mais ont seulement des fonctions (C,C++). 2) De plus, il faudrait passer toutes les variables comme parametres Probleme d’efficacite: il est plus rapide d’avoir acces a des variables globales dans une fonction. Decider d’un ordre d’evaluation d’operandes: Pas une bonne ide car les methodes d’optimization de compilateurs change parfois l’ordre d’evaluation des operandes
Expressions Arithmetique: Evaluation d’Arguments et Effets Secondaires (continue) Solutions pour ce probleme (continue): En Fortran 77: expressions qui ont des appels de fonctions sont legaux seulement si les fonctions ne changent pas les valeurs des autres operandes de l’expression probleme: il est tres difficile pour le compilateur de determiner l’effet exact qu’une fonction peut avoir sur les variables contenues a l’exterieur de cette fonction.
Expressions Arithmetiques: Operations Ternaires Expression conditionnelles: En Algol60: If x>0 then 1 . else if x=0 then 0 . else –1 En C, il y a l’operateur: “?” qui est un operateur ternaire “:” est un separateur: ( x > 0 ? 1 : ( x == 0 ? 0 : -1 ) )
Operateurs Overloades Un operateur est overloade si le meme nom ou le meme symbole a plusieurs usages distincts. Examples en Pascal: + addition d’entier et de reels, concatenation de chaines de caracteres, union d’ensembles. * multiplication d’entiers et de reels, intersection d’ensembles. abs entier entier, reel reel Il n’y a pas d’overloading pour mod et div
Operateurs Overloades (continue) L’overloading peut etre resolu en regardant le contexte (tous les operandes ont un type connu). Exemples: 2+3 entiers [‘a’] + [‘c’, ‘d’] ensembles Dans certains langages, comme l’Ada ou le C++ (qui sont des langages extensibles), le programmeur peut overloader lui/elle-meme des operateurs. En Ada, ou il n’y a que 2 procedures de I/O: get, put, ces procedures sont tres overloades
Operateurs Overloades (continue) L’Overloading peut porter a la confusion: En C, par exemple, & veut dire “conjonction par bits” et “addresse”. * veut dire “multiplication” et “deference”. En PL/1, par exemple, = veut dire “egalite” et “affectation” Cependant, l’overloading est aussi tres utile car il peut rendre la lecture plus aisee.
Operateurs Overloades (continue) En Prolog, la virgule est tres overloadee, elle aussi: a :- b, c, d. and a(b, c, d) Separation d’arguments [b, c, d]. Separation d’elements de liste
Coercition de Types Les conversions de types sont ou bien aggrandiassantes ou retrecissantes. Il vaut toujours mieux aggrandir que retrecir: En Fortran, l’ordre de la coercition est: entier < reel < double < complex En Pascal, on a: entier < reel Neanmoins, il peut y avoir des problemes meme dans une conversion aggrandissante etant donnees les limites de la precision des types. Bien que la coercition soit bien pratique, la detection d’erreur de type est reduite.
Expressions Logiques Il existe six operateurs de comparaison: Pascal/Ada C Fortran Egal = == .EQ. Inegal <>, /= != .NE. Moins que < < .LT. Moins que ou Egal <= <= .LE. Plus que > > .LT. Plus que ou Egal >= >= .LE. L’egalite est bien definie pour tous les types, mais il n’existe pas d’ordre naturel pour les types non scalaires.
Expressions Logiques (Continue) L’ordre de precedence de tous les operateurs de l’Ada: **, abs, not *, /, mod, rem +, - (unitaire) +, - (binaire) =, /=, <, >, <=, >=, in, not in and, or, xor, and then, or else Ce n’est pas toujours comme cela: en Pascal, par exemple, les operateurs booleens ont une precedence plus haute que les operateurs relationnels a > 5 or a < 0 est illegal car cela veut dire a > (5 or a) < 0
Expressions Logiques Evaluations Court-Circuites Une evaluation court-circuite est une evaluation dans laquelle le resultat est determine sans evaluer tous les operandes ou operateurs. Par exemple, dans l’expresion: (13 * A) * (B/13 –1), si A=0, on n’a pas besoin d’evaluer (B/13 –1). Neanmoins, dans les operations arithmetiques, il n’est pas facile de detecter de telles situations. Ce court-circuit n’est donc jamais utilise. Par contre, il peut etre utilise pour les operations logiques: Pascal ne l’utilise pas du tout problemes; C l’utilise tout le temps problemes; Ada permet les operations court-circuites et celles non court-circuites Meilleure approche.
Affectations Affectations simples: Resultat := Expression Affectations Multiples: PL/1: A, B := Expression Algol 60: A := B := Expression 1. Il faut trouver la valeur de l’Expression 2’. Il faut affecter cette valeur a A puis a B 2’’.Il faut affecter cette valeur a B uis a A L’ordre d’affectation est important et l’ordre dans lequel les addresses des resultats sont evaluees est aussi important.
Affectations (Continue) Affectation Composee (en C): a += b; a = a +b; a *= b; a = a * b; etc… Affectations Conditionnelles (en C): (x != 0 ? Y : z) = 17 ou bien x ? Y : z = 17; Affectation qui est une expression (en C): a = b = Expression; b=Expression a une valeur (Expression qui est affectee a a) while ((ch=getchar()) != EOF) { … }