IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
next up previous contents index
Next: Exercice Up: Les pointeurs Previous: Lecture formattée

Sous-sections

Les dernières instructions

Le langage C comporte 3 instructions que nous n'avons pas encore vu : un if généralisé, un goto et une instruction nulle.

Instruction switch

        Le langage C offre une instruction switch qui est un if généralisé.
$\bullet$
Syntaxe :

instruction :
$\Rightarrow$ switch ( expression )
{
case expression1 : liste-d'instructions $_{1 \hspace{1mm}option}$ break;option
case expression2 : liste-d'instructions $_{2 \hspace{1mm}option}$ break;option

....

case expressionn : liste-d'instructions $_{n \hspace{1mm}option}$ break;option
default : liste-d'instructions
}  

De plus :

-
toutes les expressioni doivent délivrer une valeur connue à la compilation ;
-
il ne doit pas y avoir deux expressioni délivrant la même valeur ;
-
l'alternative default est optionnelle.
$\bullet$
Sémantique :
1.
expression est évaluée, puis le résultat est comparé avec expression1, expression2, etc.
2.
à la première expressioni dont la valeur est égale à celle de expression, on exécute la (ou les) 3.3 liste-d'instructions correspondante(s) jusqu'à la rencontre de la première instruction break;. La rencontre d'une instruction break termine l'exécution de l'instruction switch.
3.
si il n'existe aucune expressioni dont la valeur soit égale à celle de expression, on exécute la liste-d'instructions de l'alternative default si celle-ci existe, sinon on ne fait rien.

Discussion

Vu le nombre de parties optionnelles dans la syntaxe, il y a 3 types d'utilisations possibles pour le switch. Première possibilité, on peut avoir dans chaque alternative une liste-d'instructions et un break; comme dans l'exemple suivant :
enum {BLEU=1, BLANC, ROUGE};

void print_color(int color)
{
switch(color)
   {
   case BLEU : printf("bleu"); break;
   case BLANC : printf("blanc"); break;
   case ROUGE : printf("rouge"); break;
   default : printf("erreur interne du logiciel numéro xx\n");
   }
}

Deuxième possibilité, on peut avoir une ou plusieurs alternatives ne possédant ni liste-d'instructions, ni break;. Supposons que l'on désire compter dans une suite de caractères, le nombre de caractères qui sont des chiffres, et le nombre de caractères qui ne le sont pas. On peut utiliser le switch suivant :

switch(c)
   {
   case '0':
   case '1':
   case '2':
   case '3':
   case '4':
   case '5':
   case '6':
   case '7':
   case '8':
   case '9': nb_chiffres++; break;
   default: nb_non_chiffres++;
   }

Troisième possibilité, une alternative peut ne pas avoir de break comme dans l'exemple suivant :

enum {POSSIBLE, IMPOSSIBLE};

void print_cas(int cas)
{
switch (cas)
   {
   case IMPOSSIBLE: printf("im");
   case POSSIBLE:   printf("possible\n"); break;
   case default:    printf("erreur interne du logiciel numéro xx\n");
   }
}
Une telle utilisation du switch pose un problème de lisibilité, car l'expérience montre que l'absence du break; est très difficile à voir. Il est donc recommandé de mettre un commentaire, par exemple de la façon suivante :
   case IMPOSSIBLE: printf("im");   /*   ATTENTION: pas de break;   */

Remarque

  Le mot-clé break est surchargé : nous avons vu au chapitre 2.2.4 que l'instruction break permettait de stopper l'exécution d'une instruction itérative for, while, do. Il est utilisé ici de manière complètement différente.

Instruction goto

     

$\bullet$
Syntaxe :

instruction :
$\Rightarrow$ goto identificateur ;

$\bullet$
Sémantique :

Toute instruction peut être précédée d'un identificateur suivi du signe :. Cet identificateur est appelé étiquette.   Une instruction goto identificateur a pour effet de transférer le contrôle d'exécution à l'instruction étiquetée par identificateur. L'instruction goto et l'instruction cible du goto doivent se trouver dans la même procédure : le langage C est un langage à branchement locaux.

$\bullet$
Exemple :
{
etiq2:
...            /*   des instructions                      */
goto etiq1;    /*   goto avant définition de l'étiquette  */
...            /*   des instructions                      */
etiq1:
...            /*   des instructions                      */
goto etiq2;    /*   goto après définition de l'étiquette  */
}

   
Instruction nulle

$\bullet$
Syntaxe :

instruction :
$\Rightarrow$ ;

$\bullet$
Sémantique :

ne rien faire !

Cette instruction ne rend que des services syntaxiques. Elle peut être utile quand on désire mettre une étiquette à la fin d'une instruction composée. Par exemple :

{
...
fin: ;
}

Elle est également utile pour mettre un corps nul à certaines instructions itératives. En effet, à cause des effets de bord dans les expressions, on peut arriver parfois à faire tout le travail dans les expressions de contrôle des instructions itératives. Par exemple, on peut initialiser à zéro un tableau de la manière suivante :

for (i = 0; i < N; t[i++]= 0) 
   ;    /*   instruction nulle   */
 

Attention

Cette instruction nulle peut parfois avoir des effets désastreux. Supposons que l'on veuille écrire la boucle :
for (i = 0; i < N; i++)
   t[i] = i;
si par mégarde on met un ; à la fin de ligne du for, on obtient un programme parfaitement correct, qui s'exécute sans broncher, mais ne fait absolument pas ce qui était prévu. En effet :
for (i = 0; i < N; i++) ;
   t[i] = i;
exécute le for avec le seul effet d'amener la variable i à la valeur N, et ensuite exécute une fois t[i] = i ce qui a probablement pour effet d'écraser la variable déclarée juste après le tableau t.


next up previous contents index
Next: Exercice Up: Les pointeurs Previous: Lecture formattée
Bernard Cassagne
1998-12-09