Finishing off your decision, part 2
Using default with the switch Statement
The next and last item to look at in the decision-making chapter is the default keyword. This does the same thing as the else keyword in if statements; it provides an alternative if none of the other conditions were implemented in the switch/case statement.
Consider the following modification to the switch statement from the previous topic.
// select result using employee age
switch( employeeAge )
{
// check for case 55
case 55:
// display partial company retirement message
conIO.printString( "Partial Company retirement, no Social Security" );
conIO.printEndline();
break;
// check for case 62
case 62:
// display full company retirement message
conIO.printString( "Full Company retirement, limited Social Security" );
conIO.printEndline();
break;
// check for case 65
case 65:
// display full company retirement
// and social security message
conIO.printString( "Full Company retirement, full Social Security" );
conIO.printEndline();
break;
// all other cases, default
default:
// display no retirement changes message
conIO.printString( "No retirement changes possible at present age" );
conIO.printEndline();
break;
}
Consider the conditions for partial and full retirement. They are at very specific ages. However, since your program will probably have data for employees of all ages, there should be a default option that provides an output for those individuals as well. Like the else statement, you can also simply end your set of tests with a default option by using the default keyword.
Here is another example from the previous topic.
int daysInMonth, monthValue, yearValue;
// gets a month value between 1 and 12
monthValue = GetMonthValue();
yearValue = getYearValue();
// select result on month value
switch( monthValue )
{
// case - 30 day months
case 4: // April
case 6: // June
case 9: // September
case 11: // November
// set days in month to 30
daysInMonth = 30;
break;
// case - February
case 2:
// check for leap year
// method: isLeapYear
if( isLeapYear( yearValue ) )
{
// set days in month to 29
daysInMonth = 29;
}
// otherwise check for not leap year
else if( !isLeapYear( yearValue ) )
{
// set days in month to 28
daysInMonth = 28;
}
break;
// default, all other months
default:
// set days in month to 31
daysInMonth = 31;
break;
}
By placing the default keyword in this switch statement, you have accomplished two things. First, you removed the need for some code to be used for the 31 day condition. Secondly, just in case a bad data value got into your monthValue variable, you will still get a legitimate (albeit maybe not correct) day number out of the process.
As a note, the assumption would be that GetMonthValue() would only return a value between 0 and 12. Any other values would not be in the method specification. Consider however, that if the method has a "bug" in it, and it does return a bad data value. You have just protected your program from this in a simple way.
The problem here is that 31 days may not be the correct day count, given the user input. However, a programmer diagnosing the problem would notice this incorrect day, and be able to backtrack the process to the faulty method. Using the default keyword in switch statements, and the else keyword in if statements both offer the potential for program protection, but they should be used carefully.
Remember that their use will "force" a decision of some kind, and there are still conditions where the correct operation is not to make a decision. With this in mind, the code just shown can be improved again by adding an else to the test for leap year. This is significantly superior over calling one method for a positive result and the same method for a potentially negative result.
Consider the following.
int daysInMonth, monthValue, yearValue;
// gets a month value between 1 and 12
monthValue = GetMonthValue();
yearValue = getYearValue();
// select a result based on the month value
switch( monthValue )
{
// case - 30 day months
case 4: // April
case 6: // June
case 9: // September
case 11: // November
// set days in month to 30
daysInMonth = 30;
break;
// case - February
case 2:
// check for leap year
// method: isLeapYear
if( isLeapYear( yearValue ) )
{
// set days in month to 29
daysInMonth = 29;
}
// otherwise if not leap year
else
{
// set days in month to 28
daysInMonth = 28;
}
break;
// default, all other months
default:
// set days in month to 31
daysInMonth = 31;
break;
}
It is critical that you recognize the logical outcome of the isLeapYear vs. the else “not isLeapYear”. Redundant testing is commonly the result of missing the logic in a particular situation so you want to make sure you have conducted a thorough analysis before writing your code.
As mentioned, these last two topics are fairly short. This was done so you would look at the if and switch statements that do not have default operations separately from the ones that do have default operations. The logic is different. Without defaults, your program may stop and look for chances to change its path (i.e., to "branch" to another path), but the decision making process allows for no decision to be made. With defaults, some action will be taken, and some decision will be made, no matter what data is evaluated. Keep this concept clear in your mind.
Like the default if situation, the default switch situation is not much different. However, if you watch this video, you can keep an eye on any problems that might pop up, with a little extra commentary on pre-condition circumstances.
Wrapping Up Branching
At this point, you have some fundamental experience with if, if..else if, and if..else branching, as well as switch/case branching. The next level of branching will be when your program turns around and repeats its processes over and over, a process called iteration or looping.