Chapter Three: Switch Statements

Matthew Campbell, October 16, 2011

switch statements are used when we want to execute different bits of code based on the value of an integer variable. While the if statement from the last chapter gave us two options (either the condition was met or it wasn’t), switch statements give us a way to conditionally execute code with more than two possibilities. Here is the general form that the switch statement takes.

int level = 0;

switch (level) {
     case 0:{
         //execute code when level == 0
         break;
     }
     case 1:{
         //execute code when level == 1
         break;
     }
     case 2:{
         //execute code when level == 2
         break;
     }
     default:{
         //execute code if level does not
         //meet any of the conditions above
         break;
     }
}

The switch statement above has three major components: the first is the expression that we are evaluating. In this case, we’re checking the value of the integer variable level. The second component is a series of case statements that correspond to each possible value of the expression. Each case will include the keyword case, followed by the expression that corresponds to the case, and a colon. Everything after the colon is code that will execute when the expression evaluates to the integer for that case. In the example above, the code after case 0 and before the first break will execute, because the current value of level is 0. If you changed the value of level, a different case would be executed.

break statements mark the end of the code that will execute for a case. By putting a break statement in a case you make sure that any remaining code in the switch statement will not execute.

The last part of the switch statement is a special type of case called default. This appears after the case statements, and works in a similar way. The main difference is that default does not have a value associated with it-the code after default will only execute when the expression does not correspond to any of the values in the case statements.

Finding the Area of a Shape with switch

Let’s see how a switch statement might work in a real application. Imagine that we had an app that figured out the area of a shape for us. We don’t know beforehand what type of shape we’re dealing with, and since there are different rules to compute the area of different shapes we’ll need to use different code to compute the area for each type of shape we’ll support.

This is a good time to use a switch statement. In our real app we would ask the iPhone user what type of shape they wanted to compute the area for. Then we would use a switch statement to execute the appropriate code based on the user’s choice. In this example, we’ll just use default values for our shape and other parameters since we have not yet learned how to ask the user for input. Of course, in a real program we would need to ask the user both for the type of shape as well as the relevant input parameters.

The first thing we will need is two variables: the first will be an integer that will represent the shape the user is interested in, and the second will be a float that will hold the shape’s area.

int shape = 2;
//0 == Square, 1 == Parallelogram
//2 == Triangle, 3 == Circle

float area; 

As you can see from the comments, we are going to support four types of shapes: squares, parallelograms, triangles, and circles. Next, let’s fill in the skeleton of our switch statement. What we need now is to start the switch statement. We’ll start with the default case, which in this example means the user specified an unsupported shape. If this happens, we’ll assign -999 to the area variable:

int shape = 2;
//0 == Square, 1 == Parallelogram
//2 == Triangle, 3 == Circle

float area;

switch (shape) {
     default:{
          //Set to negative number if
          //no shape is specified
          area = -999;
          break;
     }
}

Now let’s add the case for finding the area of a square, which will execute when shape is equal to 0:

int shape = 2;
//0 == Square, 1 == Parallelogram
//2 == Triangle, 3 == Circle

float area;

switch (shape) {
     case 0:{
          //Square
          float length = 3;
          area = length * length;
          break;
     }
     default:{
          //Set to negative number if
          //no shape is specified
          area = -999;
          break;
     }
}

Now our switch statement will compute the area of a square when the shape variable equals 0, and for any other value of shape it will just assign the value of -999 to the area variable.

Next we can fill in the case for a parallelogram, which uses different variables and a different equation:

int shape = 2;
//0 == Square, 1 == Parallelogram
//2 == Triangle, 3 == Circle

float area;

switch (shape) {
     case 0:{
          //Square
          float length = 3;
          area = length * length;
          break;
     }
     case 1:{
          //Parallelogram
          float base = 16;
          float height = 24;
          area = base * height;
          break;
     }
     default:{
          //Set to negative number if
          //no shape is specified
          area = -999;
          break;
     }
}

In the two case statements above, you can see how each case uses different variables and a different equation. You may add as many cases to a switch statement as you need to support the levels that you can expect in your program.

Here are the remaining two cases we’ll support for now, a triangle and a circle:

int shape = 2;
//0 == Square, 1 == Parallelogram
//2 == Triangle, 3 == Circle

float area;

switch (shape) {
     case 0:{
          //Square
          float length = 3;
          area = length * length;
     break;
     }
     case 1:{
          //Parallelogram
          float base = 16;
          float height = 24;
          area = base * height;
          break;
     }
     case 2:{
          //Triangle
          float base = 16;
          float height = 24;
          area = .5 * base * height;
          break;
     }
     case 3:{
          //Circle
          float pi = 3.14159;
          float radius = 6;
          area = pi * radius * radius;
          break;
     }
     default:{
          //Set to negative number if
          //no shape is specified
          area = -999;
          break;
     }
}

Omitting break Statements

The example above is the most common way to use switch statements, but it’s possible to get your switch statements to behave in a different way. If you omit the break statements at the end of each case, control of the program will not return to the next level of code. Instead, each successive case statement will continue to execute, until a break is reached or the switch statement ends. What happens is that once a case is evaluated to be true then every bit of code remaining in theswitch statement is executed.

To illustrate this point, I created a switch statement below that doesn’t have any break statements. What this is going to do is pretend to count so we are going to start with an int called count and an int called addThisMany. The idea is that when the switch statement has a case that matches the value of addThisMany then we will start adding values to the int count. This means that if we make the value of addThisMany equal to 3 then the switch statement will evaluate each case until it finds one that matches 3. When it does, all the remaining code in the switch statement will execute. In our case, these means that count gets incremented in each case statement. We will step through this in a second, but here is the code:

int addThisMany = 3;
int count = 0;
switch (addThisMany) {
     case 5:
          count++;
     case 4:
          count++;
     case 3:
          count++;
     case 2:
          count++;
     case 1:
          count++;
     default:
          break;
}

Let’s step through each case statement to see how this is working. Again, we are going to assume that the variable value is 3 so that we will not start counting until we find a case that is equal to 3. In put each case in a table below to make it easier to follow. The first column is the case, the second indicates whether the case expression is true, the third column shows you the code that executes and the final column will show count’s value as it increases through each case.

Case Expression True Executed Code count’s Value
case 5: NO 0
case 4: NO 0
case 3: YES count++ 1
case 2: YES count++ 2
case 1: YES count++ 3

Hand’s On Time

Imagine that you wanted to create a “secret decoder ring” app. A secret decoder ring is a toy that let’s kids create secret messages by changing letters in the alphabet into numbers and this could be a fun iPhone app. In real life, the decoder ring would have a circle on it that matches up numbers and letters so that you could get a sequence of numbers to represent a phrase. So, instead of writing ABC you could write 123.

The first step to making an app like this would start with a switch statement. Instead of a mechanical disk you would write a switch statement that had cases for each letter of the alphabet. The code in each case would assign a different number to a variable depending on what letter of the alphabet the case represented.

For this exercise, create a char variable called letterToEncode and an int variable called letterCodedAsInteger. Next, write a switch statement that evaluates the letterToEncode variable and then assigns a number to the letterCodedAsInteger variable based on what letter in the alphabet letterToEncode represents. The only rule is that each case must assign a unique number.