The following code demonstrates the declaration of a constant and the usage for such a declaration: Const num As Integer = 100 Const lightSpeed As Long = 186355 'lightspeed is always con
Trang 1CastTarget ( Expression )
CastTarget ::=
CBool | CByte | CChar | CDate | CDec | CDbl |
CInt | CLng | CObj | CShort | CSng | CStr
Table 4−15: Classic VB Conversion Functions and Framework Conversion Methods
Here are more examples of code using the cast functions and the conversion methods:
Dim myNumber As Integer = 0
Dim booHoo As Boolean = CBool(myNumber)
Console.WriteLine(booHoo)
"False" is written to the console in the above example (by the way, the default value of Integer is 0).
Depending on your application's target platform, it might be safer to use the Convert class's methods instead
of the classic Visual Basic cast functions (or any other cast functions wrapped for NET usage) Your codewill also be more palatable to other NET languages, like C# On the other hand, there might be a tradeoff in
performance, because the call to one of Convert's methods is not necessarily faster than the classic cast
function
In addition to the Convert class methods listed in Table 4−16 are a number of additional framework
type−handling methods that are also accessible from the Convert class, such as ChangeType and ISDBNull.Working with Variables and Constants
In the average life of an application, it is not uncommon, for example, to find a similar expression to thefollowing in an application:
Private discount As Integer
Private total, amount As Double
'
discount = 10
Working with Variables and Constants
Trang 2amount = 56.85
'Compute the discount percent
total = (amount * discount) / 100
This little "algorithm" computes two types of numbersIntegers and Doubles As you know, an Integer is a data type that represents a whole number, an ordinal.A Double, on the other hand, represents fractions, a double−precision floating−point value, which in this example is holding the value 56.85 But discount and
total have something in common They are both variables.
The variable reserves a place in memory where its value is placed and where it can be accessed by the
processor In the preceding highly scientific example, the variable allocates 4 bytes of memory for the Integer
discount, which may be any number between −2,147,483,648 and 2,147,483,648 and just happens to be 10.
The variables amount and total allocate 8 bytes each for a Double, which can be any number or fractional in
a wide range of possibilities The syntax for variable declaration is as follows:
VariableMemberDeclaration ::=
[ Attributes ] [ VariableModifier+ ] [ Dim ] VariableDeclarators LineTerminator
VariableModifier ::= AccessModifiers | Shadows | Shared | ReadOnly | WithEvents
2, but in order for us to work with them, we have to dress them up in a variety of wrapping paper, with
specific storage spaces and treatment instructions Variable values can change at any time during execution,unless they are explicitly modified as read−only
Constants are like variables and are declared in similar fashion But, as the name implies, their values remain
Working with Variables and Constants
Trang 3constant from the time they are initialized to the time they are removed from memory when the application oralgorithm terminates You do not have to declare constants read−only, which makes your code easier to read.The syntax for constant declaration is as follows:
ConstantMemberDeclaration ::=
[ Attributes ] [ ConstantModifier+ ] Const Identifier [ As TypeName ] =
ConstantExpression LineTerminator
ConstantModifier ::= AccessModifiers | Shadows
Note Both variable and constant fields are private by default (see the section, "Keeping Data
Private")
The following code demonstrates the declaration of a constant and the usage for such a declaration:
Const num As Integer = 100
Const lightSpeed As Long = 186355 'lightspeed is always constant
Dim feb As Integer = 28 'The number of days in February is not always 28
Const September As Integer = 30 'but there should always be 30 in September
Public Sub IncrNum()
num = num + 1 'cannot happen because num is a constant
End Sub
Public Sub FlightTime()
warpTime = warp * lightSpeed
End Sub
The first example may be a bad choice for a constant because the value of num needs to be changed The call
to the method IncrNum trashes the application The second choice, lightSpeed, is an excellent choice for a constant because the speed of light is itself a constant that cannot change Declaring feb as a variable is a good
idea because the number of days in February changes from time to time The number of days in September, onthe other hand, is constantly 30 Constants are read−only values and can be used in place of literal values
A variable is defined in your code with a name, the identifier, the data type it represents, and a value Here's
an example of the minimum declaration of a variable in Visual Basic NET:
Dim myNumber = 1
The preceding line of code will compile and work fine as long as declaration and semantics checking are
turned off, by setting both Option Explicit and Option Strict to Off The reason it compiles is that the compiler can justify, by the initial value of 1, that the variable myNumber refers to an object "an Integer"
with a value of 1 The compiler then keeps its fingers crossed and hopes for the best In this simple case,nothing untoward happens and the code processes fine However, this is not a very safe way of writing code,nor is it practical (see the "Compiler Option Directives" section earlier in this chapter, and the sections on late
binding in Chapters 9 and 14) Switch both compiler options to On and you will notice the errors reported and
that the compiler will continue only with the strongest of objections
The code can be fixed with the following changes:
Dim myNumber As Integer = 1
This line of code adds a slew of characters to the declaration but it now represents a safe and fully declared
Working with Variables and Constants
Trang 4variable called myNumber, which is declared "As" an Integer, the most widely used of the built−in data
types The formal syntax is as follows:
[ Attributes ] [ VariableModifier+ ] [ Dim ] VariableDeclarators LineTerminator
Notice in the middle of the syntax the word Dim Dim is the fundamental keyword for declaring a variable of
a type, assigning it a value, and directing the compiler to allocate storage space for it While Dim can be used
almost everywhere in your code, you must further define the access level and thus "visibility" of the variable,
or anything will be able to target the field dataan undesirable situation Dim, however, is not used to declare
constants, either within a method or anywhere else
Also important to notice in the preceding declaration of myNumber is that the value is immediately assigned.
This is known as dynamic assignment, which will be discussed further shortly This immediate assignment or
initialization, so to speak, is preferred over the longer syntax, which is as follows:
Dim myNumber As Integer
myNumber = 1
In addition, variable access varies according to its declaration space, where it is declared, and the context inwhich it is declared In other words, declaring a variable at the class or module level is very different from
declaring a variable inside a method blockwithin its declaration space Also, the Dim keyword is
automatically removed from class−level variables declared with the access modifiers However, Dim is
required for any declarations inside method blocks
The following access modifiers can be applied to variables of the base data types:
Public Variables declared as Public are visible from everywhere and thus become globally
accessible even outside of the class in which they are declared You cannot declare a Public variable
inside the method declaration space and implementation
•
Protected Variables declared as Protected can only be accessed from within the class in which they
are declared and from derived classes You cannot declare a Protected variable inside the method
declaration space and implementation
•
Friend Variables declared as Friend can be accessed from the outside world but only from other
classes of the assembly, which are classes that make up the application You cannot declare a Friend
variable inside the method declaration space and implementation
Private Variables declared Private are only accessible within their declaration space You cannot
declare a Private variable inside the method declaration space and implementation because the
variable is implicitly private
•
Static Variables declared Static can be used in the implementation of methods and maintain their
values even after the method has been processed Static variables cannot be declared at the class level and cannot take Shared or Shadows as access modifiers.
•
Shared Variables modified with Shared are technically global variables and can thus be accessed
from any class or file You cannot declare a Shared variable inside the method declaration space and
implementation
•
Shadows Variables inherited from a base class can be identically redeclared in the derived class with
the Shadows modifier, which does not affect the accessibility provided in the base declaration In other words, if a base variable is declared Private, it remains Private in the shadowed declaration.
•
Working with Variables and Constants
Trang 5You cannot declare a variable modified with Shadows inside the method declaration space and
implementation
ReadOnly Variables declared as ReadOnly cannot be changed by any local or derived process The
values these variables hold are thus constant However, these variables can be declared with any
access modifier, such as Private, and can be additionally modified with both the Shared and
Shadows facility You cannot declare a ReadOnly variable inside the method declaration space and
Note The use of the keyword Static is rather confusing for variables that survive the termination of the
methods in which they are declared For the most part, the term universally refers to shared global data
and methods, the equivalent of which is Shared in Visual Basic See the discussion of the C#
BitShifters class in Chapter 5 for an example of so−called static methods The words "static" and
"shared" are frequently interchanged in general discussion throughout this book
Constants are similarly declared with access and implementation modifiers The following code declares apublic constant:
Public Const maxWarp As Integer = 9
Variable and Constant Declaration Shorthand
The declarations for both constants and variables can take the dynamic initialization shortcut, as demonstratedearlier for variables Rather than declaring or initializing the variable or constants on the second line, like this:Const hisNumber As Integer
hisNumber = 1
you can immediately assign the value as demonstrated in the following code:
Const hisNumber As Integer = 10
Const herNumber As Integer = 5
Const aCoupleAs Integer = hisNumber / herNumber
You can use any expression that will yield a legal value to be assigned to the variable or constant In the
preceding code, aCouple is assigned a value computed from the product of the two earlier constants The
following code, assigning the result of some fancy function, is also perfectly legal for a variable or constant
declarationand assignment:
Const familyNumber As Integer = Complex(Sqrt(aCouple.AtWork))
Another form of declaration shorthand lets you declarebut not initializemore than one variable (declarator) inthe same expression The following code declares three variables, and each variable is assigned the default of
0 by the CLR:
Dim hisNumber, herNumber, itsNumber As Integer
Both of the following lines of code, however, are not legal:
Variable and Constant Declaration Shorthand
Trang 6Dim hisNumber, herNumber, itsNumber As Integer = 1
Const hisNumber, herNumber, itsNumber As Integer
In the preceding incorrect examples, the first line fails because you are not allowed to assign values to
multiple declarators in the same declaration; each variable declaration must be separately declared and
initialized The second example fails because you are not allowed to declare multiple constants in the samedeclaration expression The correct style for each declaration example is as follows:
Dim hisNumber As Integer = 1, herNumber As Integer = 2, myNumber As
Const hisNumber As Integer = 1, herNumber As Integer = 2, itsNumber As
Default Initialization
The Visual Basic NET compiler can also provide default values for the various value types These values arelisted in Table 4−16 and are assigned if the declarations omit any initial value assignment in the declaration of
a variable or constant
Table 4−16: Default Initialization Values for Value Types
Numbers (Integers, Bytes, Longs, Decimals and so on) 0
String is included here because it is used a lot as a primitive type However, it is not in the strictest sense a
value type but rather an immutable reference type (see Chapter 15)
Null
The Null constant is no longer supported in Visual Basic NET If you need to represent a null value, such as a null database field, use the System.DBNull class and its Value field.
The following code generates a type mismatch error:
Public Shadows Sub ShadowMethod(ByVal myArg As Integer)
myArg = System.DBNull.Value
End Sub
The compiler will tell you that you cannot convert an Integer value to DBNull.
Many Visual Basic functions also no longer return Null, as was the case with CurDir, LCase, LTrim, Left,
Right, and so on In cases where it is possible to receive the DBNull.Value field, like null database records,
you should test null with the IsDBNull function, as follows:
Trang 7second address line in a table, which is often left "blank."
The DBNull class differentiates between a null value (a null object) and an uninitialized value (represented by
DBNull and its Value field, which is a shared public value) When a table contains records with uninitialized
fields, these fields will be assigned the DBNull value (This class is also used in COM−.NET interoperation to distinguish between a VT_NULL variant, which is associated with a null object, and a VT_EMPTY variant, which is associated with the DBNull.Value instance See Chapter 14, which discusses COM adaptation.)
You cannot equate DBNull with anything It is also a singleton class, which means only one instance of this class can exist at any given time in your application That sole instance represents the DBNull.Value.
Data−intensive applications accessing SQL databases must use the System.Data.SqlTypes classes, which
have inherent support for null values
If you need to reference a Null constant and Nothing is not useful to you, you can create your own Null
object as described in the discussion of the Null pattern in Chapter 13
Keeping Data Private
Variables and constants are declared at the class level or scope for two main reasons The first and mostfrequently used reason is to allow the variable or constant fields to be accessed by all members of the class,and composite classes Access to the field is either direct from the class methods or via class properties Thedata is thus global to the class
The second reason a field is scoped to the class level is to allow it to be accessed externally To make it
available or visible to the outside world, the field must be declared Public, Friend, or Protected Friend (Protected Friend makes the field visible to derived classes) An example of such a public field is the
read−only Value field of the System.DBNull class The value lives inside a singleton class and thus the "null"
value is available to anyone that needs it
You may have other reasons to make a class's field public, but you should stick to the practice of keepingfields, and thus the data, private The reason for keeping data fields hidden, and thus off limits, is that it makesyour code easier to maintainmaking it more robust and less prone to errors (which also is a reason why
variable lifetimes should be kept as short as possible)
Note Research has shown that hidden data can improve code robustness by a factor of four Other benefits ofhidden data include security and reentrance
When data fields are kept hidden, only a small number of changes need to be made in the class when the field
is changed Changes to the fields will no doubt affect the methods of the class, but they should only affect themethods of the class that encapsulates them, not any consumers of the class (besides, the less you hard−code
to global fields, the easier your software will be to maintain; see Chapter 7)
If you need to expose values of an object to the consumers of the object, you can do so via properties (seeChapters 7 and 9) The property acts as a "gateway" that conveys data to and from the field and the externalenvironment of the class Properties are methods, so the interface and implementation of the property allowlater improvements without having to change the way a consumer accesses the data
The principle of keeping fields private or hidden is one of the central tenets in both structured and
object−oriented engineering It extends the principle of black box functions in the structured design age In
object−oriented engineering, information hiding is known as encapsulation Encapsulation refers to the
containment and hiding of not only data fields, but all class members, so we will return to the subject again in
Keeping Data Private
Trang 8later chapters, particularly Chapter 7 on methods and Chapter 9 on classes and objects.
Encapsulation makes the classes easy to version because a field and a referencing property cannot be changed
to a property while maintaining binary compatibility The following code example illustrates the correct use of
private or hidden instance fields with Get and Set property accessors:
Public Structure Trajectory
Private xCoord As Integer
Private yCoord As Integer
Public Sub New(ByVal xArg As Integer, ByVal yArg As Integer)
And the above structure can be accessed as follows:
Dim spaceT As New Trajectory()
Public Sub Location(ByVal aArg As Integer, ByVal bArg As Integer)
spaceT.PositionX = aArg
spaceT.PositionY = bArg
End Sub
It is good practice to expose a field to a derived class by using a Protected property that returns the value of
the field This is illustrated in the following code example:
Public Class MyBaseControl
Private visible As Boolean
Protected ReadOnly Property IsVisible() As Boolean
Keeping Data Private
Trang 9Scope
Variables and constants can be written in any block in a class, the class itself, composite classes, or in anymethod When a variable (and that means constants, as well, from here forward unless noted otherwise) isdeclared in the class bodynot within a method bodyit is typically accessible to all other class methods withoutqualification or additional reference We call this unfettered access the "scope" within which a variable can beaccessed Viewed another way, we can say that generally a variable is not accessible outside the scope inwhich it is declared
The scope of a variable can range from the deepest or narrowest level, in a block of code such as an IfThen
block (see Chapter 6) to the widest level in the open declaration space of the outermost class (see Chapter 9)
Variables declared at the class level and modified as Public are "global" variables and this implies public
access to the variable from outside the class, even a considerable distance away "Class variable" is probably abetter choice to describe a so−called "global" variable that is not public However, a variable that is declaredwithin the confines of a method or a block is known as a "local variable." For example, the following blocks
of code encapsulate the variable in the narrowest scopes, methods, and blocks:
So three key variable scopes exist in a NET class: the scope that is defined by a class, the scope defined by a
method, and the scope defined by a nested block of code within a method (such as the IfThen construct
shown in the preceding example) Also, variables declared in composite or inner classes are not accessiblefrom the outer or container classes
Composite class methods can also access the variables but need to qualify the accessthrough inheritance orvariable reference This is demonstrated in the following code as in the following code two "out−of−scope"code segments:
'Example 1
Class Class1
Dim myVar As Integer = 4
Class Class4 : Inherits Class1
Trang 10myVar is redeclared using the Shadows keyword.
The hierarchy of access is from the inner classes to the outer classes In other words, the innermost classmembers have the potential to "see" all the variables of each encapsulating class, but the outer classes cannotsee the variables of the inner classes
If you need to work with a variable from an outer class at the class level of a composite class, then you need to
redeclare the variables in the composite class with the Shadows keyword.
Variable and Constant Lifetimes
The scope of variables and constants, previously discussed, also provides the "lifetime" that the variable hasafter its declaration The variable is created when its scope is entered, and this can happen in several ways.When a class is referenced, its scope is entered and this serves to create the variable For example, in this
code, Dim ClassOf69 As New MyClass serves to begin the lifetime for the variables declared within the
class, at the class level The lifetime ends when the object is disposed of The same lifetime policy applies toboth static classes as well as instances of a classan object's lifetime
Variables local to methods begin their lives when the method is activated or called, and end their lives whenthe method code completes Each time that the method or class is referenced, the variable is reassigned itsdefault or initialization value
Also, while a variable can be declared anywhere in the class or method, the code that uses the method mustproceed the declaration The compiler will pick up the following code as an error that cannot be tolerated:Debug.WriteLine(myValue)
Dim myValue As Integer = 5
Variable and Constant Lifetimes
Trang 11The first line cannot possibly write the value of myValue to the output window because the variable has not
yet been declared It's not difficult to remember this rule; just think of the classic chicken−and−egg or
horse−and−cart clichés In general, all variables and constants at the class level should be declared at the top
of the class, and all variables and constants in methods should be declared at the top of the method, just afterthe signature It is also important to remember that parameter declarations are scoped to the method and thustheir scope is no different to variables or constants declared within the method body (see Chapter 7)
Span
The distance between a declare in a class or a method and the code that references the data is often referred to
as span In the following example, the space between the lastName declare and the line of code that accesses
it is three lines Thus, we can say that the span is three lines.
Dim lastName As String
Dim firstName As String
Dim birthDate As Date
GetName(lastName)
You can compute the average span in a class to test for its readability But why should you be concernedabout span? The short answer is that it makes it easier to construct code and to read the code you construct.Declares that are not used until much later in a method, or class, force you to keep referring back to areashigher up in the unit to refer to the data in the field
Note You can declare variables without providing the initial value, because the compiler will always provide
the default initialization value For example, if you declare an Integer without an initial value, the
compiler will automatically assign it 0
Keeping Lifetimes Short
Keeping lifetimes short also helps to make code less buggy and easier to maintain Variables that are "live"from the moment a class is instantiated to its death introduce more opportunities for bugs The live variablesalso make the code harder to maintain, even if the data is encapsulated in private fields You are forced toconsider all class members and code as possibly misusing a variable, as opposed to localizing the access toone line, a few lines away from where it first declared, or inside the methods that use them (see Chapter 7 formore on method parameter lists, passing arguments and so on)
This is, however, a somewhat controversial subject, because one school of thought says that declaring classvariables and constants is better than having to pass the data though methods like a game of rollerball Ipersonally prefer to keep the class−level variables to a minimum, and instead pass arguments to methodfields The fields are more hidden, more secure, and easier to maintain, and the code is easier to read In short,this keeps the problem of "hard coding" to a minimum
Nevertheless, if data needs to be live for the duration the instance is live, then instance data is perfectlyreasonable However, a good rule is to use read−only fields instead of properties where the value is a globalconstant This pattern is illustrated in the following code example:
Public Structure Int32
Public Const MaxValue As Integer = 2147483647
Public Const MinValue As Integer = −2147483648
End Structure
Variable and Constant Lifetimes
Trang 12Avoid Magic Numbers
Magic numbers are the literal numbers that appear out of nowhere in the middle of your code Here is anexample:
Dim alarm() As Integer = {}
Dim intI As Integer
For intI = 0 To 40
alarm(alarmValue) = 190
Next intI
The number 40 here is a magic number Magic numbers should be avoided for several reasons:
Code is harder to read In the preceding example, it's not immediately apparent why 40 is the limit.
•
Changes are hard to make and can break code more easily In the preceding example, the array
length (40) can't be changed without changing the ForNext loop The value 190 is also a magic
number that can cause errors
•
Code is less reliable Magic numbers like this force you to make changes in every method that relies
on the magic number By using a named constant that all interested items can refer to, you only need
to make the changes in one place The preceding code eliminates the magic number syndrome by
using the UBound function, as follows:
Dim alarm() As Integer = {}
For intI = 0 To UBound(alarm)
We know that Visual Basic is a language with a rich and diverse syntax and that it has very peculiar andunique lexical and idiomatic elements that set it apart from all other languages We also know that VisualBasic, while maintaining syntax and a number of grammatical similarities to its predecessor, has also beenfundamentally changedrewritten in fact from the ground upto allow it to perform as a first class member of the.NET Framework
We investigated the base or fundamental types in this chapter, often referred to as primitive types We
investigated where they derive from, and how they are declared, accessed, and used And we also saw thatthere are some very important differences between the fundamental types of Visual Basic 6 and Visual Basic.NET
The most important observation is perhaps that a Visual Basic class consists of three critical spaces The firstspace is the class declaration space which names the class, declares how it can be accessed, and states whether
it inherits from any other class The second space is the Options space Here we see that you can choose to write code either with loose semantics and syntax or with tight semantics and syntax by toggling the Option
Variable and Constant Lifetimes
Trang 13Strict and Option Explicit directives to the On or Off position The Options space must precede all other
declarations and code The third space is the Namespace declaration space Here we see how namespaces andclasses are referenced such that they can be accessed from within the implementation space of the class.The next three chapters deal more specifically with class implementation Chapter 5 extensively covers theuse of operators; Chapter 6 covers flow and control constructs as well as conditional constructs; and Chapter 7provides the means of accessing the functionality through the construction and provision of the methods ofour classes
Variable and Constant Lifetimes
Trang 14Chapter 5: Visual Basic NET Operators
Overview
Operators are to computer programming what nails, staples, glue, and studs are to carpentry Without thesesmall elements, there would be no way to prevent the various parts of our creations from falling apart This istrue of standard operators: the many languages that exist within and outside of the NET Framework use thesame standard operators even though their symbol usage and data processing may differ
Even if you know your operators, the information in this chapter will be worthwhile to assimilate becauseVisual Basic introduces fresh topics This is also the first chapter that mixes in some C# code for some
interesting language interop possibilities We delve into bit shifting and see examples of how to use the C#
shift operators in VB projects This chapter lays the foundation for many of the algorithms we tackle in laterchapters
Note The word interop stands for interoperation In the context above it relates to the interoperation of C#
code with Visual Basic code, or interop with a Visual Basic application The term is also used to expressthe interoperation of NET (managed) code with unmanaged code such as COM components
What an Operator Does
An operator performs an operation on one or two operands: a unary operator executes an operation on one operand, a binary operator does so on two.
Unary operators use prefix or postfix notation against their operands
If the operator comes before the operand, it is a prefix unary operator, as is demonstrated here:
operator operand
or in code as
+ X
where X is the operand.
If it comes after the operandwhich is an uncommon occurrenceit is a postfix unary operator Here's an
example:
operand operator
or in code as
X++
(The above ++ is the C# NET unary operator for incrementing the operand by 1 The Visaul Basic NET
equivalent is X += 1 or X −= 1, which are unary in "nature" but are considered binary because the operator
increments or decrements the value on the left with the value on the right In this chapter, we will elucidate thesignificant differences between Visual Basic NET and C# NET operators.)
Trang 15A binary operator performs an operation on more than one operand and uses infix notation, because the
operator is positioned between the operands as follows:
operand operator operand
or in code as
X < Y
The ternary conditional operator (?:), which is used in many languages such as C#, J#, and JScript, is
"shorthand" for the IfElse conditional construct discussed in the next chapter (If = ? Else = :) If you ever
plan to use C# or JScript, it helps to know about this operator, which we will exemplify in C# sample code inthis chapter
Operators return the values based on their functions and on the type of operand For instance, if you add two
integers, the + operator returns the result of the integer addition Operators thus evaluate to their results The operator returns the type of value (known as operator resolution) for which it has been defined When
dealing with operands of different types, you need to be sure that the operator is going to return the type youexpect
The default behavior of the operator is as follows: operands that are wider or narrower than the range for
which the operator is defined will be narrowed to the type the operator will return Conversely, operands that are narrower than the type for which the operator has been defined will be widened to the type the operator
will return (see also Chapter 4)
Note An operand can be a single value or an entire expression, which should be enclosed in parenthesis forclarity and to minimize bugs
This chapter will also classify operators into their specific function groups as follows:
Arithmetic Operators Operators that perform arithmetic functions on the operandssuch as +, − ,or *
Concatenation Operators Operators that combine the data of their operands and then return the new
combined valuesuch as + and &
•
Bitwise Operators Operators that perform bitwise (acting on the bits) operations on numbers and
then return the bit result
•
Numbering Systems Reviewed
This section discusses the numbering systems that programmers of all languages use Understanding them iskey not only to coding useful algorithms and solving mathematical problems, but also to writing analysissoftware, working with arrays, and writing sophisticated game programs These systems are also applicable toany software that communicates down to the so−called metal in the world, where only combinations of 1s and0s are recognized currency As you may know, NET makes extensive use of large numbers for securityuniqueness, complex mathematics, and numerical operations
Numbering Systems Reviewed
Trang 16Here are the fundamental numbering systems used in computer programming:
Binary (Base 2) This is the language computers use internally to represent bits Binary means 2 and
the only digits used are 1 and 0 Digit 1 is known as the high−order bit (one less than the base of 2)and 0 is known as the low−order bit
•
Octal (Base 8) This system encompasses digits 0 through 7 (one less than the base of 8).
•
Decimal (Base 10) This familiar numbering system is used for writing integers These are the
standard numbers which use digits 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 (9 is one less than the base of 10)
•
Hexadecimal (Base 16) This system employs the 10 digits of the decimal system plus the letters A
through F
•
The octal and hexadecimal (hex) numbering systems are popular in computer programming because it's easier
to work with their numbers versus binary numbers, which can become very large Today's 32−bit systems arerapidly yielding to 64−bit computers and software (arriving in 2002/2003), which makes it imperative to fullyunderstand the octal and hexadecimal systems, especially the latter one The following table demonstrates thedifferences among the four systems
Trang 17Base 2, or binary position lingo, describes the value of the bits from left to right The number 5 in binary is
101, so we say that a high−order bit is in the right−most position, which is the ones position, the 0 is in the twos position, and the left−most bit of 1 is in the fours position As the number increases, the notation grows
from the right to the left by the power of the base1, 2, 4, 8, 16and so on Increasing or decreasing the number
is known as shifting By shifting the bit 1 left in the ones position to the twos position, we are raising the
number by the power of 2, the base Shifting three positions is the same as raising the number to shift by thepower of 4, such as 2 to the 4th power
The positional values for the octal numbering system increase by its base of 8 So for a number like 350, we
say that the 0 is in the ones, 5 in the eights, and 3 in the sixty−fours position.
Hexadecimal numbers work the same way, but the positional values rise by the power of the base, 161s, 16s,
256 th positions, respectively
The following tables list the positional values in each number system
Binary Number System: Base 2 ( 128, 64, 32, 16, 8, 4, 2, 1)
Converting from One System to Another
Now that you understand the various conventions for positional notation within each numbering system, itwill be easy to convert from one number in a system to another and to perform conversions in your code Let'sfirst see how we convert from the familiar decimal system to binary, octal, and hexadecimal We'll begin byconverting the number 42 from the decimal system
Converting From Decimal to Binary, Octal, and Hexadecimal
In order to convert to binary, first decide which high−positional value shown in the binary positions andpowers chart above is higher than the number 42 Then stop at the smaller positional value In other words,
128 and 64 are bigger than 42, so we would need to stop at 32 Now how many times can 32 go into 42 andwhat's the remainder? Write down the results in the grid as follows:
Converting from One System to Another
Trang 18The same technique works for converting from decimal to octal, as seen here in the octal grid:
The result is that decimal 42 is octal 52
Let's do the same thing now for hex:
The hexadecimal system makes sense for large numbers; however, with the number 42 there could be a slightconfusion The last column leaves us with 10, which is A in the hex system Thus, the hex result is 2A
Converting From Octal and Hexadecimal to Binary
Converting from these systems to binary is straightforward You simply place octal and hex value positions upagainst the binary value positions in a grid For example, octal to binary works by placing the octal right−mostvalue up against the 3−digit binary equivalent like this:
Converting From Binary, Octal, and Hexadecimal to Decimal
When you encounter one of the "alternate" numbers in your code, you'll need to convert the numbers todecimal to present them to users or do math that requires you to work with the decimal system You can easilywrite software that multiplies 2A by 2A, but chances are very slim that 6E4 will mean anything to your user
Converting from One System to Another
Trang 19The formula for converting to decimal is very easy and can be derived manually or in a grid With binaryvalues, simply multiply the binary digit (starting left to right) with its positional value and sum the results Forexample, to arrive back at 42 from 10 1010, perform the following math:
Table 5−1 lists the precedence of operators when evaluating expressions
Table 5−1: Operator Precedence Table (*The ++ or − − Unary Operators are Not Accessible in VB NET)Class of Operator Precedence of the operators in the class
Comparison =, <>, <, >, <=, >=, Like, Is, TypeOfIs
Operator Precedence
Trang 20Miscellaneous Or, OrElse, New, TypeOf
Changing Precedence Order with Parenthesis
You can change the order of operations by enclosing the expression you want to process first betweenparentheses In the preceding example, if we had bracketed the operands around the additive operator, wewould have gotten 12 as the return value:
Now 12 is the output to the Debug window Can you work out why? This complex example
Dim Value As Double
Value = 3 * 10 / 3 ^ 2 + 10 − 11
Debug.Writeline(Value)
writes 2.33333333333333 to the Debug window But this one
Dim Value As Double
Here is a short list of additional rules to remember:
The math or arithmetic operators evaluate first, followed by comparison operators, then by logicaloperators
Trang 21Unary Operators
There are three unary operators supported by Visual Basic: +, −, and Not (Unary Plus, Unary Minus, and
Unary Logical Not, respectively) They are defined as follows:
Unary Plus The value of the operand
•
Unary Minus The value of the operand subtracted from zero
•
Unary Logical Not Performs logical negation on its operand (This operator also performs bitwise
operations on Byte, Short, Integer, and Long [and all enumerated types], which we'll discuss later in
this chapter.)
•
Unary Plus is also the additive operator However, the operator is "overloaded" to perform a concatenation
function if the operands are discovered to be of type string For example, the following code
Dim S As String = "what is "
Debug.WriteLine(S + "this")
writes "what is this" to the Debug window
Tip Use the & symbol for concatenation because it makes code easier
to read
Unary Minus converts a positive number into a negative one For instance, this simple math
x = 3 + −1
Debug.WriteLine(x)
writes 2 to the Debug window However, it's the same thing as 3 minus 1
The Unary Logical Not is different altogether It can change a Boolean result (False becomes True or True becomes False) As mentioned earlier, it can also perform a bitwise comparison on a numeric expression Here are the rules for the Unary Not Boolean expressions:
If the Expression is False, then the Result is True
Normally, the result would be "True" to the debug window, but in the above case truth is Not true The
Boolean condition inside the parentheses (this entire expression is the operand) is reversedin this case True is
made False See Chapter 6 for examples of using the Not operator in conditional statements, especially Null
If conditionals You will also learn about Logical Operators and Bitwise Operators later in this chapter.
Unary Operators
Trang 22Arithmetic Operators
The full complement of arithmetic operators is available to Visual Basic NET Unary Plus and Unary
Minus can also be considered arithmetic operators, as shown in Table 5−2.
Table 5−2: Visual Basic NET Arithmetic Operators
Mod Modulus (division returns only the
remainder; % in J#, C# C++, etc)
Value = Expression Mod Expression
Arithmetic operators are straightforward in their performance; however, there are several delicate situations.When number crunching, it is possible to cause a number of system exceptions, such as an
OverflowExceptionwhen the sum of two operands is outside the range that the operator returns (see Table
5−3) For example, Byte is a data type that can have a value from 0 to 255 In the following code, the sum of the two operands raises the OverflowException, because the type cannot hold 258.
Public Sub TryItOut()
Try
Dim num1 As Byte = 253
Dim num2 As Byte = 5
Debug.WriteLine(num1 + num2)
Catch Except As OverflowException
Debug.WriteLine("Bad Byte Math: " & "num1 + num−−−" & Except.Message)
End Try
End Sub
Note Debug statements are stripped from release builds so the Debug statement inside the Catch handler willnot be executed For more information on using Debug, see Chapter 17
Table 5−3: Arithmetic Exceptions
Exception : ArithmeticException Purpose
DivideByZeroException To handle an exception raised when an attempt is made to divide a
number by zero
OverflowException To handle an exception raised when the result overflows the range
of the type (usually the result of an invalid cast or conversion)
Tip TryCatch are the constructs for structured exception handling (SEH) If you are new to SEH you can
jump to Chapter 7 for a short treatise on SEH or tackle Chapter 11 which specializes in this subject, but Iwould not worry too much about the SEH stuff just now
Assignment Operators
These operators assign values to variables, which are the left operands of an assignment expression Theassignment operators come in two forms, simple and compound, as listed in Table 5−4
Arithmetic Operators
Trang 23Table 5−4: Assignment Operators
+= Addition/Concatenation assignment Variable += Expression
/= and \= Division assignment FloatingPointVariable /= Expression
IntegerVariable \= Expression
&= Concatenation assignment Variable &= Expression
The simple assignment uses the equal sign to assign the operand on the right side to the operand on the leftside For example, the following code
X = 5
assigns the number 5 to the operand x
The compound version assigns the result of a numeric operation specified by the operator to the left operand
The most useful of these compounds is the += operator, which increments the left operand by the value of the
right one and then assigns the result back to the left operand For example
Dim x As Integer = 5
x += 1
increments the value of x by 1, so the new value of x is 6 This operator is the equivalent of the C# unary
increment/decrement operators, ++ and −− respectively However, you are not limited to incrementing or
decrementing by 1 The following code is also valid
Dim x As Integer = 5
x += 5
Debug.WriteLine(x)
This equation prints 10 to the debug window The *= operator would yield 25, the −= would yield 0.
Tip When you declare variables, you can use a shortcut to make your code more concise and readable
by assigning the value of the variable in the same line as its declaration: Dim X As Integer = 5 isthe same as Dim X As Integer, X = 5
Notice how the compound operators function in an example of the addition/concatenation operator (+=):Dim firstname As String = "Donald "
Dim lastname As String = "Duck"
firstname += lastname
Debug.WriteLine(firstname)
This writes "Donald Duck" to the Output window
When using the assignment equals compound, remember that if the expression is numeric, the operation will
be addition However, if the expression is a string, it will be concatenation
Arithmetic Operators
Trang 24You can also use the compounds with array operations In this example, an array value is incremented by 1using the += operator.
The comparison, or relational, operators evaluate an expression on the right side of the equal sign and return
True or False (Boolean), depending on the comparison, as seen in Table 5−5.
When comparing types, the following behaviors must be noted:
With Byte, Short, Integer, and Long we compare the numeric (literal) values of the operands.
With Boolean values (True and False) compared for equality, the equals operator (=) will return
True if both operands are either True or False The Not Equals (<>) is the reverse.
compares the numeric Unicode value of each character in the operands If each is the same, it returns
True Text mode makes the comparison on the current culture in use in the application environment
(see Chapter 4)
•
Table 5−5: Comparison Operators Supported in Visual Basic NET
Trang 25anticipate IEEE will merge these standards that guide software language architects in accessing the
floating−point facilities in modern computer hardware
According the IEEE, the latest version of the standard proposes the following: "[754] provides a discipline forperforming floating−point computation that yields results independent of whether the processing is done inhardware, software, or a combination of the two For operations specified in this standard, numerical resultsand exceptions are uniquely determined by the values of the input data, sequence of operations, and
destination formats, all under programmer control."
In particular, IEEE 754 specifies how software languages should provide support for precision, underflow,overflow, and extended precision Software languages like Visual Basic and C# look to IEEE 754 for
implementing square−root functions and the like
Concatenation Operator
The concatenation operator, represented by the ampersand (&), combines two string operands and returns a
single string expression The usage is
Value = operand & operand
Here is an example:
Dim X As String = "1"
Dim Y As String = "23"
Debug.WriteLine(X & Y)
The result of the operation X & Y writes "123" to the debug window
When this operator encounters integer operands, it will convert the integers to strings The conversion is safebecause the process results in a widening cast The + operator is implicitly overloaded to perform
concatenation when it encounters strings for operands To avoid ambiguity, concatenate strings using the &
operator
Logical Operators
Logical operators take Boolean (logical) operands and return the Boolean result of their operations Logical operators (see Table 5−6logical And, Or, and Xor) can be confused with their bitwise counterparts because
they have the same operator symbol Classic VB documentationas opposed to that of every other
languagemerged the two operator functions Microsoft tried to introduce a more "logical" separation of thesefunctions, but met with resistance from the VB community Thus Visual Basic NET remains "different" thanthe other NET languages
Bitwise operators return bitsthey do not return True or False It is important to understand and differentiate
between the functions of logical and bitwise operators: both are critical in software development Here we'llexamine logical operators; we'll discuss bitwise ones in the next section
Note The operator is overloaded to return bits in Visual Basic NET when it is required to operate on
Concatenation Operator
Trang 26Or (logical Or) Returns True even if one of the operands is Truereturns
False only if both are False
|
Xor (logical Xor) Returns False if both operands are either True or
Falseotherwise it returns True
!
AndAlso Returns True if both operands are True returns False if only
the first operand is True but if the first operand is False, the second operand is not evaluated and True is returned
**
OrElse If the first operand is True, the second is not evaluated and
the operator returns True Returns False if both are False and True if only the second operand is True
**
The key to understanding logical operations is to forget about numbers and bits Think only in terms of True
or False, which represent the types of operands and the return type of the operator For example, in the following code, a logical And operation is performed on two Boolean operands:
Dim catlovesdog As Boolean = False
Dim doglovescat As Boolean = True
Dim weirdromance As Boolean
weirdromance = catlovesdog And doglovescat
Debug.WriteLine(weirdromance)
The operator And returns False here because the Cat operand is False (cats are unimpressed with dogs) If the Cat operand were initialized True, the operator would have returned True Let's look at the different
types of logical operators and their functions in Table 5−7, then we can examine how to use them
Logical And, Or, and Xor
Table 5−7: Conditions upon which Logical Operators Return True or False
If cat loves dog Or dog loves cat is love in the air?
Logical And, Or, and Xor
Trang 27If cat loves dog Xor dog loves cat is love in the air?
If cat loves dog AndAlso dog loves cat is love in the air?
If cat loves dog OrElse dog loves cat is love in the air?
Short−Circuit Logical Operators
The AndAlso and OrElse are new short−circuit operators introduced to Visual Basic NET If you use And, the runtime will evaluate the entire expression, even if the first operand is False Compare this to the And example in the preceding tableif the first operand is False, the operator returns False, even if the second one is
True; thus you don't need to evaluate the second operand and the procedure "short circuits" the comparison.
The best way to understand this is through code
Module LogicTest
Sub Main()
Dim x As Integer = 1
Dim y As Integer = 1
If A(x) Or B(y) Then
Debug.WriteLine("x= " & CStr(x) & ", y = " & CStr(y))
End If
If A(x) OrElse B(y) Then
Debug.WriteLine("x= " & CStr(x) & ", y = " & CStr(y))
Copy and paste this code into Visual Studio or build and run the LogicTest console application in the Vb7cr
solution (see the Introduction for instruction for downloading this demo) Insert a break point in the code atthe following line:
If A(x) Or B(y) Then
Short−Circuit Logical Operators
Trang 28When execution stops at the above breakpoint step into the code using the F11 key You can now observe the
short−circuit in action The standard Or causes the compiler to invoke both methods A and B, but as you step into OrElse you will notice that method B does not get invoked.
Note See the project LogicTest in the Vb7cr solution.
Originally, all Visual Basic NET logical operators short−circuited, but in Beta 2 they reverted back to the
way they operate in VB 6 We'd prefer to see "Option Classic Off" let "seventh generation" Visual Basic
programmers choose the modern operators found in the other NET languages
Bitwise Operators
When your operands are numbers instead of Boolean values, And, Or, and Xor perform bitwise operations
on the operands instead of logical ones Instead of returning True or False, they return either a 1 or a 0
depending on the outcome For example, in the following statement
expression1 And expression2
the operator returns 1 if both operands are 1; but it returns 0 if one of the operands is 0 However, the
following statement
expression1 Or expression2
returns 1 even if only one of the operands is 1 It will return 0 only if both are 0 In the first example, nothinghappens unless both operands are 1 This is fundamental electrical engineering: you have a gate and the circuitwill be completed only if both the anode and the bnode are closed In the second example above, only one
operand or the other needs to be 0 to trigger the action.
You can use the bitwise Not operator with numerical expressions to negate the return value provided by the operator The following rules apply to using Not:
If the bit is 0, then Not makes the bit result 1.
The value returned is the negation of the bits that represent binary x and y (1s and 0s) ; thus, for x the value
returned is 6 and for y it's 2 Looking at this in binary as demonstrated earlier, 5 is expressed as 00000101.Negating the bits turns the binary version of 5 into the following 11111010, which is 6 in decimal This would
be clearer seen in the following binary chart negating the bits representing 5 (Not 1 is 11111110, which is −2):
Bitwise Operators
Trang 29−6 = 1 1 1 1 1 0 1 0
Note See the BitShifters demo later in this chapter which can do the conversion for you.
Table 5−8 shows the bitwise operators and the value they return
Flag Sets
Bitwise operations are useful for manipulating flag sets (also known as bit sets, bit maps, bit tables, flagtables, or flag maps) for state management in a variety of applications and algorithms You'll find manyopportunities for employing flag sets, such as components, visual controls, state machines, schedulers, anddatabase applications
Table 5−8: Bitwise Operators and the Values They Return; the C# and JScript Equivalents
And (bit And) Returns 1 if both operands are 1otherwise 0 Valid types are
Byte, Short, Integer, Long, or enumerated types.
&
Or (bit Or) Returns 1 if either is 1otherwise 0 Valid types are Byte,
Short, Integer, Long, or enumerated types.
|
Xor (bit Xor) Returns 1 if either operand is 1, 0 if both are 1, and 0 if both
are 0 Valid types are Byte, Short, Integer, Long, or
enumerated types
^
Not (bit Not) If the bit of an operand = 0, then bit in result = 1 If the bit of
an operand = 1, then bit in result = 0
~ (complement)
In computer telephony, PBX, or call−processing applications, flag sets are used to indicate the current state of
a message (fax mail, email, or voice mail) or phone extensions (on−hook, busy, call waiting, signed off/on) Atypical flag set for messages could be declared as follows:
Trang 30states rather than Boolean operations or If conditionals on the actual value.
The GetMessages application shown next loads the flag set for a message and then performs bitwise
comparisons on the flags to control execution and flow (See Chapters 13 and 14, which provide examples of
state machines.) Besides exemplifying bitwise operators, this code uses If Else conditionals, Select Case construction, and nested exception handlers extensively Chapter 6 covers the If conditional and Select Case
and Chapters 7 and 11 cover exception handling
Module GetMessages
Dim menuChoice As String
Dim inPut As String 'string to be blasted to bits
Dim outPut As Integer
Dim Completed As Boolean = False
'Flags representing flag fields table for a message
Dim messageFlag As Integer
Dim isAccessed As Integer
Dim isArchived As Integer
Dim isDeleted As Integer
Dim newMessage As Integer
Console.WriteLine("Press 1 to hear message ")
Console.WriteLine("Press 2 to archive message.")
Console.WriteLine("Press 3 to delete message.")
Console.WriteLine("Press return to end.")
Public Function ProcessMessage(ByVal messageAction As Integer) As Boolean
If (messageFlag And newMessage) = 1 Then
Console.WriteLine("There are no more messages ")
Return False
Else
Select Case messageAction
Case Is = 1 'Access the message
AccessMessage()
Flag Sets
Trang 31Case Is = 2 'Archive the message
If (messageFlag Xor isArchived) = 1 Then 'check if archived
Console.WriteLine("The message is now archived")
If (messageFlag And isAccessed) = 1 Then 'check if accessed
If (messageFlag Xor isArchived) = 1 Then 'check if archived
Console.WriteLine("The message was deleted")
Bit shifting is an important facility for enabling computer languages to handle sophisticated numeric
programming and complex numbers Visual Basic NET does not have bit−shifting operators (or the ability tooverload operators); its architects chose not to endow it with advanced numeric and number−crunchingfacilities (at least in the first version of Visual Basic NET) However, C# has these featureslanguage interopallows us to work with C# "muscle" by accessing C# classes and structure directly from Visual Basic
Language interop makes it far less important that these features are missing in Visual Basic, because once youcompile the entire application and reference C# class down to MSIL, the boundaries between the C# code andVisual Basic code vanish C# becomes a natural extension of Visual Basic (and any other NET language),something that has never been achieved before The following code demonstrates both the language interopand C#'s bit−shifting operators To keep this simple, I have created a console application that presents a menu
Shifting Bits
Trang 32similar to the GetMessages demo application discussed earlier The menu lets you choose to return a decimal
value in its binary form using the shift operators to populate a bit−mask You can also choose to shift left orshift right a decimal value and simple return the decimal result
You could have arithmetic exceptions in these operations so we have enclosed the calling methods between
Try Catch blocks.
Imports Vb7cr.BitShifters
Module SeeBits
Private inPut, byShift As String
Private outPut As Integer
Private isCompleted As Boolean = False
Console.WriteLine("a: Decimal to Binary.")
Console.WriteLine("b: Left Shift.")
Console.WriteLine("c: Right Shift.")
Console.WriteLine("d: Anything else to end.")
Public Sub DecToBinDemo()
Console.Write("Enter a number to convert from Dec to Bin: ")
Public Sub LeftShiftDemo()
Console.Write("Enter a number to shift left: ")
inPut = Console.ReadLine()
Console.Write("How many shifts left?: ")
Shifting Bits
Trang 33byShift = Console.ReadLine()
If Not (inPut = "") Then
isCompleted = GoLeft(inPut, byShift)
Else
isCompleted = True
End If
End Sub
Public Sub RightShiftDemo()
Console.Write("Enter a number to shift right: ")
inPut = Console.ReadLine()
Console.Write("How many shifts right?: ")
byShift = Console.ReadLine()
If Not (inPut = "") Then
isCompleted = GoRight(inPut, byShift)
Note See the project SeeBits in the Vb7cr solution.
The following C# source code is the class that contains the bit−shifting methods The class is sealed and themethods are declared static (shared) so that the class does not need to be instantiated in order for you to usethese bit−shifting methods
using System;
Shifting Bits