IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

la fonction switch en c (sélection dans un intervalle de nombres)


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2014
    Messages : 2
    Points : 3
    Points
    3
    Par défaut la fonction switch en c (sélection dans un intervalle de nombres)
    Salut a tous et a toutes,
    Une petite question met venue à l'esprit alors que je faisait un générateur aléatoire de labyrinthe en C. Quelqu'un sait-il comment faire ou est-il possible de faire un switch dont la sélection de l'action a réaliser correspond a un intervalle de valeur? Moi même j'ai un peu de mal avec ma question donc voila un exemple:


    la version normal:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    switch(choix)
        {
            case 0: --action 1-- break;
            case 1: --action 1-- break;
            case 2: --action 2-- break;
            case 3: --action 3-- break;
     
        }
    la version que je voudrais réaliser:


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    switch(choix)
        {
            case  0<choix<10:     --action 1--; break;
            case 10<choix<20:     --action 1--; break;
            case 20<choix<30:     --action 2--; break;
            case 30<choix<40:     --action 3--; break;
     
        }
    merci pour vos réponses.

  2. #2
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 119
    Points
    28 119
    Par défaut
    A ma connaissance, il n'est pas possible de specifier des intervalles. Mais tu peux faire comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    switch (choix)
    {
      case 1 : 
      case 2 : 
      case 3 : 
      case 4 :  /* code pour 1, 2, 3 ou 4 */  break ;
     
      case 5 : 
      case 6 : 
      case 7 :  /* code de 5 a 7 */ break
     
      default : /* other */ break;
    }
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par dudu_man Voir le message
    switch(choix)
    {
    case 0<choix<10: --action 1--; break;
    case 10<choix<20: --action 1--; break;
    case 20<choix<30: --action 2--; break;
    case 30<choix<40: --action 3--; break;

    }
    On peut le faire en C , en sachant que le switch n'accepte que des entiers
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        if ((choix >= 0) && (choix <= 9)) {
    //      action 1
        } else if ((choix >= 10) && (choix <= 19)) {
    //      action 1
        } else if ((choix >= 20) && (choix <= 29)) {
    //      action 2
        } else if ((choix >= 30) && (choix <= 39)) {
    //      action 3
        }
    Et si on combine 2 intervalles
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        if (((choix >= 0) && (choix <= 9)) || ((choix >= 20) && (choix <= 29))) {
    //      action 1
        } else if ((choix >= 10) && (choix <= 19)) {
    //      action 2
        } else if ((choix >= 30) && (choix <= 39)) {
    //      action 3
        }
    Édit: gangsoleil a raison case est un mot clef . Et pour un coup en français

  4. #4
    Modérateur
    Avatar de gangsoleil
    Homme Profil pro
    Manager / Cyber Sécurité
    Inscrit en
    Mai 2004
    Messages
    10 150
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Manager / Cyber Sécurité

    Informations forums :
    Inscription : Mai 2004
    Messages : 10 150
    Points : 28 119
    Points
    28 119
    Par défaut
    Attention, ce n'est pas if ((case < ..., mais if ((choix < ...

    if (( case va provoquer une erreur de syntaxe.
    "La route est longue, mais le chemin est libre" -- https://framasoft.org/
    Les règles du forum

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    A proprement parlé, switch n'est pas une fonction mais un opérateur. Et non il ne permet pas de faire des sélections sur des plages.

    Tu as la solution de gangsoleil, à mon avis peu lisible et maintenable. Tu as la solution de foetus, qui peut-être améliorée avec une fonction ou une macro isInRange(min, max).

  6. #6
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Idée "stupide", mais dans le même genre que foetus : faire une enum, et faire un switch/case sur l'énumération !

    Si l'énumération "inversée" existait ce serait fabuleux !... mais en C ça serait ardu de déclarer des ensembles de valeurs !
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par Metalman Voir le message
    Idée "stupide", mais dans le même genre que foetus : faire une enum, et faire un switch/case sur l'énumération !

    Si l'énumération "inversée" existait ce serait fabuleux !... mais en C ça serait ardu de déclarer des ensembles de valeurs !
    Si tu es [très] joueur tu peux faire un espèce de "hash" pour les intervalles

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        int hash = generate_hash(choice);
     
        switch (hash) {
        case HASH_ACTION_1: /* action1 */ break;
        case HASH_ACTION_2: /* action2 */ break;
        case HASH_ACTION_3: /* action3 */ break;
        default: /* other */ break;
        }

  8. #8
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Exact... c'est ce que j'imaginais pour la solution "pratique" ! :p
    Du coup une banale enum sur 0, 1, 2, 3, 4 + le hash qui divise par 10 et renvoie l'enum...
    Et on a la solution. (l'enum servant "uniquement" à symboliser/abstraire les résultats "bruts")

    Et ça s'approche de la fonction IsInRange() dans l'idée !
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  9. #9
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Pourquoi faire simple quand on peut faire compliqué, hein ?

  10. #10
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    En soit, le coup du hash serait le plus "lisible" et le plus simple à maintenir :

    - Une fonction génère un "truc" qui désigne un intervalle de valeurs [le "truc" c'est l'enum du coup]
    - Le switch qui décrit clairement ce que l'on fait pour chaque intervalle

    Et seule la fonction de hash évoluera si d'autres cas apparaissent (l'ajout de case n'est pas monstrueusement complexe à faire évoluer, pareil pour l'enum).


    C'est simple, lisible, et la fonction de hash peut être exportée dans un autre fichier pour ne pas densifier le code initial.
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  11. #11
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    C'est vrai si tu as besoin de faire le même test de plage ailleurs, je te l'accorde.

    Dans le cas contraire, l'intérêt semble limité : fonction faisant des if / else pour renvoyer un type énuméré à maintenir puis switch / case sur à faire sur toutes les valeurs de l'énumération d'un côté ; uniquement les if / else de l'autre.

  12. #12
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2014
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mai 2014
    Messages : 2
    Points : 3
    Points
    3
    Par défaut
    Merci à tous pour vos réponse. Je vais donc mettre un peu d'ordre. Apres avoir posé cette question j'ai continué a faire des recherche, j'ai eu la réponse et vous me l'avez confirmé. il est impossible de faire un switch avec une plage de nombre. Par contre les deux solution proposé ont, à mon avis du bon et du moins bon. Pour les if; else if ... faut le dire c'est pas super lisible mais dans un petit programme c'est le plus court je pense. Le hash, la première solution à laquelle j'avais pensé et beaucoup plus lisible mais plus longue à mettre en place je pense que dans un gros programme j'opterais pour cette alternative, ça fait plus propre

  13. #13
    Membre actif
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2012
    Messages
    170
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Septembre 2012
    Messages : 170
    Points : 234
    Points
    234
    Par défaut
    Bonjour,
    je pense que l’idéal serait de faire du très simple: si tu as des intervalles regulier comme dans ta question
    tu fais une division entiere par le maximum du premier intervalle c a d:
    10 dans ton cas:
    5 etant compris entre 0 et 10 te renverra 0
    12 etant compris entre 10 et 20 te renverra 1
    25 etant compris entre 20 et 30 te renverra 2
    ca reviendrait à faire un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    switch (choix/10) 
     {
            case 0: --action 1-- break;
            case 1: --action 1-- break;
            case 2: --action 2-- break;
            case 3: --action 3-- break;
     
        }
    sinon tu génère grace a une fonction des éléments sur lesquels tu switch...
    bon courage

  14. #14
    Membre du Club
    Homme Profil pro
    Formateur en informatique
    Inscrit en
    Août 2009
    Messages
    77
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Formateur en informatique

    Informations forums :
    Inscription : Août 2009
    Messages : 77
    Points : 55
    Points
    55
    Par défaut
    Je débute vraiment en C++, et j'ai une question sans doute bête : POURQUOI le C++ ne permet-il pas les intervalles avec Switch, ça me semblerait tellement pratique.

  15. #15
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 985
    Points
    30 985
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par frouppy Voir le message
    Je débute vraiment en C++
    C'est super car ici c'est un forum de C !!! Donc non seulement tu viens déterrer un topic de 4 ans mais non pas pour y répondre mais pour poser ta bête question et en plus en te trompant au final de rubrique. T'as pas l'impression d'être une grosse tanche le formateur ?

    Citation Envoyé par frouppy Voir le message
    POURQUOI le C++ ne permet-il pas les intervalles avec Switch,
    Parce que tu ne sais pas ce qu'il se passe derrière. Le switch(expression) évalue l'expression qui doit correspndre à une valeur puis va se brancher sur les étiquettes qui sont en fait des "labels" de goto. Donc derrière le compilateur transforme ça en goto et ces labels doivent être figés et connus lors de la compilation.

    Citation Envoyé par frouppy Voir le message
    ça me semblerait tellement pratique.
    Oh et le monde serait tellement plus beau. Ben tu fais sans. Ou alors tu choisis un langage plus adapté à tes besoins. Parce que tu ne peux pas avoir à la fois un langage proche de la machine et à la fois proche des besoins expressifs du développeur.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  16. #16
    Expert éminent sénior
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 630
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 630
    Points : 10 556
    Points
    10 556
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Le switch(expression) évalue l'expression qui doit correspondre à une valeur puis va se brancher sur les étiquettes qui sont en fait des "labels" de goto. Donc derrière le compilateur transforme ça en goto et ces labels doivent être figés et connus lors de la compilation
    Cela s'appelle des branch table ou jump table (<- lien wiki en anglais)
    Et c'est d'ailleurs pour cela qu'un switch est plus performant/ efficace qu'une série de si

    Ensuite pour le pourquoi , je me dis qu'en 2018, les compilateurs ne doivent plus utiliser de simples tableaux - pour des cas où l'intervalle est très grand.
    Et il y a aussi la gestion des intervalles qui se chevauchent : est-ce que la détection est simple ? est-ce que la prise de décission est simple ?

    Et au passage (si cela n'a pas été dit ) gcc propose/ proposait une extension pour avoir des intervalles Case Ranges (<- lien en anglais)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 29/07/2012, 12h22
  2. [AC-2007] Attribuer une valeur en fonction d'une sélection dans une liste
    Par Gregk84 dans le forum VBA Access
    Réponses: 7
    Dernier message: 09/07/2012, 17h31
  3. Réponses: 11
    Dernier message: 23/04/2012, 09h55
  4. Réponses: 23
    Dernier message: 07/05/2008, 08h09
  5. slection dans une intervalle d'enregistrement
    Par toome dans le forum Langage SQL
    Réponses: 1
    Dernier message: 30/08/2005, 15h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo