If statements test whether a condition is true. Often you will want to test whether two conditions are both true, or only one is True, or neither is True. VB.NET provides a set of logical operators for this, as shown in Table 3-3. This table assumes two variables, x and y, in which x has the value 5, and y the value 7.
Operator |
Given this statement: |
The expressionevaluates to: |
Logic |
---|---|---|---|
And |
x = 3 And y = 7 |
False |
Both must be true to evaluate true. |
Or |
x = 3 Or y = 7 |
True |
Either or both must be true to evaluate true. |
XOr |
X = 5 XOr y = 7 |
False |
True only if one (and only one) statement is true. |
Not |
Not x = 3 |
True |
Expression must be false to evaluate true. |
The And operator tests whether two statements are both true. The first line in Table 3-3 includes an example that illustrates the use of the And operator:
x = 3 And y = 7
The entire expression evaluates false because one side (x = 3) is false. (Remember that x = 5 and y = 7.)
With the Or operator, either or both sides must be true; the expression is false only if both sides are false. So, in the case of the example in Table 3-3:
x = 3 Or y = 7
the entire expression evaluates true because one side (y = 7) is true.
The XOr logical operator (which stands for eXclusive Or) is used to test if one (and only one) of the two statements is correct. Thus, the example from Table 3-3:
x = 5 XOr y = 7
evaluates false because both statements are true. (The XOr statement is false if both statements are true, or if both statements are false; it is true only if one, and only one, statement is true.)
With the Not operator, the statement is true if the expression is false, and vice versa. So, in the accompanying example:
Not x = 3
the entire expression is true because the tested expression (x = 3) is false. (The logic is: "It is true that it is not true that x is equal to 3.")
All of these examples appear in context in Example 3-26.
Option Strict On Imports System Module Module1 Sub Main( ) Dim x As Integer = 5 Dim y As Integer = 7 Dim andValue As Boolean Dim orValue As Boolean Dim xorValue As Boolean Dim notValue As Boolean andValue = x = 3 And y = 7 orValue = x = 3 Or y = 7 xorValue = x = 3 Xor y = 7 notValue = Not x = 3 Console.WriteLine("x = 3 And y = 7. {0}", andValue) Console.WriteLine("x = 3 Or y = 7. {0}", orValue) Console.WriteLine("x = 3 Xor y = 7. {0}", xorValue) Console.WriteLine("Not x = 3. {0}", notValue) End Sub 'Main End Module Output: x = 3 And y = 7. False x = 3 Or y = 7. True x = 3 Xor y = 7. True Not x = 3. True
Consider the following code snippet:
Dim x As Integer = 7 If (x < 8) Or (x > 12) Then
The If statement here is a bit complicated. Everything in the If statement must evaluate true for the If statement to be true. Within the If statement are two expressions (x < 8) and (x > 12) separated by the keyword Or. It turns out that x is less than 8, so it does not matter whether or not x is greater than 12, and there is no logical reason for the compiler to evaluate the second term (i.e., after the Or).
As it stands, however, the second term will be evaluated. You can instruct the compiler not to evaluate the second term if the first term is true, by changing the Or keyword to OrElse:
If (x < 8) OrElse (x > 12) Then
You can prove to yourself that the evaluation was short-circuited by moving the comparisons (less than and greater than) to methods, as shown in Example 3-27.
Option Strict On Imports System Module Module1 Function IsBigger( _ ByVal firstVal As Integer, _ ByVal secondVal As Integer) _ As Boolean If firstVal > secondVal Then Return True Else Return False End If End Function Function IsSmaller( _ ByVal firstVal As Integer, _ ByVal secondVal As Integer) _ As Boolean If firstVal < secondVal Then Return True Else Return False End If End Function Sub Main( ) Dim x As Integer = 7 If IsSmaller(x, 8) OrElse IsBigger(x, 12) Then Console.WriteLine("x < 8 OrElse x > 12") Else Console.WriteLine("Not True that x < 8 OrElse x > 12") End If End Sub 'Main End Module
In Example 3-27 you create two methods, IsBigger and IsSmaller. Each takes two parameters. IsBigger returns true if the first parameter is larger than the second, IsSmaller returns true if the first parameter is smaller than the second.
If you write Example 3-27 in Visual Studio .NET and then put a break point on the If statement in Main( ), you can see the evaluation of the two sides of the OrElse statement. The compiler will step into IsBigger, but will never step into IsSmaller. Since IsBigger returned true, IsSmaller need not be called.
Change the value of x to 15 and you will find that both IsBigger and IsSmaller are invoked. Since IsBigger returns false, the compiler must test IsSmaller to see if it might return true.
You can accomplish short-circuit evaluation for the And keyword by using the keyword AndAlso. If you leave x set to 15, but change the If statement in Main( ) to the following:
If IsSmaller(x, 8) AndAlso IsBigger(x, 12) Then
you will see the compiler step into IsSmaller but never step into IsBigger. Since the IsSmaller method returns false, there is no need to test IsBigger. AndAlso requires that both parts of the statement evaluate true. Once you have the first side evaluate false, there is no need to test the second side.
The compiler must know the order in which to evaluate a series of operators. For example, if you write:
myVariable = 5 + 7 * 3
there are three operators for the compiler to evaluate (=, +, and *).
The compiler could evaluate this equation from left to right, which would:
Assign the value 5 to myVariable.
Add 7 to the 5, resulting in 12.
Multiply the result (12) by 3, giving a final answer of 36.
However, because the assignment is done in step 1, the final value of 36 would then be thrown away. This is clearly not what is intended.
The rules of precedence tell the compiler which operators to evaluate first. As is the case in algebra, multiplication has higher precedence than addition, so 5 + 7 * 3 is equal to 26 rather than 36. Both addition and multiplication have higher precedence than assignment, so the compiler will do the math, and then assign the result (26) to myVariable only after the math is completed. In VB.NET, parentheses are used to change the order of precedence much as they are in algebra. Thus, you can change the result by writing:
myVariable = (5+7) * 3
Grouping the elements of the assignment in this way causes the compiler to add 5+7, multiply the result by 3, and then assign that value (36) to myVariable.
Within a single line of code, operators are evaluated in the following order:
Relational operators are evaluated left to right. Mathematical operators are evaluated in this order:
Exponentiation (^)
Division and multiplication (/, *)
Integer division (\)
Modulus operator (Mod)
Addition and subtraction (+,-)
The logical operators are evaluated in this order:
Not
And
Or
XOr
In some complex equations, you might need to nest parentheses to ensure the proper order of operations. For example, assume I want to know how many seconds my family wastes each morning. It turns out that the adults spend 20 minutes over coffee each morning and 10 minutes reading the newspaper. The children waste 30 minutes dawdling and 10 minutes arguing.
Here's my algorithm:
(((minDrinkingCoffee + minReadingNewspaper) * numAdults) + ((minDawdling + minArguing) * numChildren)) * secondsPerMinute
Although this works, it is hard to read and hard to get right. It's much easier to use interim variables:
wastedByEachAdult = minDrinkingCoffee + minReadingNewspaper wastedByAllAdults = wastedByEachAdult * numAdults wastedByEachKid = minDawdling + minArguing wastedByAllKids = wastedByEachKid * numChildren wastedByFamily = wastedByAllAdults + wastedByAllKids totalSeconds = wastedByFamily * 60
The latter example uses many more interim variables, but it is far easier to read, understand, and (most important) debug. As you step through this program in your debugger, you can see the interim values and make sure they are correct.
A more complete listing is shown in Example 3-28.
Option Strict On Imports System Module Module1 Sub Main( ) Dim minDrinkingCoffee As Integer = 5 Dim minReadingNewspaper As Integer = 10 Dim minArguing As Integer = 15 Dim minDawdling As Integer = 20 Dim numAdults As Integer = 2 Dim numChildren As Integer = 2 Dim wastedByEachAdult As Integer Dim wastedByAllAdults As Integer Dim wastedByEachKid As Integer Dim wastedByAllKids As Integer Dim wastedByFamily As Integer Dim totalSeconds As Integer wastedByEachAdult = minDrinkingCoffee + minReadingNewspaper wastedByAllAdults = wastedByEachAdult * numAdults wastedByEachKid = minDawdling + minArguing wastedByAllKids = wastedByEachKid * numChildren wastedByFamily = wastedByAllAdults + wastedByAllKids totalSeconds = wastedByFamily * 60 Console.WriteLine("Each adult wastes {0} minutes", wastedByEachAdult) Console.WriteLine("Each child wastes {0} mintues", wastedByEachKid) Console.WriteLine("Total minutes wasted by entire family: {0}", _ wastedByFamily) Console.WriteLine("Total wasted seconds: {0}", totalSeconds) End Sub ' End of Main( ) module definition End Module Output: Each adult wastes 15 minutes Each child wasts 35 mintues Total minutes wasted by entire family: 100 Total wasted seconds: 6000
Top |