Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Passing arrays

A procedure that takes an array writes the parameter as name( ) as Type, and the caller passes name( ). The empty parentheses are required at both ends:

'' An array parameter is written name( ) as Type, and so is the
'' argument. The procedure works on the caller's array, not a copy.
sub Fill( values( ) as int32, byval start as int32 )
    for i as int32 = lbound( values ) to ubound( values )
        values( i ) = start
        start += 1
    next
end sub

function Sum( values( ) as const int32 ) as int64
    dim as int64 total = 0
    for each v in values
        total += v
    next
    return total
end function

'' The bounds travel with the array.
dim as int32 small( 1 to 3 )
dim as int32 odd( -2 to 2 )
Fill( small( ), 10 )
Fill( odd( ), 1 )
print "small:"; small( 1 ); small( 2 ); small( 3 ); ", sum"; Sum( small( ) )
print "odd: " & lbound( odd ) & " to " & ubound( odd ) & ", sum"; Sum( odd( ) )

'' A dynamic array can be resized by the procedure it is passed to.
sub Grow( values( ) as int32, byval extra as int32 )
    redim preserve values( lbound( values ) to ubound( values ) + extra )
end sub

dim as int32 list( )
redim list( 1 to 2 )
Grow( list( ), 3 )
print "list now " & lbound( list ) & " to " & ubound( list )

'' A parameter's dimensions are written with commas: ( , ) is two.
sub Describe( m( , ) as int32 )
    print "a grid of"; ubound( m, 1 ) - lbound( m, 1 ) + 1; " rows and"; _
          ubound( m, 2 ) - lbound( m, 2 ) + 1; " columns"
end sub

dim as int32 table( 1 to 4, 0 to 5 )
Describe( table( ) )

Output

small: 10 11 12, sum 33
odd: -2 to 2, sum 15
list now 1 to 5
a grid of 4 rows and 6 columns

An array is always passed by reference: Fill writes straight into the caller's array, and nothing is copied however large the array is. To promise that a procedure only reads, write the parameter as const, as Sum does.

The bounds travel with the array. odd runs from -2 to 2 and Fill sees exactly that, which is why a procedure written between lbound and ubound works on any array of the right type without being told its size.

A dynamic array can be resized by the procedure it was passed to: Grow adds three elements to the caller's list.

A const array parameter is meant to refuse writes, so this should not compile:

'' An array parameter declared as const cannot be written. Does not
'' compile.
sub Reset_( values( ) as const int32 )
    values( lbound( values ) ) = 0
end sub

dim as int32 counts( 1 to 3 ) = { 4, 5, 6 }
Reset_( counts( ) )
print counts( 1 )

Status in this version

The program above compiles and prints 0: an element of a const array parameter can be assigned, and the array can be resized with redim, without an error. for each byref over one is refused, as it should be. Until this is fixed, as const on an array parameter documents the intent but does not enforce it.

The parameter states the number of dimensions with commas and nothing else: m( , ) as int32 takes any two-dimensional int32 array, whatever its bounds.

Activities

  1. Write sub Reverse( values( ) as int32 ) that reverses an array in place, and test it on small and on odd.
  2. Write function Largest( m( , ) as const int32 ) as int32.