Quelle police devrais-je utiliser pour mon code?

L'indentation du code doit en refléter la structure. Il existe plusieurs normes pour exprimer la structure d'un programme, mais l'important est d'en respecter une (idéalement celle en vigueur dans votre école ou dans votre entreprise) de manière rigoureuse.

Du code non indenté ou mal indenté devient illisible dès qu'il quitte le stade un peu bancal des programmes ne contenant qu'une simple séquence d'opérations.

Version non-indentée

Une version non indentée est complexe à lire parce que la disposition du code ne donne pas d'indices quant à sa structure.

Dans le cas proposé à droite, la question à quel if se rattache chaque else se répond de manière mécanique (le compilateur y arrive sans peine) mais il est difficile pour un humain de trouver la bonne réponse sans entraînement et sans effort.

Si un bug apparaît dans un programme se trouvant sous cette forme, surtout s'il est sournois (s'il manque une accolade, par exemple), le trouver et le régler peut être cauchemardesque.

int main()
{
const int BORNE_MINIMUM = 1,
BORNE_MAXIMUM = 100;
int NombreAVerifier; // valeur entrée par l'usager
cout << "Entrez un nombre entier entre "
<< BORNE_MINIMUM
<< " et "
<< BORNE_MAXIMUM
<< ": ";
cin >> NombreAVerifier;
// La valeur est-elle dans les bornes demandées?
if (NombreAVerifier >= BORNE_MINIMUM)
{
if (NombreAVerifier <= BORNE_MAXIMUM)
{
cout << "Vous êtes sage!" << endl;
}
else
{
cout << NombreAVerifier
<< " est trop grand!"
<< endl;
}
}
else
{
cout << NombreAVerifier
<< " est trop petit!"
<< endl;
}
}

Version non indentée, sans accolades

Une version non indentée sans accolades comporte les mêmes problèmes que la versions avec accolades, mais de manière pire encore puisque des indices visuels ont été supprimés du programme.

Encore une fois, le compilateur s'en sort très bien mais nous, pauvres humains, souffrons à la lecture d'une telle soupe de mots et de concepts.

int main()
{
const int BORNE_MINIMUM = 1,
BORNE_MAXIMUM = 100;
int NombreAVerifier; // valeur entrée par l'usager
cout << "Entrez un nombre entier entre "
<< BORNE_MINIMUM
<< " et "
<< BORNE_MAXIMUM
<< ": ";
cin >> NombreAVerifier;
// La valeur est-elle dans les bornes demandées?
if (NombreAVerifier >= BORNE_MINIMUM)
if (NombreAVerifier <= BORNE_MAXIMUM)
cout << "Vous êtes sage!" << endl;
else
cout << NombreAVerifier
<< " est trop grand!"
<< endl;
else
cout << NombreAVerifier
<< " est trop petit!"
<< endl;
}

Version mal indentée

Pas vraiment mieux que les précédentes : un code indenté mais de manière trompeuse.

Ici, le programme proposé à droite donne des indices visuels incorrects et mène les gens appelés à lire le code vers des conclusions trompeuses.

Notez qu'une discipline rigoureuse d'indentation facilite le repérage des problèmes dans un tel cas. À droite, chacun des else n'est pas disposé vis à vis l'accolade fermante qui le précède, une indication qui met rapidement la puce à l'oreille aux lectrices et aux lecteurs d'expérience.

int main()
{
   const int BORNE_MINIMUM = 1,
             BORNE_MAXIMUM = 100;
   int NombreAVerifier; // valeur entrée par l'usager
   cout << "Entrez un nombre entier entre "
        << BORNE_MINIMUM
        << " et "
        << BORNE_MAXIMUM
       << ": ";
   cin >> NombreAVerifier;
   // La valeur est-elle dans les bornes demandées?
   if (NombreAVerifier >= BORNE_MINIMUM)
   {
      if (NombreAVerifier <= BORNE_MAXIMUM)
      {
         cout << "Vous êtes sage!" << endl;
      }
   else
   {
      cout << NombreAVerifier
           << " est trop grand!"
           << endl;
   }
   }
else
{
cout << NombreAVerifier
     << " est trop petit!"
     << endl;
}
}

