Chapter 11. Using Variables and Performing Calculations

Variables hold values in memory so a program can manipulate them. Different kinds of variables hold different types of data: numbers, text, pictures, Halo scores, even complex groups of data such as employee records.

In this lesson you learn what variables are and how to use them. You learn how to define variables, put data in them, and use them to perform simple calculations.

WHAT ARE VARIABLES?

Technically speaking, a variable is a named piece of memory that can hold some data of a specific type. For example, a program might allocate 4 bytes of memory to store an integer. You might name this memory "payoffs" so you can easily refer to it in the program's code.

Less technically, you can think of a variable as a named place to put a piece of data. The program's code can use variables to store values and perform calculations. For example, a program might store two values in variables, add the values together, and store the result in a third variable.

DATA TYPES

Every variable has a particular data type that determines the kind of data that it can hold. In general, you cannot place data of one type in a variable of another. For example, if price is a variable that can hold a number in dollars and cents, you cannot put the string "Hello" in it.

If you like, you can think of a variable as an envelope with a name written on the outside that can hold some data, but each type of data requires a differently shaped envelope. Integers need relatively small envelopes, singles (which hold numbers with decimal points) need envelopes that are long and thin, and strings need big fat envelopes.

Sometimes the line between two data types is a bit fuzzy. For example, if a variable should hold a number, you cannot put in the string "ten." The fact that "ten" is a number is obvious to a human but not to a Visual Basic program.

You can't even place a string containing the characters "10" in a variable that holds a number. Though it should be obvious to just about anyone that "10" is a number, Visual Basic just knows it's a string containing the two characters 1 and 0; it doesn't try to determine that the characters in the string represent a number.

Programs often need to convert a value from one data type to another (particularly switching between strings and numbers), so Visual Basic provides an assortment of data conversion functions to do just that. The section "Type Conversions" later in this lesson describes these functions.

Table 11-1 summarizes Visual Basic's built-in data types. The signed types can store values that are positive or negative, whereas the unsigned types can hold only positive values.

Table 11.1. TABLE 11-1

DATA TYPE

MEANING

RANGE

Byte

Byte

0 to 255

SByte

Signed byte

−128 to 127

Short

Small signed integer

−32,768 to 32,767

UShort

Unsigned short

0 to 65,535

Integer

Integer

−2,147,483,648 to 2,147,483,647

UInteger

Unsigned integer

0 to 4,294,967,295

Long

Long integer

−9,223,372,036,854,775,808 to 9,223,372,036,854,775,807

ULong

Unsigned long

0 to 18,446,744,073,709,551,615

Single

Single-precision floating point

Roughly −3.4e38 to 3.4e38

Double

Double-precision floating point

Roughly −1.8e308 to 1.8e308

Decimal

Higher precision and smaller range than floating-point types

See the following section, "Single, Double, and Decimal Data Types."

Char

Character

A single Unicode character. (Unicode characters use 16 bits to hold data for text in scripts such as Arabic, Cyrillic, Greek, and Thai.)

String

Text

A string of Unicode characters

Boolean

Boolean

Can be True or False

Object

An object

Can point to almost anything

Some of these data types are a bit confusing but the most common data types (Integer, Long, Single, Double, and String) are fairly straightforward, and they are the focus of most of this lesson. Before moving on to further details, however, it's worth spending a little time comparing the Single, Double, and Decimal data types.

Single, Double, and Decimal Data Types

The computer represents values of every type in binary using bits and bytes, so some values don't fit perfectly in a particular data type. In particular, real numbers such as 1/7 don't have exact binary representations, so the Single, Double, and Decimal data types often introduce slight rounding errors.

For example, a Single represents 1/7 as approximately 0.142857149. Usually the fact that this is not exactly 1/7 isn't a problem, but once in a while if you compare two Single values to determine whether they are exactly equal, rounding errors make them appear to be different even though they should be the same.

The Decimal data type helps reduce this problem for decimal values such as 1.5 (but not non-decimal real values such as 1/7) by storing an exact representation of the decimal value. Instead of storing a value as a binary number the way Single and Double do, Decimal stores the number's digits and its exponent separately as integral data types with no rounding. That lets it hold 28 or 29 significant digits (depending on the exact value) for numbers between roughly −7.9e28 and 7.9e28.

Note that rounding errors can still occur when you combine Decimal values. For example, if you add 1×1028 plus 1×10−28, the result would have more than the 28 or 29 significant digits that a Decimal can provide so it rounds off to 1×1028.

The moral of the story is that you should always use the Decimal data type for values when you need great accuracy and the values won't get truly enormous. In particular, you should always use Decimal for currency values. Unless you're Bill Gates' much richer uncle, you'll never get close to the largest value a Decimal can represent, and the extra precision can prevent rounding errors during some fairly complex calculations.

Note

