1. Trang chủ
  2. » Công Nghệ Thông Tin

Visual Basic .NET The Complete Reference phần 3 potx

67 273 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Working With Variables And Constants
Trường học University of Information Technology
Chuyên ngành Computer Science
Thể loại bài tập
Thành phố Ho Chi Minh City
Định dạng
Số trang 67
Dung lượng 230,3 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

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 1

CastTarget ( 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 2

amount = 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 3

constant 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 4

variable 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 5

You 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 6

Dim 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 7

second 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 8

later 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 9

Scope

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 10

myVar 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 11

The 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 12

Avoid 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 13

Strict 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 14

Chapter 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 15

A 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 16

Here 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 17

Base 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 18

The 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 19

The 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 20

Miscellaneous 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 21

Unary 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 22

Arithmetic 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 23

Table 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 24

You 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 25

anticipate 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 26

Or (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 27

If 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 28

When 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 30

states 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 31

Case 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 32

similar 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 33

byShift = 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

Ngày đăng: 14/08/2014, 01:20