Skip to content

Pseudocode 24 fr

Scover edited this page Dec 18, 2024 · 9 revisions

Pseudocode 24 (nom de code CLM-T)

Durée effective : university year 2024 – 2025

Table des matières

Avant-propos — Le Pseudocode et vous

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é.

Changelog

  • Supression du mot-clé c'est du 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 lireClavier est désormais une forme spéciale: ⟨lvalue⟩ = lire();
    • Noter l'utilisation du symbole = (:= est aussi autorisé)
    • Cette forme est équivalente à une affectation
  • La procédure builtin écrireÉcran a é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é en fin_si
  • Le mot-clé sinonsi (alternatives) a été renommé en sinon_si
  • Les mot-clés tant et que (boucle tant_que) ont été combinées en tant_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é en fin_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

Règles d'orthographe

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.

Espaces blancs

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  
 ;

Identifiants

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.

Commentaires

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.

Sur une seule ligne

Les commentaires sur une seule ligne commencent par // et continuent jusqu'à la fin de la ligne.

// Ceci est un commentaire sur une seule ligne

Sur plusieurs lignes

Les commentaires sur plusieurs lignes commencent par /* et se terminent par */. Ils peuvent s'étendre sur plusieurs lignes.

/* Ceci est un multiligne

clown comment
*/

Directives du compilateur

Les directives de compilateur sont des instructions spéciales exécutées au moment de la compilation.

assert

#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.

Exemple

#assert faux
#assert 1 == 1 "Ceci ne devrait jamais échouer"

eval expr

#eval expr ⟨expr⟩

Affiche la valeur et le type d'une expression connue au moment de la compilation.

Exemple

#eval expr 1 + 1 // Affiche "entier: 2"

eval type

#eval type ⟨type⟩

Affiche les informations d'un type.

Exemple

#eval type entier // Affiche "entier"

Types

Les types définissent le type de données qu'une variable peut contenir.

Primitives

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.

entier

Le type entier représente des entiers.

réel

Le type réel représente des nombres réels.

booléen

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.

caractère

Le type caractère représente des caractères. L'encodage est défini par le langage cible.

chaîne

Le type chaîne représente des chaînes de longueur connue à l'exécution.

chaîne(N)

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.

Tableaux

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.

Exemples

tableau(entier)[5] // Tableau unidimensionnel de 5 entiers
tableau(réel)[5][6] // Matrice (tableau bidimensionnel) 5x6 de réels

Tableaux multidimensionnels

La 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]

Structures

structure début
    ⟨type⟩ : ⟨composant⟩;
    // …
fin

Les 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;

Déclarations

Les déclarations divisent le programme en parties nommées et réutilisables.

Programme principal

programme ⟨nom⟩ début
    // instructions…
fin

Le programme principal est le point d'entrée du programme.

Il doit y avoir exactement un programme principal.

Constantes

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.

Exemple

constante réel : PI := 3.14159;

Initialiseurs

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édures

procédure ⟨nom⟩(⟨paramètres-formels⟩) début
    // instructions…
fin

Les 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.

Exemples

procédure sayHello(entF name : chaîne) début
    écrire("Hello ", name);
fin
procédure add(entier : a, entier : b, sortie entier : r) début
    r := a + b;
fin

Fonctions

fonction ⟨nom⟩(⟨liste-paramètres-formels⟩) délivre ⟨type⟩ début
    // instructions…
    retourne ⟨valeur⟩;
fin

Les 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.

Exemples

fonction carré(réel : a) délivre réel début
    retourn a * a;
fin
fonction add(entier : a, entier : b) délivre entier début
    retourne a + b;
fin
fonction nb_jours_depuis_dernier_accident() délivre entier début
    retourne 0;
fin

Paramètres

Les 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.

Entrée (par défaut)

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.

Sortie ou entrée/sortie

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;

Paramètres formels

  1. ⟨type⟩ : ⟨nom⟩
  2. 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.

Paramètres effectifs

  1. ⟨expression⟩
  2. sortie ⟨expression⟩

La seconde forme passe un paramètre en sortie.

Prototypes

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.

Alias ​​de type

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 entier

Les 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;

Instructions

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.

No-op

L'instruction no-op ne fait rien. Elle se compose d'un seul point-virgule ;.

Builtins

Les builtins sont des sous-routines fournies par le compilateur.

écrire

é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.

lire

⟨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

ent(3.5) // 3
ent(-3.5) // -3

$ent(x : \text{réel}) \to \lvert x\rvert$

La fonction builtin ent(réel : x) retourne la valeur absolue de x.

Affectations

⟨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.

Instructions d'expression

Toute expression suivie d'un point-virgule est une instruction valide.

Variables locales

⟨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.

Bloc anonyme

Un bloc anonyme définit une nouvelle portée. Syntaxe :

début
    // instructions…
fin

Flux de contrôle

Les 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.

Boucles

Les boucles vous permettent de répéter un bloc de code plusieurs fois.

Boucle tant_que

tant_que (⟨condition⟩) faire
    // instructions…
fin_tant_que

La 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.

Boucle faire … tant_que

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.

Boucle pour

pour (⟨initialisation⟩; ⟨condition⟩; ⟨incrémentation⟩) faire
    // instructions…
fin_pour

La 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
fin

Alternatives

Les alternatives vous permettent d'exécuter différents blocs de code en fonction d'une condition.

Si

si (⟨condition⟩) alors
    // instructions…
sinon_si (⟨condition⟩) alors
    // instructions…
sinon
    // instructions…
fin_si

L'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

selon (⟨expression⟩) faire
    quand ⟨valeur⟩ =>
        // instructions…
    quand ⟨valeur⟩ ou ⟨valeur⟩ =>
        // instructions…
    quand autre =>
        // instructions…
fin_selon

L'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.

Expressions

Appels

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.

Opérations

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.

Conversions

Voici un graphique des conversions autorisées entre les types.

flowchart LR
booléen -.faux &rarr; 0<br>vrai &rarr; 1.-> entier
entier -.0 &rarr; faux<br>&ne;0 &rarr; 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>"]
Loading
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.

Valeurs

Chaînes

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.

Caractères

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

Entiers

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.

Réels

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.

Booléens

Les booléens sont soit vrai (true) soit faux (false).

Clone this wiki locally