User Tools

Site Tools


deconstructing_20arrays

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

deconstructing_20arrays [2018/03/31 13:19]
127.0.0.1 external edit
deconstructing_20arrays [2018/04/17 15:45] (current)
tbest3112 Added syntax highlighting
Line 4: Line 4:
 ==== Reading the array pointer ==== ==== Reading the array pointer ====
 \\  The most important part of an array is the pointer to the array data block and reading this is the first step in deconstructing an array. But we also need an array to deal with and one such example is created below.\\ \\  \\  The most important part of an array is the pointer to the array data block and reading this is the first step in deconstructing an array. But we also need an array to deal with and one such example is created below.\\ \\ 
 +<code bb4w>
         DIM array(1, 2, 3, 4)         DIM array(1, 2, 3, 4)
         parr% = ^array():​REM Pointer to array         parr% = ^array():​REM Pointer to array
 +</​code>​
 \\  Here we dimension an example array **array()** and set **parr%** to the pointer to this array.\\ \\  \\  Here we dimension an example array **array()** and set **parr%** to the pointer to this array.\\ \\ 
 ==== Basic array information ==== ==== Basic array information ====
 \\  \\ 
 +<code bb4w>
         PRINT "​Pointer to parameter block address: &";​~parr%         PRINT "​Pointer to parameter block address: &";​~parr%
         PRINT "​Address of parameter block: &";​~!parr%         PRINT "​Address of parameter block: &";​~!parr%
         PRINT "​Number of dimensions: ";?​!parr%         PRINT "​Number of dimensions: ";?​!parr%
         PRINT "​Address of data area: &";​!parr%+1+?​!parr%*4         PRINT "​Address of data area: &";​!parr%+1+?​!parr%*4
 +</​code>​
 \\  Here we display basic information about the array. The pointer to the parameter block could be expressed as **^array()**,​ the parameter block address could be expressed as **!^array()** and the number of dimensions could be expressed as **?​!^array()**.\\ \\ **Note:** The following code could be rewritten with **^array()** replacing each instance of **parr%** but this would limit us to only examining an array called **array()**. By storing the pointer to the array in **parr%** we can use this code to examine any type of array.\\ \\  \\  Here we display basic information about the array. The pointer to the parameter block could be expressed as **^array()**,​ the parameter block address could be expressed as **!^array()** and the number of dimensions could be expressed as **?​!^array()**.\\ \\ **Note:** The following code could be rewritten with **^array()** replacing each instance of **parr%** but this would limit us to only examining an array called **array()**. By storing the pointer to the array in **parr%** we can use this code to examine any type of array.\\ \\ 
 ==== Reading the size of each dimension ==== ==== Reading the size of each dimension ====
 \\  To find the size of each dimension in the array and calculate the total number of elements in the array use the following code:\\ \\  \\  To find the size of each dimension in the array and calculate the total number of elements in the array use the following code:\\ \\ 
 +<code bb4w>
         tele% = 1:REM Total number of elements         tele% = 1:REM Total number of elements
         FOR i% = 0 TO ?!parr% - 1         FOR i% = 0 TO ?!parr% - 1
Line 23: Line 28:
         NEXT i%         NEXT i%
         PRINT "Total number of elements: ";​tele%         PRINT "Total number of elements: ";​tele%
 +</​code>​
 \\  Here we iterate through the dimensions of the array and read the number of elements in each dimension (**nele%**) and display the result. The running total number of elements in the array is calculated and stored in **tele%**, this value is used to calculate the size of the array data block.\\ \\  \\  Here we iterate through the dimensions of the array and read the number of elements in each dimension (**nele%**) and display the result. The running total number of elements in the array is calculated and stored in **tele%**, this value is used to calculate the size of the array data block.\\ \\ 
 ==== Determining the array type ==== ==== Determining the array type ====
 \\  Arrays can contain different types of variable and each variable type occupies a different number of bytes in memory. Knowing the type of an array is important when manipulating the data in the array or the array itself. The array variable name is precedes the array pointer in memory. This allows us to find the type of variable stored in the array. The variable type is stored three bytes before the array pointer.\\ \\  We can use this information to find the type of variable stored in the array:\\ \\  \\  Arrays can contain different types of variable and each variable type occupies a different number of bytes in memory. Knowing the type of an array is important when manipulating the data in the array or the array itself. The array variable name is precedes the array pointer in memory. This allows us to find the type of variable stored in the array. The variable type is stored three bytes before the array pointer.\\ \\  We can use this information to find the type of variable stored in the array:\\ \\ 
 +<code bb4w>
         PRINT "Array type: ";         PRINT "Array type: ";
         CASE parr%?-3 OF         CASE parr%?-3 OF
