passing arrays to procedures: byval vs. byref. passing arrays to procedures passing the array –...

15
Passing Arrays to Procedures: ByVal vs. ByRef

Post on 21-Dec-2015

227 views

Category:

Documents


0 download

TRANSCRIPT

Passing Arrays to Procedures:ByVal vs. ByRef

Passing Arrays to Procedures• Passing the Array

– Specify the name of the array without using parentheses– Every array object “knows” its own upper bound

• Do not need to pass the upper bound of the array as a separate argument

• Dim hourlyTemperatures As Integer() = New Integer(24) {}• DayData(hourlyTemperatures)

In Visual Basic, arrays always are passed by reference

• Receiving the array– The procedure’s parameter list must specify that an array will be

received. Sub DayData(ByVal temperatureData As Integer())

• Although entire arrays are always passed by reference, individual array elements can be passed in the same manner as simple variables of that type.

• For instance, array element values of primitive data types, such as Integer, can be passed by value or by reference, depending on the procedure definition.

• To pass an array element to a procedure, use the indexed name of the array element as an argument in the call to the procedure.

• The following program demonstrates the difference between passing an entire array and passing an array element.

Passing Arrays to Procedures

1 ' Fig. 7.8: PassArray.vb2 ' Passing arrays and individual array elements to procedures.3 4 Imports System.Windows.Forms5 6 Module modPassArray7 Dim output As String8 9 Sub Main()10 Dim array1 As Integer() = New Integer() {1, 2, 3, 4, 5}11 Dim i As Integer12 13 output = "EFFECTS OF PASSING ENTIRE ARRAY " & _14 "BY REFERENCE:" & vbCrLf & vbCrLf & _15 "The values of the original array are:" & vbCrLf16 17 ' display original elements of array118 For i = 0 To array1.GetUpperBound(0)19 output &= " " & array1(i)20 Next21 22 ModifyArray(array1) ' array is passed by reference23

24 output &= vbCrLf & _25 "The values of the modified array are:" & vbCrLf26 27 ' display modified elements of array128 For i = 0 To array1.GetUpperBound(0)29 output &= " " & array1(i)30 Next31 32 output &= vbCrLf & vbCrLf & _33 "EFFECTS OF PASSING ARRAY ELEMENT " & _34 "BY VALUE:" & vbCrLf & vbCrLf & "array1(3) " & _35 "before ModifyElementByVal: " & array1(3)36 37 ' array element passed by value38 ModifyElementByVal(array1(3))39 40 output &= vbCrLf & "array1(3) after " & _41 "ModifyElementByVal: " & array1(3)42 43 output &= vbCrLf & vbCrLf & "EFFECTS OF PASSING " & _44 "ARRAY ELEMENT BY REFERENCE: " & vbCrLf & vbCrLf & _45 "array1(3) before ModifyElementByRef: " & array1(3)46

47 ' array element passed by reference48 ModifyElementByRef(array1(3))49 50 output &= vbCrLf & "array1(3) after " & _51 "ModifyElementByRef: " & array1(3)52 53 MessageBox.Show(output, "Passing Arrays", _54 MessageBoxButtons.OK, MessageBoxIcon.Information)55 End Sub ' Main56 57 ' procedure modifies array it receives (note ByVal)58 Sub ModifyArray(ByVal arrayParameter As Integer())59 Dim j As Integer60 61 For j = 0 To arrayParameter.GetUpperBound(0)62 arrayParameter(j) *= 263 Next64 65 End Sub ' ModifyArray66

67 ' procedure modifies integer passed to it68 ' original is not be modified (note ByVal)69 Sub ModifyElementByVal(ByVal element As Integer)70 71 output &= vbCrLf & "Value received in " & _72 "ModifyElementByVal: " & element73 element *= 274 output &= vbCrLf & "Value calculated in " & _75 "ModifyElementByVal: " & element76 End Sub ' ModifyElementByVal77 78 ' procedure modifies integer passed to it79 ' original is be modified (note ByRef)80 Sub ModifyElementByRef(ByRef element As Integer)81 82 output &= vbCrLf & "Value received in " & _83 "ModifyElementByRef: " & element84 element *= 285 output &= vbCrLf & "Value calculated in " & _86 "ModifyElementByRef: " & element87 End Sub ' ModifyElementByRef88 89 End Module ' modPassArray

Passing Arrays: ByVal vs. ByRef

• ByValByVal– Causes the value of the argument to be copied to a local Causes the value of the argument to be copied to a local

variable in the procedurevariable in the procedure– Changes to the local variable are reflected in the local copy Changes to the local variable are reflected in the local copy

of that variable, not in the original variable in the calling of that variable, not in the original variable in the calling programprogram

