Version en ligne

Tutoriel : Apprendre à programmer avec Ada

Table des matières

Apprendre à programmer avec Ada
Programmation, algorithmique et Ada ?
Qu'est-ce qu'un programme ?
Comment réaliser un programme ?
Pourquoi Ada et pas autre chose ?
Les logiciels nécessaires
IDE et compilateur : kesako ?
Télécharger et installer Adagide.
Télécharger et installer GNAT.
Télécharger et installer GPS
Notre premier programme en Ada
Découvrir son IDE en quelques secondes
Notre premier programme
Mon dieu, qu'ai-je fait ?
Vous en voulez encore ?
Variables I : Typage et affectation
Déclaration de variables
Différents types
Affectation
Constantes et attributs
Variables II : Opérations
Opérations sur les Integer et les Natural
Opérations sur les float
Opérations sur les character
Exercices
Les conditions I
Conditions simples avec IF
Conditions multiples avec IF
Conditions multiples avec CASE
Les opérateurs de comparaison
Les conditions II : les booléens
Introduction aux booléens
La négation avec Not
Les opérations Or et And
L'opération xor (optionnel)
Bilan de notre programme
Priorités booléennes et ordre de test (Supplément)
Les boucles
La boucle Loop simple
La boucle While
La boucle For
Les antiquités : l'instruction goto
Boucles imbriquées
Exercices
Procédures et fonctions I
Les procédures
Les fonctions
Prédéfinir ses paramètres
In, Out, In Out
[TP1] le craps
Les règles du craps
Cahier des charges
Simuler le hasard (ou presque)
Un plan de bataille
Une solution
Les tableaux
Les types composites, c'est quoi ?
Tableaux unidimensionels
Tableaux multidimensionels
Des tableaux un peu moins contraints
Quelques exercices
Les chaînes de caractères
Présentation des Chaînes de Caractères
Déclaration et affectation d'un string
Quelques opérations sur les strings
Chaînes de caractères non contraintes
La programmation modulaire I : les packages
Les fichiers nécessaires
Notre première procédure... empaquetée
Compléter notre package (exercices)
Compléter notre package (solutions)
Vecteurs et calcul vectoriel (optionnel)
Les fichiers
Ouvrir / Fermer un fichier texte
Le paramètre Mode
Opérations sur les fichiers textes
Les fichiers binaires séquentiels
Les fichiers binaires directs
Quelques exercices
Créer vos propres objets
Créer à partir de types prédéfinis
Enumérer les valeurs d'un type
Les types structurés
Les types structurés : polymorphes et mutants !
[TP2] logiciel de gestion de bibliothèque
Cahier des charges
Conception du programme (suivez le guide)
Solutions possibles
Les pointeurs I : allocation dynamique
Mémoire, variable et pointeur
Le type access
Libération de la mémoire
Exercices
Les pointeurs II
Cas général
Pointeur comme paramètre
Pointeur sur un programme (optionnel)
Exercices
Fonctions et procédures II : la récursivité
Une première définition
Exemple d'algorithme récursif
Un premier exemple de fonction récursive
Algorithme de recherche par dichotomie
Quelques exercices
Les Types Abstraits de Données : listes, files, piles ...
Qu'est-ce qu'un Type Abstrait de Données ?
Les piles
Les files
Les listes chaînées
[TP3] le jeu du serpent
Cahier des charges
Un package bien utile
... et encore un autre !
Quelques indications
Une solution possible
Algorithmique : tri et complexité
Algorithmes de tri lents
Algorithmes de tri plus rapides
Théorie : complexité d'un algorithme
Mesures de complexité des algorithmes
Variables III : Gestion bas niveau des données
Représentation des nombres entiers
Représentation du texte
Représentation des nombres décimaux en virgule flottante
La programmation modulaire II : Encapsulation
Qu'est-ce qu'un objet ?
Un package... privé
Un package privé et limité
Exercices
La programmation modulaire III : Généricité
Généricité : les grandes lignes.
Créer et utiliser une méthode générique
Paramètres génériques de types simples et privés
Paramètres génériques de types composites et programmes
Packages génériques
La programmation modulaire IV : Héritage et dérivation
Pour bien commencer
Héritage
Dérivation et types étiquetés
La programmation modulaire V : Polymorphisme, abstraction et héritage multiple
Polymorphisme
Abstraction
Héritage multiple
La programmation modulaire VI : Finalisation et types contrôlés
Objectifs et prérequis
Mise en œuvre
[TP4] Bataille navale
Règles du jeu
Cahier des charges
Une solution possible
Les exceptions
Fonctionnement d'une exception
Traitement d'une exception
Exceptions prédéfinies
Créer et lever ses propres exceptions
Assertions et contrats
Multitasking
Parallélisme, tâches et types tâches
Communication inter-tâche directe
Communication inter-tâche indirecte
Compléments : priorités et POO
Exercices fondamentaux
GTKAda : introduction et installation
Vous avez dit GTK ?
Télécharger et installer GTKAda
Votre première fenêtre
Analysons notre code
Personnaliser la fenêtre
Ajout d'un widget
Retour sur la POO
Les conteneurs I
Des conteneurs pour ... contenir !
Les alignements
Les boîtes
Les tables
Le widget pour position fixe
Les signaux
Le principe
Connecter un signal à un callback
Interagir avec les widgets
Les widgets I
Les étiquettes
Les images
Les zones de saisie
D'autres boutons
Les boîtes de dialogue
Widgets divers

Apprendre à programmer avec Ada

Vous voudriez apprendre à programmer mais ne savez pas par où commencer ? Vous avez commencé à apprendre le C mais vous vous embrouillez dans les accolades et autres symboles bizarroïdes ? Ou encore vous souhaitez apprendre un nouveau langage de programmation ? Alors ce tutoriel est fait pour vous.

Le langage Ada est certainement le meilleur langage pour apprendre à programmer : pour peu que vous connaissiez deux ou trois mots d'anglais, il vous sera facile de lire un code en Ada. Moins abstrait que beaucoup de langages, mais toutefois rigoureux, facilement compréhensible et lisible, même par un novice ... le langage Ada vous permettra de comprendre les logiques propres à la programmation et vous donnera tout de suite de bonnes habitudes.

Qui plus est, le langage Ada ne présente ni plus ni moins de fonctionnalités que les langages les plus connus (C, C++, Java, Python...). Il est seulement différent et, je me répète, plus compréhensible pour un novice.

Alors si vous êtes intéressé, nous allons pouvoir débuter de tutoriel. ;)

Ce tutoriel est prévu pour être organisé en six parties :

Le cours sera ponctué de travaux pratiques. Ce sont des chapitres vous proposant un projet (parfois ludique) allant du logiciel de gestion de vos DVD à des jeux de dés. Ils seront pour vous l'occasion de mettre en application vos connaissances acquises. Ces travaux pratiques sont signalés dans leur titre par la notation [TP#] (le symbole # étant remplacé par le numéro du TP). De plus, ils portent tous l'icône :

Image utilisateur

Programmation, algorithmique et Ada ?

Qu'est-ce qu'un programme ?

Nous allons dans ce chapitre répondre à quelques questions préliminaires. Qu'est-ce qu'un programme ? A quoi cela ressemble-t-il ? Comment crée-t-on un programme ? Qu'est-ce que l'algorithmique ? Pourquoi Ada et pas un autre langage ? Ce que j'apprends ici sera-t-il utilisable avec un autre langage ?

Bref, beaucoup de réponses existentielles trouveront (je l'espère) leur réponse ici. Ce chapitre, relativement court et sans difficultés, permettra de poser un certain nombre d'idées et de termes. Pour bien commencer, mieux vaut en effet que nous ayons le même vocabulaire. ;)

A ceux qui auraient déjà des notions de programmation, vous pouvez bien entendu éviter ce chapitre quoique je ne saurais trop vous conseiller d'y jeter un œil, histoire de remettre quelques idées au clair.

Qu'est-ce qu'un programme ?

Programmation, algorithmique et Ada ? Comment réaliser un programme ?

Avant de commencer, il est important que nous nous entendions sur les termes que nous allons utiliser.

Qu'appelle-t-on programme ?

Les programmes sont des fichiers informatiques particuliers. Sous Windows, ce sont généralement des fichiers se terminant par l'extension .exe ; sous MacOS ce sont globalement des fichiers .app ; sous Linux ce sont schématiquement des fichiers .bin. Cette explication est très (TRÈS) schématique, car d'autres types de fichiers peuvent correspondre à des programmes.

Ces fichiers ont comme particularité de ne pas seulement contenir des données, mais également des instructions. Lorsque vous ouvrez un fichier .exe sous windows, celui-ci transmet à votre ordinateur une liste de choses à faire comme :

Cette liste d'instructions envoyées au processeur, forme alors ce que l'on appelle un processus.

Voici quelques images de programmes :

Image utilisateur
Image utilisateur
Image utilisateur

Attention, tous les programmes ne sont pas nécessairement visibles. Beaucoup n'ouvrent même pas de fenêtre ! Pour s'en rendre compte, sous Windows, appuyez simultanément sur les touches Alt + Ctrl + Suppr puis cliquez sur le second onglet, cela affichera la liste de tous les processus en cours.

Image utilisateur

Bon nombre d'entre eux effectuent des tâches tranquillement sans que vous ne vous en rendiez compte.

Alors qu'allons-nous faire ?

Eh bien, programmer (en Ada ou autre) c'est tout simplement créer des programmes. Mais je vous arrête tout de suite, malgré tout le talent de votre humble guide, :p vous ne confectionnerez pas un jeu vidéo en 3D d'ici la fin de ce tutoriel. La plupart des logiciels, comme le navigateur internet que vous utilisez actuellement, exigent la participation de nombreuses personnes et de nombreuses autres compétences ne relevant pas de ce cours (modélisation 3D par exemple).

Les premiers programmes que nous allons concevoir seront des programmes en console. C'est à dire qu'ils ressembleront à ce qui suit :

Image utilisateur

Nous ne pourrons utiliser que le clavier ! Pas de souris ou de joystick ! Pas d'images ou de vidéos ! Pas de 3D puisqu'il n'y aura même pas de 2D ! Que tu texte blanc sur fond noir.