Line 35: Line 42:
         ENDCASE         ENDCASE
         PRINT "Size of each element: ";​esize%"​ bytes"         PRINT "Size of each element: ";​esize%"​ bytes"
 +</​code>​
 \\  Here **esize%** is set to the size in bytes of the variable type stored in the array. One variable type, the 40-bit real, does not have a type suffix so it is possible to assume that any variable name that does not end in **%**, **#**, **$** or **&** is a 40-bit real. When BBC BASIC is in //float 64// mode all new real variables have the **#** suffix silently added to the end of the name. This is essential for BBC BASIC to tell the difference between the two types of real variable.\\ \\ **Note:** We are ignoring structures and arrays here as these variable types cannot be contained within an array. Structure variable names have a '​**{**'​ suffix and array variable names have a '​**(**'​ suffix.\\ \\  \\  Here **esize%** is set to the size in bytes of the variable type stored in the array. One variable type, the 40-bit real, does not have a type suffix so it is possible to assume that any variable name that does not end in **%**, **#**, **$** or **&** is a 40-bit real. When BBC BASIC is in //float 64// mode all new real variables have the **#** suffix silently added to the end of the name. This is essential for BBC BASIC to tell the difference between the two types of real variable.\\ \\ **Note:** We are ignoring structures and arrays here as these variable types cannot be contained within an array. Structure variable names have a '​**{**'​ suffix and array variable names have a '​**(**'​ suffix.\\ \\ 
 ==== Calculating the total size of the array ==== ==== Calculating the total size of the array ====
 \\  The total size of the array data area equals the total number of elements (**tele%**) multiplied by the size of each element (**esize%**). The total size of the array block equals the size of the data area plus one byte for the number of dimensions and four extra bytes for the description of each dimension.\\ \\  We can now use all the information collected so far to determine the total size of the array in memory:\\ \\  \\  The total size of the array data area equals the total number of elements (**tele%**) multiplied by the size of each element (**esize%**). The total size of the array block equals the size of the data area plus one byte for the number of dimensions and four extra bytes for the description of each dimension.\\ \\  We can now use all the information collected so far to determine the total size of the array in memory:\\ \\ 
 +<code bb4w>
         PRINT "Total data area size: ";​tele%*esize%"​ bytes"         PRINT "Total data area size: ";​tele%*esize%"​ bytes"
         PRINT "Total array size: ";​1+4*?​!parr%+tele%*esize%"​ bytes"         PRINT "Total array size: ";​1+4*?​!parr%+tele%*esize%"​ bytes"
 +</​code>​
 \\  \\ 
 ==== How to verify the array pointer ==== ==== How to verify the array pointer ====
 \\  When writing code that manipulates arrays by reference it is a good idea to check that the array pointer **parr%** is actually a pointer to an array. Not doing so will lead to undefined behaviour and may crash //BBC BASIC// if your code is called with an invalid array pointer.\\ \\  To check if a pointer points to an array use the following code:\\ \\  \\  When writing code that manipulates arrays by reference it is a good idea to check that the array pointer **parr%** is actually a pointer to an array. Not doing so will lead to undefined behaviour and may crash //BBC BASIC// if your code is called with an invalid array pointer.\\ \\  To check if a pointer points to an array use the following code:\\ \\ 
 +<code bb4w>
         IF NOT (parr%?-1 = 0 AND parr%?-2 = 40) THEN         IF NOT (parr%?-1 = 0 AND parr%?-2 = 40) THEN
           REM parr% does not point to an array           REM parr% does not point to an array
Line 48: Line 59:
           REM parr% points to an array           REM parr% points to an array
         ENDIF         ENDIF
 +</​code>​
 \\  Here we check for a variable descriptor that matches an array. If the array pointer **parr%** does not point to a valid array block the routine should not attempt to access or manipulate data in the invalid array. \\  Here we check for a variable descriptor that matches an array. If the array pointer **parr%** does not point to a valid array block the routine should not attempt to access or manipulate data in the invalid array.
deconstructing_20arrays.txt ยท Last modified: 2018/04/17 15:45 by tbest3112