Variables II : Opérations

Nous allons, dans ce chapitre, aborder les opérations que l'on peut effectuer sur les différents types de variables : Integer, Natural, Float et Character. En effet, il ne suffit pas de créer des variables et de leur affecter une valeur ; encore faut-il qu'elles servent à quelque chose, que l'on effectue quelques opérations avec elles sans quoi, le compilateur GNAT risque de nous renvoyer le message suivant:

Warning : variable «Machin» is never read and never assigned

Autrement dit, votre variable ne sert à rien ! :p

Un dernier rappel : toutes les opérations d'affectation devront être écrites, je le rappelle, entre BEGIN et END.

Opérations sur les Integer et les Natural

Voici quelques opérations de base.

Symbole

Opération

Exemple

+

Addition

N := 3 + 4 (résultat 7)

-

Soustraction

N := 5 - 4 (résultat 1)

*

Multiplication

N := 3 * 4 (résultat 12)

/

Division euclidienne (sans nombre à virgule)

N := 7 / 2 (résultat 3 et pas 3.5)

mod

Modulo ("reste" de la division euclidienne)

N := 7 mod 2 (résultat 1)

**

Puissance

N := 5**2 (résultat 25 car 5*5 = 25)

Je pense que les exemples abordés précédemment parlent d'eux-mêmes, mais ils sont très faciles. Voici quelques exemples un peu plus complexes :

1
2
3
4
5
Get(N) ; skip_line ; --on saisit deux variables de type Integer
Get(M) ; skip_line ;  

Resultat := N + M + 1 ; --La variable Resultat prend la valeur résultant 
                        --de l'addition des deux variables N et M

Au lieu d'effectuer un calcul avec des valeurs connues, il est possible de faire des calculs avec des variables dont on ne connait pas, a priori, leur valeur.

Pour que votre programme soit compilé, il faut ABSOLUMENT que Resultat, N et M soient tous des Integer ! Il est toutefois possible de mélanger des Integer et des Natural dans un même calcul car les Natural sont un sous-type des Integer.

Voici une autre utilisation possible de ces opérations :

1
2
N := 5 + 5 *2 ; 
M := 15 - (3+2) ;

Combien vaudront N e M selon vous ? Si vous me répondez 20 et 14 alors je vais devoir vous rappeler les règles de priorité en Mathématiques. Ada respecte ces priorités. Dans le premier cas, Ada commence par effectuer la multiplication avant d'additionner : N vaut donc 15. Dans le second cas, les parenthèses ont la priorité donc M vaut 10. Un dernier exemple :

1
2
Get(Var) ; skip_line ; --on saisit une variable de type integer
Var := Var + 1 ;

Comment ? Var est égal à Var + 1 ?!?

NON ! Le symbole n'est pas = mais := ! Ce n'est pas un symbole d'égalité mais d'affectation ! Supposons que Var soit égal à 5. L'ordinateur commencera par calculer Var + 1 qui vaudra 6. Le code ci-dessus affectera donc 6 à la variable Var, qui valait auparavant 5. On augmente donc la valeur de la variable d'une unité, c'est l'incrémentation. Ne vous avais-je pas dit que les variables variaient ? ^^

Opérations sur les float

Opérations élémentaires

Voici quelques opérations sur les float.

Symbole

Opération

Exemple

+

Addition

X := 3.0 + 4.1 (résultat 7.1)

-

Soustraction

X := 5.8 - 4.3 (résultat 1.5)

*

Multiplication

X := 3.5 * 4.0 (résultat 14)

/

Division décimale

X := 7.0 / 2.0 (résultat 3.5)

**

Puissance

X := 36.0**0.5 (résultat 6, la puissance 0.5 équivaut à la racine carre)

ABS

Valeur absolue

X := ABS(-8.7) (résultat 8.7)

Globalement, on retrouve les mêmes opérations qu'avec les Integer et les Natural. Attention toutefois à ne pas additionner, soustraire ou multiplier… un Integer et un Float. Si le symbole de l'addition est le même pour les deux types, il s'agit dans les faits de deux instructions distinctes : l'une pour les Integer, l'autre pour les Float.

Ne faites pas d'erreur de casting

Mais comment je fais si j'ai besoin d'additionner un Float et un Integer ?

C'est très simple, vous devrez effectuer des conversions (aussi appelées cast). Les conversions de types se font très simplement en Ada : il suffit d'encadrer le nombre ou le calcul à convertir avec des parenthèses et d'écrire le type désiré devant ces mêmes parenthèses. Voici un exemple :

1
2
3
4
5
6
7
8
9
Procedure addition is
   M : integer := 5 ; 
   X : float := 4.5 ; 
   Res_int : integer ;
   Res_float : float ; 
Begin
   Res_int := M + Integer(X) ;   Put(Res_int) ; 
   Res_float := Float(M) + X ;   Put(Res_float) ; 
End addition ;