Another interesting feature of the Decimal type is that, due to the way it stores its significant digits, it remembers zeros on the right. For example, if you add the values 1.35 and 1.65 as Singles, you get the value 3. In contrast, if you add the same values as Decimals, you get 3.00. The Decimal result remembers that you were working with two digits to the right of the decimal point so it stores the result that way, too.

DECLARING VARIABLES

To declare a variable in Visual Basic code, use the Dim keyword, followed by the name that you want to give the variable, the As keyword, and the data type. For example, the following code creates a variable named numMistakes. The variable's data type is Integer, so it can hold an integer between −2,147,483,648 and 2,147,483,647.

Dim numMistakes As Integer

After you declare the variable, you can use the equals symbol to assign a value to a variable. For example, the following code sets numMistakes to 1337:

numMistakes = 1337

As an added convenience, you can declare a variable and give it a value at the same time:

Dim numMistakes As Integer = 1337

You can declare several variables of the same type all at once by separating them with commas as in the following code:

Dim x, y, z As Single

LITERAL VALUES

A literal value is a piece of data stuck right in the code. For example, in the following statement, numMistakes is a variable and 1337 is a literal integer value:

Dim numMistakes As Integer = 1337

Usually Visual Basic is pretty smart about using the correct data types for literal values. For example, in the preceding statement Visual Basic knows that numMistakes is an integer and 1337 is an integer, so it can safely put an integer value in an integer variable.

You should use double quotes to surround or delimit Strings and Chars, as in the following code:

Dim firstName As String = "William"
Dim lastName As String = "Gates"
Dim middleInitial As Char = "H"

