switch
Nous avons vu que, lorsquon devait choisir entre deux possibilités, on utilisait une instruction de branchement if...else
. Il existe une autre instruction de branchement, nommée switch
, dont la syntaxe est la suivante :
switch (expression) { case constante1 : instructions1; case constante2 : instructions2; ............................ case constanteN : instructionsN; default : instructions0; }
Lexpression expression
est évaluée (elle doit être dun type numérique), puis comparée à constante1
, constante2
, etc., jusquà ce quune identité soit trouvée ; dans ce cas, les instructions qui suivent (il peut y en avoir plusieurs) sont exécutées, jusquà laccolade fermante finale, et non jusquà linstruction case
suivante. Si aucune des constantes nest égale à lexpression, ce sont les instructions qui suivent default
qui sont exécutées. Cette dernière clause est semblable au else
du branchement simple, et peut également être omise.
Il est important de noter que toutes les instructions suivant la constante qui coïncide avec lexpression sont exécutées. Ainsi, si lon écrit :
switch (i) { case 1 : i = 0; case 2 : i = 10; // probablement erroné default i++; }
la variable i sera mise à 11 si elle valait 1 ou 2 au départ, sinon elle sera incrémentée. En effet, si i vaut 1 au départ, les trois instructions i = 0; i = 10; i++;
sont exécutées à la suite.
Dans ce cas, il sagit certainement dune erreur. Pour la corriger, on utilise linstruction dinterruption break
, qui interrompt la circulation dans linstruction de branchement, passant directement à celle qui suit laccolade fermante :
switch (i) { case 1 : i = 0; break; case 2 : i = 10; break; default i++; }
Ici, on a bien le comportement imaginé. Cette utilisation de break
dans une instruction switch
est extrêmement fréquente ; il est important de ne pas loublier.
Dans certains cas cependant on ne souhaite pas placer de break
derrière certaines constantes, en particulier lorsquil y en a plusieurs. Voici par exemple une fonction qui remplace dans une chaîne les caractères accentués par leur équivalent sans accent :
char *sansaccent(char *chaine) { for (char *s = chaine; *s; s++) switch (*s) { case 'à':; case 'â':; // continuer... case 'ä': *s = 'a'; break; // ... ici case 'é':; case 'è':; case 'ê':; // idem case 'ë': *s = 'e'; break; case 'ì':; case 'î':; // idem case 'ï': *s = 'i'; break; case 'ô':; case 'ò':; // idem case 'ö': *s = 'o'; break; case 'ù':; case 'ü':; // idem case 'û': *s = 'u'; break; case 'ÿ': *s = 'y'; break; } return chaine; }
Seules les minuscules ont été traitées ; le lecteur étendra sans peine la méthode aux majuscules. On notera le point-virgule obligatoire entre le deux-points et le case
suivant, même sil ny a pas dinstruction. Il ny a pas ici de clause default
, puisquil ny a pas daction si le caractère nest pas accentué.
Lécriture dun branchement multiple nest pas toujours la meilleure méthode. Il est parfois préférable dutiliser des systèmes plus rapides. Ainsi, dans notre exemple, un tableau de correspondance des caractères initialisé une fois pour toutes aurait permis un traitement plus expéditif.
Dans certains cas, il est franchement impossible dutiliser une instruction switch
, parce quelle serait trop pénible à écrire. Ainsi, la fonction toupper
de la librairie <ctype.h>
, qui transforme un caractère en la majuscule correspondante, devrait être écrite avec un switch
:
char toupper(char c) { switch (c) { case 'a' : return 'A'; case 'b' : return 'B'; // etc... case 'z' : return 'Z'; default : return c; } }
Il sagit évidemment dune écriture bien trop longue. On notera toutefois deux points importants à son sujet. Tout dabord, le fait décrire une instruction return
nous dispense décrire un break
, puisque cela termine directement la fonction. Dautre part, il sagit dune situation typique où le compilateur ne peut pas savoir si tous les cas ont été traités ou non ; en conséquence, si lon oublie la clause default
ici essentielle, la fonction retournera une valeur aléatoire si son argument nétait pas une minuscule (cest dailleurs le comportement de la variante _toupper
de cette fonction).
Exercice 4.1 |
Comment programmer plus facilement cette fonction, sans utiliser |
Voir solution |
Enfin, il ne faut pas tenter dutiliser switch
pour des intervalles de nombres, puisquon ne peut pas placer une condition derrière case
; pour la même raison, il vaut mieux ne pas lutiliser avec des décimaux.
Les mots switch
, case
et default
sont réservés en C++.
Précédent | Sommaire | Suivant |