Switch Statements
We’ve learned that there are two different ways syntactically to make loops: the for loop, and the while loop.
But did you know there’s also another way syntactically to write a if/else statements? We can use something called a Switch Statement.
switch( expression )
{
case value1:
{
//do stuff
}
break;
case value2:
{
//do different stuff
}
break;
case value3:
{
//do OTHER different stuff
}
break;
default:
break;
}What’s going on in the code above? When our program reaches the switch statement, we start looking at each individual case. If the value of a case matches the value of the expression above, we will execute the code for that case.
Huh?
This really is just like if/else, but the syntax is a bit different. Let’s look at an example to really illustrate the differences:
//Let's do something based on user input!
int x = int.Parse(Console.ReadLine());
switch(x)
{
case 0:
{
Console.WriteLine("Yeah they entered zero");
}
break;
case 1:
{
Console.WriteLine("Sure, the user entered '1' ");
}
break;
case 2:
{
Console.WriteLine("They entered '2' let's change it to 15");
x = 15;
}
break;
default:
{
Console.WriteLine("Ugh whatever");
x = 762;
}
break;
}The big difference here is that we’re predicating our different code paths on a variable’s value (or the value of an expression), rather than a condition! That means, we can just put a number, a string, or WHATEVER we want into the switch, and look for different values in our cases.
If the value of x is 0, we will execute the code for case 0, and then break out of the switch statement (just like an if statement!) If the value of x is 1, we will execute the code for case 1, and then break out (just like an else if statement!) If the value of x is 2, we execute case 2, then break. If the value of x is anything other than the cases specified above, we execute the default case (just like an else statement!)
OK, it sort of IS a condition… here’s the equivalent code using if statements:
if(x == 0)
{
Console.WriteLine("Yeah they entered zero");
}
else if (x == 1)
{
Console.WriteLine("Sure, ONE");
}
else if (x == 2)
{
Console.WriteLine("They entered '2' let's change it to 15");
x = 15;
}
else
{
Console.WriteLine("Ugh whatever");
x = 762;
}OK, neat… why does this exist at all? Why not just use if statements?
It can be useful to write things using a particular syntax if the syntax itself is a hint to the programmer about the code’s purpose. For example, the following loops are the same:
for(int i = 0; i < 10; ++i)
{
Console.WriteLine("Ah right, the poison");
Console.WriteLine("The poison for Kuzco");
Console.WriteLine("The poison chosen specifically to kill Kuzco");
Console.WriteLine("Kuzco's poison");
Console.WriteLine();
Console.WriteLine("... that poison?");
}
int i = 0;
while(i < 10)
{
Console.WriteLine("Ah right, the poison");
Console.WriteLine("The poison for Kuzco");
Console.WriteLine("The poison chosen specifically to kill Kuzco");
Console.WriteLine("Kuzco's poison");
Console.WriteLine();
Console.WriteLine("... that poison?");
//Increment is all the way down here!
++i;
}However, a for loop is a signal to anyone looking at the code that “this loop will run exactly THIS many times”. You can gather that information by looking at a single line of code! Not so with a while loop; parsing that information takes a bit more time, because you need to scan through the code to find where a counter variable is being modified, or some other variable is being altered to change the loop’s condition. Separating out particular syntax for particular uses can be a way to mentally categorize code, making it easier on yourself when reading/writing programs.
Enums
In Lab5 (console game) we did something similar to the code below. What are the downsides of this kind of code?
int color1 = 2;If someone sat down to look at your code, would they be able to match up the color and the number used to represent it? They wouldn’t know the color without seeing the running program! You COULD make comments in your code to show what’s going on:
// 0 -> black
// 1 -> dark blue
// 2 -> dark green
// 3 -> dark cyan
// ...etcBut then, this would only be available in one place in your code. What if you’re using hundreds of files, and thousands of lines of code? And what if somehow the console background colors are changed in Windows 12, and these numbers are out of date? Or worse, what if a user (or programmer!) tries to use a number like 742 that doesn’t represent an actual color?
Let’s look at a different example. Suppose we’re creating a Pokemon fangame, and we wanted to keep track of the kind of Pokeball a trainer throws.
In this case, we could use something called an Enumeration.
enum PokeballType { Pokeball, GreatBall, UltraBall, MasterBall }What the heck is this thing? It’s basically just a little user-made type! And we can define exactly what kind of values this “type” can have. And now we could even create a variable that uses this new “type”:
PokeballType myBall = PokeballType.UltraBall;Let’s create a few more enums:
enum PokeType { Bug, Dark, Dragon, Electric, Fairy, Fighting, Fire, Flying, Ghost, Grass, Ground, Ice, Normal, Poison, Psychic, Rock, Steel, Water }
enum Difficulty {Easy, Normal, Hard, Insane}
enum Movement {Up, Down, Left, Right}
enum Seasons {Spring, Summer, Autmn, Winter}OK, neat… how does this help us? Well, it’s nice to be able to refer to something in code using an enum instead of just an integer, or some other built in type:
//The old way
int color1 = 2;
//A better way... now we can understand it!
ConsoleColor color2 = ConsoleColor.Blue;How might we ACTUALLY use this in code though?
float GetBallCatchRate(PokeballType ballType)
{
int catchRate = 0f;
if(ballType == PokeballType.Pokeball)
{
catchRate = 1.0f;
}
else if(ballType == PokeballType.GreatBall)
{
catchRate = 1.5f;
}
else if(ballType == PokeballType.UltraBall)
{
catchRate = 2.0f;
}
else if(ballType == PokeballType.MasterBall)
{
catchRate = -1.0f;
}
return catchRate;
}Or, using the switch statement we just learned:
float GetBallCatchRate(PokeballType ballType)
{
int catchRate = 0f;
switch(ballType)
{
case PokeballType.Pokeball:
{
catchRate = 1.0f;
}
break;
case PokeballType.Pokeball:
{
catchRate = 1.5f;
}
break;
case PokeballType.UltraBall:
{
catchRate = 2.0f;
}
break;
case PokeballType.MasterBall:
{
catchRate = -1.0f;
}
break;
}
return catchRate;
}