:waw: Aaargh ! Mais, c'est possible ?

Bon, c'est vrai qu'aujourd'hui on a tendance à oublier la console, mais il est nécessaire de passer par ce stade pour apprendre les bases de la programmation. Nous pourrons ensuite nous atteler à des programmes plus conséquents (avec des boutons, des images, la possibilité d'utiliser la souris ... ). Il faudra être patient ;)


Programmation, algorithmique et Ada ? Comment réaliser un programme ?

Comment réaliser un programme ?

Qu'est-ce qu'un programme ? Pourquoi Ada et pas autre chose ?

Alors comment faire pour créer votre propre programme ? Il faut avant tout savoir comment est constitué un programme (ou tout autre type de fichier). Vous le savez peut-être déjà, mais un ordinateur a un langage très très basique. Il ne connaît que deux chiffres : 1 et 0 ! Donc tout fichier (et donc tout programme) ne peut ressembler qu'à ceci :

10001001111010110110111011011 ...

Ca rappelle Matrix ! :lol: Mais comment je fais moi ? J'y comprends rien moi à tous ces chiffres ? Il faut faire Math sup pour afficher une fenêtre ?

Non, rassurez-vous. Personne n'est capable de créer un programme informatique ainsi. C'est pourquoi ont été inventés différents langages pour la programmation : le Pascal, le Basic, le C, le C++, le Python, le Java ... et bien sûr l'Ada. Ce sont ce que l'on appelle des langages de haut niveau. A quoi cela ressemble-t-il ? voyez vous-même :

with Ada.Text_IO, Ada.Integer_Text_IO ; 
use Ada.Text_IO, Ada.Integer_Text_IO ; 

procedure exemple is
   n : integer ; 
begin
   loop
      Put("Saisir un nombre : ") ; 
      Get(n) ; Skip_line ; 
      if n mod 2 = 0
         then Put("Ce nombre est pair ! Tres bien !") ; exit ; 
         else Put("Ce nombre est impair ! Recommencez. ") ; 
      end if ; 
   end loop ; 
end exemple ;

Vous serez capables d'ici quelques chapitres de comprendre ce texte aisément. C'est comme apprendre une langue étrangère ; d'ailleurs si vous connaissez l'Anglais vous avez peut-être reconnu quelques mots (end, if, else, then, begin, is). C'est ainsi que nous créerons nos programmes.

Et comment on traduit ça en 1 et en 0 ?

Une fois notre texte rédigé en Ada (mais c'est aussi valable pour les autres langages), il faudra utiliser un programme-traducteur pour le convertir en un programme lisible par l'ordinateur. Les programmes-traducteurs sont appelés compilateurs.


Qu'est-ce qu'un programme ? Pourquoi Ada et pas autre chose ?

Pourquoi Ada et pas autre chose ?

Comment réaliser un programme ? Les logiciels nécessaires

Algorithmique

Il ne vous reste donc plus qu'à apprendre un langage de programmation, et avec ce langage, vous apprendrez également ce que l'on appelle l'algorithmique.

Qu'est-ce que c'est encore que ça ?

L'algorithmique est une branche des mathématiques qui traite de la résolution de problèmes à l'aide d'instructions simples. J'en vois déjà certains qui paniquent à la vue du mot "Mathématiques", mais n'ayez crainte vous avez déjà vu plusieurs fois dans votre vie des algorithmes. Par exemple, comment faire pour diviser 742 par 5 ? Vous vous souvenez, c'était en primaire ? Vous aviez appris à poser l'opération comme ci-dessous et à répéter les instructions suivantes :

Image utilisateur

Dans 7, combien de fois 5 ?

Image utilisateur

Il y va 1 fois et il reste 2 !

Image utilisateur

On abaisse le 4 derrières le reste. Dans 24, combien de fois 5 ?
Il y va 4 fois et il reste 4.

Image utilisateur

On abaisse le 2 derrières le reste. Dans 42, combien de fois 5 ?
Il y va 8 fois et il reste 2.

Il n'y a plus de chiffre à abaisser. On arrête : le résultat est 148 et il reste 2 !.

Eh bien ça, c'était un algorithme : vous répétiez des instructions simples dans un certain ordre (abaisser les chiffres de 742, se demander "dans machin, combien de fois truc ?"...) afin de résoudre un problème plus compliqué (combien vaut $$742 \div 5$$ ?). Et tout programme informatique n'est en fait qu'un algorithme écrit dans un langage compréhensible par votre ordinateur. Donc apprendre à programmer, c'est en fait apprendre la science de l'algorithmique dans un langage informatique donné.

Pourquoi Ada ?

Mais alors, pourquoi apprendre l'Ada et pas simplement l'algorithmique ? Et pourquoi l'Ada et pas un autre langage ?

Tout d'abord, l'algorithmique n'est pas compréhensible par les ordinateurs, je vous rappelle que c'est une science. L'algorithme de la division euclidienne vu au-dessus est expliqué en Français, or je vous ai dit qu'il doit être écrit dans un langage qui pourrait être traduit par un compilateur, un langage très structuré et normé (qui ne changera pas en changeant de compilateur), et ça c'est ce qu'on appelle la programmation. Et l'Ada répond à ces exigences.

Maintenant, pourquoi Ada et pas un autre langage ? Il est vrai que l'Ada n'est pas le langage le plus répandu. Mais il présente de nombreux avantage par rapport à d'autres langages plus répandus comme le C, le C++, le Java ...

Tout d'abord il présente un avantage pédagogique. Ada consitue un langage parfait pour apprendre à programmer. D'ailleurs de nombreuses écoles ou universités l'utilisent comme support à leurs cours de programmation. La rigueur qu'il impose au programmeur permet aux débutants d'apprendre à coder correctement, de prendre de bonnes habitudes qu'ils conserveront par la suite, même s'ils venaient à changer de langage de programmation durant leur carrière. Qui plus est, c'est un langage facilement lisible car il utilise des mots complets (begin, end, function, if ... c'est de l'Anglais en effet) plutôt que les symboles "barbares et bizarroïdes" pour un débutant que préfèrent la plupart des langages actuels. Les codes des programmes sont certes moins condensés, mais plus faciles à reprendre en cas de bogue ce qui constitue un avantage non négligeable quand on sait que les coûts de maintenance d'un logiciel sont souvent plus élevés que le coût de son développement.

Ensuite, le langage présente également des avantages pour les professionnels. Son fort typage (vous aurez l'occasion de le découvrir durant la deuxième partie) ou sa très bonne gestion des erreurs (abordé lors de la quatrième partie) garantissent des programmes fiables. Ce n'est pas pour rien qu'Ada est utilisé pour de gros projets comme Ariane, chez Thalès pour ses avions ou radars, ou encore pour la sécurité des centrales nucléaires, du trafic aérien ou ferroviaire ... Utiliser Ada est un gage de fiabilité et pour cause, il a été développé par le département de la défense américain, le fameux DoD (vous vous doutez bien que rien n'a été laissé au hasard ;) ).

Maintenant que ces quelques explications préliminaires sont faites, j'espère que vous vous sentez toujours prêts à vouloir apprendre un langage. Si cela vous semble compliqué, n'ayez crainte, nous commencerons doucement et je vous guiderai pas à pas. Nos premiers programmes seront peut-être inutiles ou ringards, mais nous apprendrons peu à peu de nouvelles notions qui nous permettront de les perfectionner.

Alors, en avant pour l'installation des logiciels nécessaires ! :pirate:


Comment réaliser un programme ? Les logiciels nécessaires

Les logiciels nécessaires

Pourquoi Ada et pas autre chose ? IDE et compilateur : kesako ?

Nous allons au cours de ce chapitre, télécharger et installer les logiciels nécessaires à l'utilisation d'Ada.

Comment ça LES logiciels ? Il n'y a pas un seul logiciel Ada ?

Eh bien non. Comme tout langage, Ada a besoin de deux types de logiciels : un éditeur de texte avancé (appelé IDE) et un compilateur. Nous utiliserons l'IDE appelé Adagide (même si le logiciel GPS pourra être utilisé) et le compilateur GNAT. Après quoi nous pourrons découvrir (enfin) le joyeux monde de la programmation.

IDE et compilateur : kesako ?

Les logiciels nécessaires Télécharger et installer Adagide.

Le compilateur

Nous avons dors et déjà parlé du compilateur : il s'agit d'un programme qui va traduire notre langage Ada en un vrai programme utilisable par l'ordinateur. Le compilateur est aussi chargé de vérifier la syntaxe de notre code : est-il bien écrit ? Sans fautes d'orthographe ou de grammaire ? Il existe plusieurs compilateurs en Ada, mais rassurez-vous, quel que soit celui que vous choisirez, les règles sur le langage Ada seront toujours les mêmes car Ada est un langage normé (il bénéficie d'une norme internationale assurant que tous les compilateurs Ada respecteront les mêmes règles). Il existe plusieurs compilateurs Ada (vous en trouverez une liste à l'adresse suivante), mais la plupart sont des programmes payants et propriétaires.

Euh ... c'était pas prévu au contrat ça ! o_O

Rassurez-vous, nous allons plutôt opter pour un compilateur libre et gratuit. ;) Ce compilateur s'appelle GNAT et est développé par la société Adacore. Il a longtemps été payant mais une version gratuite existe désormais (GNAT GPL).

L'IDE ou EDI

Mais le compilateur n'est en définitive qu'un "traducteur". Il ne créera pas de programme à votre place, c'est à vous d'écrire les instructions dans des fichiers textes. Pour cela, vous pouvez écrire vos documents sous l'éditeur de texte de votre ordinateur (notepad sous Windows par exemple), ou utiliser un éditeur de texte un peu plus avancé comme Notepad++ qui colorera votre texte intelligemment en reconnaissant le langage dans lequel vous programmerez (on appelle ça la coloration syntaxique).

Mais le plus intelligent est d'utiliser un Environnement de Développement Intégré, EDI en Français ou IDE en Anglais. Pourquoi ? Eh bien parce que ce logiciel vous fournira un éditeur de texte avec coloration syntaxique (waaah... :euh: ) et surtout vous permettra de compiler votre texte aisément, sans avoir à chercher votre compilateur et lui entrer tout plein de paramètres auxquels vous ne comprenez rien. :p Qui plus est, un IDE vous fournira divers outils utiles à la programmation.

L'IDE que nous allons utilisé s'appelle Adagide et il est gratuit.


Les logiciels nécessaires Télécharger et installer Adagide.

Télécharger et installer Adagide.

IDE et compilateur : kesako ? Télécharger et installer GNAT.

Disponible sous Windows uniquement

Téléchargement

Cliquez ici pour télécharger Adagide dans sa version 7.45 (dernière en date à l'heure où j'écris ces lignes). Puis cliquez sur "adagide-7.45-setup.exe" pour lancer le téléchargement de l'installateur.

Installation

L'installation d'Adagide ne devrait pas vous poser de problèmes. Il vous suffit de suivre les différentes étapes en cliquant sur suivant. Acceptez les termes de la licence et à l'écran "Setup Type" choisissez "Typical".

Image utilisateurImage utilisateurImage utilisateurImage utilisateur

IDE et compilateur : kesako ? Télécharger et installer GNAT.

Télécharger et installer GNAT.

Télécharger et installer Adagide. Télécharger et installer GPS

Disponible sous Windows et Linux

Téléchargement

Pour télécharger le compilateur GNAT GPL, rendez-vous sur le site d'Ada Core en cliquant ici.

Si vous êtes sous Windows, vérifiez que le système d'exploitation est bien "x-86 Windows" (à la ligne "Select your platform"), puis cliquez sur GNAT_GPL et sélectionnez "gnat-gpl-2011-i686-pc-mingw32-bin.exe". Enfin, tout en bas de la page, cliquez sur le bouton "Download selected files".

Pour les utilisateurs de Linux, le système d'exploitation devrait être "x86 - Linux" (ou "x86_64 - Linux" si votre processeur est en 64 bits). De la même manière que sous Windows, cliquez sur GNAT_GPL et sélectionnez "gnat-gpl-2011-i686-gnu-linux-libc2.3-bin.tar.gz". Pour finir, cliquez sur le bouton "Download selected files" en bas de page.

Installation

L'installation est un poil plus compliquée (même si ça ne casse pas trois pattes à un canard, comme dirait ma grand-mère :p ). Le fichier téléchargé s'appelle "AdaCore.tar" et ce n'est pas un programme d'installation, seulement un fichier compressé. Pour le décompresser, utilisez un logiciel comme Winrar ou 7zip. Sous Linux, vous pouvez procéder graphiquement ou par la console. Dans le second cas, vous devrez taper la commande suivante :

tar -xvzf gnat-gpl-2011-i686-gnu-linux-libc2.3-bin.tar.gz

Sous Windows, vous obtiendrez ainsi le fameux fichier d'installation "gnat-gpl-2011-i686-pc-mingw32-bin.exe". Ouvrez-le et suivez les différentes étapes. Je vous conseille de sélectionner l'option "Install for all users", notamment si votre ordinateur dispose de plusieurs sessions, à moins que vous ne vouliez être le seul à pouvoir programmer en Ada.

Sous Linux, l'installation se fera via le fichier script appelé "doinstall". Celui-ci vous demandera si vous souhaitez installer GNAT et si oui où. Vous n'aurez qu'à appuyer deux fois sur entrée puis répondre "Yes" aux deux dernières questions en appuyant sur les touches Y ou y.


Télécharger et installer Adagide. Télécharger et installer GPS

Télécharger et installer GPS

Télécharger et installer GNAT. Notre premier programme en Ada

GPS est un autre IDE, mais développé par AdaCore. Il est un peu plus compliqué et j'avoue ne pas avoir réussi à le démarrer sous mon PC Windows personnel (même s'il fonctionne sur mon PC Windows de bureau ou sous mon PC Ubuntu :( ). Adagide a l'avantage d'être simple et performant, je le préfèrerai donc à GPS. Mais si vous souhaitez tout de même utilisez GPS, sachez qu'à cette étape du chapitre ... il est déjà installé ! :p Cet IDE est en effet livré avec GNAT, vous pourrez donc le tester si la curiosité vous prend : il suffit d'aller dans le menu démarrer > Programmes > GNAT > 2010 > GPS.

Bien ! Nous voilà fin prêts pour réaliser notre premier programme ! Nous allons dès le prochain chapitre entrer dans le vif du sujet. Alors soyez prêts, à vos armes ! :pirate:


Télécharger et installer GNAT. Notre premier programme en Ada

Notre premier programme en Ada

Télécharger et installer GPS Découvrir son IDE en quelques secondes

Bon, nous avons installé notre IDE, Adagide, notre compilateur, GNAT. Je sens que vous commencez à perdre patience. Nous allons immédiatement pouvoir nous atteler à notre premier programme en Ada. Il s'agira de créer un programme qui nous salue.

Bon, c'est sûrement pas folichon comme objectif, mais c'est un début. Voyons ici la démarche que nous allons suivre.

Toujours pas découragé ? Alors au travail !

Découvrir son IDE en quelques secondes

Notre premier programme en Ada Notre premier programme

Soyons rapide avec Adagide

Pour pouvoir programmer, nous avons déjà expliqué que nous aurons besoin de l'IDE Adagide. Donc, lancez Adagide ! Vous voilà donc face à une fenêtre tout ce qu'il y a de plus ... austère :( Mais rassurez-vous, cela n'a que peu d'importance pour nous.

Image utilisateur

Tout d'abord nous allons créer un nouveau document. Pour cela, cliquez sur File > New ou sur l'icône "Nouveau" indiqué ci-dessus. Vous pourrez également à l'avenir ouvrir un document existant en cliquant sur File > Open ou sur l'icône "ouvrir".

Pour l'heure, nous allons enregistrer notre document. Cliquez sur File > Save as ou sur l'icône "enregistrer". Je vous conseille de créer un répertoire que nous nommerons "Hello", et dans ce répertoire nous allons enregistrer notre document (appelons-le également Hello). Vous remarquerez que l'extension proposée est adb. Notre code en Ada portera le nom de Hello.adb ; par la suite nous verrons à quoi peut servir l'extension ads qui est également proposée.

Bien entendu, il est possible d'écrire dans la fenêtre principale, la taille du texte pouvant être modifiée en cliquant sur le bouton "taille". En revanche, il est impossible d'écrire dans la partie basse de la fenêtre, celle-ci étant réservée au compilateur. C'est ici que le compilateur affichera les informations qui vous seront nécessaires : échec de la compilation, réussite de la compilation ...

Pour les utilisateurs de GPS (plus long)

Le logiciel GPS est un peu plus compliqué que Adagide. Il est toutefois mieux adapté à de gros projets, ce qui explique qu'il soit plus complexe et donc moins adapté pour ce cours. Lorsque vous lancez GPS, une fenêtre devrait vous demander ce que vous souhaitez faire.

Image utilisateur

Pour l'heure, choisissez "Create new project with wizard" et cliquez sur OK. Choisissez l'option "Single project" puis cliquez sur Forward. Choisissez un nom pour votre projet (j'ai choisi HelloWorld) et précisez un répertoire où l'enregistrer (je vous conseille de créer un répertoire spécifique par projet). Cliquez ensuite sur Apply sans renseigner les autres informations. Vous devriez arriver à l'écran suivant :

Image utilisateur

La fenêtre est découpée en quatre zones. La première ne nous intéresse pas pour l'instant. La seconde, juste en dessous affichera les fichiers et programmes de votre projet. Pour l'heure vous n'aurez qu'un seul fichier donc cela ne comportera pas d'intérêt pour les premiers cours. Son utilité se révèlera à partir de la Partie III. La troisième zone de la fenêtre est la zone principale, celle où vous rédigerez votre programme. Enfin, la quatrième zone est celle réservée au compilateur et à la console. Vous comprendrez son utilité bientôt.

Commençons donc par créer un nouveau fichier en cliquant sur l'icône "Nouveau" ou sur File > New. Sauvegardez tout de suite votre fichier en cliquant soit sur l'icône "Enregistrer" soit sur File > Save As. Votre fichier devra s'appeler Hello.adb" (même si vous n'avez pas besoin d'écrire l'extension). Comme je vous le disais plus haut, il existe également un fichier .ads que nous verrons plus tard et que le logiciel GPS gère aussi. Pour ouvrir un document, vous pourrez utiliser l'icône "Ouvrir" ou sur File > Open.

Voila pour l'essentiel, toutefois, je vais vous demander d'effectuer deux petites manipulations avant d'aller plus loin afin d'ajouter deux icônes importants. Cliquez sur le menu Build > Settings > Targets. Une fenêtre devrait s'ouvrir.

Image utilisateur

A gauche, dans la section Project, cliquez sur Build <current file> et cochez la case In the toolbar. Puis, dans la section Run, cliquez sur Custom et cochez la case In the toolbar. Enfin, cliquez sur le bouton Apply. Les deux icônes suivants devraient s'ajouter (retenez-les bien).

Image utilisateurImage utilisateurImage utilisateurImage utilisateur

Construire

Exécuter


Notre premier programme en Ada Notre premier programme

Notre premier programme

Découvrir son IDE en quelques secondes Mon dieu, qu'ai-je fait ?

Un petit copier-coller !

Maintenant que nous avons, rapidement, pris connaissance du logiciel, il est temps de nous lancer corps et âme dans la création de notre magnifique programme Hello ! Nous allons pour cela effectuer une opération de haute voltige : un copier-coller ! Voici le code d'un programme, ne cherchez pas à comprendre pour l'instant, je vous expliquerai par la suite. Pour l'heure, sélectionnez le texte, copiez-le et collez-le dans votre fichier Hello.adb sans poser de questions.

with ada.text_io ; 
use ada.text_io ; 

procedure Hello is
--partie réservée aux déclarations
begin
put("Salut tout le monde !") ; --on affiche un message
end Hello ;

Vous remarquerez que certains mots sont automatiquement colorés, je vous en ai déjà parlé c'est la coloration syntaxique. Elle permet de faire ressortir certains mot-clés (Adagide colore par défaut en bleu les mots réservés au langage Ada) ou certains types de texte.

Avant d'aller plus loin, si vous êtes sous Adagide (GPS effectuera cette manœuvre tout seul le moment venu), il serait bon de cliquer sur l'icône "Reformat", il est simple à trouver, c'est celui avec un grand R dessiné dessus. Cela va mettre votre code en forme : la ligne entre is et begin et la ligne entre begin et end vont être "avancées" à l'aide d'une tabulation (trois espaces sous adagide). On appelle ça l'indentation. Ca n'a l'air de rien mais c'est très important car à l'avenir votre code pourra s'étendre sur plusieurs pages, il est donc important qu'il soit le plus lisible possible. Lorsque l'on rédige un roman, on crée des paragraphes, des chapitres ... en programmation on indente son texte.

Compiler, créer ... lancer !

Maintenant que votre texte est écrit et mis en forme, il est temps de le faire fonctionner. Nous allons donc utiliser le compilateur. Pour cela, rien de plus simple, cliquez sur l'icône "Compiler" (ou appuyer sur F2 avec Adagide, ou encore Compile > Compile File). Le compilateur vérifiera la syntaxe de votre code. S'il n'y a pas d'erreur (et il ne devrait pas y en avoir), le compilateur devrait vous indiquer (dans la fenêtre du bas) "Completed successfully".

Mais à ce stade, votre programme n'existe pas encore, vous devez construire l'exécutable. Pour cela cliquez sur l'icône "construire" (ou appuyez sur F3 avec Adagide ou cliquez sur Compile > Build).

Pour les utilisateurs de GPS, les manipulations étant un peu longues, je vous conseille d'utiliser les icônes (c'est bien pour cela que je vous ai fait faire une petite manipulation préliminaire). Lorsque vous cliquerez sur l'icône "Construire", une fenêtre peut s'ouvrir. Ne vous souciez pas des paramètres et cliquez sur OK.

Votre fichier exécutable est désormais créé. Vous pouvez soit aller le chercher dans le répertoire Hello que vous avez créé tout à l'heure, soit cliquer sur l'icône "Exécuter" (ou appuyer sur F4 avec Adagide ou cliquer sur Run > Execute). Sous GPS, une fenêtre s'ouvrira. Ne cochez aucune case et, si la barre de texte est vide, écrivez-y le nom de votre programme : Hello (sans extension !). Puis cliquez sur OK.

Avec Adagide, vous devriez ainsi obtenir une magnifique fenêtre noire vous indiquant :

Salut tout le monde !

(Sous GPS, ces actions apparaîtront dans la fenêtre du compilateur, c'est à dire la quatrième zone de la fenêtre)

Euh ... comment dire ... c'est tout ? J'ai lu tous ces chapitres pour voir ça !!! :colere:

Ne perdez pas patience. Le chemin sera long avant que vous ne puissiez créer un programme digne d'intérêt. :ange: Prenons le temps de décortiquer ce que nous avons copié pour mieux comprendre.


Découvrir son IDE en quelques secondes Mon dieu, qu'ai-je fait ?

Mon dieu, qu'ai-je fait ?

Notre premier programme Vous en voulez encore ?

Si nous jetons un œil à notre code nous pouvons nous rendre compte qu'il peut se décomposer en deux parties majeures : une sorte de titre (avec with et use) et un gros paragraphe (commençant par le mot procedure).

Image utilisateur

Le corps du programme : la procédure Hello

Le titre étant un peu compliqué à expliquer, nous allons commencer par nous intéresser au "gros paragraphe" : la procédure appelée Hello. Elle peut se décomposer elle-même en deux parties comme sur l'image ci-dessus.

Les trois bornes de la procédure

Pour l'instant, disons que le terme de "procédure" est un synonyme de "programme". Notre paragraphe commence donc par l'introduction suivante : procedure Hello is. Cette phrase permet de donner un nom à notre procédure et indique le début du texte la concernant. Remarquez que les mots procedure et is sont colorés en bleu : ce sont des mots réservés par le langage Ada, ils ont donc un sens très précis et ne peuvent être utilisés n'importe comment.

Deuxième "borne" de notre procedure : le terme begin. C'est lui aussi un mot réservé. Il indique au compilateur le début des instructions que le programme devra exécuter.

Troisième "borne" : le mot end, ou plus exactement la phrase : "end Hello ; ". Cette phrase indique au compilateur la fin de la procédure Hello. À noter que contrairement aux deux bornes précédentes, cette phrase se termine par un point-virgule. Si vous oubliez de l'écrire, le compilateur vous avertira : missing ";" !

La partie déclarations

Les trois bornes vues précédemment délimitent deux zones. La première, celle comprise entre is et begin est réservée aux déclarations. Nous verrons dans les prochains chapitres de quoi il retourne, sachez pour l'instant qu'il faut prévenir votre ordinateur lorsque avez besoin de réquisitionner de la mémoire (et nous aurons besoin d'en réquisitionner) et que c'est dans cette partie que s'effectueront ces "demandes de réquisition". Pour l'heure, il n'y a rien.

Comment ça il n'y a rien ? Il y a bien quelque chose d'écrit : "--partie réservée aux déclarations"

Eh bien non. Pour le compilateur, il n'y a rien ! :p Cette ligne verte commence par deux tirets, c'est l'indication qu'il s'agit d'un commentaire, c'est à dire d'un texte qui ne sera pas pris en compte par le compilateur. Quel intérêt d'écrire du texte s'il n'est pas pris en compte par le compilateur ? Eh bien cela permet d'apporter des annotations à votre code. Si vous relisez un code écrit par quelqu'un d'autre ou par vous même il y a longtemps, vous risquez d'avoir du mal à le comprendre. Les commentaires sont donc là pour expliquer ce que fait le programme, à quoi servent telle ou telle ligne etc... un bon code est déjà un code bien commenté (et bien indenté également).

La partie actions et notre première instruction

Puis, après le begin, vient la partie la plus intéressante, celle où l'on indique au programme ce qu'il doit faire, autrement dit, c'est là que nous écrirons les différentes instructions.

L'instruction citée ici est : "Put("Salut tout le monde!") ;". C'est assez simple à comprendre : l'instruction Put() indique à l'ordinateur qu'il doit afficher quelque chose. Et entre les parenthèses, on indique ce qu'il faut afficher. Il est possible d'afficher un nombre (par exemple, Put(13) ; affichera le nombre 13) comme du texte, mais le texte doit être écrit entre guillemets.

Remarquez là encore que l'instruction se termine par un point-virgule. D'ailleurs, toutes les instructions devront se terminer par un point virgule, à quelques exceptions près (souvenez-vous de is et begin). Le texte qui suit est bien entendu un commentaire et tout ce qui suit les double-tirets ne sera pas pris en compte par le compilateur.

Il est bien sûr possible d'afficher autre chose que "salut tout le monde !" ou d'effectuer d'autres actions. Toutefois, lorsque toutes vos actions ont été écrites, n'oubliez pas d'indiquer au compilateur que vous avez atteint la fin en utilisant le mot end.

Les Packages avec With et Use

Le mot-clé WITH

Revenons maintenant au titre. Pourquoi cet intitulé ? Et d'ailleurs pourquoi l'écrire deux fois ? Je vous propose de le supprimer pour mieux comprendre. Compiler à nouveau votre code.

:waw: Argh ! ! ! Ca marche plus ! J'ai tout plein de messages rouge ! Tout est fichu !

En effet, le code n'est plus correct et ce n'est pas la peine d'essayer de reconstruire notre programme. Mais lisons les avertissements du compilateur. Tout d'abord : "Put" is undefined.

Cela signifie tout simplement que le compilateur ne connaît plus l'instruction Put() ! En effet, le compilateur ne connaît que très peu de mots et d'instructions : les mots réservés et puis c'est presque tout. Pour aller plus loin, il a besoin de fichiers qui contiennent d'avantage d'instructions comme l'instruction Put() par exemple qui se situe dans un fichier appelé Ada.Text_IO. Ces fichiers portent le nom de package en Ada (paquetages en Français). Dans d'autres langages, on parlerait de librairies.

Le compilateur nous dit également : possible missing "WITH Ada.Text_IO ; USE Ada.Text_IO ;". Traduction : ce serait bien de remettre les lignes que vous avez supprimé tout à l'heure ! Écoutons-le mais ne réécrivons que la première ligne (au tout début) :

WITH Ada.Text_IO ;

Le mot-clé USE

Réessayons de compiler.

Nouveau problème. Le compilateur m'indique : "Put" is not visible plus plein d'autres insultes incompréhensibles. Apparemment, il connait mon instruction Put() mais il n'arrive plus à la voir ?!?

Exactement. Et les lignes qui suivent indiquent que dans le package ada.Text_IO il y a plusieurs références à l'instruction Put(). En fait, il est possible après l'instruction with d'écrire de nombreux packages, autant que vous voulez même (nous verrons un exemple juste après). Mais il peut exister (et il existe) plusieurs instructions portant le nom Put(), du coup le compilateur ne sait pas d'où vient cette instruction. De laquelle s'agit-il ? Une solution est de remplacer Put() par Ada.Text_IO.Put() ! C'est compliqué, c'est long à écrire et nous aurons tout le loisir de comprendre tout cela plus tard. Donc une façon de s'épargner ces difficultés, c'est d'écrire notre instruction Use au tout début, juste après l'instruction with.

Ces deux lignes (appelées Context Clause en Ada) sont donc indispensables et vous serez souvent amenés à réécrire les mêmes (vous bénirez bientôt l'inventeur du copier-coller). Ne croyez pas que cette lourdeur soit spécifique à Ada, tout langage a besoin de packages ou librairies annexes, tout n'est pas prédéfini et heureusement pour nous : c'est ce que l'on appelle la modularité. Au final, voici la structure de notre programme (et de tout programme Ada) :

Image utilisateur

Avec plusieurs packages

J'ai essayé de bidouiller le code pour qu'il affiche 13 comme tu le disais dans un exemple. Mais le compilateur râle encore : warning : no entities of "Text_Io" are referenced, no candidate match the actuals : ... enfin bref rien ne va plus. Faut-il un autre package ?

Exactement ! Ada.Text_IO est un package créé pour gérer le texte comme son nom l'indique (Text = texte et IO = In Out, entrée et sortie). Pour afficher un nombre entier (ici 13) il faut utiliser le package Ada.Integer_Text_IO. Exemple :

WITH Ada.Text_IO,Ada.Integer_Text_IO ; 
USE Ada.Text_IO,Ada.Integer_Text_IO ;

Pour plus de clareté, il est également possible d'écrire ceci :

WITH Ada.Text_IO,
   Ada.Integer_Text_IO ; 
USE Ada.Text_IO,
   Ada.Integer_Text_IO ;

Et oui ! Bien indenter son code, c'est très important !

Une dernière remarque qui a son importance

Vous devez savoir avant de vous lancer à l'aventure que le langage Ada n'est pas "case sensitive", comme diraient nos amis Anglais, il ne tient pas compte de la casse. Autrement dit, que vous écriviez en majuscule ou en minuscule, cela revient au même : BEGIN, Begin, begin ou bEgIn seront compris de la même manière par le compilateur. Toutefois, Ada sait faire la différence lorsqu'il faut : si vous modifiez la casse dans la phrase à afficher "Salut tout le monde !", l'affichage en sera modifié.

De même, une tabulation ou un espace seront pris en compte de la même façon. Et que vous tapiez un, deux ou trois espaces ne changera rien.


Notre premier programme Vous en voulez encore ?

Vous en voulez encore ?

Mon dieu, qu'ai-je fait ? Variables I : Typage et affectation

Exercice 1

Ce premier programme est peut-être simple, mais voici quelques exercices pour nous amuser encore. Nous avons vu l'instruction Put() qui affiche du texte, en voici maintenant une nouvelle : New_line. Elle permet de retourner à la ligne. N'oubliez pas le point virgule à la fin.

Énoncé

Écrire un programme affichant ceci :

Coucou
tout le
monde
! ! !

Solution

With ada.text_io ; 
use ada.text_io ; 

procedure Hello2 is

begin
   Put("Coucou") ; New_line ; 
   Put("tout le") ; New_line ; 
   Put("monde") ; New_line ; 
   Put("! ! !") ; 
end Hello2 ;

Exercice 2

Troisième instruction : Put_line(). Elle fonctionne comme Put(), sauf qu'elle crée automatiquement un retour à la ligne à la fin.

Énoncé

Même exercice que précédemment, mais sans utiliser New_line.

Solution

With ada.text_io ; 
use ada.text_io ; 

procedure Hello3 is

begin
   Put_line("Coucou") ; 
   Put_line("tout le") ; 
   Put_line("monde") ; 
   Put("! ! !") ;           --pas besoin de put_line ici, on est arrivé à la fin
end Hello3 ;

Exercice 3

Enoncé

Pourquoi ne pas créer des programmes affichant autre chose que "coucou tout le monde ! ".

Vous avez désormais créé votre premier programme. Certes, il n'est pas révolutionnaire, mais c'est un début. Nous allons pouvoir quitter la première partie de ce tutoriel et entrer dans les bases de la programmation en Ada. La prochaine partie nous permettra de manipuler des nombres, d'effectuer des opérations, de saisir des valeurs au clavier ... peu à peu nous allons apprendre à créer des programmes de plus en plus complexes.

Maintenant que Adagide et GNAT sont installés et que nous avons une idée plus précise de ce qui nous attend, nous allons pouvoir commencer notre apprentissage du langage Ada.


Mon dieu, qu'ai-je fait ? Variables I : Typage et affectation

Variables I : Typage et affectation

Vous en voulez encore ? Déclaration de variables

Nous avons dors et déjà réalisé notre premier programme. Mais chacun comprend vite les limites de notre programme "Hello". A dire vrai, un tel programme n'apporte absolument rien. Ce qui serait intéressant, ce serait que l'utilisateur de notre programme puisse entrer des informations que l'ordinateur lui demanderait. Par exemple :

Quel âge avez-vous ? _

Et là nous pourrions entrer 25, 37 ou 71 ! Le programme pourrait ensuite se charger d'enregistrer cette information dans un fichier, de nous avertir si nous sommes considérés comme majeur dans l'état du Minnesota ou encore de nous donner notre âge en 2050 ... autant d'applications que nous ne pourrons pas réaliser si l'âge que l'utilisateur indiquera n'est pas enregistré dans une zone de la mémoire.

Et c'est là que les variables interviennent ! Attention, ce chapitre n'est peut-être pas exaltant mais il est absolument nécessaire à la compréhension des prochains.

Déclaration de variables

Variables I : Typage et affectation Différents types

Nous allons reprendre l'exemple de l'introduction. Nous voulons indiquer un âge à notre programme. Nous aurons donc besoin d'un espace mémoire capable de stocker un nombre entier. Il faudrait effectuer une demande d'allocation d'une zone mémoire et retenir l'adresse mémoire qui nous a été attribuée et la taille de la zone allouée. o_O

Euh ... c'était pas marqué Niveau facile ?

Pas d'inquiétude. Tout cela c'est ce qu'il aurait fallu faire (entre autre) si nous n'avions pas utilisé un langage comme Ada. C'est ce qu'on appelle un langage de haut niveau, c'est à dire que l'on n'aura pas besoin de se casser la tête pour faire tout cela. Il suffira de dire " :pirate: Je veux de la mémoire !". :p

Toutefois, l'ordinateur a tout de même besoin de connaître la place mémoire dont vous aurez besoin et cela dépend du type d'information que l'on souhaite y enregistrer. Ici nous voulons enregistrer un nombre entier que nous appelons age. Le mot age est le nom de notre variable, c'est à dire l'endroit de la mémoire où seront enregistrées nos informations. Pour faire tout cela, il faut déclarer notre variable (comme on le ferait à la douane, cela permet de savoir qui vous êtes et comment vous retrouver). Une déclaration se fait toujours de la façon suivante :

NOM_DE_LA_VARIABLE:TYPE;

Il est possible de déclarer plusieurs variables d'un coup de la manière suivante :

NOM_DE_LA_VARIABLE1,NOM_DE_LA_VARIABLE2:TYPE;

Il est aussi possible, aussitôt la variable déclarée, de lui affecter une valeur à l'aide du symbole ":=". On écrira alors :

NOM_DE_LA_VARIABLE:TYPE:=VALEUR;

Où dois-je faire cette déclaration ? En préfecture ? :(

Vous vous souvenez notre premier programme ? Je vous avais parlé d'une zone réservée aux déclarations (entre is et begin). Et bien c'est ici que nous déclarerons notre variable.

Procedure VotreAge is
   NOM_DE_LA_VARIABLE1 : TYPE1 := VALEUR ; --zone réservée aux déclarations
   NOM_DE_LA_VARIABLE2 : TYPE2 ; 
begin
   Put("Quel age avez-vous ?") ; 
end ;

Bien, il est temps de rentrer dans le vif du sujet : comment déclarer notre variable age ?


Variables I : Typage et affectation Différents types

Différents types

Déclaration de variables Affectation

Les types Integer et Natural

Définition

Le type Integer est réservé aux nombres entiers relatifs. Pour ceux qui ne se souviendraient pas de leur cours de Mathématiques, un entier est un nombre "qui n'a pas de chiffres après la virgule à part 0". Relatif signifie que ces entiers peuvent être positifs (avec un signe +) ou négatifs (avec un signe -).

Le type Natural est réservé aux nombres entiers naturels (c'est à dire positifs ou nul). Il est donc impossible, si vous déclarez votre variable comme un Natural, que celle-ci soit négative (ou alors vous planterez votre programme). Pour être plus précis, c'est un sous-type du type Integer. Quelle importance ? Eh bien, cela signifie que l'on pourra "mélanger" les natural et les integer sans risquer le plantage : nous pourrons les additionner entre eux, les soustraire, les multiplier ... ce qui n'est pas possible avec d'autres types. La seule restriction, que notre natural ne devienne pas négatif.

Valeurs possibles

Si N est une variable de type Integer, elle peut prendre les valeurs suivantes :
0 ; 1 ; 2 ; 3 ; 4 ... 2 147 483 647
-1 ; -2 ; -3 ... - 2 147 483 648

Si N est une variable de type Natural, elle peut prendre les valeurs suivantes :
0 ; 1 ; 2 ; 3 ... 2 147 483 647

Exemple

Si nous voulons pouvoir utiliser les Integer ou les Natural, il faudra ajouter Ada.Integer_Text_IO dans la listes des packages :

With Ada.Text_IO, Ada.Integer_Text_IO ; 
Use Ada.Text_IO, Ada.Integer_Text_IO ;

Et voila pour le début de notre code :

Procedure VotreAge is
   age : Integer := 27; 
begin 
...

Ou bien, sans affecter de valeur :

Procedure VotreAge is
   age : Integer ; 
begin 
...

Le type Float

Définition

Le type float est chargé de représenter les nombres décimaux. Dans les faits, il n'en représente en fait qu'une partie (comme les Integer ne couvrent pas tous les nombres entiers).

Autant Natural = Naturel ; Integer = Entier, ça semblait évident, autant là : Float = Décimal !?! Je vois mal la traduction :(

Valeurs possibles

Si X est une variable de type float, elle peut prendre les valeurs suivantes :
0.0 ; 1.0 ; 2.0 ... 3,40282E38 (un nombre avec 39 chiffres)
-1.0 ; -2.0 ... -3,40282E38 (un nombre avec 39 chiffres)
1.5 ; 2.07 ; 3.141592 ...

Exemple

Si nous voulons pouvoir utiliser les Float, il faudra ajouter Ada.Float_Text_IO dans la listes des packages :

With Ada.Text_IO, Ada.Float_Text_IO ; 
Use Ada.Text_IO, Ada.Float_Text_IO ;

Et voila pour le début d'un programme qui demanderait votre taille et votre poids :

Procedure TaillePoids is
   Taille : Float := 1.85 ; 
   Poids : Float := 63.0 ; 
begin 
...

Ou bien, sans affecter de valeur et en déclarant les deux variables en même temps :

Procedure TaillePoids is
   Taille, Poids : Float ; 
begin 
...

Le type Character

Définition

Le type Character est réservé pour les caractères, c'est à dire les lettres. Toutefois, les espaces, les tabulations constituent aussi des caractères de même que le retour à la ligne, la fin de fichier ... qui sont des caractères non imprimables. Le type Character ne contient pas une phrase mais un seul caractère.

Valeurs possibles

Si C est une variable du type Character, elle peut prendre les valeurs suivantes :
'a', 'b', 'c' ... 'z', 'A', 'B', 'C' ... 'Z', '#', ' ', '%' ...

En réalité, les characters ont les valeurs suivantes : 0, 1, 2 ... 255. Les ordinateurs ne gèrent pas les lettres, mais les chiffres oui ! A chacun de ces nombres est associé un caractère. Dans certains langages il est donc possible d'écrire 'a'+1 pour obtenir 'b'. Mais le langage Ada, qui a un typage fort (certains diront excessif), empêche ce genre d'écriture : une lettre plus un nombre, c'est une aberration en Ada :colere: . Ne vous inquiétez pas, nous verrons plus tard les opérations possibles sur les character.

Exemple

Si nous voulons pouvoir utiliser les Character, il suffit d'avoir écrit Ada.Text_IO dans la listes des packages :

With Ada.Text_IO ; 
Use Ada.Text_IO ;

Et voila pour le début d'un programme qui demanderait votre initiale :

Procedure Initiales is
   Ini : Character := 'K' ;  --Comme Kaji9 :-)
begin 
...

Déclaration de variables Affectation

Affectation

Différents types Constantes et attributs

Bien ! Maintenant que l'on sait déclarer les principaux types de variables, voyons comment leur attribuer une valeur (on dit qu'on leur affecte une valeur). En effet, nous avons réquisitionné une zone de la mémoire de notre ordinateur mais il n'y a encore rien d'écrit dédans. Pour cela, revenons à notre programme VotreAge :

with Ada.Text_IO, Ada.Integer_Text_IO ; 
use Ada.Text_IO, Ada.Integer_Text_IO ; 

Procedure VotreAge is
   Age : integer ; 
Begin
   ...

Il y a deux personnes qui peuvent affecter une valeur à la variable Age : vous (le programmeur) ou l'utilisateur( peut-être vous aussi, mais pas dans le même rôle).

Affectation par le programmeur (ou le programme)

On va utiliser le symbole ":=" vu auparavant, mais cette fois, après le Begin.

with Ada.Text_IO, Ada.Integer_Text_IO ; 
use Ada.Text_IO, Ada.Integer_Text_IO ; 

Procedure VotreAge is
   Age : integer ; 
Begin
   Age := 27 ; 
End VotreAge ;

Ce programme se contentera d'affecter 27 à une variable Age.

Affectation par l'utilisateur

Nous savons comment poser une question à l'utilisateur avec l'instruction Put. Pour récupérer sa réponse on utilisera la fonction Get.

with Ada.Text_IO, Ada.Integer_Text_IO ; 
use Ada.Text_IO, Ada.Integer_Text_IO ; 

Procedure VotreAge is
   Age : integer ; 
Begin
   Put("Quel age avez-vous ?") ;      -- on est poli, on demande l'âge
   Get(Age) ;                         -- puis on saisit la réponse de l'utilisateur
   Skip_line ;                        -- ???
   Put("Ah, vous avez ") ; Put(Age) ; -- on fait une phrase affichant la réponse
End VotreAge ;

Bien, bien. C'est pas trop compliqué. Sauf que c'est quoi ce Skip_line ?

L'instruction Skip_line

Skip_line est une instruction que je vous conseille fortement d'écrire après chaque utilisation de l'instruction Get. Pour comprendre son utilité, reprenons l'exemple du programme TaillePoids :

with Ada.Text_IO, Ada.Float_Text_IO ; 
use Ada.Text_IO, Ada.Float_Text_IO ; 

Procedure TaillePoids is
   Taille, Poids : float ; 
Begin
   Put("Quelle est votre taille ?") ;
   Get(Taille) ;
   Put("Vous mesurez ") ; 
   Put(Taille) ; 
   Put(" m.") ; 

   Put("Quel est votre poids ?") ;
   Get(Poids) ;

   Put("Vous pesez ") ; 
   Put(Poids) ; 
   Put(" kg.") ; 

End TaillePoids ;

Puis voyons ce qu'il se passe dans la console :

Quelle est votre taille ? 1.8R
Vous mesurez 1.8 m. 
Quel est votre poids ?
raised ADA.IO_EXCEPTIONS.DATA_ERROR : a-tiinio.adb:89 instantiated at a-inteio.ads:18

Notre utilisateur a tapé 1.8R au lieu de 1.85 (erreur de frappe). Logiquement, le programme plante. Mais regardons en détail ce qu'il s'est passé. La taille enregistrée est 1.8, le R n'a pas été pris en compte. Alors pourquoi le programme ne nous laisse-t-il pas entrer une nouvelle taille ? Pourquoi détecte-t-il une erreur alors que nous n'avons entré aucun poids ? Et qui plus est : pourquoi ne la détecte-t-il pas plus tôt ?

En fait, en tapant 1.8R nous avons envoyé dans le buffer (la mémoire tampon) 1.8 puis R puis le "entrée" (qui constitue également un caractère). L'instruction Get(Taille) s'est emparée de 1.8, mais le R est resté en mémoire tampon puisqu'à l'évidence, il ne faisait pas partie du nombre demandé. Par conséquent, l'instruction Get(Poids) a regardé dans le buffer ce qu'il y avait à récupérer : la lettre R que vous aviez tapé par erreur ! L'instruction Get(Poids) s'est donc emparé du R qui est un character et non un Float. D'où l'erreur.

Et Skip_line dans tout ça ? o_O

Et bien l'instruction Skip_line aurait évité cette erreur, car Get(Taille) aurait saisit 1.8 pour la taille (comme tout à l'heure) et Skip_line aurait ensuite vidé la mémoire tampon : plus de R ou de touche "entrée" en mémoire. Nous aurions ainsi pu saisir notre poids tranquillement.

Voici le code, corrigé avec Skip_line :

with Ada.Text_IO, Ada.Float_Text_IO ; 
use Ada.Text_IO, Ada.Float_Text_IO ; 

Procedure TaillePoids is
   Taille, Poids : float ; 
Begin
   Put("Quelle est votre taille ?") ;
   Get(Taille) ; Skip_line ;
   Put("Vous mesurez ") ; 
   Put(Taille) ; 
   Put(" m.") ; 

   Put("Quel est votre poids ?") ;
   Get(Poids) ; Skip_line ; 

   Put("Vous pesez ") ; 
   Put(Poids) ; 
   Put(" kg.") ; 

End TaillePoids ;

Différents types Constantes et attributs

Constantes et attributs

Affectation Variables II : Opérations

Cette dernière partie est plus technique. Si vous avez peur qu'elle ne vous embrouille. Je vous conseille de relire ce qui précède et de faire des exemples (c'est en forgeant que l'on devient forgeron ^^ ). Toutefois, je vous invite à revenir lire ce qui suit, aussitôt que vous maîtriserez les notions de types car les constantes et les attributs (surtout les attributs) nous serons forts utiles par la suite.

Constantes

Une variable peut ... varier. Étonnant non ? :p Ce n'est pas parce que vous l'avez initialisée à 15 qu'elle ne peut pas être modifiée plus tard pour valoir 18, bien au contraire. C'est d'ailleurs là tout leur intérêt.

N := 10 ;     --la variable N prend la valeur 10
N:= 13 ;      --Puis la valeur 13
N:= 102 ;     --Et enfin la valeur 102 !

Mais il est parfois intéressant de fixer leur valeur une fois pour toute. La variable ne varie alors plus, elle devient une constante et doit être déclarée de la manière suivante :

MaVariable : Constant Integer := 15 ;

Nous avons ainsi une variable MaVariable qui vaudra toujours 15. Tentez seulement de modifier cette valeur et vous entraînerez un plantage de votre programme (ou plutôt, votre compilateur refusera de compiler votre code).

A quoi servent les constantes ? Exemple simple :

PI : Constant Float := 3.1415926535 ;

Chacun comprend que si la valeur de ma variable PI est modifiée, tous mes calculs d'aire de disque, de périmètre de cercle ou de volume de boule ... seront faux. Donc PAS TOUCHE A MA CONSTANTE ! ! ! :lol:

Attributs

Comment obtenir le plus petit et le plus grand Integer ? Comment savoir quel est le 93ème character ? Grâce aux attributs, bien sûr. Ce sont des sortes d'instructions qui s'appliquent aux types.

Avant d'en voir quelques uns, rappel d'Anglais : Repeat after me ! "Susan's dog" signifie "le chien de Susan". Ainsi, le petit mot " 's" exprime l'idée d'appartenance et il faut penser à inverser l'ordre des noms par rapport au Français. Pourquoi ce rappel ? Eh bien parce que les attributs s'utilisent de la même manière :

N := integer'first ;      --N sera le premier des integer
M := integer'last ;       --M sera le dernier des integer
C := character'val(93) ;  --C sera la 93ème valeur des character
P := character'pos('f') ; --P aura pour valeur la position du character 'f'

Nous reverrons plus abondamment les attributs dans les chapitres suivants. Commencez déjà par vous faire la main sur ces quatre là : quel est le plus petit float ? Le plus grand ? Quel est la position de 'a' et du 'A' ?

Bien, nous savons maintenant déclarer une variable et lui affecter une valeur. Nous avons vu également quelques types de variables. Nous serons amenés par la suite à voir d'autres types plus complexes (tableaux, chaînes de caractères, classes, pointeurs, ...).

Avant cela, nous devrons voir un second chapitre sur les variables. C'est en effet intéressant de les avoir enregistrées en mémoire, mais il serait bien plus intéressant de pouvoir les modifier à l'aide de quelques formules mathématiques simples.


Affectation Variables II : Opérations

Variables II : Opérations

Constantes et attributs Opérations sur les Integer et les Natural

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 :

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

Variables II : Opérations Opérations sur les float

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 ci-dessus parlent d'eux-mêmes. Mais ils sont très légers. Voici quelques exemples un peu plus poussés :

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.

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

Hein ? 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. Alors Var + 1 vaudra 6. Le code ci-dessus affectera donc 6 à la variable Var, qui valait auparavant 5. On change donc la valeur de la variable (Ne vous avais-je pas dit que les variables variaient ? ^^ )


Variables II : Opérations Opérations sur les float

Opérations sur les float

Opérations sur les Integer et les Natural Opérations sur les character

Voici quelques opérations

Symbole

Opération

Exemple

+

Addition

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

-

Soustraction

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

*

Multiplication

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

/

Division décimale

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

**

Puissance

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

ABS

Valeur absolue

N := 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 (ou soustraire, 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.

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

C'est très simple. Voici un exemple :

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 sur les Integer et les Natural Opérations sur les character

Opérations sur les character

Opérations sur les float Exercices

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.

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 langage autorisaient l'écriture du calcul "'a' + 1" pour obtenir le character 'b'. Pratique, 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 :

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

Explication : les calculs seront effectués dans l'ordre suivant :

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

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. :)


Opérations sur les float Exercices

Exercices

Opérations sur les character Les conditions I

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

Exercice 1

Enoncé

Rédiger 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

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

Enoncé

Rédiger 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

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

Enoncé

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 !

Solution

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

Enoncé

Rédiger 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. A défaut, s'il y a deux lettres, le programme choisira la "plus petite".

Solution

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 ;

Bien, 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 effectuant des actions différentes selon certains critères. Ce sont les conditions.


Opérations sur les character Les conditions I

Les conditions I

Exercices Conditions simples avec IF

Un programme informatique permet d'automatiser des tâches (souvent répétitives) mais n'oublions pas qu'il va s'adresser à des utilisateurs humains qui auront envie d'avoir la main et d'effectuer des choix. Nos programmes doivent donc en tenir compte et gérer ces choix : "SI l'utilisateur fait tel choix ALORS faire ceci SINON faire cela".

Nous profiterons également de ce chapitre pour voir différents opérateurs permettant de comparer nos variables. Par la suite, nous aborderons l'algèbre booléenne, terme effrayant mais qui recouvre des règles de logique qui nous permettront de gérer des conditions plus complexes.

Le programme étant suffisamment chargé, ce chapitre sera partagé en deux.

Conditions simples avec IF

Les conditions I Conditions multiples avec IF

Un début en douceur

Nous allons réaliser un programme qui demande à son utilisateur s'il dispose de plusieurs ordinateurs. Cette question n'appellera que deux choix possibles : Oui et Non. Le programme renverra un message à l'écran qui dépendra de la réponse obtenue. Ce programme peut se décomposer de la manière suivante :

AFFICHER la question : "Avez-vous plusieurs ordinateurs ?"
SAISIR la réponse (Oui ou Non)
SI la réponse est oui
   ALORS AFFICHER : "Vous avez bien de la chance."

Nous enregistrerons la réponse dans une variable Reponse qui sera de type Character. L'utilisateur devra taper "o" pour oui et "n" pour non. L'instruction SI se note IF en Ada, l'instruction ALORS se note quant à elle THEN. D'où le code suivant :

Procedure Questionnaire is
   Reponse : Character := 'n' ; --on définit Reponse et on lui attribue
                                --par défaut la valeur n (pour non)
begin

Put("Avez-vous plusieurs ordinateurs ? (o/n) ") ;
Get(Reponse) ; Skip_line ;       --On saisit la réponse et on vide la mémoire tampon
if Reponse = 'o'                 --SI Reponse est égal à o
   then Put("Vous avez bien de la chance.");  --ALORS on affiche la phrase. 
end if ; 

end Questionnaire ;

Mais pourquoi tu as écrit juste = et pas := comme avant ?

Tout simplement parce que le symbole := est utilisé pour affecter une valeur à une variable. Si nous avions écrit :

Reponse := 'o'

... alors nous aurions modifier la valeur de Reponse en lui attribuant la valeur 'o'. Or ici nous posons une question au programme : Reponse est-il bien égal à 'o' ? Le programme se chargera de répondre vrai ou faux. C'est pourquoi nous utiliserons ici le symbole =. D'ailleurs, après une instruction if, le compilateur refuserait que vous utilisiez le symbole :=.

Autres remarques, l'instruction if doit être clôturée par une instruction end if qui marquera la fin des actions à exécuter dans cette instruction if. Et s'il ne faut pas de ";" à la fin de l'instruction if, il en faut bien après end if !

Mais ce programme présente de grooooosses lacunes. Que se passe-t-il si l'utilisateur répond non (n) ? Eh bien pour l'instant, c'est très simple : rien. :lol:

Une première alternative

Nous allons donc compléter notre code de la manière suivante :

AFFICHER la question : "Avez-vous plusieurs ordinateurs ?"
SAISIR la réponse (Oui ou Non)
SI la réponse est oui
   ALORS AFFICHER : "Vous avez bien de la chance."
   SINON AFFICHER : "Ha ... Dommage."

L'instruction SINON se traduit par Else et nous permettra de varier un peu notre programme. ^^ Au lieu d'avoir le code suivant :

if Reponse = 'o'
   then Put("Vous avez bien de la chance.") ; 
end if ;

Nous allons donc écrire :

if Reponse = 'o'
   then Put("Vous avez bien de la chance.") ; 
   else Put ("Ha ... Dommage. ") ; 
end if ;

Désormais, si l'utilisateur répond non (n), il recevra tout de même une réponse, différente qui plus est ! :soleil:

Et que se passerait-t-il si l'utilisateur tapait une autre lettre, comme z par exemple ?

Pour avoir la réponse reprenons notre code ! Celui-ci ne teste qu'une seule égalité : la variable Reponse est-elle égale à 'o' ? Donc si Reponse vaut 'z', le programme apportera la même réponse que si elle vaut 'n', 'a', '@' ou autre ! Dit différemment, nous n'avons pas envisagé tous les cas. L'utilisateur peut tout à fait répondre autre chose que oui ou non. :waw: Et là vous vous demandez s'il n'existerait pas une troisième instruction après then et else. Eh bien non. Pour envisager d'avantage de cas, il va falloir ruser.


Les conditions I Conditions multiples avec IF

Conditions multiples avec IF

Conditions simples avec IF Conditions multiples avec CASE

L'astuce (pas si compliquée d'ailleurs) est de réaliser plusieurs tests :

SI la réponse est oui
   ALORS AFFICHER ("Vous avez bien de la chance")
   SINON SI la réponse est non
      ALORS AFFICHER("Ah ... Dommage.")
      SINON Afficher("C'est pas une réponse ça !")

Il est en effet possible d'imbriquer plusieurs instructions if les unes dans les autres :

if Reponse = 'o'
   then Put("Vous avez bien de la chance"); --cas où la réponse est oui
   else if Reponse = 'n'
      then Put("Ah ... Dommage.");  --cas où la réponse est non
      else Put("C'est pas une réponse ça !"); --cas où la réponse est... autre chose
   end if ; 
end if ;

Et voilà le tour est joué ! Allez, plus compliqué, si l'utilisateur répond 'p' (pour "p'têt bin que oui, p'têt bin que non") on affiche le message "Reponses normandes non valides". A vous de jouer :

if Reponse = 'o'
   then Put("Vous avez bien de la chance");
   else if Reponse = 'n'
      then Put("Ah ... Dommage."); 
      else if Reponse = 'p'
         then Put("Reponses normandes non valides");
         else Put("C'est pas une réponse ça !");
      end if ; 
   end if ; 
end if ;

Alors vous avez réussi ? Bien joué ! Regardez toutefois le code que je vous propose : à chaque nouveau then/else, j'ai ajouté une tabulation (ou 3 espaces avec Adagide). Nous avons déjà vu cette pratique, elle s'appelle l'indentation et elle n'est pas anodine car elle vous permettra de proposer un code aéré, organisé et donc facilement lisible par vous ou un tiers. Prenez cette habitude le plus tôt possible ! C'est un conseil que je ne cesserai de vous répéter.

Toutefois vous avez du vous rendre compte que cela devient vite fatiguant d'écrire plusieurs end if et d'augmenter de plus en plus le nombre de tabulations pour avoir un code bien indenté. Heureusement zorro est arrivé :zorro: Oups. Non, heureusement les instructions else if peuvent être remplacées par une autre : elsif !

Ah ........... Et ça change quoi ? (À part une lettre en moins)

Et bien, observez par vous-même :

if Reponse = 'o'
   then Put("Vous avez bien de la chance");
elsif Reponse = 'n'
   then Put("Ah ... Dommage."); 
elsif Reponse = 'p'
   then Put("Reponses normandes non valides");
   else Put("C'est pas une réponse ça !");
end if ;

Plus besoin de multiplier les end if, du coup chaque instruction elsif se présente comme un "prolongement" du if initial, limitant ainsi l'indentation.

Mais il y a une instruction encore plus lisible et particulièrement appropriée pour des choix multiples.


Conditions simples avec IF Conditions multiples avec CASE

Conditions multiples avec CASE

Conditions multiples avec IF Les opérateurs de comparaison

Cette nouvelle instruction s'appelle case. Comme son nom l'indique (si vous êtes un peu anglophone), elle permet de traiter différents CAS (= case). Alors pour la beauté de l'art, nous allons nous ajouter un cas supplémentaire : si l'utilisateur appuie sur 'f' (pour "I don't speak French" = "Je ne parle pas Français" pour les anglophobes). Et en route pour l'aventure !

case Reponse is --on indique que l'on va regarder les différents cas possibles pour Reponse
   when 'o' => Put("Vous avez bien de la chance.") ;           -- si oui
   when 'n' => Put("Ah ... dommage. ") ;                       -- si non
   when 'p' => Put("Reponses normandes non valides") ;         -- si peut-être
   when 'f' => Put("J'aurais pas du prendre Allemand ...") ;   -- si "not French"
   when others => Put("C'est pas une reponse.") ;              -- si autre chose
end case ;  -- on termine notre instruction comme avec if !

Cette nouvelle instruction a des avantages : plus compacte, elle est donc plus claire, plus lisible et surtout plus rapide à taper lorsque les choix s'avèrent nombreux. Elle présente toutefois des limites que nous verrons dans les prochaines parties.

Pour l'instant regardons la structure. La portion de code ci-dessus (on parlera de bloc) est introduite de la même manière que la procédure de votre programme : Procedure Questionnaire is. Elle se termine par end case. Les flèches sont faites du signe égal (=) suivi du signe "supérieur à" (>). Rappelons enfin que le mot when signifie QUAND et que le mot others signifie AUTRE (n'utilisez l'instruction when others qu'après avoir traité tous les cas).

Vous avez bien compris ? Alors rien ne vous empêche de trouver d'autres réponses farfelues pour vous exercer (pensez toutefois à indiquer ces nouvelles réponses possibles à l'utilisateur). Je vous invite à reprendre les parties précédentes si vous avez encore quelques doutes car la partie suivante sera un poil plus compliquée. ;)