Version indentée correctement

Enfin, une version indentée correctement est telle que sa forme, visuellement, rejoint sa structure.

Il devient alors possible de se concentrer sur le contenu plutôt que sur les détails.

int main()
{
   const int BORNE_MINIMUM = 1,
             BORNE_MAXIMUM = 100;
   int NombreAVerifier; // valeur entrée par l'usager
   cout << "Entrez un nombre entier entre "
        << BORNE_MINIMUM
        << " et "
        << BORNE_MAXIMUM
       << ": ";
   cin >> NombreAVerifier;
   // La valeur est-elle dans les bornes demandées?
   if (NombreAVerifier >= BORNE_MINIMUM)
   {
      if (NombreAVerifier <= BORNE_MAXIMUM)
      {
         cout << "Vous êtes sage!" << endl;
      }
      else
      {
         cout << NombreAVerifier
              << " est trop grand!"
              << endl;
      }
   }
   else
   {
      cout << NombreAVerifier
           << " est trop petit!"
           << endl;
   }
}

Indentation et pseudocode

En pseudocode, du moins dans la version appliquée au département d'informatique du Collège Lionel-Groulx et dans mes propres cours, la chose est encore pire puisque l'indentation est seule garante de la structure du programme et qu'il est impossible d'y voir le début et la fin des blocs si une indentation stricte n'y est pas appliquée.

Version non-indentée Version correctement indentée

Dans la version à droite, chacun des Si est un bloc vide et les Sinon sont tous deux illégaux puisqu'ils ne suivent pas logiquement un bloc Si.

BORNE_MINIMUM ← 1
BORNE_MAXIMUM ← 100
Lire NombreAVerifier
Si NombreAVerifier >= BORNE_MINIMUM
Si NombreAVerifier <= BORNE_MAXIMUM
Écrire "Vous êtes sage!"
Sinon
Écrire NombreAVerifier
Écrire " est trop grand!"
Sinon
Écrire NombreAVerifier
Écrire " est trop petit!"

En retour, une version indentée correctement est claire et syntaxiquement correcte.

Les repères visuels, dans le pseudocode, sont plus que le simple reflet de sa structure. Dans le pseudocode, la disposition est la structure.

BORNE_MINIMUM ← 1
BORNE_MAXIMUM ← 100
Lire NombreAVerifier
Si NombreAVerifier >= BORNE_MINIMUM
   Si NombreAVerifier <= BORNE_MAXIMUM
      Écrire "Vous êtes sage!"
   Sinon
      Écrire NombreAVerifier
      Écrire " est trop grand!"
Sinon
   Écrire NombreAVerifier
   Écrire " est trop petit!"

Souvenons-nous que l'indentation, dans la plupart des langages (pas tous!), est surtout destinée aux lectrices et aux lecteurs humains. Les compilateurs de la plupart des langages de programmation utilisés aujourd'hui consomment des lexèmes (des mots, disons) plutôt que des lignes et n'ont que faire de la disposition effective du code. En retour, vos professeurs, vos collègues et vous-mêmes êtes appelé(e)s à lire du code sur une base régulière. Un peu comme la séparation en paragraphes, sections et chapitres d'un livre aident à en comprendre la structure, l'indentation d'un programme est la bouée de sauvetage qui en facilite la compréhension. Du code mal indenté, ça ne se lit pas; ça se met aux poubelles.

Sachant cela, il est essentiel que la police de caractères permette de disposer le code correctement. Pour qu'il soit possible d'appliquer des normes programmatiques, il faut avoir accès à des indices visuels fiables et stables. Ainsi :

Pour des explications sur les polices proportionnelles ou non proportionnelles, voir ce site Wiki.

