The Decision Table IF statement is a coding method used to to handle more than two choices in an algorithm. (Single choices and two choices can be directly handled by IF and IF/ELSE statements.)
The Decision Table IF format is used only when testing the same variable against multiple (more than two) different values.
A typical decision table contains a list of three or more value ranges and some message to be issued or action to be taken for each of the value ranges. For example:
Value Range Message 0 - 9 small 10 - 19 medium 20 - 29 large over 30 huge
As with many informal decision tables, the boundaries between the conditions may not be defined precisely enough to be coded directly. You, the programmer, must fix the specification of each value range so that no numbers are missing in gaps between the ranges, and so that none of the ranges overlap. The ranges must include the entire number line from minus infinity to plus infinity, with no gaps, no matter how small. For example, the table above has the following gaps:
The decision table cannot be programmed until you rewrite it to fix the gaps. You must decide what to do with numbers less than zero. You must decide whether a "gap" between value ranges belongs in the value range below the gap or in the value range above the gap.
Here is the same table with the gaps filled in. Most of the gaps were assigned to be part of the value range below the gap, and a new value range was added to handle numbers below zero:
Value Range Message less than 0 too small 0 to less than 10 small 10 to less than 20 medium 20 to less than 30 large over and including 30 huge
The new table covers all the numbers from minus infinity to plus infinity; nothing is left out and none of the value ranges overlap. This table can be programmed.
Using the above assumptions to fill in the gaps, the code to implement Decision Table #1 looks like this:
if ( x < 0 ) /* Condition #1 */ printf("too small"); /* TRUE #1 */ else /* FALSE #1 */ if ( x < 10 ) /* Condition #2 */ printf("small"); /* TRUE #2 */ else /* FALSE #2 */ if ( x < 20 ) /* Condition #3 */ printf("medium"); /* TRUE #3 */ else /* FALSE #3 */ if ( x < 30 ) /* Condition #4 */ printf("large"); /* TRUE #4 */ else /* FALSE #4 */ printf("huge");
Note how in a Decision Table If statement we only need to test one number in each component IF statement condition, even though each value range has both a top and a bottom value. This coding structure will be discussed after we look at another Decision Table.
Here is another table of value ranges and messages. The specified value range is labelled "Original Value Range", on the left:
Original
Value RangeMessage Fixed
Value Range below 0 less than zero below 0 0 - 25 first quarter 0 to less than 25 25 - 50 second quarter 25 to less than 50 50 - 75 third quarter 50 to less than 75 75 - 100 fourth quarter 75 to and including 100 over 100 bigger than 100 over 100
As with the first table, this second table is not defined precisely enough to be coded directly. For example, the number 25 appears to belong to both the first and the second quarter; other numbers are also in two quarters. We must fix the table so that every possible number falls into only one range, and so that the table has no gaps in the ranges.
In this example, we will assume that each quarter extends up to, but does not include, the topmost value in each range, except for the final quarter that must also include the last value 100. These assumptions cover all the numbers from minus infinity to plus infinity; nothing is left out and none of the ranges overlap. This table can be programmed. The fixed value ranges are on the right in the above table.
Using the above assumptions to fix the problems with overlapping value ranges, the code to implement Decision Table #2 (right half) looks like this:
if ( x < 0 ) /* Condition #1 */ printf("less than zero"); /* TRUE #1 */ else /* FALSE #1 */ if ( x < 25 ) /* Condition #2 */ printf("first quarter"); /* TRUE #2 */ else /* FALSE #2 */ if ( x < 50 ) /* Condition #3 */ printf("second quarter"); /* TRUE #3 */ else /* FALSE #3 */ if ( x < 75 ) /* Condition #4 */ printf("third quarter"); /* TRUE #4 */ else /* FALSE #4 */ if ( x <= 100 ) /* Condition #5 */ printf("fourth quarter"); /* TRUE #5 */ else /* FALSE #5 */ printf("bigger than 100");
All the TRUE halves of each IF statement contain one printf() statement. All the FALSE halves of each IF statement also contain exactly one statement, and for every IF (except the very last IF) that one statement is another IF statement.
An IF statement is always one statement, even though it may contain many other statements (including other IF statements) and may span many lines. Thus, the entire Decision Table is one C language statement, since it is one IF statement (that happens to contain other IF statements that contain other IF statements, etc.).
Note how in a Decision Table If statement we only need to test one number in each component IF statement condition, even though each value range has both a top and a bottom value.
Here is a number-line diagram to illustrate how the first few nested IF statements in the above code work. The TRUE and FALSE halves of each condition are shown:
Each IF statement divides the number line into two halves; the half below the test value (e.g. x < 0) and the half above or equal to the test value (e.g. x >= 0). If X is below the test value in an IF statement, the TRUE half of that IF statement is executed; if X is above or equal to the test value, the FALSE half of that IF statement is executed.
Inside each FALSE half of each IF statement is another IF statement. This nested IF statement is only executed if the IF statement above it is FALSE, that is, when X is above or equal to the test value in the statement above it. In this way, the FALSE branch of each nested IF statement divides in two a second time the number line that was divided in two by the IF statement above it.
Let's look at how this works using an example involving just the first and second IF statements.
if ( x < 0 ) /* Condition #1 */ printf("less than zero"); /* TRUE #1 */ else /* FALSE #1 */ if ( x < 25 ) /* Condition #2 */ printf("first quarter"); /* TRUE #2 */ else /* FALSE #2 */ ...
The first IF statement tests Condition #1: "x < 0". This condition divides the number line into two halves around the value zero. For numbers less than zero, the condition is TRUE and the TRUE half of the IF prints a message "less than zero". For numbers greater than or equal to zero, the condition is FALSE and the FALSE half of the IF, containing another IF statement, is executed instead. Condition #1 says that the TRUE half of the first IF statement is executed when X is in the half of the number line to the left of zero; the FALSE half of the first IF statement is executed when X is in the half of the number line to the right of zero.
The second IF statement is in the FALSE half of the first IF statement; so, it is only executed if Condition #1 of first IF statement is FALSE and thus X must be to the right of zero on the number line. Let's concentrate on this FALSE clause dealing with the right half of the number line.
The second IF statement tests Condition #2: "x < 25". This condition divides its part of the number line into two halves around the value 25. For numbers less than 25, the condition is TRUE and the TRUE half of the second IF prints a message "first quarter". For numbers greater than or equal to 25, the condition is FALSE and the FALSE half of IF, containing another IF statement, is executed instead. Condition #2 says that the TRUE half of the second IF statement is executed when X is in the half of the number line to the left of 25; the FALSE half of the second IF statement is executed when X is in the half of the number line to the right of 25.
Now, note that even though X might be to the left of 25 in Condition #2, it cannot be to the left of zero, because we are in the FALSE branch of Condition #1 and the FALSE branch of Condition #1 assures us that X is to the right of zero. (If X were left of zero, Condition #1 would be TRUE and we would never execute Condition #2.)
Condition #2 gets to divide its half of the number line in two only if Condition #1 is FALSE. This means that the two new parts of the number line produced by Condition #2 are:
- X between zero and 25, corresponding to Condition #2 being TRUE
- X greater than or equal to 25, corresponding to Condition #2 being FALSE
Thus, the TRUE part of the second IF statement is TRUE for X lying above the value in the IF statement above it (Condition #1), and for X lying below 25 (Condition #2).
Thus, the TRUE part of each nested IF statement is TRUE for X lying within the desired range of the decision table. The IF statement above the nested IF sets the lower bound; the TRUE branch of the nested IF sets the upper bound.
The order of the IF statements must match the conditions used, or the Decision Table won't work.
If the decision table uses the "less than" condition in all the IF statements, as above, the order of the test conditions in the IF statements must proceed from the smallest value range to the largest value range, as above. Doing so divides up the number line correctly from left to right, from smallest value to largest value.
If the "greater than" condition were used in all the IF statements, the IF statements would have to be rearranged to test for the largest values first, so that the number line gets divided up correctly by the FALSE condition of each IF statement. Doing so divides up the number line from right to left, from largest value to smallest value.
The following two sets of code produce identical output. All the test conditions are reversed, and the order of the IF statements is also reversed to put the larger tests first, to keep the output the same:
Code using "less than" |
Code using "greater than" |
---|---|
if ( x < 0 ) printf("less than zero"); else if ( x < 25 ) printf("first quarter"); else if ( x < 50 ) printf("second quarter"); else if ( x < 75 ) printf("third quarter"); else if ( x <= 100 ) printf("fourth quarter"); else printf("bigger than 100"); |
if ( x > 100 ) printf("bigger than 100"); else if ( x >= 75 ) printf("fourth quarter"); else if ( x >= 50 ) printf("third quarter"); else if ( x >= 25 ) printf("second quarter"); else if ( x >= 0 ) printf("first quarter"); else printf("less than zero"); |
Note how the code using "less than" conditions divides up the number line from left to right (smallest to largest), where the code using "greater than" conditions divides up the number line from right to left (largest to smallest).
The output of either method is identical. Choose the method that most closely matches the decision table used in the algorithm design.
To avoid having too many levels of indentation, we adjust the spacing of Decision Table IF statements as follows:
Normal Spacing and Indentation |
Decision Table Spacing and Indentation |
---|---|
if ( x < 0 ) printf("less than zero"); else if ( x < 25 ) printf("first quarter"); else if ( x < 50 ) printf("second quarter"); else if ( x < 75 ) printf("third quarter"); else if ( x <= 100 ) printf("fourth quarter"); else printf("bigger than 100"); |
if ( x < 0 ) printf("less than zero"); else if ( x < 25 ) printf("first quarter"); else if ( x < 50 ) printf("second quarter"); else if ( x < 75 ) printf("third quarter"); else if ( x <= 100 ) printf("fourth quarter"); else printf("bigger than 100"); |
The code is identical; only the spacing and indentation has been changed to make it easier to read. The new spacing takes fewer lines and has only one level of indentation. Use it for all Decision Tables.
The TRUE and FALSE parts of an IF statement must be either a single statement, or a block of statements enclosed in brace brackets '{}'. This applies in Decision Tables as well.
The above examples used only single printf() statements in the TRUE part of each IF. The FALSE parts were also single (nested) IF statements. If the algorithm requires more than one statement in the TRUE parts of each IF statement, the code needs to use brace brackets to group the statements into one block:
if ( x < 0 ) { printf("less than zero"); ++countzeroes; } else if ( x < 25 ) { printf("first quarter"); ++countfirsts; } else if ( x < 50 ) { printf("second quarter"); ++countseconds; } else if ( x < 75 ) { printf("third quarter"); ++countthirds; } else if ( x <= 100 ) { printf("fourth quarter"); ++countfourths; } else { printf("bigger than 100"); ++countbigger; }
Replacing each single printf() statement with a block of statements in brace brackets doesn't change the fact that the entire Decision Table above is still seen as one single IF statement. The TRUE half of the IF statement is a block of statements, the FALSE half is another nested IF statement whose TRUE half is a block of statements and whose FALSE half is another nested IF statement, etc.