Condition Based Control Structures


A condition based control structure is exactly what it seems to be; that is a program control structure that selects a control path based upon a condition. More commonly this is referred to as an If statement (or an If-Then statement). Before we look at actual If statements, it will be helpful to understand what is behind the If statement, which is logic. Logic systems or statements evaluate one or more premises, then form a conclusion based on the validity of the premises. Evaluation of the premises result in one of two possible outcomes, truth or falsity. This is referred to as a Boolean result; that is the result is either True or False, and never anything else. Thus, we can think of a logical statement being evaluated as follows:

	If all premises are true, then the conclusion must also be true.
Consider the statement:
	If it is raining, then the ground will be wet.
Thus, we can evaluate whether or not it is raining, and form our conclusion about the ground based upon the truth of the premise (i.e. is it raining). See additional details regarding logic here. ([Koehler])

Back then to our topic of If statements, a simple VB If statement looks as follows:

	If condition Then
	    statement
	    [statement(s)]
	End If
where the condition must evaluate to a Boolean result. The code between the Then and the End If is referred to as the body of the If statement. A simple If-Then statement must adhere to the following rules:

Failure to follow these rules will result in the generation of syntax errors.

1 I am fibbing a tiny bit here; actually you may have zero or more statements in the body of an If-Then statement, but an empty body would be silly (although syntatically correct).


Relational Operators

Looking more closely at If statments, we can focus our attention upon the condition mentioned above. The condition usually results from a comparison of two values; however, in actuality it can be any expression that evaluates to a Boolean value (i.e. True or False). To evaluate an expression, we need operators which allow us to perform some comparison. These operators are referred to as the relational operators. Similar to arithmetic operators (recall), relational operators determine or evaluate the relationship between two operands. The relational operators are listed in the table below:

Operator NameSymbol
equality=
inequality<>
less than<
less than or equal to<=
greater than>
greater than or equal to>=

Because all relational operators compare relationships, all are binary operators (i.e. compare two operands). The result from any relational comparison operator is always a Boolean result. For example,

RelationshipResult
6 = 9False
6 <> 9True
6 <= 9True
6 > 9False
9 >= 9True
"a" = "b"False
"Fred" = "fred"False
"Fred" <> "fred"True
"Fred" = ""False

In the first example, the relational equality operator1 compares an Integer value of 6 with an Integer value of 9, and returns a False result. Why? Because the value of 6 is not equal to a value of 9, so the relationship is False. In the 2nd example, 6 is not equal to 9, so the operator returns a resulting value of True. Note in the last several examples, we are comparing String type values. For example, a String value of "a" is compared with a String value of "b", and since the Strings are not equal, a value of False is returned. We also compare a String value of "Fred" with a string containing "fred", and since an uppercase "F" is not equal to a lowercase "f", this comparison returns True. Note that the two operands must be of comparable types. For example, if we try the following comparison, an error will occur:

	2 = "a"
since 2 is an Integer and "a" is a String.


One must be very careful when attempting to compare two operands of Single, Double or Decimal types. For example, consider the following:
	dblValue1 = 0.3333333

        dblValue2 = 1.0 / 3.0

	If (dblValue1 = dblValue2) Then
		
