219 votes

Instruction switch : doit par défaut être le dernier cas ?

Considérez ce qui suit `` déclaration :

Copiez le code suivant compile, mais est cela valide (= comportement défini) pour C90/C99 ? Je n’ai jamais vu code où la casse par défaut n’est pas le dernier cas.

EDIT :
En écriture Jon Cage et KillianDS : il s’agit de code vraiment moche et confus et je suis bien conscient de celui-ci. Je souhaite juste la syntaxe générale (est-il défini ?) et les résultats escomptés.

113voto

Salil Points 20300

Le cas des états et le défaut de déclaration peut se produire dans n'importe quel ordre, dans l'instruction switch. La valeur par défaut de clause est une clause facultative qui correspond si aucune des constantes dans le cas des déclarations peut être mis en correspondance.

Bon Exemple :-

switch(5) {
  case 1:
    echo "1";
    break;
  case 2:
  default:
    echo "2, default";
    break;
  case 3;
    echo "3";
    break;
}


Outputs '2,default'

très utile si vous voulez que votre cas à être présentés dans un ordre logique dans le code (comme dans, ne dis pas le cas 1, cas 3, cas 2/par défaut) et votre cas sont très longs, alors vous ne voulez pas répéter la totalité des cas de code dans la partie inférieure pour la valeur par défaut

94voto

Secure Points 2838

Le standard C99 n'est pas explicite à ce sujet, mais en prenant tous les faits ensemble, il est tout à fait valide.

Un case et default label sont l'équivalent d'un goto label. Voir 6.8.1 Marqué consolidés. Particulièrement intéressante est 6.8.1.4, qui permet déjà mentionné Duff de l'Appareil:

Tout énoncé peut être précédé par un préfixe qui déclare un identificateur un nom d'étiquette. Les étiquettes elles-mêmes ne ne pas altérer le flux de contrôle, qui se poursuit sans obstacle à travers eux.

Edit: Le code à l'intérieur d'un commutateur n'est rien de spécial, c'est un bloc de code comme dans un if-déclaration, avec saut supplémentaire étiquettes. C'est ce qui explique la chute-à travers le comportement et pourquoi break est nécessaire.

6.8.4.2.7 donne même un exemple:

switch (expr) 
{ 
    int i = 4; 
    f(i); 
case 0: 
    i=17; 
    /*falls through into default code */ 
default: 
    printf("%d\n", i); 
} 

Dans l'artificiel, fragment d'un programme de l' objet dont l'identifiant est que j'existe automatique de la durée de stockage (dans le bloc), mais n'est jamais initialisé, et donc si l' le contrôle de l'expression a une valeur non nulle en valeur, l'appel à la fonction printf accéderez à une valeur indéterminée. De même, l'appel à la fonction f ne peut pas être atteint.

Le cas des constantes doivent être uniques au sein d'une instruction switch:

6.8.4.2.3 L'expression de chaque cas, l'étiquette doit être une constante entière l'expression et le pas de deux de l'affaire des expressions constantes dans le même instruction switch doit avoir le même valeur après la conversion. Il peut être au plus une étiquette par défaut dans un switch l'énoncé.

Tous les cas sont évalués, puis il saute à l'étiquette par défaut, si:

6.8.4.2.5 L'entier des promotions sont effectuées sur le contrôle de de l'expression. L'expression constante dans chaque cas l'étiquette est converti à l' promu type de contrôle de l'expression. Si une valeur convertie les matches de la promotion le contrôle de l'expression, le contrôle des sauts pour la déclaration à la suite de la correspondance cas d'étiquette. Sinon, si il y a un étiquette par défaut, le contrôle passe à la étiquetés la déclaration. Si non converti cas l'expression constante et correspond à il n'y a pas d'étiquette par défaut, aucune partie de le corps de l'interrupteur est exécutée.

58voto

kriss Points 10450

Il est valable et très utile dans certains cas.

Considérons le code suivant:

switch(poll(fds, 1, 1000000)){
   default:
    // here goes the normal case : some events occured
   break;
   case 0:
    // here goes the timeout case
   break;
   case -1:
     // some error occurred, you have to check errno
}

Le point est que le code ci-dessus est plus lisible et plus efficace que le en cascade if. Vous pourriez le mettre par défaut à la fin, mais c'est inutile, car il permettra de concentrer votre attention sur les cas d'erreur au lieu de la normale de cas (qui est ici l' default des cas).

En fait, il n'est pas un bon exemple, dans le sondage, vous savez comment beaucoup d'événements peuvent se produire tout au plus. Mon point est qu'il est des cas avec un ensemble défini de valeurs d'entrée où il y a des "exceptions" et le cas normal. Si c'est mieux de mettre des exceptions ou des cas normaux à l'avant est une question de choix.

Dans le domaine des logiciels, je pense à un autre cas habituel : récurrences avec certaines valeurs de ces terminaux. Si vous pouvez l'exprimer à l'aide d'un commutateur, default sera la valeur habituelle qui contient de l'appel récursif et éléments distincts (cas individuels) les valeurs de ces terminaux. Il n'y a pas besoin de se concentrer sur les valeurs de ces terminaux.

20voto

Jens Gustedt Points 40410

Oui, ceci est valable, et dans certaines circonstances, il est encore utile. Généralement, si vous n’avez pas besoin, ne pas le faire.

11voto

tristopia Points 5074

Il n’y a aucun ordre défini dans une instruction switch. Vous pouvez regarder les cas quelque chose comme une étiquette nommée, comme un étiquette. Contrairement à ce que les gens semblent penser ici, dans le cas de la valeur 2 l’étiquette par défaut sans saut. Pour illustrer avec un exemple classique, voici [dispositif de Duff](http://en.wikipedia.org/wiki/Duff%27s_device), qui est l’enfant d’affiche des extrêmes de c.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X