User Tools

Site Tools


re-dimensioning_20arrays

This is an old revision of the document!


Re-dimensioning arrays

by Richard Russell, May 2014

BBC BASIC does not have a REDIM or REDIM PRESERVE statement, as found in some other dialects of BASIC (REDIM allows you to increase the dimensions of an existing array - the contents are lost - and REDIM PRESERVE allows you to increase the dimensions of an array without destroying its contents). However it is not difficult to provide an equivalent functionality using user-defined procedures:

      DEF PROCredim1d(RETURN P%,S%,D%)
      LOCAL A%
      IF ?P%<>1 ERROR 14, "Bad use of array"
      IF P%<LOMEM OR P%>HIMEM SYS "GlobalFree", P%
      SYS "GlobalAlloc", 64, 5+S%*(D%+1) TO A%
      IF A%=0 ERROR 11, "DIM space"
      ?A%=1 : A%!1=D%+1
      P% = A%
      ENDPROC
      DEF PROCredim2d(RETURN P%,S%,D%,E%)
      LOCAL A%
      IF ?P%<>2 ERROR 14, "Bad use of array"
      IF P%<LOMEM OR P%>HIMEM SYS "GlobalFree", P%
      SYS "GlobalAlloc", 64, 9+S%*(D%+1)*(E%+1) TO A%
      IF A%=0 ERROR 11, "DIM space"
      ?A%=2 : A%!1=D%+1 : A%!5=E%+1
      P% = A%
      ENDPROC
      DEF PROCredimpreserve1d(RETURN P%,S%,D%)
      LOCAL A%,N%,O%
      IF ?P%<>1 ERROR 14, "Bad use of array"
      N% = 5+S%*(D%+1)
      O% = 5+S%*P%!1
      SYS "GlobalAlloc", 64, N% TO A%
      IF A%=0 ERROR 11, "DIM space"
      IF N%>O% SWAP N%,O%
      SYS "RtlMoveMemory", A%, P%, N%
      A%!1=D%+1
      IF P%<LOMEM OR P%>HIMEM SYS "GlobalFree", P%
      P% = A%
      ENDPROC
      DEF PROCredimpreserve2d(RETURN P%,S%,D%,E%)
      LOCAL A%,N%,O%
      IF ?P%<>2 ERROR 14, "Bad use of array"
      N% = 9+S%*(D%+1)*(E%+1)
      O% = 9+S%*P%!1*P%!5
      SYS "GlobalAlloc", 64, N% TO A%
      IF A%=0 ERROR 11, "DIM space"
      IF N%>O% SWAP N%,O%
      SYS "RtlMoveMemory", A%, P%, N%
      A%!1=D%+1 : A%!5=E%+1
      IF P%<LOMEM OR P%>HIMEM SYS "GlobalFree", P%
      P% = A%
      ENDPROC

The above procedures support 1-dimensional and 2-dimensional arrays; equivalent routines for arrays with more dimensions can be derived if required. If you REDIM PRESERVE a 2-dimensional (or more) array you should normally only change the first dimension; if you change another dimension the data will be 'preserved' but will appear to have moved. Note that it isn't usually sensible to reduce the size of an array.

In each case the parameters to the procedure are the name of the array, the size of each element of the array (see table below) and the required dimension(s). As with the normal DIM statement, the available indices run from zero to the specified value.

Here is a simple demonstration program:

      DIM array(100)
      FOR I% = 0 TO 100
        array(I%) = SQR(I%)
      NEXT
      PROCredimpreserve1d(array(), ^array(1)-^array(0), 200)
      FOR I% = 101 TO 200
        array(I%) = SQR(I%)
      NEXT
      FOR I% = 0 TO 200
        IF array(I%) <> SQR(I%) STOP
      NEXT
      PRINT "Test completed successfully"
      END

Note that if you REDIM (not REDIM PRESERVE) a string array you must explicitly empty the array first:

      array$() = ""
      PROCredim1d(array$(), ^array$(1)-^array$(0), newsize%)


The most reliable way of determining the element size is to calculate it at run-time, as in the above examples, but for reference here are the appropriate sizes for each type of array:

byte e.g. array&()
size=1
32-bit integer e.g. array%()
size=4
40-bit float e.g. array()
size=5
string e.g. array$()
size=6
64-bit float e.g. array#()
size=8
string e.g. array$()
size=8*
64-bit integer e.g. array%%()
size=8*
80-bit float e.g. array()
size=10*

* BB4W version 6 only

This website uses cookies. By using the website, you agree with storing cookies on your computer. Also you acknowledge that you have read and understand our Privacy Policy. If you do not agree leave the website.More information about cookies
re-dimensioning_20arrays.1522502376.txt.gz · Last modified: 2024/01/05 00:16 (external edit)