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 :

Switch / case mais sur deux variables ?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut Switch / case mais sur deux variables ?
    Bonjour !

    Réalisant un analyseur de code XML, je dois tester pas mal de conditions pour savoir si ce que je trouve dans le code XML doit être mémorisé ou ignoré.

    Et là, je me demandais s'il était possible de faire un switch / case mais en testant les valeurs d'un couple de variables. Après quelques recherches rapides mais infructueuses sur le net, je me prend en main et j'essaye dans Codeblocks (Windows XP) pour voir si ça compile.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    #include <stdlib.h>
    #include <stdio.h>
     
    int main(void)
    {
        int a = 1;
        int b = 2;
     
        switch(a,b)
        {
            default:
                break;
        }
        system("pause");
    }
    Ca, ça compile sans warning.

    En revanche,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    #include <stdlib.h>
    #include <stdio.h>
     
    int main(void)
    {
        int a = 1;
        int b = 2;
     
        switch(a,b)
        {
            case(1,2):
                puts("OMG !\n");
                break;
            default:
                break;
        }
        system("pause");
    }
    ne compile pas et me met comme erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ...|11|error: a comma operator cannot appear in a constant-expression|

    Alors la question : hasard que le premier code compile ou est-ce que ça peut vraiment marcher ? Si oui, comment écrire ça pour ne pas avoir l'erreur citée SVP ?


    Merci d'avance !


    PS : dans mon application, le switch serait à faire sur un couple de variables définies à l'aide d'un typedef enum.

  2. #2
    Invité(e)
    Invité(e)
    Par défaut
    Bonjour,

    Ce que tu cherches à faire est impossible comme tu l'écrit. Derrière un case, doit se trouver une expression équivalente à un entier constant.

    Cela dit, on peut ruser.

    Si ton enum n'utilise pas plus de 16 bits, on peut créer une macro qui va stocker deux enums sur un même int :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    #include <stdio.h>
     
    #define MAKE_BIG_INT(a, b) (a + (b << 16))
     
    typedef enum {
        e_0,
        e_1,
        e_2,
        e_3
    } etats;
     
    int main(void) {
        etats a = e_0;
        etats b = e_2;
     
        switch(MAKE_BIG_INT(a, b)) {
        case MAKE_BIG_INT(e_0, e_0):
            printf("0:0\n");
            break;
     
        case MAKE_BIG_INT(e_0, e_1):
            printf("0:1\n");
            break;
     
        case MAKE_BIG_INT(e_0, e_2):
            printf("0:2\n");
            break;
     
        case MAKE_BIG_INT(e_0, e_3):
            printf("0:3\n");
            break;
     
        case MAKE_BIG_INT(e_1, e_0):
            printf("1:0\n");
            break;
     
        default:
            printf("autre\n");
            break;
        }    
     
        return 0;
    }
    Et si on veut en faire encore moins, on peut aussi définir SWITCH et CASE :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    #include <stdio.h>
     
    #define MAKE_BIG_INT(a, b) (a + (b << 16))
     
    #define SWITCH(a, b) switch(MAKE_BIG_INT(a, b))
    #define CASE(a, b) case MAKE_BIG_INT(a, b)
     
    typedef enum {
        e_0,
        e_1,
        e_2,
        e_3
    } etats;
     
    int main(void) {
        etats a = e_0;
        etats b = e_2;
     
        SWITCH(a, b) {
        CASE(e_0, e_0):
            printf("0:0\n");
            break;
     
        CASE(e_0, e_1):
            printf("0:1\n");
            break;
     
        CASE(e_0, e_2):
            printf("0:2\n");
            break;
     
        CASE(e_0, e_3):
            printf("0:3\n");
            break;
     
        CASE(e_1, e_0):
            printf("1:0\n");
            break;
     
        default:
            printf("autre\n");
            break;
        }
     
     
        return 0;
    }

  3. #3
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Alors la question : hasard que le premier code compile ou est-ce que ça peut vraiment marcher ? Si oui, comment écrire ça pour ne pas avoir l'erreur citée SVP ?
    Comme l'explique mabu, ce n'est pas sur le switch(a,b) mais sur les cases (1,2) que se pose le problème.

    Dans switch(a,b), l'expression a,b utilise l'opérateur , (virgule) : a est évalué puis b est évalué et l'expression prend pour valeur celle de b. Naturellement l'expression a ne sert à rien si elle n'a pas d'effets de bord . C'est ton cas et tout se passe comme si tu avais simplement switch(b).

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 493
    Billets dans le blog
    1
    Par défaut
    @Mabu : ah oui ! C'est bon ça ! Comme je travaille sur une architecture 16 bits, j'ai 8 bits par variables. Donc si mon enum a moins de de 255 valeurs (mon enum est juste une liste d'identifiant, je n'ai donné aucune valeur particulière), ça va marcher ?


    @Diogene : oui j'ai bien compris que le switch(a,b) ne posait pas de problème, mais j'étais bien incapable d'expliquer pourquoi, alors que le case ne marchait pas. Si je comprend ce que dit mabu, c'est que le case n'évalue pas l'expression 1,2 (qui donne 2) et donc produit une erreur de compilation (contrairement au switch qui l'évalue)?

    Je ne connaissais pas l'opérateur virgule, c'est marrant. J'ai fait ce petit code exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <stdio.h>
    int main(void)
    {
        int a= 42;
        int b= 666;
        int c=0;
        int d=-1;
        d=(c=a,b);
        printf("valeur de c : %d\nvaleur de d : %d",c,d);
        return 0;
    }
    C'est marrant. Mais je me pose une nouvelle question (désolé pour vous mais je n'arrête jamais) : à quoi sert l'opérateur virgule ?

  5. #5
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Mais je me pose une nouvelle question (désolé pour vous mais je n'arrête jamais) : à quoi sert l'opérateur virgule ?
    On peut toujours se débrouiller pour s'en passer. Son utilisation la plus fréquente est sans doute dans les boucles for() lors de l'initialisation ou de l'instruction terminale où on ne peut terminer ces instructions par ; . Par exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for(i=0 , j=MAX; i<MAX; i++, j--).....
    Sinon, on peut trouver des choses comme
    mais qui peuvent être remplacée par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     {
       free(ptr);
       ptr= NULL;
     }

Discussions similaires

  1. Itération sur deux variables à la fois
    Par tamtam64 dans le forum Débuter
    Réponses: 8
    Dernier message: 24/08/2013, 18h54
  2. [SQL] UPDATE + CASE + ceci, sur deux variables
    Par logiclogic dans le forum SAS Base
    Réponses: 6
    Dernier message: 31/05/2013, 14h47
  3. Boucle do sur deux variables
    Par bouabid_hanen dans le forum Fortran
    Réponses: 2
    Dernier message: 11/10/2010, 09h35
  4. [VxiR2] Alerteur sur deux variables
    Par Frank Holstein dans le forum Deski
    Réponses: 5
    Dernier message: 16/02/2010, 13h22
  5. Requête avec 2 conditions sur deux variables
    Par mensoif dans le forum Langage SQL
    Réponses: 8
    Dernier message: 01/10/2009, 13h50

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