Le
pseudocode est un langage pour exprimer clairement et formellement un algorithme.
Ce langage est près d'un
langage de programmation comme Pascal,
C#
ou C++,
sans être identique à l'un ou à l'autre. Il exprime des
idées formelles dans une langue près du langage naturel de ses
usagers (pour nous, le français) en lui imposant une forme rigoureuse.
Quelques trucs suivent pour vous aider à rédiger du « bon »
pseudocode.
Identification
Il est essentiel d'identifier l'auteur de tout document remis au professeur,
même s'il ne s'agit « que » de
pseudocode.
Assurez-vous de respecter les règles d'identification en vigueur dans votre
cours.
Nomenclature
Quelques règles de nommage simples suivent :
- Le nom d'une variable ou d'une constante doit être significatif. On devrait
savoir immédiatement, à partir de son nom, à quoi sert la variable ou la
constante, et quel sens donner à sa valeur
- Les majuscules et les minuscules sont des symboles distincts dans la
plupart des langages de programmation, mais pas tous. Ainsi, pour éviter les
ennuis, ne donnez pas à deux entiés (une variable et une constante, par
exemple) des noms qui ne différeraient que sur cet aspect
- Les règles de programmatique imposées doivent être respecées (ces règles
varient selon les entreprises ou les cours, alors renseignez-vous!)
Règles générales
En
pseudocode :
- Les instructions se font une ligne à la fois (pas de
';' en
pseudocode)
Correct |
Incorrect |
PI ← 3,14159
Lire rayon
volume ← 4 / 3 * PI * rayon ^ 3
Écrire volume
|
PI ← 3,14159;
Lire rayon;
volume ← 4 / 3 * PI * rayon ^ 3;
Écrire volume;
|
- Si une ligne est trop longue, on vise une indentation permettant de
comprendre où l'expression se termine
Correct |
Incorrect |
TAUX_CHANGE_CANADIEN ← 0,79
lire montantCanadien
montantAmérican ← montantCanadien * TAUX_CHANGE_CANADIEN
// ou encore
montantAmérican ← montantCanadien *
TAUX_CHANGE_CANADIEN
Écrire montantAméricain
|
TAUX_CHANGE_CANADIEN ← 0,79
lire montantCanadien
// présentation confuse
montantAmérican ← montantCanadien *
TAUX_CHANGE_CANADIEN
Écrire montantAméricain
|
- On ne se préoccupe pas des types des variables et des constantes
Correct |
Incorrect |
PI ← 3,14159
Lire rayon
volume ← 4 / 3 * PI * rayon ^ 3
Écrire volume
|
const float PI ← 3,14159
float rayon,
volume
Lire rayon
volume ← 4 / 3 * PI * rayon ^ 3
Écrire volume
|
- Certains profs accepteront des commentaires à même le pseudocode
(typiquement préfixés de // comme c'est le cas
dans plusieurs langages). Dans le doute, consultez votre professeur pour
connaître sa position sur le sujet
Opérations primitives
Le symbole ← utilisé pour l'affectation en
pseudocode est un emprunt
direct au langage
APL,
qui a inspiré plusieurs autres langages
À propos des opérations primitives exprimées en
pseudocode :
- Les opérations primitives sont Lire,
Écrire et ←
- Les constantes littérales peuvent être des nombres comme
3, des expressions reposant sur des constantes comme
4/3, ou du texte comme "J'aime mon prof" ou
"123"
- Les entrées se font avec Lire. Cette primitive
modélise une lecture (par exemple au clavier) et le dépôt de la valeur lue dans une variable
Correct |
Incorrect |
Lire hauteur
Lire largeur
Lire nom
|
// une constante ne peut être lue au clavier, par définition
Lire HAUTEUR
// le littéral "largeur" est du texte; ce n'est pas une variable
Lire "largeur"
// la primitive Lire ne lit qu'une variable à la fois
Lire hauteur, largeur ,nom
|
- Les sorties se font avec Écrire. Cette
primitive modélise la projection d'une valeur (littéral, variable, constante)
à l'écran
Correct |
Écrire surface
Écrire TAILLE
Écrire 3
Écrire "J'aime mon prof"
// affichera 5
Écrire 2 + 3
// affichera le texte 2 + 3
Écrire "2 + 3"
// Présumant une fonction Sqrt qui calcule et retourne la racine carrée
// de son paramètre, ce qui suit affichera 4
Écrire Sqrt(16)
|
- L'affectation se fait avec ←
Correct |
Incorrect |
PI ← 3,14159
Lire hauteur
surface ← hauteur ^ 2
résultat ← Sqrt(4)
message ← "J'aime mon prof"
|
// on ne peut modifier un littéral
3 ← hauteur
"J'aime mon prof" ← message
// on ne peut modifier un appel de fonction
Sqrt(4) ← résultat
// on ne peut modifier une expression
2 + 3 ← 5
|
- On ne permet qu'une seule opération primitive par ligne
Correct |
Incorrect |
PI ← 3,14159
E ← 2,71828
Lire hauteur
surface ← hauteur ^ 2
résultat ← Sqrt(4)
message ← "J'aime mon prof"
|
PI ← 3,14159, E ← 2,71828
Lire hauteur, largeur
Écrire "J'aime mon prof" nomDuProf "!"
|
- Une constante ne peut être initialisée qu'une seule fois, et ce doit être
à l'aide du symbole d'affectation lors de sa déclaration. Après tout, par
définition, une fois
déclarée, une constante ne peut plus changer de valeur
Correct |
Incorrect |
PI ← 3,14159
E ← 2,71828
MESSAGE ← "J'aime mon prof"
|
PI ← 3,14159
// on ne peut lire la valeur d'une constante : cette valeur est fixée a priori
Lire PI
MESSAGE ← "J'aime mon prof"
// on ne peut plus modifier une constante une fois celle-ci initialisée
MESSAGE ← "Moi aussi!"
|
Exemple simple d'un programme calculant et affichant le volume d'une sphère,
étant donné son rayon, le tout exprimé en
pseudocode. Notez la constante en
majuscules, les noms de variables, la notation pour l'affectation, etc.
PI ← 3,14159
Lire rayon
volume ← 4 / 3 * PI * rayon^3
Écrire volume
Autres opérations
Le
pseudocode ne se limite pas aux
opérations primitives.
Opérations arithmétiques
Les opérateurs arithmétiques admis sont les suivants :
Notation en
pseudocode
|
Équivalent en notation mathématique
|
Sens
|
|
|
Addition de a et de b
|
|
|
Valeur de a à laquelle
on aurait soustrait b
|
|
|
Produit de a et de b
|
|
|
Quotient de la division de a par b (indéfini si
)
|
|
|
Reste de la division de a par b (indéfini si
)
|
|
|
Résultat de l'élévation de a à la puissance b
|
Sur le plan de la notation, le
pseudocode se limite à du texte susceptible
d'être écrit au clavier. De même, la multiplication doit être exprimée explicitement
Correct |
Incorrect |
PI ← 3,14159
Lire x
y ← 2 * x
volume ← 4 / 3 * PI * rayon ^ 3
Écrire Sqrt(x+y)
|
← 3,14159
Lire x
y ←
volume ←
Écrire
|
Opérations relationnelles
Les opérateurs relationnels admis sont les suivants :
Notation en
pseudocode
|
Équivalent en notation mathématique
|
Sens
|
|
|
a est plus petit que b (a précède b)
|
|
|
a est plus petit ou égal
à b
|
|
|
a est plus grand que b (a suit b)
|
|
|
a est plus grand ou égal
à b
|
|
|
a est égal à
b
|
|
|
a est différent de b
|
Opérations logiques
Les opérateurs logiques admis sont les suivants :
Notation en pseudocode |
Équivalent en notation mathématique |
Sens |
|
|
Vrai seulement si a et b sont tous deux vrais
|
|
|
Faux seulement si a et b sont tous deux faux
|
|
|
Vrai seulement si a est faux
|
Fonctions et répétitives
Pour les fonctions, les règles sont pour l'essentiel les mêmes : on ne se
préoccupe pas des types, on s'intéresse aux noms, on adopte une indentation
rigoureuse, etc.
Pour les répétitives, seul le Tant que importe
vraiment (les boucles do...while et les boucles
for sont en fait des while qui formalisent
des cas particuliers). Notez que j'accepte personnellement les formes
d'affectation composites (++,
+=, -=, etc.) en pseudocode mais qu'il vaut
mieux vérifier avec votre professeur avant de les utiliser, pour vous assurer
que c'est aussi le cas avec elle ou avec lui.
Quelques exemples :
En C++ |
En C# |
En pseudocode |
int carre(int n) {
return n * n;
}
|
static int Carré(int n)
{
return n * n;
}
|
Carré(n)
Retourner n * n
|
int calculer_somme_valeurs(int de, int vers) {
int somme = 0;
for(int i = de; i <= vers; ++i)
somme += i;
return somme;
}
|
static int CalculerSommeValeur(int de, int vers)
{
int somme = 0;
for(int i = de; i <= vers; ++i)
{
somme += i;
}
return somme;
}
|
CalculerSommeValeurs(de, vers)
somme ← 0
cpt ← de
Tant que cpt <= vers
somme += cpt // ou somme ← somme + cpt
++cpt // ou cpt ← cpt + 1
Retourner somme
|
int lire_entier(string invite, int min, int max) {
cout << format("{} [{},{}] : ", invite, min, max);
int nb;
cin >> nb;
while(nb < min || max < nb) {
cout << format("{} [{},{}] : ", invite, min, max);
cin >> nb;
}
return nb;
}
|
static int LireEntier(string invite, int min, int max)
{
Console.Write($"{invite} [{min},{max}] : ");
int nb = int.Parse(Console.ReadLine());
while(nb < min || max < nb)
{
Console.WriteLine($"Entrée erronnée : {nb}");
Console.Write($"{invite} [{min},{max}] : ");
nb = int.Parse(Console.ReadLine());
}
return nb;
}
|
LireEntier(invite, min, max)
Écrire invite // min, max
Lire nb
Tant que nb < min OU max < nb
Écrire "erreur"
Écrire invite // min, max
Lire nb
Retourner nb;
|
// exemple qui suppose l'existence des constantes
// CHOIX_MIN, CHOIX_MAX et du prédicat
// est_entre_inclusif(val,min,max)
char lire_choix() {
char choix;
do {
cout << format("Votre choix [{}, {}] : ", CHOIX_MIN, CHOIX_MAX);
cin >> choix;
} while(!est_entre_inclusif(choix, CHOIX_MIN, CHOIX_MAX));
return choix;
}
|
// exemple qui suppose l'existence des constantes
// CHOIX_MIN, CHOIX_MAX et du prédicat
// EstEntreInclusif(val,min,max)
static char LireChoix()
{
char choix;
do
{
Console.Write($"Votre choix [{CHOIX_MIN}, {CHOIX_MAX}] : ");
choix = char.Parse(Console.ReadLine());
}
while(!EstEntreInclusif(choix, CHOIX_MIN, CHOIX_MAX));
return choix;
}
|
// exemple qui suppose l'existence des constantes
// CHOIX_MIN, CHOIX_MAX et du prédicat
// est_entre_inclusif(val,min,max)
LireChoix()
Lire choix
Tant que NON EstEntreInclusif(choix, CHOIX_MIN, CHOIX_MAX)
Lire choix
Retourner choix
|
#include <iostream>
using namespace std;
bool est_pair(int n) {
return n % 2 == 0;
}
char determiner_symbole(int noLigne) {
char symbole;
if(est_pair(noLigne)) {
symbole = '-';
} else {
symbole = '*';
}
return symbole;
}
void dessiner_symboles(int noLigne) {
int nbSymboles = 2 * noLigne - 1;
char symbole = determiner_symbole(noLigne);
for(int cpt = 1; cpt <= nbSymboles; ++cpt) {
cout << symbole;
}
}
void dessiner_espaces(int nbLignes, int noLigne) {
int nbEspaces = nbLignes - noLigne;
for(int cpt = 1; cpt <= nbEspaces; ++cpt) {
cout << ' ';
}
}
void dessiner_ligne(int nbLignes, int noLigne) {
dessiner_espaces(nbLignes, noLigne);
dessiner_symboles(noLigne);
}
void dessiner_sapin(int hauteur) {
for(int cptLignes = 1; cptLignes <= hauteur; ++cptLignes) {
dessiner_ligne(hauteur, cptLignes);
cout << endl;
}
}
// programme principal
// https://wandbox.org/permlink/eIcnfuuH5cgxp1VY
int main() {
const int NB_LIGNES = 10;
dessiner_sapin(NB_LIGNES);
}
|
using System;
// programme principal
// https://dotnetfiddle.net/tKwUfq
const int NB_LIGNES = 10;
DessinerSapin(NB_LIGNES);
static bool EstPair(int n)
{
return n % 2 == 0;
}
static char DéterminerSymbole(int noLigne)
{
char symbole;
if(EstPair(noLigne))
{
symbole = '-';
}
else
{
symbole = '*';
}
return symbole;
}
static void DessinerSymboles(int noLigne)
{
int nbSymboles = 2 * noLigne - 1;
char symbole = DéterminerSymbole(noLigne);
for(int cpt = 1; cpt <= nbSymboles; ++cpt)
{
Console.Write(symbole);
}
}
static void DessinerEspaces(int nbLignes, int noLigne)
{
int nbEspaces = nbLignes - noLigne;
for(int cpt = 1; cpt <= nbEspaces; ++cpt)
{
Console.Write(' ');
}
}
static void DessinerLigne(int nbLignes, int noLigne)
{
DessinerEspaces(nbLignes, noLigne);
DessinerSymboles(noLigne);
}
static void DessinerSapin(int hauteur)
{
for(int cptLignes = 1; cptLignes <= hauteur; ++cptLignes)
{
DessinerLigne(hauteur, cptLignes);
Console.WriteLine();
}
}
|
// programme principal
NB_LIGNES ← 10
DessinerSapin(NB_LIGNES)
EstPair(n)
Retourner n % 2 == 0
DéterminerSymbole(noLigne)
Si EstPair(noLigne)
symbole ← '-'
Sinon
symbole ← '*'
Retourner symbole
DessinerSymboles(noLigne)
nbSymboles ← 2 * noLigne - 1
symbole ← DéterminerSymbole(noLigne)
cpt ← 1
Tant que cpt <= nbSymboles
Écrire symbole
++cpt
DessinerEspaces(nbLignes, noLigne)
nbEspaces ← nbLignes - noLigne
cpt ← 1
Tant que cpt <= nbEspaces
Écrire ' '
++cpt
DessinerLigne(nbLignes, noLigne)
DessinerEspaces(nbLignes, noLigne)
DessinerSymboles(noLigne)
DessinerSapin(hauteur)
cptLignes ← 1
Tant que cptLignes <= hauteur
DessinerLigne(hauteur, cptLignes)
ChangerDeLigne()
++cptLignes
|
Tests
Un programme peut être testé même lorsqu'il n'existe que
sous forme de
pseudocode :
- Tester un algorithme, écrit en
pseudocode ou dans un autre langage,
demande d'utiliser comme jeu d'essai à la fois des valeurs typiques
et des cas limites.