Je suis tombé sur un morceau de code de cas d'interrupteur aujourd'hui et j'ai été un peu surpris de voir comment cela a fonctionné. Le code était: à ma surprise dans le scénario où la variable était C code>, le chemin est allé à l'intérieur du segment "CODE ICI". Je suis d'accord, il n'y a pas de pause à la fin de la partie code> C code> de l'interrupteur de cas, mais je l'aurais imaginé pour passer par code> par défaut code> à la place. Lorsque vous atterrissez dans un cas BLAH: code> ligne, ne vérifiez-t-il pas si votre valeur actuelle correspond au cas particulier
5 Réponses :
C'est le bon comportement, et il est appelé "tombant". Cela vous permet d'avoir plusieurs cas traités par le même code. Dans des situations avancées, vous voudrez peut-être effectuer un code dans un cas, puis tomber à travers un autre cas.
Exemple de contreveille: P>
switch(command)
{
case CMD_SAVEAS:
{
this->PromptForFilename();
} // DO NOT BREAK, we still want to save
case CMD_SAVE:
{
this->Save();
} break;
case CMD_CLOSE:
{
this->Close();
} break;
default:
break;
}
Le célèbre exemple d'automne est Duff's Device .
C'est une utilisation assez cool, mais j'imagine que c'est quelque chose que le compilateur fera généralement pour vous lorsque vous optimisez la vitesse. Je ne voudrais jamais voir cela écrit en C sauf s'il y avait une très bonne raison et un bloc de commentaire approprié expliquant pourquoi il est nécessaire et comment le maintenir.
Ceci est appelé cas de cas, et est un comportement souhaitable. Il vous permet de partager le code entre les cas.
Un exemple de comment utiliser le comportement de l'automate: p> si vous entrez le commutateur lorsque blah = = A code>, alors vous allez exécuter fonction1 () code>, fonction2 () code> et fonction3 () p> p> Si vous ne voulez pas avoir ce comportement, vous pouvez vous en sortir en incluant les instructions Break CODE>. P> switch(blah)
{
case a:
function1();
break;
case b:
function2();
break;
case c:
function3();
break;
default:
break;
}
: -Merci pour la réponse élaborée! J'obtiens comment ça marche. C'est juste que c'est contre quel sens commun vous dicte à moi. Je pense toujours que le comportement est contre-intuitif.J'ai jusqu'à ce que cette date a pensé que ces "cas (Blah)" était un peu comme un chèque pour assurer Si votre variable est en effet (bla) ..appariement ce n'est pas comment c fonctionne!
@Manish: le commutateur est souvent mis en œuvre avec un " Table de branche ", de sorte que cela pourrait aider votre compréhension trop. Le bon sens n'existe pas dans la programmation, BTW. Vous avez besoin de "sens du programmeur" à la place :)
@Manish Les deux comportements sont souhaitables, il est possible d'avoir une défaillance par défaut et explicitement continuer code> au cas suivant si désiré. Du point de vue de bon sens, ce dernier peut sembler plus naturel, mais avec la mise en œuvre à l'esprit, l'automne par défaut est plus naturelle, ce qui a été choisi.
Heureusement pour nous, C ++ ne dépend pas de votre imagination: -) p>
Pensez aux étiquettes de commutation comme étiquettes "goto" et le commutateur (bla) code> simplement "va à" l'étiquette correspondante, puis le code coule simplement de là. P>
En réalité, l'instruction de commutation fonctionne comme vous l'observez. Il est conçu pour que vous puissiez combiner plusieurs cas ensemble jusqu'à ce qu'une pause soit rencontrée et agit comme un tamis.
Voici un exemple du monde réel de l'un de mes projets: P>
struct keystore_entry *new_keystore(p_rsd_t rsd, enum keystore_entry_type type, const void *value, size_t size) {
struct keystore_entry *e;
e = rsd_malloc(rsd, sizeof(struct keystore_entry));
if ( !e )
return NULL;
e->type = type;
switch (e->type) {
case KE_DOUBLE:
memcpy(&e->dblval, value, sizeof(double));
break;
case KE_INTEGER:
memcpy(&e->intval, value, sizeof(int));
break;
/* NOTICE HERE */
case KE_STRING:
if ( size == 0 ) {
/* calculate the size if it's zero */
size = strlen((const char *)value);
}
case KE_VOIDPTR:
e->ptr = rsd_malloc(rsd, size);
e->size = size;
memcpy(e->ptr, value, size);
break;
/* TO HERE */
default:
return NULL;
}
return e;
}
C'est ce qu'on appelle une chute.
Il fait exactement ce que vous voyez: plusieurs cas vont exécuter la même pièce de code. P>
Il est également pratique dans la transformation supplémentaire pour Certains cas, et une logique partagée: p> Il s'agit d'une utilisation typique de l'automne dans le commutateur. En cas de démarrage et de démarrage, nous devons faire des personnesLocaTources et modifier le statut en arrêté, mais en commençant pas besoin d'un nettoyage supplémentaire. Par la manière ci-dessus, vous pouvez clairement présenter la "logique commune" plus une logique supplémentaire dans le début. p> arrêté, l'arrêt et la valeur par défaut sont similaires, tous tombent à travers la logique par défaut (qui ignore). P> Ce n'est pas toujours un bon moyen de coder comme ça, mais s'il est est bien utilisé, il peut mieux présenter la logique. p> p>