C'est pourquoi je tiens à ce que le code m'étant soumis pour consultation, quelle que soit la forme (imprimé, courriel, autre si vous avez de l'imagination) soit formaté à l'aide d'une police de caractères non proportionnelle (pensez à Courier New) plutôt qu'à l'aide d'une police de caractères proportionnelle (comme Arial).

Les polices non proportionnelles sont telles que tous les caractères y occupent la même largeur, du i au w en passant pas l'espace lui-même, un peu comme sur une vieille machine à dactylographier. C'est moins joli pour un article de journal ou pour un poème, mais c'est drôlement plus utile pour disposer le texte d'un programme.

Les deux programmes ci-dessous ont précisément le même texte, mais la version à gauche utilise une police proportionnelle alors que la version à droite utilise une version non proportionnelle. Portez une attention particulière aux opérations d'entrée et de sortie qui sont particulièrement difficiles à placer de manière lisible.

Police proportionnelle Police non proportionnelle Police non proportionnelle (mon style personnel)
int main()
{
   const int BORNE_MINIMUM = 1,
             BORNE_MAXIMUM = 100;
   int a_verifier; // valeur entrée par l'usager
   cout << "Entrez un nombre entier entre "
        << BORNE_MINIMUM
        << " et "
        << BORNE_MAXIMUM
        << ": ";
   if(cin >> a_verifier)
   {    // La valeur est-elle dans les bornes demandées?
      if (a_verifier >= BORNE_MINIMUM)
      {
         if (a_verifier <= BORNE_MAXIMUM)
         {
            cout << "Vous êtes sage!" << endl;
         }
         else
         {
            cout << a_verifier
                 << " est trop grand!"
                 << endl;
         }
      }
      else
      {
         cout << a_verifier
              << " est trop petit!"
              << endl;
      }
   }
}
int main()
{
   const int BORNE_MINIMUM = 1,
             BORNE_MAXIMUM = 100;
   int a_verifier; // valeur entrée par l'usager
   cout << "Entrez un nombre entier entre "
        << BORNE_MINIMUM
        << " et "
        << BORNE_MAXIMUM
        << ": ";
   if (cin >> a_verifier)
   {
      // La valeur est-elle dans les bornes demandées?
      if (a_verifier >= BORNE_MINIMUM)
      {
         if (a_verifier <= BORNE_MAXIMUM)
         {
            cout << "Vous êtes sage!" << endl;
         }
         else
         {
            cout << a_verifier
                 << " est trop grand!"
                 << endl;
         }
      }
      else
      {
         cout << a_verifier
              << " est trop petit!"
              << endl;
      }
   }
}
int main() {
   const int BORNE_MINIMUM = 1,
             BORNE_MAXIMUM = 100;
   cout << "Entrez un nombre entier entre "
        << BORNE_MINIMUM
        << " et "
        << BORNE_MAXIMUM
        << ": ";
   if (int a_verifier; cin >> NombreAVerifier) {
      if (a_verifier >= BORNE_MINIMUM) {
         if (a_verifier <= BORNE_MAXIMUM) {
            cout << "Vous êtes sage!" << endl;
         } else {
            cout << a_verifier
                 << " est trop grand!"
                 << endl;
         }
      } else {
         cout << a_verifier
              << " est trop petit!"
              << endl;
      }
   }
}

Le code sur les pages Web

Si vous produisez du code pour une page Web, évitez les balises <font>...</font>. Je sais qu'il y en a quelques-unes sur cette page, mais c'est strictement pour donner une apparence spécifique de police; en général, les balises de formatage brutes comme <font> sont, à juste titre, mal vues (en fait, elles sont interdites en HTML5)

Privilégiez plutôt les balises <pre>...</pre> (pour texte préformaté, ce qui sied bien le code disposé avec des espaces) et <code>...</code> (pour... code, un signal sémantique quant à la nature de ce qui se situe entre les balises).

Lectures complémentaires

Pour comprendre les paramètres d'une police de caractères :

Pour une suggestion de polices pour le code :

Pour un plaidoyer contraire au mien (si vous êtes curieuse/ curieux) :


Valid XHTML 1.0 Transitional

CSS Valide !