Opérateurs et expressions
EN algèbre à l'école, vous avez appris à représenter l'information sous forme de facteurs et de termes, et à manipuler cette information avec des formules. Dans le QuickPascal, les informations prennent la forme d'opérandes et la manipulation de ces opérandes se produit dans les expressions. Un opérande est le terme formel pour ce que nous avons appelé un élément de données. Un opérande peut être n'importe quel nombre, caractère, fonction, variable ou constante. Une expression est toute combinaison légale (une formule) d'un ou plusieurs opérandes réduite à une valeur unique ayant un type de données spécifique. À quelques exceptions près, vous pouvez utiliser une expression partout où QuickPascal vous permet d'utiliser un élément de données individuel.
Supposons que vous louez une voiture pour 20 $ par jour et 0,25 $ par mile. Combien paierez-vous si vous conduisez la voiture 215 miles en cinq jours ? Vous pouvez calculer la Charge algébriquement comme suit :
Charge = 5 x $20 + 215 x $0,25 = $100 + $50 = %150 |
Vous devrez calculer séparément le tarif journalier et les frais kilométriques, puis ajouter leurs coûts individuels. De plus, vous savez que l'expression unique doit être évaluée pièce par pièce. Le QuickPascal analyse également une expression en la décomposant en ses opérandes de composantes. En fait, chaque opérande peut être lui-même une expression distincte.
Les programmeurs classent généralement une expression en fonction du type de données de la valeur qu'elle renvoie. Par conséquent, les expressions numériques nécessitent des opérateurs arithmétiques, les expressions Boolean nécessitent des opérateurs Boolean, les expressions de chaîne de caractères nécessitent des opérateurs de chaîne de caractères,...
Opérateurs et expressions arithmétiques
Les opérateurs d'addition (+), de soustraction (-) et de multiplication (*) de QuickPacal fonctionnent exactement comme leurs noms l'indiquent. Par conséquent, si x = 5 et y = 2, l'expression x + y renverra une valeur de 7. De même :
x - y retournera 3 x * y retournera 10 |
La division est la seule opération inhabituelle. Le mot clef DIV est l'opérateur que vous utilisez pour effectuer une division entière tandis que le symbole barre oblique (/) est l'opérateur effectuant une division réelle. En division entière, seule la partie entière d'un quotient est enregistrée :
20 DIV 6 retournera 3 |
Le reste, s'il y en a, est simplement jeté. L'opérateur DIV ne tente pas d'arrondir son résultat. Alternativement, dans la division réelle, le quotient contient à la fois un entier et une valeur décimale :
20 / 6 retournera 3,3333333333333.... |
L'opérateur / renverra toujours un quotient réel, même si les deux opérandes sont des entiers. A l'inverse, l'opérateur DIV ne peut être utilisé qu'avec des opérandes entiers. L'opérateur MOD (comme dans l'arithmétique modulaire) renvoie le reste de la division de deux entiers. Par exemple, 3 peut être divisé de manière égale en 17 cinq fois, avec un reste de 2 ; donc 17 MOD 3 est égal à 2. De même :
12 MOD 7 retournera 5 10 MOD 5 retournera 0 16 MOD 3 retournera 1 |
L'opérateur MOD peut également être utilisé avec des opérandes négatifs. Cependant, vous devez faire attention à éviter d'utiliser 0 pour le deuxième opérande ; sinon, vous produirez une erreur de division par zéro. Si x et y sont des nombres entiers et que x est supérieur à y, la relation suivante sera toujours valable :
x = y * (x DIV y) + (x MOD y) |
Soit dit en passant, si vous n'avez jamais programmé auparavant, vous pouvez vous attendre à utiliser le symbole x pour la multiplication et le ÷ symbole de division. Malheureusement, les claviers d'ordinateur n'ont généralement pas la flexibilité nécessaire. Ainsi, la plupart des claviers n'ont pas les touches x et ÷. Les symboles * et / sont donc un bon compromis.
Types de données arithmétiques
Le QuickPascal vous permet de mélanger des opérandes entiers et réels dans la même expression. Si un opérande dans une expression numérique est un réel, cependant, ou si vous utilisez l'opérateur / au lieu de l'opérateur DIV pour la division, l'expression entière est un réel. Par conséquent, les expressions suivantes renvoient des résultats réels :
3 + 5 + 7.0 + 9 retournera 24.0 6.0 * 2 retournera 12.0 10 / 5 retournera 2.0 |
Bien que chaque entier puisse être exprimé sous forme de valeur de type réel, tous les réels ne peuvent pas être exprimés sous forme d'entier. Par exemple, 58 peut être écrit sous la forme 58,0, mais 3,14159 n'a pas d'équivalent entier. Pour cette raison, le QuickPascal vous permet d'utiliser des expressions entières partout où les nombres réels sont autorisés. Si QuickPascal attend un entier, cependant, vous devez une expression entière.
Opérateurs unaires et binaires
Un opérateur est soit unaire, soit binaire, selon qu'il agit sur un ou deux opérandes. Les symboles de multiplication et de division agissent toujours sur deux opérandes :
- TotalFacture:=Quantite*CoutUnitaire;
- TauxMoyen:=SalaireTotal/HeureTravailler;
La multiplication et la division sont donc des opérations binaires. Parce que les signes plus et moins peuvent agir sur l'un ou l'autre des opérandes :
- TemperatureAMontreal:=-5;
- TemperatureASeptIles:=-30;
ou des paires d'opérandes :
- CompteurEmployee:=Clair+Exemptions;
- NombreDeBureau:=CompteurEmployee+Licenciement;
ces opérateurs sont unaires ou binaires (le QuickPascal peut faire la différence à partir du contexte).
Priorité de l'opérateur
Revenons un instant au calcul du coût de location d'une voiture à 20 $ par jour et 0,25 $ par mile. Vous pouvez écrire une expression QuickPascal pour calculer Charge en fonction de Jours et Miles comme suit :
- Charge:=Jours*20+Miles*0.25;
Ici, l'expression se compose de quatre opérandes : les deux nombres 20 et 0,25, et les deux variables Jours et Miles. L'expression contient également deux opérateurs : l'addition et la multiplication. Lorsque vous lisez la formule, vous comprenez immédiatement comment les variables et les opérateurs sont liés les uns aux autres :
- Multipliez Jours par 20
- Multipliez Miles par 0,25
- Ajoutez ce qui précède.
L'ordre naturel dans l'expression suivante est moins évident :
- Resultat:=2+3*4;
La valeur finale de Resultat peut être 20 ou 14, selon que l'opérateur d'addition ou de multiplication est exécuté en premier. Faire l'addition donne d'abord :
Resultat := 2 + 3 * 4; := 5 * 4; := 20; |
Faire la multiplication donne d'abord :
Resultat := 2 + 3 * 4; := 2 + 12; := 14; |
Afin de lever de telles ambiguïtés potentielles, le QuickPascal exécute les opérateurs dans une séquence prédéfinie appelée priorité. Il existe trois niveaux de priorité. Les opérateurs unaires sont exécutés en premier. Viennent ensuite les opérateurs de multiplication et de division, suivis des opérateurs d'addition et de soustraction binaires (comme indiqué dans le tableau suivant). Dans QuickPascal 2+3*4 est interprété comme 2 + (3*4), ce qui équivaut à 14 :
Niveau de préséance | Opérateurs |
---|---|
1. (haute) | unaire +, - |
2. | *, /, DIV, MOD |
3. (basse) | binaire +, - |
Tous les opérateurs sur la même ligne ont la même priorité et sont évalués de gauche à droite, dans l'ordre dans lequel ils sont écrits. Un opérande entre deux opérateurs est supposé appartenir à l'opérateur ayant la priorité la plus élevée.
Cette règle de gauche à droite ne pose aucun problème en raison d'un autre principe algébrique : la commutativité. En français ordinaire, cela signifie que les opérateurs de priorité égale peuvent être évalués dans n'importe quel ordre sans affecter la valeur de l'expression. D'où :
- 10 + 5 - 3
sera toujours évalué à 12, puisque (10+5)-3 est égal à 10+(5-3). De même, l'expression :
- 3 * 4 / 2
Utiliser des parenthèses
Vous pouvez utiliser des parenthèses pour remplacer la priorité des opérateurs. Dans l'expression :
- (2 + 3) * 4
les parenthèses forcent l'addition à se produire en premier, ce qui donne 20 comme valeur finale de l'expression. Les parenthèses sont toujours évaluées vers l'extérieur à partir de la paire la plus interne. Par exemple, l'expression :
- 2 * (40 - (5 * (7 - 2)))
il est évaluer comme ceci :
= 2 * (40 - (5 * (7 - 2))) = 2 * (40 - (5 * 5)) = 2 * (40 - 25) = 2 * 15 = 30 |
Bien que la priorité vous permette d'éviter l'utilisation excessive de parenthèses, vous devriez toujours les utiliser pour augmenter la clarté de votre programme. La formule de location de voiture, par exemple, peut être considérablement clarifiée comme suit :
- Charge:=(Jours*20)+(Miles*0.25);
Opérations au niveau du bit
Jusqu'à présent, vous avez vu comment les opérateurs arithmétiques agissent sur la valeur d'un opérande dans son ensemble. Vous pouvez ajouter, soustraire, multiplier et diviser un nombre entier avec un autre nombre entier. Parfois, cependant, vous voudrez travailler avec les bits individuels dans un opérande. Heureusement, le QuickPascal fournit un riche ensemble de routines de manipulation de bits que vous pouvez utiliser avec des opérandes entiers.
Utilisation d'opérateurs de décalage
Lorsque vous voulez multiplier un nombre par dix, il vous suffit d'ajouter un zéro à droite du nombre. Inversement, lorsque vous souhaitez diviser un nombre par dix, vous déplacez la virgule décimale d'une position vers la gauche.
De la même manière, si vous souhaitez multiplier ou diviser un opérande entier QuickPascal par deux, il vous suffit de décaler de manière appropriée les bits de l'opérande d'une position vers la gauche ou la droite. Le QuickPascal fournit les opérateurs SHL (décaler les bits à gauche) et SHR (décaler les bits à droite) pour faire glisser les bits d'un entier vers la gauche ou la droite. De nombreux programmeurs utilisent des opérations de décalage pour effectuer une multiplication et une division rapides par les puissances de deux. Se déplacer deux fois vers la gauche multiplie par quatre, se déplacer trois fois vers la gauche multiplie par huit, et ainsi de suite.
Tout comme vous pouvez multiplier un nombre par dix sans trop d'effort, le microprocesseur de la famille 8086 peut décaler une valeur beaucoup plus rapidement qu'il ne peut exécuter une instruction de multiplication ou de division fonctionnellement équivalente. En fait, l'utilisation de quarts de travail peut souvent accélérer les opérations d'un facteur dix ou plus.
La figure suivante décrit les opérations effectuées par les opérateurs SHL et SHR.
Lorsque l'opérateur SHL déplace les bits d'un entier vers la gauche, tous les bits tombant du bord gauche sont perdus. Les bits à droite sont remplis de zéros au fur et à mesure que leur contenu d'origine est déplacé. Si x est un opérande entier et n est une valeur entière, alors :
- x SHL n
fait glisser les bits en x vers la gauche de n positions. Si x est égal à 34, l'énoncé :
- Y:=X shl 2;
remplace Y par la valeur 136 (décaler de deux places vers la gauche équivaut à multiplier par quatre). L'opérande X lui-même n'est pas affecté. De même, lorsque l'opérateur SHR décale les bits d'un entier vers la droite, les bits tombant du bord droit sont perdus. Les bits de gauche sont remplis de zéros au fur et à mesure que leur contenu d'origine est déplacé. Si x est un opérande entier et n est une valeur entière, alors :
- x shr n
fait glisser les bits dans un x vers la droite par n positions. Si x est égal à 34, l'énoncé :
- Y:=X shr 2;
remplace la variable Y par la valeur 8 (ici, un décalage de deux places vers la droite équivaut à une instruction DIV 4). Comme auparavant, l'opérande X lui-même n'est pas affecté. N'oubliez pas qu'un entier signé dénote une valeur négative en plaçant un un dans le bit de poids fort. Étant donné que le décalage vers la droite remplit les bits de gauche avec des zéros, vous pouvez utiliser SHR pour diviser uniquement les nombres positifs.
N'oubliez pas qu'un entier signé dénote une valeur négative en plaçant un un dans le bit de poids fort. Étant donné que le décalage vers la droite remplit les bits de gauche avec des zéros, vous pouvez utiliser SHR pour diviser un nombre positif uniquement.
Les opérateurs SHL et SHR renverront tous deux zéro si l'expression est décalée d'un nombre égal ou supérieur au nombre de bits dans l'entier. Par conséquent, si x est déclaré comme un mot de 16 bits, les deux expressions suivantes :
renverra toujours zéro, quelle que soit la valeur actuelle de x.
Utilisation d'opérateurs au niveau du bit
Les opérateurs NOT, AND, OR et XOR de QuickPascal sont appelés opérateurs au niveau du bit car vous pouvez les utiliser pour effectuer des manipulations Boolean sur les bits individuels dans n'importe quel opérande entier. Les résultats diffèrent, comme le montre le tableau suivant :
Opérande | Hexadécimal | Décimal | Description | |
---|---|---|---|---|
a) 1100 1100 1100 1100 AND 1010 1010 1010 1010 |
$CCCC $AAAA |
52 428 43 690 |
L'opérateur AND binaire compare chaque paire de bits, définissant le résultat uniquement si les deux bits sont définis. Par conséquent, le résultat de $CCCC AND $AAAA est de $8888. | |
b) 1000 1000 1000 1000 1100 1100 1100 1100 OR 1010 1010 1010 1010 |
$8888 $CCCC $AAAA |
34 395 52 428 43 690 |
L'opérateur OR binaire compare chaque paire de bits et définit le résultat si l'un des bits est défini, de sorte que le résultat de $CCCC OU $AAAA est $EEEE. | |
c) 1110 1110 1110 1110 1100 1100 1100 1100 XOR 1010 1010 1010 1010 |
$EEEE $CCCC $AAAA |
61 166 52 428 43 690 |
L'opérateur XOR (eXclusive OR) binaire compare chaque paire de bits et définit le résultat uniquement si les bits sont différents. Le résultat de $CCCC XOR $AAAA est de $6666. | |
d) 0110 0110 0110 0110 NOT 1010 1010 1010 1010 |
$6666 $CCCC |
26 214 52 428 |
L'opérateur unaire NOT renvoie un résultat dans lequel chaque bit est l'inverse du bit de l'opérande. Par conséquent, le résultat de NOT $CCCC est de $5555. |
Exécution d'opérations au niveau du bit
Les opérateurs AND, OR, XOR et NOT sont particulièrement utiles pour les applications dans lesquelles vous souhaitez analyser des bits individuels. Vous pouvez combiner les opérateurs au niveau du bit pour effacer, définir ou inverser des bits individuels dans n'importe quel opérande entier. Il vous suffit de comparer les modèles de bits de l'opérande d'origine avec les modèles de bits que vous souhaitez obtenir dans le résultat.
Supposons, par exemple, que vous souhaitiez examiner la valeur de seulement 3 bits dans un entier de la taille d'un mot nommé Compress, structuré comme suit :
xxxxxx???xxxxxxx |
Votre défi consiste à isoler ces bits (affichés ici avec des points d'interrogation) de tous les autres bits de l'opérande (le symbole x indique qu'il ne s'en soucie pas). Voici la mise en page que vous souhaitez obtenir :
0000000000000??? |
Il s'agit en fait d'un processus en deux étapes. Tout d'abord, vous devez éliminer les bits indésirables. Ensuite, vous devez déplacer les bits restants vers la droite. Vous pouvez extraire les bits que vous voulez en effectuant un AND sur la valeur de Compress avec un motif de uns et de zéros. Ce modèle (plus communément appelé masque) doit contenir un zéro pour chaque bit que vous souhaitez ignorer et un pour chaque bit que vous souhaitez laisser inchangé. Dans ce cas particulier, le masque que vous devez utiliser est de $0380 :
Compress xxxxxx???xxxxxxx $0380 0000001110000000 ---------------- Compress AND 000000???0000000 $0380 |
Enfin, vous pouvez déplacer les bits avec l'opérateur SHR. La valeur des trois bits d'origine est :
La manipulation de bits n'est pas un passe-temps anodin. En fait, à moins que vous ne fassiez de la programmation au niveau du système (c'est-à-dire que vous manipuliez le système d'exploitation lui-même), vous n'utiliserez peut-être jamais d'opérateurs au niveau du bit. Considérez, cependant, que la manipulation de bits était autrefois le domaine exclusif des programmeurs en langage de programmation assembleur. Parce qu'il met à disposition des opérateurs au niveau du bit, le QuickPascal fournit les outils de bas niveau que vous attendez d'un environnement de programmation complet.
Opérateurs et expressions booléens
Vous avez déjà appris comment une seule variable Boolean peut être utilisée pour tester une condition. Ce qui suit est un exemple de variable Boolean dont la valeur détermine si une instruction sera exécutée ou non :
- If PremierePage Then FaireEntete;
La routine FaireEntete ne s'exécutera que si PremierePage est vrai. Cependant, vous devez fréquemment tester des conditions plus complexes impliquant l'état de deux ou plusieurs valeurs Boolean. Supposons que vous souhaitiez que la routine FaireEntete s'exécute uniquement si PremierePage est vrai et MaintenantFaireText est faux. Vous devrez imbriquer les deux tests de condition comme suit :
Ne confondez pas les versions Boolean des opérateurs AND, OR, XOR et NOT avec les versions au niveau du bit. Lorsque vous utilisez les opérateurs sur des opérandes entiers, vous obtenez des résultats entiers, tandis que les opérandes Boolean évaluent les résultats Boolean. Le QuickPascal peut faire la différence par rapport au contexte.
Opérateur de relation
Un opérateur de relation compare deux opérandes. Un opérateur renvoie TRUE si la condition spécifiée par l'opérateur est satisfaite ; sinon, il renvoie FALSE. Les opérateurs relationnels et leurs valeurs de retour sont présentés dans le tableau suivant (le tableau répertorie uniquement l'opérateur relationnel pouvant agir sur les opérandes numériques et de chaîne de caractères) :
Opérateur | Syntaxe | Retourne TRUE si |
---|---|---|
= | A = B | A est égale à B |
<> | A <> B | A est différent que B |
< | A < B | A est inférieur à B |
<= | A <= B | A est inférieur ou égale à B |
> | A > B | A est supérieur à B |
>= | A >= B | A est supérieur ou égale à B |
Vous pouvez utiliser des tests relationnels partout où les expressions Boolean sont autorisées. Voici une utilisation typique dans une instruction IF :
Dans l'exemple, les deux opérandes BalanceCourante et MontantDemander sont (vraisemblablement) les deux variables réelles. En général, les opérateurs relationnels ne peuvent agir que sur des types compatibles. Il existe des règles formelles pour la compatibilité des types, mais il vous suffit de vous rappeler une règle simple : bien qu'un opérande entier puisse être comparé à un opérande réel, le non-sens résultant de tout autre mélange (comme IF 'CHAT' > 8 THEN ... ) produira inévitablement une erreur.
Vous pouvez utiliser l'opérateur NOT pour annuler l'état d'une valeur Boolean. Par exemple, si (Ligne>55) est faux, NOT (Ligne>55) est vrai. Avant de faire cela, cependant, n'oubliez pas que chaque opérateur relationnel a un opposé. Vous pouvez utiliser <> au lieu de NOT =, et vous pouvez utiliser < et > pour NOT >= et NOT <=, respectivement.
Priorité des opérateurs revisitée
Étant donné que vous pouvez utiliser des opérateurs arithmétiques et Boolean dans la même expression, vous devez connaître leur priorité relative. Le tableau suivant résume la priorité de tous les opérateurs discutés jusqu'à présent :
Niveau de préséance | Opérateurs |
---|---|
1. (haute) | NOT, unaire +, - |
2. | *, /, DIV, MOD, AND, SHL, SHR |
3. | Binaire +, -, OR, XOR |
4. (basse) | =, <>, <, >, <=, >= |
Notez que les opérateurs relationnels ont la priorité la plus basse. Cela signifie que lorsque vous combinez des opérateurs arithmétiques et relationnels dans la même expression, les opérateurs arithmétiques agissent en premier. Ainsi, dans la déclaration :
l'addition se fait en premier. Si les deux opérateurs avaient la même priorité, le résultat Boolean de Dette > MontantEnBanque serait ajouté à l'opérande numérique LigneCredit, entraînant une erreur.
Cette structure de priorité a un sens intuitif pour la plupart des expressions. Vous devrez cependant utiliser des parenthèses dans certaines situations. En particulier, chaque clause Boolean dans une expression composée doit être placée entre parenthèses, comme dans :
Sans parenthèses, le QuickPascal calculerait d'abord le résultat de 90 OR Humiditer, et une erreur de syntaxe suivrait sous peu.
Opérateurs et expressions de caractères et de chaînes de caractères
Les opérandes de caractère et de chaîne de caractères n'apparaissent généralement pas dans une expression avec des opérandes arithmétiques et Boolean. Cependant, de nombreux opérateurs déjà décrits peuvent également être appliqués dans des expressions de caractères et de chaînes de caractères.
Notez que chaque fois que des opérandes de caractère et de chaîne de caractères apparaissent dans la même expression. Le QuickPascal traite un opérande de type CHAR comme une STRING de longueur un. Par conséquent la référence à une chaîne de caractères signifie un opérande Char ou STRING.
Comparaison de caractères et de chaînes de caractères
Vous pouvez utiliser les opérateurs relationnels pour comparer des caractères et des chaînes de caractères. Deux chaînes de caractères sont toujours comparées lexicographiquement, ce qui signifie qu'elles ont le même ordre que les mots d'un dictionnaire. La séquence est basée sur la valeur ASCII de chaque caractère de la chaîne de caractères. La taille déclarée d'une chaîne de caractères est ignorée ; seul le contenu actuel compte. Le tableau suivant fournit quelques exemples de comparaisons de chaînes de caractères :
Expression | Résultat |
---|---|
'ELEPHANT' < 'SOURIS' | TRUE |
'CRAYON' > 'EPEE' | FALSE |
'minute' > 'heure' | TRUE |
'Ceci' = 'Ceci' | FALSE |
Étant donné que les chaînes de caractères sont classées par leur valeur ASCII, vous pourriez obtenir des résultats apparemment étranges. Par exemple, l'expression 'a' >; 'z' est vraie, mais l'expression 'A' > 'z' est fausse. De même, tous les blancs de début et de fin sont significatifs, comme vous pouvez le voir dans l'exemple final du tableau précédent.
Concaténation de caractères et de chaînes de caractères
Vous pouvez utiliser l'opérateur de concaténation (+) pour créer une seule chaîne de caractères en combinant deux ou plusieurs opérandes STRING. La longueur déclarée d'une opérande STRING est sans importance ; seule la partie actuellement active de la chaîne de caractères est affectée.
Si la longueur totale des opérandes est supérieure à la longueur déclarée de la chaîne de caractères résultante, tous les caractères dépassant la variable de destination seront tronqués et perdus. N'oubliez pas qu'aucune chaîne de caractères ne peut dépasser 255 caractères. Voici un exemple de concaténation :
- Str1:='Le renard brun rapide';
- Str2:=' ';
- Str3:='saute par-dessus le chien paresseux';
- Str4:=Str1+Str2+Str3;
Après l'exécution de ces instructions, la variable Str4 contient : «Le renard brun rapide saute par-dessus le chien paresseux».