0

I am in a beginning C++ programming class and I need help with nesting switch statements and using multiple conditions, because I have to translate a program I already wrote from if/else statements to switch statements, because I didn't know I was supposed to use the switch statement.

For example, how do I change something like:

if (temperature >= -459 && temperature <= -327)
{
    cout << "Ethyl Alcohol will freeze.\n";
}
else if (temperature >= -326 && temperature <= -30)
{
    cout << "Water will freeze.\n";
}
else if ...
{
}
else 
{
}

Into a switch/case statement? I can get the first level, but how do I nest and have multiple conditions like the temperature statements above?

Emily Kelly
  • 11
  • 1
  • 3
  • 5
    The `case`s of a `switch` must have constant values (so compiler can create a *jump* table or other efficient implementation). – Thomas Matthews Feb 17 '15 at 21:14
  • Standard C and C++ doesn't really allow ranges to be defined as case-labels, so if the test is really in the form you have written with hundreds of different values that lead to one piece of code, then this is not the right solution for switch. I suspect either you have misunderstood the correct way to solve the problem, or you there is something else "missing" in the question or suggestion to use switch. – Mats Petersson Feb 17 '15 at 21:16
  • I doubt you can do this using solely a `switch`, except using maybe a compiler extension https://gcc.gnu.org/onlinedocs/gcc/Case-Ranges.html – vsoftco Feb 17 '15 at 21:17
  • 2
    As it is now, this isn't really suitable for a `switch` statement. See http://stackoverflow.com/questions/9432226/how-do-i-select-a-range-of-values-in-a-switch-statement did you perhaps misunderstand the requirements of your assignment? – oefe Feb 17 '15 at 21:17
  • Is it even possible then to run this type of program with the switch statement? The constant values mean that the values cannot change, so how would a user be able to input different values? – Emily Kelly Feb 17 '15 at 21:17
  • "Constant value" isn't exactly the right term, it should have been expressed as "discrete values". `switch` handles discrete values, that you can enumerate, and then there's a "default" case. It doesn't handle ranges. – lurker Feb 17 '15 at 21:21

4 Answers4

2

Switch statements work like this:

int variable = 123; // or any other value

switch (variable)
{
  case 1:
    {
        // some code for the value 1

        break;
    }
  case 12:
    {
        // some code for the value 12

        break;
    }
  case 123:
    {
        // some code for the value 123

        break;
    }
  case 1234:
    {
        // some code for the value 1234

        break;
    }
  case 12345:
    {
        // some code for the value 12345

        break;
    }
  default:
    {
        // if needed, some code for any other value

        break;
    }
}
Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
1

First of all, this question is in C and not in C++. C++ inherited most of the C language, including the switch-case.

You can't do this with a switch, unless you start enumerating all the values one by one, like this:

switch (temperature) {
   case -459:
   case -458:
   ....
   case -327: <do something>; break;
   case -326:
   .....
}

This is because in C, switch-case is simply translated to a series of if-goto statements, with the cases just being the labels.

Eldad Mor
  • 5,405
  • 3
  • 34
  • 46
  • "switch-case is simply translated to a series of if-goto..." Sometimes. Sometimes not. – Drew Dormann Feb 17 '15 at 21:19
  • When is it not translated into a series of cmpl, jmps, labels etc? – Eldad Mor Feb 17 '15 at 21:23
  • More often, the `switch-case` is translated into an array of addresses. The `switch` value is used as an index into the array of addresses, then the appropriate address is jumped to. The value may be adjusted to correspond to the correct address. Another common implementation is an associative map using the switch value and the destination address. – Thomas Matthews Feb 17 '15 at 21:24
  • "First of all, this question is in C and not in C++..." come again? The question also uses `cout <<` which makes it pretty definitively C++. – Ian McLaird Feb 17 '15 at 21:30
  • Any of you has any link to an article or something explaining this in depth, by any chance? – Eldad Mor Feb 17 '15 at 21:32
  • @Ian McLaird, the cout is redundant here, this is a question about switch. A question re switch in C++ would be "How do I replace switch-case with polymorphism/templates/whatever". – Eldad Mor Feb 17 '15 at 21:33
  • 1
    Some compilers spend a lot of efforts on finding an efficient way to implement switch cases. Have seen jump table stuff, if/goto chains, jmp base + n * offset, ... – BitTickler Feb 17 '15 at 21:40
0

In your case, your stuck with an if-else-if ladder.

You could use a lookup table that has temperatures and the text to print:

struct Temperature_Entry
{
  int min_temp;
  int max_temp;
  const char * text_for_output;
};
static const Temperature_Entry temp_table[] =
{
  {-459, -327, "Ethyl Alcohol will freeze.\n"},
  {-326, -30,  "Water will freeze.\n"},
};
static const unsigned int entry_count =
  sizeof(temp_table) / sizeof(temp_table[0]);

//...
int temperature;
for (unsigned int i = 0; i < entry_count; ++i)
{
  if (   (temperature >= temp_table[i].min_temp)
      && (temperature < temp_table[i].max_temp))
  {
    std::cout << temp-table[i].text_for_output;
  }
}
Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
0

As many have pointed out, you cannot use switch case for ranges and dynamic formulas. So if you want to use them anyway, you will have to write a function which takes a temperature and returns a temperature range out of a pre-known set of temperature ranges. Then, finally, you can use a switch/case for the temperature ranges.

enum TemperatureRange { FrigginCold, UtterlyCold, ChillinglyCold, Frosty, ... };
TemperatureRange GetRange( int temperature );

// ...
switch( GetRange( temperature ) )
{
case FrigginCold: cout << "The eskimos vodka freezes."; break;
case UtterlyCold: cout << "The eskimo starts to dress."; break;
// ...
}
BitTickler
  • 10,905
  • 5
  • 32
  • 53