You should use number signs (#) to delimit dates and times, as shown here:

Dim birthday As Date = #8/20/2011#
Dim partyTime As DateTime = #5:30:00 PM#

Note

You must use American formats in date and time literals in your code even if your system uses other settings such as the day/month/year date format. Visual Basic code understands only these formats.

TYPE CONVERSIONS

As I mentioned earlier, you can think of a variable as an envelope of a certain size that can only hold one kind of data. For example, you can't put a string value in an Integer variable.

However, programs often do need to store one kind of value in a different kind of variable. For example, suppose a user wants to buy five rare Pokémon cards for $1.50 each. Before it can calculate the total cost, the program needs to get the values 5 and 1.50 into numeric variables such as Integers or Decimals.

Other times a program may have a value stored in a variable of one type, such as Integer, and need to copy it into a variable of another type, such as Double.

In these cases, the program must perform a type conversion to convert a value from one data type to another. Your program can use one of two basic types of conversion: implicit or explicit.

Implicit Type Conversions

In an implicit type conversion, Visual Basic converts a value from one type to another automatically, often without you even being aware of it.

Visual Basic will convert any data from one type to another if it understands how to make such a conversion. For example, if you assign a Single variable equal to an Integer value, Visual Basic will very happily convert the Integer into a Single.

In fact, any valid Integer value will fit without any loss of precision in a Single variable so this is even a safe type conversion.

Returning to the earlier analogy of data types as envelopes, you might imagine Integer as a thin envelope because it holds a relatively small range of values. In contrast, Single can hold a much bigger range of values so it is a wider envelope. Keeping this analogy in mind, converting an Integer into a Single is called a widening conversion because you are going from a relatively thin data type to a wider one.

In contrast, suppose you need to convert a Single value into an Integer. This is called a narrowing conversion because you are going from a "wider" data type to a "narrower" one. In this case, some precision may be lost. For example, if you store the Single value 1.23 in an Integer, you get the result 1.

Visual Basic is quite creative at both widening and narrowing implicit conversions and will perform them automatically if necessary. For example, all of the following conversions are legal in a Visual Basic program:

Dim i As Integer
Dim s As Single

' Copy the Integer value 123 into a Single.
i = 123
s = i

' Copy the Single value 1.23 into an Integer (giving 1).
s = 1.23
i = s

' Copying strings holding numbers into numeric variables.
i = "321"
s = "3.21"

' Set a Boolean from a string.
Dim ready As Boolean = "True"

There are limits to what Visual Basic can do, however. For example, it can convert the string values True and False into the Boolean data type but it doesn't understand Yes, No, Sure, Negatory, or any other string value.

For simple programs, implicit conversions are typically fine and they do the right thing, but it's not always obvious where they occur and that can sometimes lead to problems.

For example, suppose a program contains the following statement:

total = subtotal

This may look like a perfectly safe statement but suppose total is an Integer and subtotal is a Long. In that case, this is a narrowing conversion because not all Long values can fit in an Integer, so the program may sometimes crash. To make matters worse, many Long values do fit so you may not notice the problem until specific inputs make the value really large. For example, if subtotal is the number of items in a customer's order, then it will probably fit in an Integer; but, if it represents the total population of the world, then it won't fit in an Integer.

For an even trickier example, suppose the user enters a purchase quantity in a TextBox. If the user enters a number such as "10," then the following code works:

Dim quantity As Integer = txtQuantity.Text

However, if the user enters "ten," the program crashes with the error message "Conversion from string "ten" to type 'Integer' is not valid."

Possibly even more troubling, if the user enters the value 12.34, the program does not crash! Instead, it silently converts the string into the Double value 12.34 and then converts that into an Integer. You might prefer to have the program warn you somehow that the user didn't enter an Integer, rather than silently treat it like one.

One way you can minimize these unexpected problems is to prohibit implicit narrowing conversions. Then you can't give an Integer variable a Long value, and you can't save a String value into an Integer.

To prohibit implicit narrowing conversions, add the following line to the very top of a code module:

Option Strict On

Explicit Type Conversions

Prohibiting implicit narrowing conversions prevents some kinds of errors but what if you really need to perform a narrowing conversion? For example, suppose the user enters an order quantity in a TextBox. How do you convert the value into an Integer so you can perform calculations?

The answer is to use an explicit conversion. In an explicit conversion, you use code to convert the value. This works more or less the same way an implicit conversion would work except you are doing it on purpose. By making an explicit conversion, you are acknowledging that you know there's a risk and you are willing to take responsibility.

There are five main ways you can perform an explicit conversion: using Visual Basic conversion functions, using CType, using DirectCast and TryCast, using Convert, and using Parsing.

Using Visual Basic Conversion Functions

Visual Basic provides a set of functions for explicitly converting values into new data types. For example, the following code uses the CDec function to convert the text entered by the user in the txtCost TextBox into a Decimal and then saves it in the variable cost:

Dim cost As Decimal = CDec(txtCost.Text)

Table 11-2 lists Visual Basic's conversion functions.

Table 11.2. TABLE 11-2

FUNCTION

CONVERTS TO

CBool

Boolean

CByte

Byte

CChar

Char

CDate

Date

CDbl

Double

CDec

Decimal

CInt

Integer

CLng

Long

CObj

Object

CShort

Short

CSng

Single

CStr

String

The integer functions round floating-point values off to the nearest integer. For example, CInt(1.7) returns 2.

Another function, Int, truncates floating-point values. For example, Int(1.7) returns 1. Note that the result returned by Int has the same data type as its parameter; so, for example, if you pass Int a Double, it returns a Double. Often you will want to use CInt to convert that result into an Integer.

The Fix function is similar to Int except it truncates towards 0. That means for negative numbers Int decreases the value (Int(-8.5) = −9.0) but Fix increases the value (Fix(-8.5) = −8.0).

Each of these functions causes an error if it cannot convert the value. For example, ("1x3") causes an error because "1x3" is not a valid number.

Visual Basic also includes a special-purpose Val function that converts a value into a Double. If Val cannot convert the value into a Double, it silently returns 0. For example, if you use Val to convert a value typed by the user into a number and the user types "six," then Val ignores the error and returns 0.

This makes Val useful for converting values typed by the user into numbers if 0 is a reasonable default value. If 0 is not a reasonable default value, then your program should use some other method for converting the string into a number, such as parsing, which is described shortly.

Using CType

The CType function takes a value and a data type as parameters and returns the value converted into the data type. For example, the following code converts the text entered by the user in the txtCost TextBox into a Decimal and saves it in the variable cost:

Dim cost As Decimal = CType(txtCost.Text, Decimal)

Like the Visual Basic conversion functions, CType works only if the conversion is possible. For example, if the user types "eleven" in the TextBox, CType will cause an error.

Using DirectCast and TryCast

The DirectCast operator converts an object from one type to another. For example, event handlers have a sender parameter of type Object that holds a reference to the control that raised the event. If you know that the control is actually a Button, you can use DirectCast to convert sender into a variable of type Button as shown in the following code:

Private Sub btnSetColor_Click()
    Dim btn As Button = DirectCast(sender, Button)
    ...
End Sub

This is particularly handy when you want one event handler to catch events raised by multiple controls. After converting sender into a Button, the program can use the Button's properties to decide how to proceed.

The DirectCast operator fails if the object you are trying to convert doesn't have the correct data type. For example, if the preceding event handler were invoked by a PictureBox, then sender would not be a Button so the call to DirectCast would fail.

The TryCast operator attempts to convert an object from one data type to another much as DirectCast does but if there is a problem TryCast returns Nothing instead of throwing an exception. The following code shows the previous event handler rewritten so it doesn't crash if the sender that raised the event isn't a Button.

Private Sub btnSetColor_Click()
    Dim btn As Button = TryCast(sender, Button)
    If btn IsNot Nothing Then
        ...
    End If
    ...
End Sub

This code uses TryCast to convert sender into a Button. It then uses IsNot to see if the result is Nothing. (The IsNot operator is described later in the section "Comparison Operators.") If the result isn't Nothing, the code executes whatever is inside the If Then block.

Using Convert

The Convert class provides methods that convert from one data type to another. For example, the following code converts the text entered by the user in the txtCost TextBox into a Decimal and saves it in the variable cost:

Dim cost As Decimal = Convert.ToDecimal(txtCost.Text)

Note

A method is simply a function or subroutine provided by a class as opposed to in a separate code module. In this case, the Convert class provides these methods.

Table 11-3 lists the Convert class's conversion methods.

Table 11.3. TABLE 11-3

METHOD

CONVERTS TO

ToBoolean

Boolean

ToByte

Byte

ToChar

Char

ToDateTime

DateTime

ToDecimal

Decimal

ToDouble

Double

ToInt16

16-bit integer (Short)

ToInt32

32-bit integer (Integer)

ToInt64

64-bit integer (Long)

ToSByte

SByte

ToSingle

Single

ToString

String

ToUInt16

Unsigned 16-bit integer (UShort)

ToUInt32

Unsigned 32-bit integer (UInteger)

ToUInt64

Unsigned 64-bit integer (ULong)

One drawback to the Convert methods is that they require you to remember how long the integer data types are in bits. For example, you need to use ToInt32 to convert to a 32-bit Integer.

Using Parsing

Trying to find structure and meaning in text is called parsing. All the simple data types (Integer, Double, Decimal) provide a Parse method that converts text into that data type. For example, the Integer data type's Parse method takes a string as a parameter and returns an Integer; at least it does if the string contains an integer value.

For example, the following code parses the text entered by the user in the txtCost TextBox to get a Decimal value and saves it in the variable cost:

Dim cost As Decimal = Decimal.Parse(txtCost.Text)

Like the previous methods, this works only if the text can reasonably be converted into a decimal. If the user types "12,345.67," the parsing works. If the user types "ten" or "1.2.3," the parsing fails.

Note

Unfortunately, Visual Basic's conversion and parsing methods are confused by some formats that you might expect them to understand. For example, they can't handle currency characters, so they fail on strings like "$12.34" and "€54.32."

You can tell the Decimal class's Parse method to allow currency values by passing it a second parameter as shown in the following code:

Dim cost As Decimal =
  Decimal.Parse(txtCost.Text,
  System.Globalization.NumberStyles.Any)

All the parsing methods described so far have one really big problem: if the value they are converting cannot be converted into the desired data type, they cause an error that crashes your program (at least until you read Lesson 21 on handling errors).

One way to avoid this problem is to use TryParse. A data type's TryParse method is a lot like Parse except it returns a Boolean value indicating whether it succeeded. It takes a second parameter to hold the parsed value.

For example, consider the following code:

Dim cost As Decimal
If Decimal.TryParse(txtCost.Text, cost) Then
    ' Perform some calculations...
Else
    MessageBox.Show("Please enter a valid cost.")
End If

The first statement calls TryParse, passing it the value to convert (txtCost.Text) and the variable (cost) that should receive the Decimal value. TryParse attempts to convert the user's text into a Decimal and returns True if it succeeds. The code then uses an If Then Else statement to either process the value or display an error message.

Like Parse, TryParse doesn't automatically understand text with a currency format. To make it allow currency formats, you can add extra parameters as shown in the following code:

Dim cost As Decimal
If Decimal.TryParse(txtCost.Text,
 System.Globalization.NumberStyles.Any, Nothing, cost) Then
    MessageBox.Show("OK")
Else
    MessageBox.Show("Failed")
End If

This syntax is the most cumbersome of the conversion methods described here, but it is also the most robust.

Note

Which of these methods you use to convert between data types is largely a matter of preference. Many developers prefer the Visual Basic conversion functions such as CInt and CDec because they're short and easy to read (once you get used to them). Others prefer CType.

For parsing user-entered values, however, you should generally use TryParse so you can easily detect errors (although I often use Parse in examples because it's easier to read, even if it isn't as robust).

PERFORMING CALCULATIONS

You've already seen several pieces of code that assign a value to a variable. For example, the following code converts the text in the txtSalary TextBox into a Decimal and saves it in the variable salary:

Dim salary As Decimal = Decimal.Parse(txtSalary.Text)

You can also save a value that is the result of a more complex calculation into a variable on the left side of an equals sign. Fortunately, the syntax for these kinds of calculations is usually easy to understand. The following code calculates the value 2736 + 7281 / 3 and saves the result in the variable named result:

Dim result As Double = 2736 + 7281 / 3

The operands (the values used in the expression) can be literal values, values stored in variables, or the results of methods. For example, the following code calculates the sales tax on a purchase's subtotal. It multiplies the tax rate stored in the taxRate variable by the Decimal value stored in the txtSubtotal TextBox and saves the result in the variable salesTax:

salesTax = taxRate * Decimal.Parse(txtSubtotal.Text)

Note that a variable can appear on both sides of the equals sign. In that case, the value on the right is the variable's current value; and after the calculation, the new result is saved back in the same variable.

For example, the following code takes x's current value, doubles it, adds 10, and saves the result back in variable x. If x started with the value 3, then when this statement finishes, x holds the value 16.

x = 2 * x + 10

A variable may appear more than once on the right side of the equals sign but it can appear only once on the left.

The following sections provide some additional details about performing calculations.

Promotion

If an expression uses two different data types, Visual Basic promotes the one with the narrower data type. For example, if you try to divide an Integer by a Single, Visual Basic promotes the Integer to a Single before it performs the division.

Visual Basic also performs this promotion if the operation would lead to a wider data type. For example, if you divide two integers, the result might not be an integer. To allow for fractional results, Visual Basic promotes the values to Doubles before performing the division. The result is a Double so you need to treat it as one. For example, the following code is not allowed (if you have Option Strict turned on) because you cannot save a Double result in an Integer:

Dim result As Integer = 8 / 4

Operator Summary

Visual Basic has many operators for manipulating variables of different data types. The following sections describe the most commonly used operators grouped by operand type (arithmetic, string, logical, and so forth).

Arithmetic Operators

The arithmetic operators perform calculations on numbers. Table 11-4 summarizes these operators. The Example column shows sample results.

Table 11.4. TABLE 11-4

OPERATOR

MEANING

EXAMPLE

^

Exponentiation

3 ^ 2 is 9

+

Addition

3 + 2 is 5

Negation

−3 is −3

Subtraction

3 - 2 is 1

*

Multiplication

3 * 2 is 6

Division (integer)

3 2 is 1

/

Division (floating point)

3.0 / 2.0 is 1.5

Mod

Modulus

3 Mod 2 is 1

Integer division drops any remainder and returns the integer quotient. The modulus operator does the opposite: It drops the quotient and returns the remainder. For example, 17 Mod 5 returns 2 because 17 divided by 5 is 3 with a remainder of 2.

Logical Operators

The logical operators perform calculations on Boolean (True or False) values. They let you combine logical statements to form new ones.

Lesson 18 explains how to use these values to perform tests that let a program take action only under certain circumstances. For example, a program might pay an employee overtime if the employee is paid hourly and works more than 40 hours in a week.

Table 11-5 summarizes these operators.

Table 11.5. TABLE 11-5

OPERATOR

RETURNS TRUE WHEN...

And

Both operands are True

AndAlso

Both operands are True

Or

One or both operands is True

OrElse

One or both operands is True

Xor

One operand is True and the other is False

Not

The single operand is False

The exclusive or operator Xor is perhaps the most confusing. It returns True if one of its operands is True and the other is False. For example, you and Ann will get a single lunch check and pay each other back later if either Ann forgot her money and you brought yours, or Ann remembered her money and you forgot yours. If neither of you forgot your money, you can get separate checks. If you both forgot your money, you're both going hungry today.

singleCheck = annForgotMoney Xor youForgotMoney;

AndAlso and OrElse are called conditional operators or short-circuit operators. They work just like the regular And and Or operators except they don't evaluate their second operand unless necessary. For example, consider the following AndAlso statement:

mustBuyLunch = isLunchTime AndAlso forgotToBringLunch

Suppose it's only 9:00 a.m., so isLunchTime is false. When the program sees this expression, evaluates isLunchTime, and sees the AndAlso operator, it already knows that mustBuyLunch must be false no matter what value follows the AndAlso (in this case forgotToBringLunch), so it doesn't bother to evaluate forgotToBringLunch, which saves a tiny amount of calculation time.

Similarly, consider the following "or" statement:

canAffordLunch = haveEnoughMoney OrElse haveCreditCard

If you have enough money, haveEnoughMoney is True, so the program doesn't need to evaluate haveCreditCard to know that the result canAffordLunch is also True.

Because the conditional AndAlso and OrElse operators are slightly faster, most developers use them when they can instead of And and Or.

Note

There is one case where the conditional operators may cause problems. If the second operand is not a simple value but the returned result from some sort of subroutine call, then if you use a conditional operator, you cannot always know whether the subroutine was called. This might matter if the subroutine has side effects, consequences that last after the subroutine has finished, such as opening a database or creating a file. In that case, you cannot know later whether the database is open or the file is created, so the code might not work properly.

This is seldom a problem, and you can avoid it completely by avoiding side effects.

String Operators

The only string operator Visual Basic provides is &. This operator concatenates (joins) two strings together. For example, suppose the variable username contains the user's name. The following code concatenates the text "Hello " (note the trailing space) with the user's name and displays the result in a message box:

MessageBox.Show("Hello " & username)

Note

Actually the + operator will also concatenate strings but it can make the code hard to read and the results aren't always obvious, for example, if you use + to combine an Integer and a String. Concatenating strings with + is a bad practice.

Lesson 14 explains methods that you can use to manipulate strings: find substrings, replace text, check length, and so forth.

Note

One very non-obvious fact about string operations is that a string concatenation does not really save the results in the same memory used by the variable on the left side of an assignment statement. Instead, it creates a new string holding the result of the calculation and makes the variable refer to that.

For example, consider the following code:

String greeting = txtUserName.Text
greeting = "Hello" + username

This code looks like it saves a user's name in the variable username and then tacks "Hello " onto the front. Actually, the second statement creates an entirely new string that holds "Hello " plus the user's name and then makes greeting refer to the new string.

For most practical applications, the difference is small, and you can ignore it. However, if you're performing many concatenations (perhaps in one of the loops described in Lesson 19), then your program may have performance issues. The StringBuilder class can help address this issue, but it's a bit more advanced so I'm not going to cover it here. See msdn.microsoft.com/library/2839d5h5.aspx for more information.

Comparison Operators

The comparison operators compare two values and return True or False depending on the values' relationship. For example, x < y returns True if x is less than y.

Table 11-6 summarizes these operators.

Table 11.6. TABLE 11-6

OPERATOR

MEANING

EXAMPLE

=

Equals

2 = 3 is False

<>

Not equals

2 <> 3 is True

<

Less than

2 < 3 is True

<=

Less than or equal to

2 <= 3 is True

>

Greater than

2 > 3 is False

>=

Greater than or equal to

2 >= 3 is False

Is

Returns True if two object variables represent the same object

person1 Is person2 is True if these are the same Person object

IsNot

Returns True if two object variables do not represent the same object

person1 IsNot person2 is True if these are different Person objects

The Is and IsNot operators are a bit unusual because they work only on reference variables that refer to objects not on more ordinary data types such as Integers and Doubles.

These operators compare variables to see if they refer to the same object. They don't compare the values in two different objects. For example, suppose you have two Person objects, person1 and person2, that happen to have the same FirstName, LastName, and other property values. Even if their properties are identical, they are two distinct objects so person1 Is person2 would return False.

Assignment Operators

The assignment operators set a variable (or property or whatever) equal to something else. The simplest of these is the = operator, which you have seen several times before. This operator simply assigns whatever value is on the right to the variable on the left.

The other assignment operators, known as compound assignment operators, combine the variable's current value in some way with whatever is on the right. For example, the following code adds 3 to whatever value x currently holds:

x += 3

This has the same effect as the following statement that doesn't use the += operator:

x = x + 3

Table 11-7 summarizes these operators.

Table 11.7. TABLE 11-7

OPERATOR

MEANING

EXAMPLE

MEANS

=

Assign

x = 10

x = 10

+=

Add and assign

x += 10

x = x + 10

-=

Subtract and assign

x -= 10

x = x - 10

*=

Multiply and assign

x *= 10

x = x * 10

=

Integer-point divide and assign

x = 10

x = x 10

/=

Floating-point divide and assign

x /= 10

x = x / 10

&=

Concatenate and assign

x &= "A"

x = x & ″A″

There are no compound assignment operators for Mod or the logical operators.

Bitwise Operators

The bitwise operators enable you to manipulate the individual bits in integer values. For example, the bitwise Or operator combines the bits in two values, so the result has a bit equal to 1 wherever either of the two operands has a bit equal to one.

For example, suppose x and y are the byte values, with bits 10000000 and 00000001. Then x Or y has bits 10000001.

These are fairly advanced operators so I'm not going to do much with them, but Table 11-8 summarizes them. The shift operators are not "bitwise" because they don't compare two operands one bit at a time, but they are bit-manipulation operators so they're included here.

Table 11.8. TABLE 11-8

OPERATOR

MEANING

EXAMPLE

And

Bitwise and

11110000 And 00111100 = 00110000

Or

Bitwise or

11110000 Or 00111100 = 11111100

Xor

Bitwise xor

11110000 Xor 00111100 = 11001100

Not

Bitwise complement

Not 11110000 = 00001111

<<

Left shift

11100111 << 2 = 10011100

>>

Right shift (for signed types)

11100111 >> 2 = 11111001

>>

Right shift (for unsigned types)

11100111 >> 2 = 00111001

If the operand has a signed type (SByte, Integer, Long), then >> makes new bits on the left copies of the value's sign bit (its leftmost bit). If the operand has an unsigned type (Byte, UInteger, ULong), then >> makes new bits 0.

The shift operators also have corresponding compound assignments operators <<= and >>=.

Precedence

Sometimes the order in which you evaluate the operators in an expression changes the result. For example, consider the expression 2 + 3 * 5. If you evaluate the + first, you get 5 * 5, which is 25; but if you evaluate the * first, you get 2 + 15, which is 17.

To prevent any ambiguity, Visual Basic defines operator precedence to determine which operation is evaluated first.

Table 11-9 lists the operators in order of decreasing precedence. In other words, the operators listed at the beginning of the table are applied before those listed later. Operators listed at the same level have the same precedence and are applied left to right in the order in which they appear in the expression.

Table 11.9. TABLE 11-9

CATEGORY

OPERATORS

Exponentiation

^

Unary

+, -

Multiplication and floating-point division

*, /

Integer division

Modulus

Mod

Addition, subtraction, concatenation

+, -, &

Bit shift

<<, >>

Comparison

=, <>, <, <=, >, >=, Is, IsNot

Logical negation

Not

Logical And

And, AndAlso

Logical Or

Or, OrElse

Logical Xor

Xor

The compound assignment operators (+=, *=, ^=, and so forth) always have lowest precedence. The program evaluates the expression on the right, combines it with the original value of the variable on the left, and then saves the result in that variable.

By carefully using the precedence rules, you can always figure out how a program will evaluate an expression, but sometimes the expression can be confusing enough to make figuring out the result difficult. Trying to determine precedence in confusing expressions can be a great party game (the programmer's version of "Pictionary"), but it can make understanding and debugging programs hard.

Fortunately, you can always use parentheses to change the order of evaluation, or to make the default order obvious. For example, consider the following three statements:

x = 2 + 3 * 5
y = 2 + (3 * 5)
z = (2 + 3) * 5

The first statement uses no parentheses so you need to use the precedence table to figure out which operator is applied first. The table shows that * has higher precedence than +, so * is applied first and the result is 2 + 15, which is 17.

The second statement uses parentheses to emphasize the fact that the * operator is evaluated first. The result is unchanged but the code is easier to read.

The third statement uses parentheses to change the order of evaluation. In this case the + operator is evaluated first, so the result is 5 * 5, which is 25.

Note

Parentheses are useful tools for making your code easier to understand and debug. Unless an expression is so simple that it's obvious how it is evaluated, add parentheses to make the result clear.

CONSTANTS

A constant is a lot like a variable except you must assign it a value when you declare it and you cannot change the value later.

Syntactically, a constant's declaration is similar to a variable except it uses the keyword Const instead of Dim.

For example, the following code declares a Decimal constant named taxRate and assigns it the value 0.09D. It then uses the constant in a calculation.

Const taxRate As Decimal = 0.09D

Dim subtotal As Decimal = Decimal.Parse(txtSubtotal.Text)
Dim salesTax As Decimal = taxRate * subtotal
Dim grandTotal As Decimal = subtotal + salesTax

The D character in the code tells Visual Basic that 0.09 is a Decimal value. Without this character, Visual Basic thinks 0.09 is a Double and complains when you try to assign it to a Decimal constant.

Constants work just like literal values so you could replace the constant taxRate with the literal value 0.09D in the preceding calculation. Using a constant makes the code easier to read, however. When you see the value 0.09D, you need to remember or guess that this is a tax rate. In contrast, the meaning of the constant taxRate is obvious.

Not only can it be hard to remember what this kind of "magic number" means, but it can also make changing the value difficult if it appears in many places throughout the program. Suppose the code uses the value 0.09D in several places. If the tax rate goes up, you need to hunt down all of the occurrences of that number and change them. If you miss some of them, you could get very confusing results.

Note that constants can contain calculated values as long as Visual Basic can perform the calculation before the program actually runs. For example, the following code declares a constant that defines the number of centimeters per inch. It then uses that value to define the number of centimeters per foot.

Const cmPerInch As Double = 2.54
Const cmPerFoot As Double = cmPerInch * 12

TRY IT

In this Try It you perform some simple calculations. You take values entered by the user, convert them into numbers, do some multiplication and addition, and display the results.

Note

You can download the code and resources for this Try It from the book's web page at www.wrox.com or www.vb-helper.com/24hourvb.html. You can find them in the Lesson11 folder in the download.

Lesson Requirements

In this lesson:

  • Create the form shown in Figure 11-1.

  • Make the program do the following when the user clicks the Calculate Button:

    • Multiply each item's Quantity value by its Price Each value and display the result in the corresponding Ext. Price textbox.

    • Add up the Ext. Price values and display the result in the Subtotal textbox.

    • Multiply the Subtotal by the Tax Rate and display the result in the Sales Tax textbox.

    • Add the Subtotal, Sales Tax, and Shipping values and display the result in the Grand Total textbox.

FIGURE 11-1

Figure 11.1. FIGURE 11-1

Hints

  • It is often helpful to perform this kind of calculation in three separate phases:

    1. Gather input values from the user and store them in variables.

    2. Perform calculations.

    3. Display results.

  • Use the Decimal data type for all the variables because they represent currency.

  • Lesson 14 has more to say about manipulating and formatting strings, but for this Try It it's helpful to know that all data types provide a ToString method that converts a value into a string. An optional parameter string indicates the format to use. For this Try It, use the format "C" (including the quotes) to indicate a currency format, as in:

    txtGrandTotal.Text = grandTotal.ToString("C")

Step-by-Step

  • Create the form shown in Figure 11-1.

    1. Create the controls. Use NumericUpDown controls for the Quantity values.

    2. Set ReadOnly to True for the TextBoxes that display results (Subtotal, Sales Tax, and Grand Total).

  • Make the program do the following when the user clicks the Calculate button:

    • Multiply each item's Quantity value by its Price Each value and display the result in the corresponding Ext. Price textbox.

    • Add the Ext. Price values and display the result in the Subtotal textbox.

    • Multiply the Subtotal value by the entered Tax Rate and display the result in the Sales Tax textbox.

    • Add the Subtotal, Sales Tax, and Shipping values and display the result in the Grand Total textbox.

    This is easy to do in three steps:

    1. Gather input values from the user and store them in variables. Because they are already numeric, the code doesn't need to parse the values that come from the NumericUpDown control's Value properties. The program does need to parse the values in TextBoxes to convert them into Decimal values. The following code snippet shows how the program can read the Quantity and Price Each values for the first item. Read the other values similarly.

      ' Get input values.
      Dim quantity1 As Decimal = nudQuantity1.Value
      ...
      Dim priceEach1 As Decimal = Decimal.Parse(txtPriceEach1.Text)
      ...
    2. Perform calculations. In this Try It, the calculations are pretty simple. Notice that the code uses a separate variable for each result, instead of trying to add them all at once, to keep the code simple and easy to read:

      ' Calculate results.
      Dim extPrice1 As Decimal = quantity1 * priceEach1
      Dim extPrice2 As Decimal = quantity2 * priceEach2
      Dim extPrice3 As Decimal = quantity3 * priceEach3
      Dim extPrice4 As Decimal = quantity4 * priceEach4
      Dim subtotal As Decimal =
          extPrice1 + extPrice2 + extPrice3 + extPrice4
      Dim salesTax As Decimal = subtotal * taxRate
      Dim grandTotal As Decimal = subtotal + salesTax + shipping
    3. Display results. The program uses "C" to display values in a currency format:

      ' Display results.
      txtExtPrice1.Text = extPrice1.ToString("C")
      txtExtPrice2.Text = extPrice2.ToString("C")
      txtExtPrice3.Text = extPrice3.ToString("C")
      txtExtPrice4.Text = extPrice4.ToString("C")
      txtSubtotal.Text = subtotal.ToString("C")
      txtSalesTax.Text = salesTax.ToString("C")
      txtGrandTotal.Text = grandTotal.ToString("C")

Note

Please select Lesson 11 on the DVD to view the video that accompanies this lesson.

EXERCISES

  1. Make a program similar to the one shown in Figure 11-2. When the user checks or unchecks either of the A or B CheckBoxes, the program should check or uncheck the result CheckBoxes appropriately. For example, if A and B are both checked, the A and B CheckBox should also be checked.

    FIGURE 11-2

    Figure 11.2. FIGURE 11-2

    The last CheckBox is checked at the same time as one of the others. Which one? Does that make sense?

  2. There are many ways for a program to get information about the operating system. The following lists three useful values:

    • Environment.UserName — The current user's name

    • DateTime.Now.ToShortTimeString() — The current time in short format

    • DateTime.Now.ToShortDateString() — The current date in short format

    Make a program that greets the user when it starts by displaying a message box similar to the one shown in Figure 11-3. (Hint: You'll need to concatenate several strings together.)

    FIGURE 11-3

    Figure 11.3. FIGURE 11-3

  3. Make a program to determine whether 12345 * 54321 > 22222 * 33333. In three Labels, display the result of 12345 * 54321, the result of 22222 * 33333, and the Boolean value 12345 * 54321 > 22222 * 33333. The final value should be true or false. (Hint: Use ToString to convert the Boolean result into a string.)

  4. Make a program that converts degrees Celsius to degrees Fahrenheit. It should have two TextBoxes with associated Buttons. When the user enters a value in the Celsius TextBox and clicks its Button, the program converts the value into degrees Fahrenheit and displays the result in the other TextBox. Make the other Button convert from Fahrenheit to Celsius. (Hint: °F = °C * 9 / 5 + 32 and °C = (°F – 32) * 5 / 9.) (What's special about the temperature −40° Celsius?)

  5. Make a money converter that converts between U.S. dollars, British pounds, euros, Japanese yen, Indian rupees, and Swiss francs. Make constants for the following conversion factors (or go online and look up the current exchange rates):

    ' Exchange rates in USD.
    Const eurPerUsd As Decimal = 0.79D
    Const gbpPerUsd As Decimal = 0.64D
    Const jpyPerUsd As Decimal = 84.64D
    Const inrPerUsd As Decimal = 46.82D
    Const chfPerUsd As Decimal = 1.03D

    To make the constants usable by every event handler in the program, place these declarations outside of any event handler.

    Make a TextBox and Button for each currency. When the user clicks the Button, the program should:

    • Get the value in the corresponding TextBox.

    • Convert that value into U.S. dollars.

    • Use the converted value in U.S. dollars to calculate the other currency values.

      Display the results. (Note that these event handlers contain a lot of duplicated code, which is not good programming practice. Lesson 20 explains how you can make a subroutine to perform the duplicated work for the event handlers.)

  6. Make a program similar to the one you made for Exercise 5 but make this one convert between inches, feet, yards, miles, centimeters, meters, and kilometers.

Note

You can find solutions to this lesson's exercises in the Lesson11 folder inside the download available on the book's web site at www.wrox.com or www.vb-helper.com/24hourvb.html.

FIGURE 11-3
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset