Debugging, Static Variables, ByRef, ByValue Chapt. 6 in Deitel, Deitel and Nieto

Preview:

Citation preview

Debugging, Static Variables, ByRef, ByValue

Chapt. 6 in Deitel, Deitel and Nieto

Debugging

Debug.Print: prints messages or variable values to the Intermediate window

Example:Debug.Print “Loop”, i

would indicate how many times one was in a loop

P. 559 in Deitel, Deitel and Nieto

Debugging

Instead of running a program by clicking the Start () and encountering a problem at an unknown place, one can step through a program.

Click the F8 key, it will take you through the program statement by statement

If nothing is happening, it’s probably waiting for an event

Place the cursor over a variable in the program to see its current value

Debugging

Debug.Assert(condition)

Scope

Recall that variable’s scope is the parts of the program which have access to a variable and understand what is meant by that variable

A local variable is understood only within the the method (subroutine or function) in which it is declared

Scope (Cont.)

A global variable is declared at the top of a Module (a form is the only example we have of a module so far) and is understood by all the methods in that module

A public variable is declared using the keyword Public instead of Dim, such a variable can be understood by other modules (forms) – To be used on another form, one must put before it

the form on which it is declared– frmOrigin.Balance

Scope example

Scope Example

Scope Example

Option Explicit

Public Balance As Double

Dim Interest As Double

Dim Years As IntegerGlobal

public

Scope Example

Private Sub txtBalance_Validate(Cancel As _ Boolean)

If IsNumeric(txtBalance.Text) Then Balance = txtBalance.Text Else txtBalance.Text = "" Cancel = True End IfEnd Sub‘Similar subroutines for Interest and Years

Scope Example

Private Sub cmdCalculate_Click() Dim i As Integer For i = 1 To Years Balance = Balance * (1 + Interest / 100) Next i Me.Hide frmDerivative.ShowEnd Sub

Local

Scope Example

Option Explicit

Private Sub Form_Initialize() txtResult.Text = "" txtResult.Text = "With $" & frmOrigin.txtBalance.Text & _ " invested for " & frmOrigin.txtYears.Text & " years " & _ " at " & frmOrigin.txtInterest.Text & "% would result in “ _

& Format$(frmOrigin.Balance, "Currency") End Sub

Automatic Variables

If an automatic variable is declared (Dimmed) in a subroutine (or function) then a memory location is associated with that variable only for the duration of the subroutine

If the subroutine is returned to later, a new memory location is associated with the variable, which means the value is re-initialized rather than remembered

Static variables

If you want a variable to be local to a subroutine (or function) because it is used only a that subroutine, but you also want the variable’s value to be remembered from call to call, then you want a static variable

Static vs. Automatic Variables

Remains zero

Static vs. Automatic Variables

Option Explicit

Private Sub cmdStart_Click() If Timer1.Enabled Then Timer1.Enabled = False cmdStart.Caption = "Start" Else Timer1.Enabled = True cmdStart.Caption = "Stop" End IfEnd Sub

Static vs. Automatic VariablesPrivate Sub Timer1_Timer() Static StaticCount As Single Dim AutomaticCount As Single txtStatic.Text = Format$(StaticCount, "Fixed") txtAutomatic.Text = Format$( _

AutomaticCount, “Fixed”) StaticCount = StaticCount + 0.01 AutomaticCount = AutomaticCount + 0.01End Sub

The static variable is remembered from call to call

ByRef

The default in VB is that arguments passed to a method are passed “by reference”

This means that if the argument is a variable, then the method has access to the original variable’s memory location and can change the value therein

ByRef ExampleOption ExplicitDim Balance As DoubleDim Years As IntegerDim Interest As Double

Private Sub Command1_Click() Dim i As Integer Balance = 1000 Years = 10 Interest = 6.5

ByRef Example

For i = 1 To Years Call AddInterest(Balance, Interest) Debug.Print Balance Next iEnd Sub

Private Sub AddInterest(Balance As Double, _ Interest As Double)

Balance = Balance * (1 + Interest / 100)End Sub

Passed by reference, balance can change in subroutine

By Ref Example

ByVal

If a variable is passed to a method “by value”, then the method makes its own local copy (a distinct memory location) of the variable, any changes to the variable in the method happen only to the local copy and not the original

ByVal Example

Dim Interest As Double

Private Sub Command1_Click() Dim i As Integer Balance = 1000 Years = 10 Interest = 6.5

ByVal Example For i = 1 To Years Balance = Balance + CalculateInterest(Balance, _

Interest) Debug.Print Balance Next iEnd Sub

Private Function CalculateInterest(ByVal Balance As _ Double, ByVal Interest As Double) As Double

CalculateInterest = Balance * Interest / 100 Balance = 999999999End Function Change balance in

method, doesn’t affect original

Balance changed here, not in function

ByVal Example

“Functions” that return more than one thing One can use ByRef arguments to have

a method return more than one value How? Send what you want returned as if it

were an argument and it can be changed within the method

Multiple returns example Option Explicit

Private Sub Command1_Click() Dim A As Double Dim B As Double Dim C As Double Dim Root1 As Double Dim Root2 As Double A = 3.01 B = 16.021 C = 2.11

Multiple returns example

Call CalculateRoots(A, B, C, Root1, Root2) Debug.Print Root1, Root2End Sub

Private Sub CalculateRoots(A As Double, B As Double, _ C As Double, Root1 As Double, Root2 As Double)

Dim Discrim As Double Discrim = B ^ 2 - 4 * A * C Root1 = (-B + Discrim) / (2 * A) Root2 = (-B - Discrim) / (2 * A)End Sub

Recursion

Recursion is when a function calls itself If a function calls itself under all

conditions, then there will be an unending cycle of function calls and the program will not end properly

There must be a “base case” which in which the function does not call itself

P. 214 Deitel, Deitel and Nieto

Greatest Common Divisor as an Example of Recursion The greatest common divisor (gcd) of two

integers is the largest number that divides into both evenly (that is, both numbers can be divided by the gcd without any remainder)

“In Euclid's Elements (Book VII) we find a way of calculating the gcd of two numbers, without listing the divisors of either number. It is now called Euclid's Algorithm.”

Euclid’s Algorithm Example

“We will find the gcd of 36 and 15. Divide 36 by 15 (the greater by the smaller), getting 2 with a remainder of 6.”

“Then we divide 15 by 6 (the previous remainder) and we get 2 and a remainder of 3.”

“Then we divide 6 by 3 (the previous remainder) and we get 2 with no remainder.”

“The last non-zero remainder (3) is our gcd.

Note we are only interested in the remainders of the division

Euclid’s Algorithm Example

Here it is in general: a/b gives a remainder of r

b/r gives a remainder of sr/s gives a remainder of t...w/x gives a remainder of yx/y gives no remainder

In this case, y is the gcd of a and b. If the first step produced no remainder, then b (the lesser of the two numbers) is the gcd.

http://www.mcn.net/~jimloy/euclids.html

Euclid’s Algorithm Example

Note the procedure is recursive, the operation on the first set of numbers leads to the same operation on a second set of numbers and so on

The “base case” occurs when the second (lower) number is zero

Euclid’s Algorithm Example

Euclid’s Algorithm ExampleOption Explicit

Private Sub txtNumber_Validate(Index As Integer, Cancel As Boolean) If Not IsNumeric(txtNumber(Index).Text) Then MsgBox ("Please enter a number.") txtNumber(Index).Text = "" Cancel = True End IfEnd Sub

This is your basic validation method but on an array of inputs

Euclid’s Algorithm Example

Private Sub cmdGCD_Click() Dim Number1 As Integer Dim Number2 As Integer Dim Swap As Integer Dim GreatComDiv As Integer

Number1 = txtNumber(0).Text Number2 = txtNumber(1).Text

Euclid’s Algorithm Example

'order the two numbers

If Number1 < Number2 Then

Swap = Number1

Number1 = Number2

Number2 = Swap

End If

We exchange the numbers like in the shuffle method but only if the first one is smaller

Euclid’s Algorithm Example

GreatComDiv = _ CalculateGCD(Number1, Number2)

lblGCD.Caption = lblGCD.Caption & _ "of " & Number1 & " and " & _

Number2 & " is " & GreatComDiv

End Sub

Call our greatest common divisor function

Euclid’s Algorithm Example

Private Function CalculateGCD(ByVal _ Number1 As Integer, ByVal Number2 _ As Integer) As Integer

Dim Remainder As Integer

Debug.Print Number1, Number2

Make a copy of the numbers, don’t change the originals

Print out our progress to the Intermediate window, this will print the local copies of Number1 and Number2, not the originals

Euclid’s Algorithm Example

If Number2 = 0 Then CalculateGCD = Number1 Else Remainder = Number1 Mod Number2 Number1 = Number2 Number2 = Remainder CalculateGCD = CalculateGCD(_

Number1, Number2) End IfEnd Function

Base case!!!!

Recursive call

Intermediate Window

Recommended