Multiple variables in switch statement in c

c# c++ c
17,404

Solution 1

In general you can't. What you are doing already is fine, although you might want to add an else clause at the end to catch unexpected inputs.

In your specific example it seems that j is often twice the value of i. If that is a general rule you could try to take advantage of that by doing something like this instead:

if (i * 2 == j) /* Watch out for overflow here if i could be large! */
{
    switch (i)
    {
        case 10:
            // ...
            break;
        case 100:
            // ...
            break;
        // ...
    }
}

Solution 2

You're pressing for answers that will unnaturally force this code into a switch - that's not the right approach in C, C++ or C# for the problem you've described. Live with the if statements, as using a switch in this instance leads to less readable code and the possibility that a slip-up will introduce a bug.

There are languages that will evaluate a switch statement syntax similar to a sequence of if statements, but C, C++, and C# aren't among them.


After Jon Skeet's comment that it can be "interesting to try to make it work", I'm going to go against my initial judgment and play along because it's certainly true that one can learn by trying alternatives to see where they work and where they don't work. Hopefully I won't end up muddling things more than I should...

The targets for a switch statement in the languages under consideration need to be constants - they aren't expressions that are evaluated at runtime. However, you can potentially get a behavior similar to what you're looking for if you can map the conditions that you want to have as switch targets to a hash function that will produce a perfect hash the matches up to the conditions. If that can be done, you can call the hash function and switch on the value it produces.

The C# compiler does something similar to this automatically for you when you want to switch on a string value. In C, I've manually done something similar when I want to switch on a string. I place the target strings in a table along with enumerations that are used to identify the strings, and I switch on the enum:

char* cmdString = "copystuff";  // a string with a command identifier, 
                                //   maybe obtained from console input

StrLookupValueStruct CmdStringTable[] = {
    { "liststuff", CMD_LIST },
    { "docalcs",   CMD_CALC },
    { "copystuff", CMD_COPY },
    { "delete",    CMD_DELETE },
    { NULL,        CMD_UNKNOWN },
};

int cmdId = strLookupValue( cmdString, CmdStringTable); // transform the string 
                                                        //    into an enum

switch (cmdId) {
    case CMD_LIST:
        doList();
        break;

    case CMD_CALC:
        doCalc();
        break;

    case CMD_COPY:
        doCopy();
        break;

    // etc...    
}

Instead of having to use a sequence of if statements:

if (strcmp( cmdString, "liststuff") == 0) {
    doList();
}
else if (strcmp( cmdString, "docalcs") == 0)  {
    doCalc();
}
else if (strcmp( cmdString, "copystuff") == 0) {
    doCopy();
}
// etc....

As an aside, for the string to function mapping here I personally find the table lookup/switch statement combination to be a bit more readable, but I imagine there are people who might prefer the more direct approach of the if sequence.

The set of expressions you have in your question don't look particularly simple to transform into a hash - your hash function would almost certainly end up being a sequence of if statements - you would have basically just moved the construct somewhere else. Jon Skeet's original answer was essentially to turn your expressions into a hash, but when the or operation got thrown into the mix of one of the tests, the hash function broke down.

Solution 3

(Removed original answer: I'd missed the fact that the condition was an "OR" rather than an "AND". EDIT: Ah, because apparently it wasn't to start with.)

You could still theoretically use something like my original code (combining two 32-bit integers into one 64-bit integer and switching on that), although there would be 2^33 case statements covering the last condition. I doubt that any compiler would actually make it through such code :)

But basically, no: use the if/else structure instead.

Share:
17,404
Kashif
Author by

Kashif

Updated on June 07, 2022

Comments

  • Kashif
    Kashif almost 2 years

    How to write following statement in c using switch statement in c

    int i = 10;
    int j = 20;
    
        if (i == 10 && j == 20)
        {
           Mymethod();
        }
        else if (i == 100 && j == 200)
        {
           Yourmethod();
        }
        else if (i == 1000 || j == 2000) // OR
        {
           Anymethod();
        }
    

    EDIT:

    I have changed the last case from 'and' to 'or' later. So I appologise from people who answered my question before this edit.

    This scenario is for example, I just wanted to know that is it possible or not. I have google this and found it is not possible but I trust gurus on stackoverflow more.

    Thanks

  • Kashif
    Kashif about 14 years
    Thanks for your reply, Can I use this nested switch to do this functionality?
  • Jon Skeet
    Jon Skeet about 14 years
    @Muhammad: That depends on what your real code looks like. I doubt that it's actually what you've shown us. To be honest, the if/else is likely to end up being more readable, unless the fact that j is double i has some significant meaning. Why are you so eager to use a switch?
  • Michael Burr
    Michael Burr about 14 years
    Note that the last case doesn't quite match up since in the original problem there's an 'or' operation, not an `and', so there's more than a readability issue here.
  • Mark Byers
    Mark Byers about 14 years
    @Muhammad: You can use a nested switch, but if you have m values of i and n values of j, you will need m*n cases. That would be extremely confusing to read and you might have repeated code. If there are patterns in the inputs, try to make use of those to reuse code. Split the code up into several functions which handle related combinations if doing it in one function gets too long.
  • Kashif
    Kashif about 14 years
    @Jon please see my edit. It is so kind that you have spare time for me.
  • Mark Byers
    Mark Byers about 14 years
    Be careful. long isn't guaranteed to be longer than an int in C.
  • Jon Skeet
    Jon Skeet about 14 years
    @Michael: I'm not sure anyone was actally suggesting using a switch. Certainly my answer (both before and after the edit) encouraged using the if/else structure. It's still interesting to try to make it work, while strongly discouraging it.
  • Jon Skeet
    Jon Skeet about 14 years
    @Mark: Yes, my answer was assuming C#. It's frankly confusing to have a question tagged C, C++ and C# as they're pretty different languages. The OP's history suggests he's actually using C# - as do the method names.
  • Rune FS
    Rune FS about 14 years
    there's no nested if in the example of the question :)
  • Michael Burr
    Michael Burr about 14 years
    @Jon: You're right. So I've disregarded my own advice, and gave a more in depth answer :)
  • Michael Burr
    Michael Burr about 14 years
    @Rune FS: you're also right. Now there's no mention of nested if.