Repository navigation
Pseudocode 24 fr
Durée effective : university year 2024 – 2025
- Table des matières
- Avant-propos — Le Pseudocode et vous
- Changelog
- Règles d'orthographe
- Espaces blancs
- Identifiants
- Commentaires
- Directives du compilateur
- Types
- Déclarations
- Instructions
- Expressions
Cette nouvelle révision du fameux langage Pseudocode se concentre sur un mot d'ordre : familiarité
Finis les constructions ésotériques et les choix syntaxiques obscurs (enfin presque).
À l'ordre du jour : facilité d'utilisation et simplicité.
- Supression du mot-clé
c'estdu programme principal, procédures, fonctions - Le type d'une variable vient désormais avant le nom:
⟨type⟩ : ⟨nom⟩(idem dans les structures) - Les variables peuvent donc être initialisées indépendamment:
⟨type⟩ : ⟨nom1⟩ := ⟨init⟩; ⟨nom2⟩ := ⟨init⟩, ...; - Les tableaux commencent désormais à l'indice 0.
- La syntaxe des types tableaux a changé :
tableau⟨type-element⟩[⟨dimension1⟩][⟨dimension2⟩][...][⟨dimensionN⟩] - La syntaxe des constantes a changé :
constante ⟨type⟩ : ⟨nom⟩ := ⟨init⟩ - La syntaxe des alias de type a changé :
type ⟨type⟩ : ⟨nom⟩ - La procédure builtin
lireClavierest désormais une forme spéciale:⟨lvalue⟩ = lire();- Noter l'utilisation du symbole
=(:=est aussi autorisé) - Cette forme est équivalente à une affectation
- Noter l'utilisation du symbole
- La procédure builtin
écrireÉcrana été renommée en écrire - Nouvelle fonction builtin : ent : obtient la partie entière d'un réel.
- La gestion des fichiers a été supprimée du langage
- Le mot-clé
finsi(alternatives) a été renommé enfin_si - Le mot-clé
sinonsi(alternatives) a été renommé ensinon_si - Les mot-clés
tantetque(boucle tant_que) ont été combinées entant_que - Suppression de la boucle répéter jusqu'à
- Le corps d'une boucle tant_que est désormais terminé par le mot-clé
fin_tant_que - La condition d'une boucle faire … tant_que est désormais suivie d'un point-virgule
- La boucle pour a été simplifiée
- Les parenthèses sont désormais obligatoires autoures des conditions de flux de contrôle
- Mot clé
finselon(selon) renommé enfin_selon -
Procédures et fonctions : suppression des modes de paramètre, simplification des paramètres en sortie/entrée sortie
- Préfixe explicite des paramètres en sortie formels et effectifs
Le Pseudocode est sensible à la casse. Les accents et les diacritiques sont significatifs, sauf dans les mots réservés (mots-clés et builtins). Cela signifie que la fonction intégrée écrire peut être orthographiée écrire ou ecrire, mais pas Écrire.
Les espaces blancs sont considérés comme insignifiants. Cela signifie que les espaces supplémentaires, les tabulations et les sauts de ligne (ou tout autre caractère d'espacement Unicode) n'affectent pas la signification du code.
Par exemple, les instructions suivantes sont équivalentes :
x : entier ;et
x :
entier
;Les identifiants sont définis par l'expression régulière PCRE2 suivante : [\p{L}_][\p{L}_0-9]*
Explication : un identifiant se compose d'une ou plusieurs lettres Unicode, d'un trait de soulignement ou de chiffres. Le premier caractère ne peut pas être un chiffre.
Les commentaires sont utilisés pour documenter le code et le rendre plus lisible. Il existe deux types de commentaires : sur une seule ligne et sur plusieurs lignes.
Les commentaires n'affectent pas la signification du programme, mais ils séparent les jetons, agissant effectivement comme des espaces.
Les commentaires sur une seule ligne commencent par // et continuent jusqu'à la fin de la ligne.
// Ceci est un commentaire sur une seule ligneLes commentaires sur plusieurs lignes commencent par /* et se terminent par */. Ils peuvent s'étendre sur plusieurs lignes.
/* Ceci est un multiligne
clown comment
*/Les directives de compilateur sont des instructions spéciales exécutées au moment de la compilation.
#assert ⟨expr⟩ ⟨message⟩Assertion statique. Si ⟨expr⟩ est faux, le programme est arrêté et ⟨message⟩ est affiché. ⟨expr⟩ doit être implicitement convertible vers le type booléen. ⟨message⟩ est facultatif et doit être implicitement convertible vers le type chaîne.
#assert faux
#assert 1 == 1 "Ceci ne devrait jamais échouer"#eval expr ⟨expr⟩Affiche la valeur et le type d'une expression connue au moment de la compilation.
#eval expr 1 + 1 // Affiche "entier: 2"#eval type ⟨type⟩Affiche les informations d'un type.
#eval type entier // Affiche "entier"Les types définissent le type de données qu'une variable peut contenir.
Les types primitifs sont les types les plus basiques. Ils sont utilisés pour représenter des valeurs simples, telles que les scalaires, des valeurs de vérité et les chaînes.
Le type entier représente des entiers.
Le type réel représente des nombres réels.
Le type booléen représente des valeurs booléennes. Les valeurs de véritées sont exprimées avec les mot-clés vrai et faux.
Le type caractère représente des caractères. L'encodage est défini par le langage cible.
Le type chaîne représente des chaînes de longueur connue à l'exécution.
Le type chaîne(N) représente des chaînes de longueur connue à la compilation. N définit la longueur maximale de la chaîne. L'encodage est défini par le langage cible.
tableau(⟨type-element⟩)[⟨longueur⟩][...]Les tableaux sont utilisés pour représenter des collections de valeurs de même type.
Les tableaux commencent à l'indice 0.
- ⟨longueur⟩ est une expression unique ou une liste d'expressions séparées par des virgules qui s'évaluent au moment de la compilation à une valeur
entier. Elles définissent la longueur de chaque dimension du tableau. - ⟨type-element⟩ est le type des éléments du tableau.
tableau(entier)[5] // Tableau unidimensionnel de 5 entiers
tableau(réel)[5][6] // Matrice (tableau bidimensionnel) 5x6 de réelsLa syntaxe des tableaux multidimensionnels n'est qu'un raccourci pour des tableaux de tableaux.
tableau(entier)[4][3] Est un raccourci pour :
tableau(tableau(entier)[3])[4]structure début
⟨type⟩ : ⟨composant⟩;
// …
finLes structures sont des types de données définis par l'utilisateur qui regroupent différents types de variables sous un seul nom. Cela est particulièrement utile pour gérer ensemble des données liées. Les structures implémentent les types en produit.
Le contenu d'une structure consiste en une liste de déclarations de variables.
Exemples (utilisant les alias de types) :
type structure début
nom, prenom : chaîne(50);
age : entier;
fin : t_personne;
type structure début
libelle : chaîne(20);
eleves : tableau(t_personne)[35];
fin : t_classe;Les déclarations divisent le programme en parties nommées et réutilisables.
programme ⟨nom⟩ début
// instructions…
finLe programme principal est le point d'entrée du programme.
Il doit y avoir exactement un programme principal.
constante ⟨type⟩ : ⟨nom⟩ := ⟨valeur⟩;Les constantes désignent des valeurs connues au moment de la compilation.
⟨valeur⟩ est une expression connue au moment de la compilation ou un initialiseur.
constante réel : PI := 3.14159;Les initialiseurs initialisent les variables ou les constantes de types composés (tableau ou structure).
Ils suivent principalement la syntaxe et les règles d'initialisation entre accolades du C.
constant tableau(entier)[10] A = { 1,2,3,4,5,6,7,8,9,10 };
constante structure début
x: entier;
c: tableau(caractère)[4];
fin B := {
1
};procédure ⟨nom⟩(⟨paramètres-formels⟩) début
// instructions…
finLes procédures regroupent et réutilisent des instructions qui exécutent une tâche spécifique.
Elles peuvent avoir zéro ou plusieurs paramètres formels.
procédure sayHello(entF name : chaîne) début
écrire("Hello ", name);
finprocédure add(entier : a, entier : b, sortie entier : r) début
r := a + b;
finfonction ⟨nom⟩(⟨liste-paramètres-formels⟩) délivre ⟨type⟩ début
// instructions…
retourne ⟨valeur⟩;
finLes fonctions regroupent et réutilisent des instructions qui exécutent une tâche spécifique et renvoient une valeur.
⟨liste-paramètres-formels⟩ est une liste de 0 ou plus paramètres formels séparés par des virgules.
fonction carré(réel : a) délivre réel début
retourn a * a;
finfonction add(entier : a, entier : b) délivre entier début
retourne a + b;
finfonction nb_jours_depuis_dernier_accident() délivre entier début
retourne 0;
finLes paramètres d'une fonction sont des variables accessibles dans le corps d'une fonction ou d'une procédure. Leur valeur est passée à l'appel.
Les paramètres effectifs en entréee sont passés par valeur. Cela signifie que la fonction reçoit une copie de la valeur qu'elle peut modifier sans conséquences extérieures.
Les paramètres effectifs en sortie ou en entrée/sortie sont passés par référence. Cela signifie que les modifications effectuées dans la fonction/procédure persistent après son retour, puisque c'est la même mémoire qui est manipulée, et non pas une copie.
La différence entre les paramètres en sortie et en entrée/sortie est que la fonction/procédure n'utilise pas la valeur d'un paramètre en sortie, elle ne fait que l'affecter.
La valeur passée à un paramètre en sortie peut donc être (et sera généralement) indéfinie (telle qu'une variable non assignéee).
Pour utiliser un paramètre en sortie dans le corps de la fonction, préfixer son nom par le mot-clé sortie.
Exemple :
// x := 5; // erreur
sortie x := 5;⟨type⟩ : ⟨nom⟩sortie ⟨type⟩ : ⟨nom⟩
Les paramètres formels d'une fonction ou d'une procédure définissent les valeurs qu'elle attend recevoir de l'appelant.
Comme pour les variables, pour définir plusieurs paramètres, ⟨nom⟩ peut être plusieurs noms séparés par des virgules.
La seconde forme définit un paramètre en sortie.
⟨expression⟩sortie ⟨expression⟩
La seconde forme passe un paramètre en sortie.
Les prototypes pré-déclarent des fonctions et des procédures définies ailleurs. La syntaxe rappelle celle du C, avec la signature suivie d'un point-virgule. Exemple :
procédure sayHello(entF name : chaîne);
fonction add(entF a : entier, entF b : entier) délivre entier;Contrairement au C, les noms de paramètres ne peuvent pas être omis.
Une fonction/procédure donnée peut être prototypée plusieurs fois, à condition que toutes les signatures soient identiques.
type ⟨type⟩ : ⟨nom⟩;Les alias de type dénomment un nouveau type, afin d'ajouter un niveau d'abstraction et d'améliorer la sémantique du code.
Comme pour les variables, pour définir plusieurs alias sur le même type, ⟨nom⟩ peut être plusieurs noms séparés par des virgules.
Exemple :
type entier : t_pid;
// Maintenant t_pid est un alias pour entierLes alias de type sont couramment utilisés pour définir des types de tableau/structure complexes car ils évitent de répéter le type. Exemple :
type structure début
nom : chaîne(50);
prenom : chaîne(50);
age : entier;
fin : t_personne;
type tableau(t_personne)[50] : t_fileAttente;Les instructions sont les éléments de base d'un programme. Elles sont utilisées pour contrôler le flux d'exécution, effectuer des opérations et prendre des décisions.
L'instruction no-op ne fait rien. Elle se compose d'un seul point-virgule ;.
Les builtins sont des sous-routines fournies par le compilateur.
écrire(⟨arg1⟩, ⟨arg2⟩, …);Le builtin variadique écrire affiche les arguments donnés sur la sortie standard, suivis d'un saut de ligne. Tous les types ne sont pas pris en charge, selon le langage cible.
Il peut également prendre zéro argument, auquel cas il affiche simplement un saut de ligne.
⟨variable⟩ = lire();Le builtin ⟨variable⟩ = lire(); lit une valeur depuis l'entrée standard et l'affecte à la variable donnée. Tous les types ne sont pas pris en charge, selon le langage cible.
Extension: := est autorisé à la place de =.
ent(3.5) // 3
ent(-3.5) // -3La fonction builtin ent(réel : x) retourne la valeur absolue de x.
⟨variable⟩ := ⟨expression⟩;Les affectations changent la valeur d'une variable, qui peut être une variable locale, un élément de tableau, ou un composant de structure.
Toute expression suivie d'un point-virgule est une instruction valide.
⟨type⟩ : ⟨nom⟩;
⟨type⟩ : ⟨nom1⟩, ⟨nom2⟩;Déclare une ou plusieurs variables locales.
Les variables locales peuvent également avoir des initialiseurs.
⟨type⟩ : ⟨nom⟩ := ⟨expression⟩;
⟨type⟩ : ⟨nom1⟩ := ⟨expression⟩, ⟨nom2⟩ := ⟨expression⟩;Chaque variable déclarée est initialisée indépendamment.
Un bloc anonyme définit une nouvelle portée. Syntaxe :
début
// instructions…
finLes instructions de flux de contrôle sont utilisées pour contrôler le flux d'exécution dans un programme. Elles permettent de prendre des décisions, de répéter des instructions et de passer à différentes parties du code.
Les boucles vous permettent de répéter un bloc de code plusieurs fois.
tant_que (⟨condition⟩) faire
// instructions…
fin_tant_queLa boucle tant_que exécute des instructions tant que ⟨condition⟩ est vraie.
⟨condition⟩ doit être une expression booléenne ou implicitement convertible en booléen.
faire
// instructions…
tant_que (⟨condition⟩);La boucle faire … tant_que exécute les instructions à l'intérieur de la boucle au moins une fois, puis répète la boucle tant que ⟨condition⟩ est vraie.
⟨condition⟩ doit être une expression booléenne ou implicitement convertible en booléen.
pour (⟨initialisation⟩; ⟨condition⟩; ⟨incrémentation⟩) faire
// instructions…
fin_pourLa boucle pour exécute les instructions à l'intérieur de la boucle.
- ⟨initialisation⟩ est une instruction exécutée une fois au début de la boucle;
- ⟨condition⟩ est une expression booléenne. La boucle continue tant qu'elle est vraie;
- ⟨incrémentation⟩ est une instruction exécutée à la fin de chaque itération.
Une boucle pour est une syntaxe raccourcie pour une boucle tant_que
début
⟨initialisation⟩;
tant_que (⟨condition⟩) faire
// instructions…
⟨incrémentation⟩;
fin_tant_que
finLes alternatives vous permettent d'exécuter différents blocs de code en fonction d'une condition.
si (⟨condition⟩) alors
// instructions…
sinon_si (⟨condition⟩) alors
// instructions…
sinon
// instructions…
fin_siL'instruction si exécute les instructions à l'intérieur du bloc alors si ⟨condition⟩ est vrai.
⟨condition⟩ doit être une expression booléenne ou implicitement convertible en booléen.
Les blocs sinon_si sont facultatifs. Elles sont exécutées si le bloc si précédent est faux et que la ⟨condition⟩ du bloc sinon_si actuel est vrai.
Le bloc sinon est optionnel. Il est exécuté si tous les blocs si et sinon_si précédents sont faux.
selon (⟨expression⟩) faire
quand ⟨valeur⟩ =>
// instructions…
quand ⟨valeur⟩ ou ⟨valeur⟩ =>
// instructions…
quand autre =>
// instructions…
fin_selonL'instruction selon exécute le bloc quand dont la ⟨valeur⟩ est égale à la valeur de ⟨expression⟩, ou le bloc quand autre si aucun des blocs quand ne correspond.
Les ⟨valeur⟩ de chaque cas doivent être connues au moment de la compilation et supporter l'opération == avec ⟨expression⟩.
Les cas ne définissent implicitement pas leur propre portée, donc attention aux collisions de noms de variables.
nomFonction(⟨liste-paramètres-effectifs⟩)Les appels sont utilisés pour invoquer des fonctions et des procédures. Ce sont des expressions qui donnent une valeur. Lors de l'appel d'une procédure, la valeur de l'expression est du type void et l'utiliser provoque une erreur.
⟨liste-paramètres-effectifs⟩ est une liste de 0 ou plus paramètres effectifs séparés par des virgules.
Le tableau suivant répertorie la priorité et l'associativité de chaque opérateur. Les opérateurs sont répertoriés de haut en bas, par ordre de priorité décroissant.
| Priorité | Opérateur | Description | Associativité |
|---|---|---|---|
| 1 |
()[].
|
Appel de fonction/procédure Indice de tableau Accès au composant de structures |
De gauche à droite |
| 2 |
+ -NON(type)
|
Plus et moins unaires Négation logique ou bit-à-bit Cast |
De droite à gauche |
| 3 |
* / %
|
Multiplication, division et reste | De gauche à droite |
| 4 |
+ -
|
Addition et soustraction | De gauche à droite |
| 5 |
< <=> >=
|
Pour les opérateurs relationnels < et ≤ respectivement Pour les opérateurs relationnels > et ≥ respectivement |
De gauche à droite |
| 6 |
== !=
|
Pour les opérateurs relationnels = et ≠ respectivement | De gauche à droite |
| 7 | XOR |
Disjonction exclusive (OU exclusif) logique ou bit-à-bit | De gauche à droite |
| 8 | ET |
Conjonction (ET) logique ou bit-à-bit | De gauche à droite |
| 9 | OU |
Disjonction (OU) logique ou bit-à-bit logique | De gauche à droite |
Lors de l'analyse d'une expression, un opérateur répertorié sur une ligne sera lié plus étroitement (comme par des parenthèses) à ses arguments que tout opérateur répertorié sur une ligne plus bas. Par exemple, l'expression a + b * c est analysée comme a + (b * c), et non comme (a + b) * c.
Les opérateurs qui se trouvent dans la même cellule (il peut y avoir plusieurs lignes d'opérateurs répertoriées dans une cellule) sont évalués avec la même priorité, dans la direction donnée.
Voici un graphique des conversions autorisées entre les types.
flowchart LR
booléen -.faux → 0<br>vrai → 1.-> entier
entier -.0 → faux<br>≠0 → vrai.-> booléen
caractère -.définie par l'implémentation.-> entier
entier -.définie par l'implémentation.-> caractère
chaîneN["chaîne(<var>N</var>)"] --> chaîne
chaîneN ==Chaîne plus grande (<var>n</var> > 0)==> chaîneN2["chaîne(<var>N</var> + <var>n</var>) "]
entier --> réel
réel -.arrondir vers zéro .->entier
nomFichierLog
tableaux["<em>n'importe quel tableau</em>"]
structures["<em>n'importe quelle structure</em>"]
| Forme du lien | Type de conversion |
|---|---|
| Solide | implicite |
| Pointillé | explicite (avec syntaxe de conversion) |
| Épais | affectation uniquement |
Lorsqu'une conversion est définie par l'implémentation, le résultat dépend des règles de le langage cible.
Lorsque le résultat d'une conversion n'est pas spécifié, l'identité est supposée.
Les littéraux de chaîne sont entourés de guillemets doubles ("). Ils ne peuvent s'étendre que sur une seule ligne.
Ils prennent en charge les séquences d'échappement.
Les littéraux de caractères se composent d'un seul caractère entouré de guillemets simples (').
Ils prennent également en charge les séquences d'échappement.
| Séquence d'échappement | Signification |
|---|---|
\a |
Alerte (bip, cloche) |
\b |
Retour arrière |
\e |
Caractère d'échappement |
\f |
Saut de page |
\n |
Saut de ligne |
\r |
Retour chariot |
\t |
Tabulation horizontale |
\v |
Tabulation verticale |
\\ |
Barre oblique inverse |
\' |
Apostrophe ou guillemet simple |
\" |
Guillemets doubles |
\nnn |
L'octet dont la valeur numérique est donnée par nnn interprété comme un nombre octal |
\xhh… |
L'octet dont la valeur numérique est donnée par hh… interprété comme un nombre hexadécimal |
\uhhhh |
Point de code Unicode inférieur à 10000 hexadécimaux |
\Uhhhhhhhh |
Point de code Unicode où h est un chiffre hexadécimal |
TL;DR : identique au C, mais sans \? (car ce langage n'a pas de trigrammes).
Les entiers sont des nombres sans point décimal. Les littéraux d'entier sont exprimés sous forme de séquence de chiffres décimaux.
Les littéraux de réel sont exprimés sous forme de séquence de chiffres décimaux avec un point décimal facultatif. Les chiffres avant le point décimal sont facultatifs.
Les booléens sont soit vrai (true) soit faux (false).