This will always evaluate to False, because dblValue1 has seven digits following the decimal point and dblValue2 has more. The not so trivial remedy for this is to use a "tolerance value". Another way to state this is how close can the numbers be to each other for them to be considered equal. This can accomplished as follows:
	If ((Math.Abs(dblValue1 - dblValue2) < 0.000001) Then
		
This example computes the ablsolute value between the two operands, then determines if the result is less than some tolerance value. If the result is less than the tolerance, the numbers are deemed to be close enough to be considered equal. The difficulty herein is determining what is a valid tolerance value. That will depend upon the individual implementation being developed.

Relating our discussion back to the If statement, we combine the relational operators with the If statement to make relational decisions in code. For example, if we wish to query a persons age to determine if they are old enough to vote (i.e. at least 18), the If-Then statement would look as follows:

	If intAge >= 18 Then
	    txtOutput.Text = "Congratulations, you can vote!"
	End If
Make sure you understand the logic in the above conditional; that is if the person's age is 18 or greater, this statement will evaluate to True. Consider if the statement was written as follows:
	If intAge > 18 Then
this would result in only persons 19 and older yielding a True result, a serious error in logic! Errors such as the above are referred to as "off by 1" errors. These happen around either end of a range of values (the range boundaries). While these errors only involve a quantity of one (potentially at either end of the boundary), they can be particularly nasty and extremely difficult to find. This is one reason valid relational operators are paramount.

Note the intial logical statement could also be written correctly as:

	If intAge > 17 Then
Even thought this is valid, it tends to be a bit confusing, since it is not obvious where the value 17 came from. The easiest expression to understand is the first one above, intAge >= 18. Note that some folks, myself included, use parentheses in If statements for readiblity (or from habit), as follows:
	If (intAge > 18) Then
VB does not care, so whatever works the best for you.

1 Recall that the assignment operator also uses the equal sign (=). What is going on here, you ask? The assignment operator as well as the relational equality operator both use the equal sign; the context of the operation determines which operation. Again this is an example of operator overloading, that is one operator having more than one meaning based upon context.


More With If

There are more sophisticated If constructs that allow more than one decision, based upon the evaluation of the condition. One such construct is an If-Then-Else statement, which is a two-way branching statement. One grouping of code is processed if the condition evaluates to True (the Then portion), whereas another grouping of code is processed if the condition evaluates to False (the Else portion). This is graphically represented in the following diagram:


In Visual Basic, the general syntax of an If-Then-Else is:

	If condition Then
	    statement			' do if condition is True
	    [statement(s)]
	Else
	    statement			' do if condition is False
	    [statement(s)]
	End If

As mentioned, the statement(s) in the Then body is executed if the condition evaluates to True, and the statement(s) in the Else body are executed if the condition evaluates to False. Expanding the example above to include an Else clause would look something like:
	If intAge >= 18 Then
	    txtOutput.Text = "Congratulations, you can vote!"
	Else
	    txtOutput.Text = "Sorry, you must be 18 years old!"
	End If
In the above example, the "Congratulations" statement would be executed if the value of intAge was greater than 17 (i.e. greater than or equal to 18), and the "Sorry" statement would be executed otherwise. An If-Then-Else statement must adhere to the following rules:

Another If construct is an If-Then-ElseIf statement, which is a multi-way branching statement. This statement provides the capability to examine multiple conditions, one after another, and execute the code body from the first condition that results in a True statement. In general, the syntax is:

	If condition1 Then
	    statement			' do if condition1 is True
	    [statement(s)]
	ElseIf condition2 Then
	    statement			' do if condition2 is True and condition1 False
	    [statement(s)]
		
	ElseIf conditionn Then
	    statement			' do if conditionn is True and all above False
	    [statement(s)]
	[Else
	    statement			' do if everything above is False - Optional
	    [statement(s)]]
	End If
In this structure, first condition1 is evaluated; if it evaluates to a True value, the body for condition1 is executed and the structure is exited. If condition1 returns False, condition2 is evaluated; if it evaluates to a True value, the body condition2 is executed and the structure is exited. This continues until a condition returns True, or all conditions are False. If all conditions return False, an optional Else may be used. If used, this is called the default condition, since it will be executed if all other conditions fail. An example of the need for an If-Then-ElseIf structure is the case where an object may hold several values, and one needs to set a variable based upon one or more values. Consider the following example:
	strState = txtState.Text
	If strState = "OH" Then		' set tax rate for Ohio
	    decTaxRate = 0.065D			
	ElseIf strState = "KY" Then	' set tax rate for Kentucky
	    decTaxRate = 0.06D			
	ElseIf strState = "IN" Then	' set tax rate for Indiana
	    decTaxRate = 0.625D						
	Else				' bogus state entered, report error
	    MessageBox.Show ("You must enter a state code of OH, KY or IN", "Error")
	End If
An If-Then-ElseIf statement must adhere to the following rules:

Still another If construct is a nested-If statement, that is one If enclosed within another. Looking at one simple nested If:

	If condition Then
	    
	   If condition2 Then
	       statement
	       [statement(s)]
	   End If

	End If
Here we have one simple If statement nested inside another simple If statement. Note there must be two Then statements, and two End If statements. There is no limit to how deep and complicated one can create nested If statements. Having stated that, here is a general guideline:

If it looks really ugly, it is probably a poor design!

By ugly, we mean overly complicated code, with lots of nestings, and lots of If-End If statements, etc. The only exception to this rule is if the problem is truly a complicated problem, it may have a complicated solution. Most students will not encounter these types of problems in an introductory course. By spending time on good problem analysis and design, you will save yourself countless hours (and headaches) trying to fix broken conditional statements.


Logical Operators

Logical operators, as with arithmetic and relational operators, perform operations. Logical operators evaluate Boolean expressions and return a Boolean result based upon their evaluation. While there are several logical operators, the three most commonly used are listed in the table below (by precedence, highest to lowest):

Operator NameVB KeywordPrecedence
notNotH
andAndM
orOrL

The And logical operator evaluates two Boolean operands (thus a binary operator), and returns a True if and only if both operands have True values. If any part of an And is False, the entire statement is False, always! This is true for two operands or two hundred operands when using And; if any operand in the entire expression evaluates to False, the entire logical expression is False.

The Or operator, as with And also evaluates two Boolean operands (thus also a binary operator). However, Or returns a True if and only if either operand (one, or the other, or both) has a True value. Or only returns a False result if ALL operands in the expression are False; if any part of an Or is True, the entire expression is True.

The Not operator however, is a bit different. The Not operator only operates on one operand, thus it's a unary operator. Not is similar to the arithmetic negation operator. If the single operand is True, Not toggles its value to False; if the value of the operand is False, Not toggles it to True.

As mentioned, the three logical operators in the table above are listed in their order of precedence, from highest to lowest. Remember, if in doubt about precedence, always use parentheses. Looking at some examples:

ExpressionResult
(2 = 9) And (4 <= 9)False
(2 = 9) Or (4 <= 9)True
2 <> 9 Or 4 <= 9True
Not (2 = 9)True

In the first example, (2 = 9) is a False expression, while (4 <= 9) evaluates to True; thus with an And, if any result is False, the entire expression is False. In the second example, (2 = 9) is again a False expression, while (4 <= 9) is again a True expression; thus with an Or, if any result is True, the entire expression is True. The third example shows two True expressions, so a True result. And in the fourth example, (2 = 9) is still False, but the Not results in the opposite of False, which is True. Note the above expression with the Not is logically equivalent to (2 <> 9), which is perhaps easier to read and understand. See additional details regarding logic here. ([Koehler])

When using Boolean data types in If statements, there are two syntactical techniques which can be used. One technique is to use the relational equality operator (=) with an explicit expected value specified; the second technique is to use implicit expected values without using the equality operator. Assuming we have a Boolean variable declared named blnDone, we can observe the two techniques below:

	If blnDone = True Then				If blnDone Then
								
	End If						End If
The example on the left explicitly tests for equality to True, where the example on the right implies a value of True. Note these two techiniques are logically equivalent. The techinque you should choose is the one that makes the best logical sense to you. Similar techniques can be employed for the logical opposite of the example above:
	If blnDone = False Then				If Not blnDone Then
								
	End If						End If

A VB code example which combines relational and logical operators might look like:

	If (intAge >= 18) And (strStResidence = "OH") And (blnVotedYet = False) Then
	    txtOutput.Text = "Congratulations, you can vote in Ohio!"
	Else
	    txtOutput.Text = "Sorry, you must be 18, an Ohio resident and may only vote once!"
	End If

More advanced logical operators and techniques are addressed here.



Next Section: Data Validation Table of Contents


©2007, Mark A. Thomas. All Rights Reserved.