L'instruction Integer(X) permet d'obtenir la valeur entière de la variable X. Comme X vaut 4.5, Integer(X) donnera comme résultat 4. L'instruction Float(M) permet d'obtenir l'écriture décimale de la variable M. Comme M vaut 5, Float(M) donnera comme résultat 5.0.

Opérations mathématiques

J'aurais besoin de faire des calculs plus poussés, existe-t-il des opérations comme le sinus ou le logarithme ?

Par défaut, ces opérations n'existent pas dans le langage Ada. Mais il existe des packages vous permettant tout de même de les utiliser. Ainsi, si au tout début de votre programme vous ajoutez le package Ada.Numerics, vous aurez alors la possibilité d'utiliser les constantes $\pi$ et $e$ ($e$ étant la constante de Neper). Exemple :

1
2
P := 2 * Pi * 10 ;  --Calcule le périmètre d'un cercle de rayon10
put(e**2) ;         --Calcule et affiche e au carré

Mais le package Ada.Numerics.Elementary_Functions vous sera plus utile encore car il contient les fonctions trigonométriques et logarithmiques essentielles. Vous trouverez entre autres :

Symbole

Opération

Exemple

Sqrt( )

Racine carrée

X := Sqrt(36.0) (résultat 6.0 car $6 \times 6 = 36$)

Log( )

Logarithme népérien

X := Log(e) (résultat 1.0)

Exp( )

Exponentielle

X := Exp(1.0) (résultat environ 2.71828 soit la constante de Neper)

Cos( )

Cosinus

X := cos(pi) (résultat -1.0)

Sin( )

Sinus

X := sin(pi) (résultat 0.0)

Tan( )

Tangente

X := tan(pi) (résultat 0.0)

Arccos( )

Arc Cosinus

X := arccos(1.0) (résultat 0.0)

Arcsin( )

Arc Sinus

X := arcsin(0.0) (résultat 0.0)

Arctan( )

Arc Tangente

X := arctan(0.0) (résultat 0.0)

A ces opérations s'ajoutent également les fonctions hyperboliques : le cosinus hyperbolique (noté cosh), le sinus hyperbolique (noté sinh), la tangente hyperbolique (noté tanh) et leurs réciproques, l'arccosinus hyperbolique (noté arccosh), l'arcsinus hyperbolique (noté arcsinh) et l'arctangente hyperbolique (noté arctanh). Celles-ci s'utilisent de la même manière que leurs homologues trigonométriques.

Opérations sur les character

Nous avons déjà parlé dans la partie précédente des attributs. Nous aurons encore besoin d'eux dans cette partie pour effectuer des «opérations» sur les character. Voici un tableau récapitulatif de quelques attributs applicables au type character (n'oubliez pas d'écrire l'apostrophe !) :

Attribut

Explication

Exemple

'first

Renvoie le premier de tous les caractères.

c:=character'first ;

'last

Renvoie le dernier de tous les caractères.

c:=character'last ;

'pos(#)

Renvoie la position du caractère remplaçant #. Attention, le résultat est un Integer.

n := character'pos('z') ;

'val(#)

Renvoie le #ème caractère. Attention, le symbole # doit être remplacé par un Integer

c:=character'val(165) ;

'succ(#)

Renvoie le character suivant

c:=character'succ(c) ;

'pred(#)

Renvoie le character précédent

c:=character'pred(c) ;

Nous avons vu au chapitre précédent que certains langages autorisaient l'écriture du calcul «'a' + 1» pour obtenir le character 'b'. Pratique et rapide ! Seul souci, on mélange deux types distincts : Character et Integer. Ce genre d'écriture est donc prohibée en Ada. On utilisera donc les attributs de la manière suivante :

1
character'val(character'pos('a') + 2) ;

Explication : Ada suit le principe de la priorité des parenthèses donc les calculs seront effectués dans l'ordre suivant:

  • character'pos('a') va renvoyer le numéro de 'a', sa position dans la liste des characters disponibles.
  • Puis on effectue l'addition (Position de 'a' + 2). Ce qui renvoie un nombre entier correspondant à la position du 'c'.
  • Enfin, character'val() transformera le résultat obtenu en character : on devrait obtenir ainsi le character 'c' !

Qui plus est, cette opération aurait pu être faite à l'aide de l'attribut 'succ :

1
character'succ(character'succ('a')) ;

Si ces écritures vous semblent compliquées, rassurez-vous, nous ne les utiliserons pas tout de suite et nous les reverrons plus en détail dans le chapitre sur les fonctions.

Exercices

Pour mettre tout de suite en pratique ce que nous venons de voir, voici quelques exercices d'application.

Exercice 1

Énoncé

Rédigez un programme appelé Multiple qui demande à l'utilisateur de saisir un nombre entier et lui retourne son double, son triple et son quintuple. J'ajoute une difficulté: vous n'aurez le droit qu'à deux multiplications. Pas une de plus !

Solution

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
WITH Ada.Text_IO, Ada.Integer_Text_IO ; 
USE Ada.Text_IO, Ada.Integer_Text_IO ; 

