Conditional Expressions
The other two structures, selection and repetition, involve conditional expressions. Conditional expressions evaluate to being either true or false, and are important in programming because they can be used to signal the computer to take one action (or set of actions) if the condition is true and another set of actions if the condition is false. With selection, a set of actions is taken if a condition is true; an alternative set of actions is taken if the condition is false; with repetition, a set of actions is repeated as long as a certain condition prevails.
Conditional expressions in VB statements must be preceded by certain keywords, such as If or Do While. The conditional expression itself is formed as follows:
<expression> <relational operator> <expression>
The expression on either side of the relational operator can be a constant (string or numeric), variable (string or numeric), or an expression using symbols like +, -, etc.
The relational operator can be one of six symbols (or pair of symbols):
Relational Operator Meaning
< less than
> greater than
= equal to
<> not equal to (same as ¹ in algebra)
>= greater than or equal to (same as ³ in algebra)
<= less than or equal to (same as £ in algebra)
The expressions on either side of the relational operator should be "compatible" - that is, you should only compare a numeric item to a numeric item or a string item to a string item. (As with assignment statements, if Option Strict is off, VB will perform "implicit conversion" if you compare two data items of different types; if the conversion cannot be performed, an "invalid cast exception" error will occur. If Option Strict is on, VB will not attempt to compare items of different types and will instead generate a compiler error.)
Following are some examples of conditional expressions involving the numeric variables intI and intJ. Assume intI contains the value 5 and intJ contains the value 10:
What is being compared |
Conditional Expression |
True or False? |
variable vs. constant |
intI = 5 |
True |
variable vs. constant |
intI >= 5 |
True |
variable vs. constant |
intI <> 5 |
False |
expression vs. variable |
(intI + 5) >= intJ |
True |
variable vs. variable |
intJ > intI |
True |
expression vs. expression |
intJ * 2 < intI + 4 |
False |
constant vs. variable |
20 > intJ |
True |
When the conditional expression involves a character string compare, you can think of the relational operators as performing a comparison based on "alphabetical order". For example, the expression "A" < "D" is true, because "A" precedes "D" alphabetically. Likewise, the expression "Z" > "Q" is true, because "Z" follows "Q" alphabetically.
Following are some examples of conditional expressions involving the string variables strA and strB. Assume strA contains "MARY" and strB contains "JOE":
What is being compared |
Conditional Expression |
True or False? |
variable vs. constant |
strA > "BILL" |
True |
variable vs. constant |
strA > "XYZ" |
False |
variable vs. variable |
strB < strA |
True |
constant vs. variable |
"ABC" > strB |
False |
Technically, when character string data is compared, each character is compared one by one from left to right until the computer can determine whether the first string is less than, equal to, or greater than the second string. The determination is based on the ASCII value of each character.
If you look at a chart of the ASCII characters, you should see that, generally speaking:
special characters < digits < uppercase letters < lowercase letters
Bear in mind that when digits are used in character string comparisons, the comparison is based on the digits' ASCII value. Consider these two examples:
Type of Comparison |
Conditional Expression |
True or False? |
numeric |
3 > 107 |
False |
character string |
"3" > "107" |
True |
Using And, Or, and Not
You can have two or more individual conditions in a conditional expression if you join those conditions with the keywords And or Or. The rules for multi-condition conditional expressions are as follows:
(1) ALL conditions joined by the keyword And must be TRUE in order for the entire conditional expression to be considered TRUE - otherwise, the expression will be evaluated as FALSE.
(2) If ANY of the conditions joined by the keyword Or are TRUE, the entire conditional expression will be considered TRUE - only if ALL the conditions joined by ORs are FALSE will the entire conditional expression be considered FALSE.
(3) If you mix Ands and Ors in the same conditional expression, And has precedence over Or.
(4) The And/Or precedence can be overridden with parentheses.
Examples follow. Assume the following variables contain the indicated values:
A = 4 B = 6 C = 10 D = 3 E = 2 F = 5 G = 4
Conditional Expression |
True or False? |
C > B And B > A And A >= G |
True |
C > B And D > C And A >= G |
False |
F = G Or B = G Or A = G |
True |
F = G Or B = G Or D = G |
False |
A <> B Or C = D And F < G |
True |
(A <> B Or C = D) And F < G |
False |
The truth-value of any condition can be negated by placing the keyword Not in front of the conditional expression. For example, if the condition A > B is true, then the condition Not A > B is false.
The keywords And, Or, and Not are called logical operators.
Introducing AndAlso and OrElse
With And and Or, the system will evaluate all of the conditions within the conditional expression, even if the result is clear before all of the conditions are evaluated. For example (still using the variable values above), in the conditional expression
C > B And D > C And A >= G
it is clear that when “D > C” is evaluated, the result of the entire expression will be deemed to be False – but the system will still continue to evaluate “A >= G”.
Similarly, in the conditional expression
A = G Or F = G Or B = G
it is clear that as soon as “A = G” is evaluated, the result of the entire expression will be deemed to be True – but the system will still continue to evaluate “F = G” and “B = G”.
VB.NET introduces two new logical operators which address this inefficiency – AndAlso and OrElse. These operators work similar to And and Or, however, they apply a technique called short-circuiting - they stop evaluation of conditions as soon as the result is clear. Obviously, short-circuiting increases the performance of the application.
We know that for And to return true, all conditions must be true. AndAlso stops evaluating further the moment it encounters a false condition and returns False. So a more efficient alternative to the "And" example above would be:
C > B AndAlso D > C AndAlso A >= G
We also know that for Or to return true, any one condition must be true. OrElse stops evaluating further the moment it encounters a true condition and returns True. So a more efficient alternative to the "Or" example above would be:
A = G OrElse F = G OrElse B = G
(Note: In most other computer languages, short-circuiting of the "and" and "or" operators is standard behavior. The main exception was pre-.NET (classic) Visual Basic. However, rather than change the behavior of the "And" and "Or'" oeprators when .NET came along, MS decided to leave those as is and introduce "AndAlso" and "OrElse".)
Extra Topic:
When regular relational operators (like >, <, =) won't do, you can use the Like operator to compare a string against a specified pattern. The Like operator is similar to the LIKE operator found in the SQL of most DBMS products (although the syntax differs somewhat).
An expression using Like has this format:
string Like pattern
where string is any string expression and pattern is any string expression conforming to the pattern-matching conventions described below.
A Like expression can be used anywhere a conditional expression can be used, such as in an If statement or Do While statement:
If string Like pattern Then . . .
Do While string Like pattern
A Like expression (or any conditional expression) can also be assigned to a Boolean variable to yield a True or False value:
BooleanVariable = string Like pattern
If string matches pattern, the result is True; if there is no match, the result is False.
Built-in pattern matching provides a versatile tool for string comparisons. The pattern-matching features allow you to use wildcard characters, character lists, or character ranges, in any combination, to match strings. The following table shows the characters allowed in pattern and what they match:
Characters in pattern |
Matches in string |
? |
Any single character. |
* |
Zero or more characters. |
# |
Any single digit (0–9). |
[charlist] |
Any single character in charlist. |
[!charlist] |
Any single character not in charlist. |
A group of one or more characters (charlist) enclosed in brackets ([ ]) can be used to match any single character in string and can include almost any character code, including digits.
Note: To match the special characters left bracket ([), question mark (?), number sign (#), and asterisk (*), enclose them in brackets. The right bracket (]) can't be used within a group to match itself, but it can be used outside a group as an individual character.
By using a hyphen (–) to separate the upper and lower bounds of the range, charlist can specify a range of characters. For example, [A-Z] results in a match if the corresponding character position in string contains any uppercase letters in the range A–Z. Multiple ranges are included within the brackets without delimiters.
Other important rules for pattern matching include the following:
·
An exclamation point (!)
at the beginning of charlist means that a match is made if any character
except the characters in charlist is found in string. When used
outside brackets, the exclamation point matches itself.
·
A hyphen (–) can appear
either at the beginning (after an exclamation point if one is used) or at the
end of charlist to match itself. In any other location, the hyphen is
used to identify a range of characters.
· When a range of characters is specified, they must appear in ascending sort order (from lowest to highest). [A-Z] is a valid pattern, but [Z-A] is not.
· The character sequence [] is considered a zero-length string ("").
Examples follow:
Like Conditional Expression |
True or False? |
"aBBBa" Like "a*a" |
True (because "aBBBa" fits the pattern "letter a" – any characters – letter a") |
"F" Like "[A-Z]" |
True (because "F" is within the range "A to Z") |
"F" Like "[!A-Z]" |
False (because "F" is "not not" within the range "A to Z") |
"a2a" Like "a#a" |
True (because "a2a" fits the pattern "letter a – any single digit – letter a") |
"aM5b" Like "a[L-P]#[!c-e]" |
True (because "aM5b" fits the pattern "letter a – a letter between L and P – a single digit – a letter not between c and e) |
"BAT123khg" Like "B?T*" |
True (because "BAT123khg" fits the pattern "letter B – any single character – letter T – any characters") |
"CAT123khg" Like "B?T*" |
False (because "CAT123khg" does not fit the pattern "letter B – any single character – letter T – any characters") |
To demonstrate the Like operator using the examples described above, set up another "Try It" Console project, and place the following code in the Main method:
Sub Main()
Dim strTestString As String
strTestString = "aBBBa"
If strTestString Like "a*a" Then
Console.WriteLine("'{0}' matches the pattern 'a*a'.", strTestString)
Else
Console.WriteLine("'{0}' does not match the pattern 'a*a'.", strTestString)
End If
strTestString = "F"
If strTestString Like "[A-Z]" Then
Console.WriteLine("'{0}' matches the pattern '[A-Z]'.", strTestString)
Else
Console.WriteLine("'{0}' does not match the pattern '[A-Z]'.", strTestString)
End If
If strTestString Like "[!A-Z]" Then
Console.WriteLine("'{0}' matches the pattern '[!A-Z]'.", strTestString)
Else
Console.WriteLine("'{0}' does not match the pattern '[!A-Z]'.", strTestString)
End If
strTestString = "a2a"
If strTestString Like "a#a" Then
Console.WriteLine("'{0}' matches the pattern 'a#a'.", strTestString)
Else
Console.WriteLine("'{0}' does not match the pattern 'a#a'.", strTestString)
End If
strTestString = "aM5b"
If strTestString Like "a[L-P]#[!c-e]" Then
Console.WriteLine("'{0}' matches the pattern 'a[L-P]#[!c-e]'.", strTestString)
Else
Console.WriteLine("'{0}' does not match the pattern 'a[L-P]#[!c-e]'.", strTestString)
End If
strTestString = "BAT123khg"
If strTestString Like "B?T*" Then
Console.WriteLine("'{0}' matches the pattern 'B?T*'.", strTestString)
Else
Console.WriteLine("'{0}' does not match the pattern 'B?T*'.", strTestString)
End If
strTestString = "CAT123khg"
If strTestString Like "B?T*" Then
Console.WriteLine("'{0}' matches the pattern 'B?T*'.", strTestString)
Else
Console.WriteLine("'{0}' does not match the pattern 'B?T*'.", strTestString)
End If
Console.WriteLine("")
Console.WriteLine("(Press Enter to close this window.)")
Console.ReadLine()
End Sub
When you run the project, it will show the following output:
Download the VB.NET project code for the example above here.
Note: While most types of applications will not require the pattern matching power offered by the Like operator, it’s nice to know it's available if it is needed. If you need pattern matching capabilities beyond what is offered by the Like operator, you are encouraged to look into Regular Expressions, which can be used by VB.NET as well as earlier versions of VB. (Regular Expressions are not covered here.)
Now that you are an expert on conditional expressions, let us look at the selection and the repetition control structures.