Aller au contenu
Académie JediSith · Programmation

Tableaux, boucles et fonctions

En une phrase : trois outils pour ne jamais recopier les mêmes lignes : le tableau range plusieurs valeurs, la boucle répète, la fonction donne un nom à un morceau de code.

Pourquoi ces trois outils ?

Imagine la piste d'atterrissage sans eux : quatre pinMode, puis pour chaque LED trois lignes « allumer, attendre, éteindre »… une trentaine de lignes presque identiques. Et le jour où tu veux changer la vitesse, il faut la modifier à dix endroits sans en oublier un. Avec un tableau, une boucle et une fonction, le même programme tient en quinze lignes, et la vitesse se change à un seul endroit.

La règle des développeurs

Ils l'appellent DRY : Don't Repeat Yourself, « ne te répète pas ». Dès que tu copies-colles un bloc pour la troisième fois, c'est le signal : il faut une boucle ou une fonction.

Le tableau : une rangée de boîtes

Au lieu de quatre variables led1, led2, led3, led4, un seul tableau :

LEDS18LEDS[0]case 019LEDS[1]case 121LEDS[2]case 222LEDS[3]case 3✗LEDS[4]n'existe pas
Quatre cases, numérotées de 0 à 3. La case n°4 n'existe pas : c'est le piège classique.
const int LEDS[] = {18, 19, 21, 22};   // 4 cases, numérotées de 0 à 3
// LEDS[0] vaut 18, LEDS[1] vaut 19, LEDS[2] vaut 21, LEDS[3] vaut 22

Un tableau peut ranger n'importe quel type : des nombres, des bool (la check-list de la mission 1), ou même des textes :

const char* NOMS[] = {"éteint", "lent", "rapide"};   // NOMS[1] vaut "lent"
bool teste[19];                                      // 19 cases vrai/faux

On compte à partir de 0

La première case est LEDS[0], la dernière LEDS[3]. Il n'y a pas de LEDS[4] : y toucher lit ou écrit n'importe où dans la mémoire, et le programme fait des choses étranges, voire redémarre.

Les boucles : répéter

La boucle for : répéter en comptant

for (int i = 0; i < 4; i++) {          // i vaut 0, puis 1, 2, 3, et on s'arrête
  pinMode(LEDS[i], OUTPUT);
}

Les trois morceaux entre parenthèses :

Morceau Rôle Ici
départ exécuté une fois, au début int i = 0
condition vérifiée avant chaque tour : si elle est fausse, on sort i < 4
pas exécuté après chaque tour i++ (ajoute 1)
i = 0i < 4 ?ouile corps de la bouclepinMode(LEDS[i], …)i++ (i + 1)sortie : la suitenonTours :i = 0 ✓i = 1 ✓i = 2 ✓i = 3 ✓i = 4 ✗ sortie
Le chemin d'une boucle for : départ, question, corps, pas… et on revient à la question jusqu'à ce que la réponse soit « non ».

On peut aussi compter à l'envers ou de 2 en 2 :

for (int i = 3; i >= 0; i--)    { … }   // 3, 2, 1, 0
for (int a = 0; a <= 180; a += 2) { … } // 0, 2, 4… 180 (le balayage du servo, mission 3)

La boucle while : répéter tant que…

while (!Serial) {        // tant que le moniteur série n'est pas prêt…
  delay(10);             // … on attend
}

while répète tant qu'une condition est vraie, sans compter. Utile quand on ne sait pas d'avance combien de tours il faudra.

La boucle infinie

Une boucle dont la condition ne devient jamais fausse tourne pour toujours : le reste du programme est bloqué. loop() est d'ailleurs déjà une boucle infinie, voulue celle-là.

Choisir parmi plusieurs cas : switch

Quand une variable peut prendre plusieurs valeurs et qu'il faut faire quelque chose de différent pour chacune, switch est plus lisible qu'une longue chaîne de if :

switch (scenario) {
  case 1: lumiere = 255; break;         // clignotement lent…
  case 2: lumiere = 128; break;
  default: lumiere = 0;  break;         // tous les autres cas
}