En effet, nous pensions avoir fini notre programme, qu'il couvrait tous le choix possibles etc ... Eh bien non. Que se passera-t-il si l'utilisateur tape 'O' au lieu de 'o', ou bien 'N' au lieu de 'n' ? Pour l'ordinateur, un "n" minuscule et un "N" majuscule sont deux valeurs différentes. Il considèrera que c'est une mauvaise réponse et répondra "C'est pas une reponse" !

On va devoir créer 4 nouveaux cas pour les majuscules ? :(

Non, rassurez-vous. Mais nous allons toutefois devoir faire un peu de logique : c'est ce qu'on appelle l'algèbre booléenne. :p Nous n'aborderons pas l'algèbre booléenne dans ce chapitre. Si certaines choses ne sont pas claires, je vous conseille de relire ce chapitre car le suivant s'avèrera plus compliqué.


Conditions multiples avec IF Les opérateurs de comparaison

Les opérateurs de comparaison

Conditions multiples avec CASE Les conditions II : les booléens

Tous nos tests jusque là se contentaient de vérifier une égalité. Or il est possible d'utiliser d'autres symboles mathématiques appelés opérateurs de comparaison. En voici un liste :

Opérateur

Signification

=

"est égal à"

/=

"est différent de"

<

"est plus petit que"

>

"est plus grand que"

<=

"est plus petit ou égal à"

>=

"est plus grand ou égal à"

Ainsi notre programme initial peut-être modifié de la manière suivante :

AFFICHER "Combien d'ordinateurs avez-vous?"
SAISIR la réponse
SI la réponse est supérieure ou égal à 2
   ALORS AFFICHER "Génial"
   SINON AFFICHER "C'est toujours ca"

D'où le programme suivant :

Procedure Questionnaire2 is
   Reponse : integer := 0 ; --on définit la réponse et on l'initialise à 0
begin

Put("Combien d'ordinateurs avez-vous?") ; 
Get(Reponse) ; Skip_line ; 
if Reponse >= 2
   then Put("Genial!") ; 
   else Put("C'est toujours ca") ; 
end if ; 

end Questionnaire2 ;

A noter que la question posée (Reponse est-elle supérieure ou égale à 2) , aussi appelée prédicat peut être remplacée par :

if Reponse>1
   then Put("Genial!") ; 
   else Put("C'est toujours ca") ; 
end if ;

Ce nouveau prédicat aura la même conclusion. De même, en inversant les instruction suivant then et else et en écrivant :

if Reponse<=1
   then Put("C'est toujours ca") ; 
   else Put("Genial!") ; 
end if ;

ou

if Reponse<2
   then Put("C'est toujours ca") ; 
   else Put("Genial!") ; 
end if ;

... on obtiendra également la même chose.

Bien. Nous avons fait un premier tour des conditions en Ada. L'élément le plus important est la suite d'instruction if/then/else, mais n'oubliez pas qu'il existe l'instruction case pour simplifier votre code.

Avec ces quelques instructions en tête, vos programmes devraient dors et déjà prendre un peu de profondeur.


Conditions multiples avec CASE Les conditions II : les booléens

Les conditions II : les booléens

Les opérateurs de comparaison Introduction aux booléens

Nous avons vu au précédent chapitre l'existence des instruction if/elsif/case. Mais nous sommes tombés sur un os : nos codes ne prenaient pas en compte les majuscules. Je vous propose donc de repartir du début pour simplifier votre travail de compréhesion. Notre code se résumera à

if Reponse = 'o'
   then Put("Vous avez bien de la chance. ") ; 
   else Put("Ah ... Dommage.") ;
end if ;

Introduction aux booléens

Les conditions II : les booléens La négation avec Not

Un bref historique

L'algèbre booléenne ou algèbre de Boole (du nom du Mathématicien George Boole) est une branche des mathématiques traitant des opérations logiques. Elle a été très utile en électronique (c'est grâce à elle que nos bêtes ordinateurs savent aujourd'hui additionner, multiplier ...) et va nous servir aujourd'hui en programmation.

:euh: Mais ... euh ... je suis nul(le) en Maths ...

Pas de problème, il ne s'agit que de logique, il n'y aura pas de calcul (au sens habituel du terme).

Qu'est-ce qu'un booléen ?

Tout d'abord, lorsque l'on écrit :

if Reponse = 'o'

... il n'y a que deux alternatives possibles : ou cette affirmation est VRAIE (Reponse vaut bien 'o') ou bien elle est FAUSSE (Reponse vaut autre chose). Ces deux alternatives (VRAI/FAUX) sont les deux seules valeurs utilisées en algèbre booléenne. En ada, elles se notent true (VRAI) et false (FAUX).

Un booléen est donc un objet qui vaut soit VRAI soit FAUX. En Ada, cela se déclare de la manière suivante :

A : boolean := true ;
B : boolean := false ; 

Il est également possible d'affecter à nos variables booléennes le résultat d'un prédicat :

A := (Reponse = 'o')

Hein ? A prend la valeur contenue dans Reponse ou bien il prend la valeur 'o' ? Et puis c'était pas sensé valoir true ou false ?

La variable A prendra bien comme résultat true ou false et sûrement pas 'o' ! Tout dépend de l'égalité entre parenthèses : si Reponse est bien égal à 'o' alors A vaudra true, sinon il vaudra false.

La condition suivante pourra ainsi s'écrire :

if A 
   then ...
end if ;

Cela signifie "Si A est vrai alors ...". La variable A remplacera ainsi notre égalité.

Les opérateurs booléen

Voici les quelques "opérations" booléennes que nous allons aborder :

Opérateur

Traduction littérale

Signification

Not

Non

Not A : "il faut que A ne soit pas vrai"

Or

Ou

A or B : "il faut que A ou B soit vrai"

And

Et

A And B : "il faut que A et B soient vrais"

Xor

Ou exclusif

A xor B : "il faut que A ou B soit vrai mais pas les deux. "

Ce ne sont pas les seuls opérateurs existant en algèbre booléenne, mais ce sont ceux que vous serez amenés à utiliser en Ada.


Les conditions II : les booléens La négation avec Not

La négation avec Not

Introduction aux booléens Les opérations Or et And

Revenons à notre programme. Nous voudrions inverser les deux instructions d'affichage de la manière suivante :

if Reponse = 'o'
   then Put("Ah ... Dommage.") ; 
   else Put("Vous avez bien de la chance. ") ;
end if ;

Chacun comprend que notre programme ne répond plus correctement : si l'utilisateur a plusieurs ordinateurs, le programme lui répond "dommage" !?! Nous devons donc changer la condition : le programme doit afficher "Dommage" seulement SI Reponse ne vaut pas'o' ! La négation d'une instruction booléenne se fait à l'aide de l'instruction not. D'où le code suivant :

if Not Reponse = 'o'                           -- si la réponse n'est pas Oui
   then Put("Ah ... Dommage.") ;               -- alors on affiche "Dommage"
   else Put("Vous avez bien de la chance. ") ; -- sinon on affiche le second message
end if ;

Le programme fait ainsi de nouveau ce qu'on lui demande. Retenez cette astuce car il arrive souvent que l'on se trompe dans la condition ou l'ordre des instructions entre then et else, notamment quand les conditions deviennent plus complexes.

Un peu d'algèbre booléenne maintenant :


Introduction aux booléens Les opérations Or et And

Les opérations Or et And

La négation avec Not L'opération xor (optionnel)

L'instruction or

Nous avons vu dans la partie précédente que le code suivant ne gérait pas les majuscules :

if Reponse = 'o'
   then Put("Vous avez bien de la chance. ") ; 
   else Put("Ah ... Dommage.") ;
end if ;

Il faudrait poser la condition "SI la réponse est o ou O". C'est à dire qu'il suffirait que l'une des deux conditions soit remplie pour que le programme affiche que vous avez de la chance. Pour cela, on utilise l'instruction or (OU en Français).

if Reponse = 'o' or Reponse = 'O'
   then Put("Vous avez bien de la chance. ") ; 
   else Put("Ah ... Dommage.") ;
end if ;

Encore un peu d'algèbre booléenne : si A et B sont deux propositions (vraies ou fausses) l'instruction "A ou B" sera vraie dans les trois cas suivants :

L'instruction and

Nouveau jeu ! Inversons, comme dans la partie précédente, les instructions d'affichage. Nous devrions alors écrire une négation :

if not(Reponse = 'o' or Reponse = 'O')
   then Put("Ah ... Dommage.") ; 
   else Put("Vous avez bien de la chance. ") ;
end if ;

Vous vous souvenez de la partie sur l'instruction Not ? Nous avons fait la même chose : puisque l'on a inversé les instructions d'affichage, nous écrivons une négation dans le prédicat. Mais cette négation peut aussi s'écrire :

if not Reponse = 'o' and not Reponse = 'O'
   then Put("Ah ... Dommage.") ; 
   else Put("Vous avez bien de la chance. ") ;
end if ;

L'opérateur And signifie ET. Il implique que les deux conditions doivent être remplies en même temps :

Encore de l'algèbre booléenne.

De manière schématique, retenez que la négation d'un OU est ET. Le contraire de VRAI OU VRAI est donc FAUX ET FAUX. Bon, je crois qu'il est temps d'arrêter car certains méninges doivent commencer à griller. :p Je vous invite donc à méditer ce que vous venez de lire.