– But But if the argument is of a reference type, like an array, if the argument is of a reference type, like an array, passing it passing it ByValByVal actually passes it by reference, so actually passes it by reference, so changes to the object affect the original objects in the changes to the object affect the original objects in the callers callers

1 ' Fig. 7.9: ArrayReferenceTest.vb2 ' Testing the effects of passing array references using 3 ' ByVal and ByRef.4 5 Module modArrayReferenceTest6 7 Sub Main()8 Dim i As Integer9 10 ' declare array references11 Dim firstArray As Integer()12 Dim firstArrayCopy As Integer()13 14 ' allocate firstArray and copy its reference15 firstArray = New Integer() {1, 2, 3}16 firstArrayCopy = firstArray17 18 Console.WriteLine("Test passing array reference " & _19 "using ByVal.")20 Console.Write("Contents of firstArray before " & _21 "calling FirstDouble: ")22 23 ' print contents of firstArray24 For i = 0 To firstArray.GetUpperBound(0)25 Console.Write(firstArray(i) & " ")26 Next

Prints contents first to verify that FirstDouble indeed changes the array’s contents

Copies reference firstArray to variable firstArrayCopy, now

they reference the same object

Demonstrates the subtle difference between passing a reference ByVal vs.passing a reference ByRef.

27 28 ' pass firstArray using ByVal29 FirstDouble(firstArray)30 31 Console.Write(vbCrLf & "Contents of firstArray after " & _32 "calling FirstDouble: ")33 34 ' print contents of firstArray35 For i = 0 To firstArray.GetUpperBound(0)36 Console.Write(firstArray(i) & " ")37 Next38 39 ' test whether reference was changed by FirstDouble40 If firstArray Is firstArrayCopy Then41 Console.WriteLine(vbCrLf & "The references are " & _42 "equal.")43 Else44 Console.WriteLine(vbCrLf & "The references are " & _45 "not equal.")46 End If47 48 ' declare array references49 Dim secondArray As Integer()50 Dim secondArrayCopy As Integer()51

Compares references firstArray and firstArrayCopy

VB provides operator Is for comparing references to determine whether they are referencing the same object.

firstArray is passed to FirstDouble

Reference is passed ByVal

52 ' allocate secondArray and copy its reference53 secondArray = New Integer() {1, 2, 3}54 secondArrayCopy = secondArray55 56 Console.WriteLine(vbCrLf & "Test passing array " & _57 "reference using ByRef.")58 Console.Write("Contents of secondArray before " & _59 "calling SecondDouble: ")60 61 ' print contents of secondArray before procedure call62 For i = 0 To secondArray.GetUpperBound(0)63 Console.Write(secondArray(i) & " ")64 Next65 66 ' pass secondArray using ByRef67 SecondDouble(secondArray)68 69 Console.Write(vbCrLf & "Contents of secondArray " & _70 "after calling SecondDouble: ")71 72 ' print contents of secondArray after procedure call73 For i = 0 To secondArray.GetUpperBound(0)74 Console.Write(secondArray(i) & " ")75 Next76

77 ' test whether the reference was changed by SecondDouble78 If secondArray Is secondArrayCopy Then79 Console.WriteLine(vbCrLf & "The references are " & _80 "equal.")81 Else82 Console.WriteLine(vbCrLf & "The references are " & _83 "not equal.")84 End If85 86 End Sub ' Main87 88 ' procedure modifies elements of array and assigns 89 ' new reference (note ByVal)90 Sub FirstDouble(ByVal array As Integer())91 Dim i As Integer92 93 ' double each element value94 For i = 0 To array.GetUpperBound(0)95 array(i) *= 296 Next97 98 ' create new reference and assign it to array99 array = New Integer() {11, 12, 13}100 End Sub ' FirstDouble

Allocates a new array, and attempts to assign it’s reference

to parameter array, attempting to overwrite reference

firstArray in memory, but will fail because the reference

was passed ByVal

Multiplies all the elements of the array by 2

101 102 ' procedure modifies elements of array and assigns103 ' new reference (note ByRef)104 Sub SecondDouble(ByRef array As Integer())105 Dim i As Integer106 107 ' double contents of array108 For i = 0 To array.GetUpperBound(0)109 array(i) *= 2110 Next111 112 ' create new reference and assign it to array113 array = New Integer() {11, 12, 13}114 End Sub ' SecondDouble115 116 End Module ' modPassArray

Because the reference was passed with ByRef, the called procedure has the ability to modify what the reference actually points to

Test passing array reference using ByVal.Contents of firstArray before calling FirstDouble: 1 2 3Contents of firstArray after calling FirstDouble: 2 4 6The references are equal. Test passing array reference using ByRef.Contents of secondArray before calling SecondDouble: 1 2 3Contents of secondArray after calling SecondDouble: 11 12 13The references are not equal.