Le break est important : sans lui, le programme continue dans le case suivant ! C'est le cœur de la fonction jouerScenario() de la mission 1.

Les fonctions : un morceau de code avec un nom

void allumer(int i) {                  // « allumer » attend un numéro de case
  digitalWrite(LEDS[i], HIGH);
  delay(150);
  digitalWrite(LEDS[i], LOW);
}

// ensuite, une seule ligne suffit :
allumer(2);
Morceau Rôle
void le type de la réponse : void veut dire « ne répond rien »
allumer le nom : un verbe qui dit ce qu'elle fait
(int i) les paramètres : ce qu'on lui donne en entrée
{ … } le corps : ce qu'elle fait

Une fonction peut aussi rendre une réponse, avec return :

doubler(x)return x * 2;entrée21réponse42le paramètre entre, le return ressort
Une fonction est une petite machine : on lui donne des paramètres, elle travaille, et elle peut rendre une réponse.
int doubler(int x) {                   // « int » : la réponse sera un entier
  return x * 2;
}

int r = doubler(21);                   // r vaut 42

Dans la mission 1, vientDAppuyer(...) répond true ou false, et directionsAtteintes(x, y) répond un nombre.

Exemple : prédire une boucle

Le retour de la piste d'atterrissage

for (int i = 0; i < NB; i++) allumer(i);        // aller
for (int i = NB - 2; i > 0; i--) allumer(i);    // retour

Avec NB = 4 :

  • Aller : i = 0, 1, 2, 3 → les LEDs 0, 1, 2, 3.
  • Retour : i commence à 4 − 2 = 2, puis 1 ; à 0, la condition i > 0 est fausse → les LEDs 2, 1.
  • Puis loop() recommence à 0.

Séquence complète : 0 1 2 3 2 1 0 1 2 3 2 1… Le retour ne rallume pas la LED 3 (elle vient de s'allumer) ni la 0 (l'aller suivant s'en charge) : pas de « double flash » aux bouts.

LED 0LED 1LED 2LED 30123210123allerretouraller…
Chaque colonne est un instant : on voit la lumière aller de 0 à 3, revenir sur 2 et 1, puis repartir.

Mise en pratique

Une piste à 3 LEDs : avec le montage de la piste, enlève la LED de D22 et modifie seulement le tableau et NB :

const int LEDS[] = {18, 19, 21};
const int NB = 3;

Rien d'autre à changer : boucles et fonction s'adaptent toutes seules. C'est toute la force de ces outils.

L'astuce du sizeof : pour ne même plus écrire NB à la main, le programme peut compter les cases lui-même :

const int NB = sizeof(LEDS) / sizeof(LEDS[0]);   // taille totale ÷ taille d'une case

Exercices

1. Un tableau NOMS contient, dans l'ordre, rouge, vert et bleu. Que vaut NOMS[2] ?

"bleu" : la troisième case, puisqu'on compte à partir de 0.

2. Quelles valeurs prend i dans for (int i = 10; i > 0; i -= 3) ?

10, 7, 4, 1. Ensuite i vaudrait −2 : la condition i > 0 est fausse, on sort.

3. Écris une fonction clignoter(broche, fois) qui fait clignoter une broche un certain nombre de fois.
void clignoter(int broche, int fois) {
  for (int n = 0; n < fois; n++) {
    digitalWrite(broche, HIGH);
    delay(200);
    digitalWrite(broche, LOW);
    delay(200);
  }
}
// clignoter(2, 3); fait 3 clignotements sur la LED bleue
4. Que se passe-t-il si on oublie le break après case 1 dans un switch ?

Le programme exécute le case 1… puis continue dans le case 2 (et la suite, jusqu'au prochain break). La variable finit avec la valeur du dernier cas traversé.

À retenir

  • Tableau : plusieurs valeurs sous un nom, numérotées à partir de 0.
  • for répète en comptant, while répète tant qu'une condition est vraie.
  • switch choisit parmi plusieurs cas (sans oublier break).
  • Fonction : un nom pour un morceau de code ; elle reçoit des paramètres et peut rendre une réponse avec return.

Où ça sert dans l'atelier

Pour aller plus loin