PROCEDURE Multiple IS 
   N : Integer ; 
   Double, Triple : Integer ;
BEGIN
   Put("Saisissez un nombre entier : ") ; 
   Get(N) ; Skip_Line ; 
   
   Double := 2*N ; 
   Triple := 3*N ;
   
   Put("Le double de ") ; Put(N) ; Put(" est ") ; Put(Double) ; New_Line ; 
   Put("Le triple de ") ; Put(N) ; Put(" est ") ; Put(Triple) ; New_Line ; 
   Put("Le quintuple de ") ; Put(N) ; Put(" est ") ; Put(Double+Triple) ; 
      
END Multiple ;

Exercice 2

Énoncé

Rédigez un programme appelé Euclide qui demande deux nombres entiers à l'utilisateur puis renvoie le quotient et le reste de leur division euclidienne (c'est-à-dire la division entière telle que vous l'avez apprise en primaire).

Solution

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
WITH Ada.Text_IO, Ada.Integer_Text_IO ; 
USE Ada.Text_IO, Ada.Integer_Text_IO ; 

PROCEDURE Euclide IS 
   N,M : Integer ; 
BEGIN
   Put("Saisissez le dividende : ") ; 
   Get(N) ; Skip_Line ; 
   Put("Saisissez le diviseur : ") ; 
   Get(M) ; Skip_Line ; 
   
   Put("La division de ") ; Put(N) ; 
   Put(" par ") ; Put(M) ; 
   Put(" a pour quotient ") ; Put(N/M) ; 
   Put(" et pour reste ") ; Put(N mod M) ; 
      
END Euclide ;

Exercice 3

Énoncé

Rédigez un programme appelé Cercle qui demande à l'utilisateur de saisir la longueur d'un rayon d'un cercle et qui affichera le périmètre et l'aire de ce cercle. Contrainte : le rayon du cercle sera un nombre entier !

Le périmètre du cercle se calcule en multipliant le rayon par 2 et par Pi. L'aire du disque se calcule en élevant le rayon au carré et en le multipliant par Pi. Pi vaut environ 3,1415926535.

Solution

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
WITH Ada.Text_IO, Ada.Integer_Text_IO, Ada.Float_Text_IO ; 
USE Ada.Text_IO, Ada.Integer_Text_IO, Ada.Float_Text_IO ; 

PROCEDURE Cercle IS 
   R : Integer ; 
   PI : constant float := 3.1415926 ;
BEGIN
   Put("Saisissez le rayon du cercle : ") ; 
   Get(R) ; Skip_Line ; 
      
   Put("Un cercle de rayon ") ; Put(R) ; 
   Put(" a pour perimetre ") ; Put(2.0*PI*float(R)) ; 
   Put(" et pour aire ") ; Put(float(R**2)*Pi) ; 
      
END Cercle ;

Exercice 4

Énoncé

Rédigez un programme appelé Lettres qui demande à l'utilisateur de saisir deux lettres minuscules et qui affichera leur majuscule ainsi que la lettre se trouvant «au milieu» des deux. À défaut, s'il y a deux lettres, le programme choisira la «plus petite».

Pour obtenir la lettre majuscule, il suffit de lui «soustraire 32» (avec les précautions d'usage bien sûr).

Solution

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
WITH Ada.Text_IO ; 
USE Ada.Text_IO ; 

PROCEDURE Lettres IS 
   C1,C2,C3 : character ; 

BEGIN
   Put("Saisissez une premiere lettre minuscule : ") ; 
   Get(C1) ; Skip_Line ; 
   Put("Sa majuscule est ") ; Put(Character'Val(Character'Pos(C1)-32)) ; New_Line ;
   
   Put("Saisissez une deuxieme lettre minuscule : ") ; 
   Get(C2) ; Skip_Line ; 
   Put("Sa majuscule est ") ; Put(Character'Val(Character'Pos(C2)-32)) ; New_Line ;
   
   C3 := character'val((character'pos(C1) + character'pos(C2))/2) ;

   Put("La lettre du milieu est ") ; Put(C3) ; 
      
END Lettres ;

Nous voilà désormais armés pour effectuer des calculs, simples ou complexes, sur les différents types de variables connus pour l'heure. Nous aurons l'occasion de les réutiliser par la suite et de comprendre toute leur utilité, notamment pour l'opération MOD, qui doit pour l'instant vous sembler bien inutile (et pourtant elle sera plus utile que vous ne le pensez).Le prochain chapitre devrait nous permettre d'apporter plus de variété encore à nos programmes en proposant des choix.


En résumé :

  • Les quatre opérations de base sont accessibles sur le pavé numérique de votre clavier : +, -, * et /.
  • Ada respecte les priorités mathématiques et notamment les parenthèses.
  • Ada est un langage «à fort typage», ce qui implique l'impossibilité de mélanger des types distincts comme additionner un Integer et un Float. Toutefois, des conversions sont possibles.