Bloc d'instructions

Dans le chapitre précédent nous avons introduit la boucle for avec une seule instruction: l'affichage. Derrière for, on ne peut mettre qu'une seule instruction mais il aurait été bien de remettre la temporisation de 1s que l'on avait jusque là. Nous allons maintenant voir que l'on peut "tricher" et mettre plusieurs instructions dans une boucle for.

Instruction composée

Quand on peut mettre une instruction, on peut mettre une suite d'instructions encadrées par des accolades. Par exemple derrière un for:

for (cacheCache = 1; cacheCache < 21; cacheCache++)
{
  Serial.println(cacheCache);
  delay(2000);
}

Et c'est pareil avec un if:

if (cacheCache >= 19)
{
  Serial.print("Attention.....");
  delay(1000);
}
Serial.println(cacheCache);
...

Avec ceci, on peut donc avoir un mélange aussi complexe de boucles et d'instructions. Une liste d'instructions généralement dans loop() peut contenir des boucles qui contiennent des instructions, dont des boucles qui contiennent à leur tour des instructions, ...

On a déjà rencontré des accolades derrière setup() et loop(). On a au départ au moins ces deux paires là.

Un problème dans tout cela est de s'y retrouver. On a déjà vu que chaque parenthèse a une parenthèse copine, il en est de même pour les accolades. Et comme le nombre d'accolades que l'on a dans un programme peut être grand, il ne faut pas se perdre. Il y a deux conventions principales pour s'y retrouver.

Première convention

En programmation, les lignes de codes sont les unes sous les autres. Mais elle ne sont pas toutes alignées sur la première colonne. Elles sont décalées d'une certaine quantité, et on appelle cela l'indentation. Indenter correctement un code, c'est choisir correctement les décalages. Dans un premier temps, je conseille de décaler les lignes, quand c'est besoin, de 2 espaces avec l'IDE d'Arduino.

Règles:
- on ne met qu'une instruction par ligne
- une accolade se met seule sur une ligne
- l'accolade ouvrante est juste sous le premier caractère de la ligne précédente
- après une accolade ouvrante les lignes qui suivent sont indentées d'un cran (p.ex. 2 espaces) vers la droite
- l'accolade fermante est indentée d'un cran vers la gauche
- après une accolade fermante les lignes qui suivent sont alignées verticalement

Voici un exemple:

void setup()
{
  for (...)
  {
    ...
  }
  ...
  if (...)
  {
    ...
    for (...)
    {
      ...
    }
    ...
  }
}

Quelques remarques avec cette convention:
- les accolades copines sont alignées verticalement (même colonne), la deuxième parfaitement en dessous de la première. Cela permet de voir où est la fin d'un bloc si on descend, et où était le début.
- entre deux accolades copines, il n'y a aucun caractères (sur leur colonne, il y en aura mais à droite)
- on ne peut pas avoir deux accolades fermantes qui se suivent ni sur la même ligne ni sur la même colonne
- si on oublie de fermer un bloc par une accolade fermante, quand on arrive à la fin du setup() ou la fin de loop(), on n'est pas revenu en colonne 0.

Personnellement, j'utilise systématiquement cette convention, sauf dans les chapitres qui précèdent, ne pouvant donner ces règles avant d'avoir vu les blocs. Dorénavant, dans la suite, je vous imposerai cette convention. On a bien entendu le droit à aménager cette règle quand c'est plus lisible autrement, par exemple si une condition est trop longue, on va la mettre sur plusieurs lignes, mais on a intérêt à décaler les lignes concernant la condition:

if (temps == "pluie" &&
    courses == "oui" &&
    transport == "pied")
{
  prendreParapluie = "oui";
  pullover += 1;
}

Cela m'arrive aussi d'indenter l'instruction si elle est unique d'un if:

if (temps == "pluie")
  prendreParapluie = "oui";
else
  prendreParapluie = "non";
...

et souvent d'écrire:

if (temps == "pluie") prendreParapluie = "oui";
else prendreParapluie = "non";
...

C'est vrai aussi que je fais une entorse si j'ai une fonction ne comportant très peu de choses. Dans ce cas, je mets tout sur la même ligne. Par exemple pour un programme qui n'utilise que setup:

void loop() {}

Le but n'est pas de respecter la règle bêtement, mais de rendre le code le plus lisible possible. Petit exercice: réécrivez le programme du chapitre précédent en respectant intelligemment cette convention.

Notez aussi que quelle que soit l'indentation, le code final sera strictement identique, (même vitesse d’exécution, même taille de code) et que bien ou mal présenté seul le programme source diffère. Mais bien présenté, le code est lisible, et les personnes susceptibles de vous aider seront plus enclin à le faire. Et se sera plus facile de reprendre le code ultérieurement.

Deuxième convention

C'est quasiment pareil, sauf qu'au lieu de mettre une accolade ouvrante sur une ligne seule et non indentée par rapport à la ligne précédente, on met l'accolade à la fin de la ligne précédente juste derrière un espace. Cela peut donner:

void setup() {
  for (...) {
    ...
  }
  ...
  if (...) {
    ...
    for (...) {
      ...
    }
    ...
  }
}

Cela diminue le nombre de ligne du code, mais je trouve que c'est nettement moins lisible. C'est par défaut la présentation de l'IDE quand il donne un programme vide. C'est pour cela que jusqu'à présent les codes que je vous ai demandés étaient plutôt avec cette convention.

La structure des blocs apparaît toujours, mais on n'a plus l'alignement des accolades. Je trouve que c'est plus difficile à suivre.

cnt-T

Petit exercice: prenez un code et faites en sorte qu'il soit mal indenté, et qu'il y ait le moins de caractères "espace" possible, et faites dans l'IDE un cnt-T (ou un cmd-T avec un mac). Que se passe-t-il?
- votre code se trouve parfaitement indenté
- il y a un espace entre les variables, les opérateurs et les nombres. Cela permet de mieux voir les relations, les calculs.

Cela ne coûte pas grand chose de faire passer cnt-T, mais cela rend le code plus lisible si vous n'avez pas respecté les règles. Et c'est important pour demander de l'aide. Pensez que celui qui vous lit, n'utilise pas forcément autre chose que son navigateur sur lequel cnt-T ne fonctionne évidemment pas.

La boucle for   <<     >>   Blink with delay

Vous avez tous les renseignement pour mener à bien cette étape, mais n'hésitez pas à utiliser les forums pour avoir de l'aide. N'hésitez pas à faire des essais, de tester d'autres possibilités. C'est ainsi que l'on apprend. Bon apprentissage.