ArrayElementAddresses
 

Array Element Addresses


I N D E X:





About


      The array commands are one of the most powerful and often misunderstood aspects of PlayBASIC. Their powerful because they can work with any layout or type of array, and misunderstood, as they work differently to how we'd normally access information in an array. Normally we'd use indexes with arrays, but the array commands use element addresses.

      Up until now, when we've talked about accessing the information within an array, we're used Array Indexes to pin point the exact element we wish to manipulate. While this is convenient for the user, behind the scenes your Array Indexes have to be multiplied out to calc the actual position within the array. This value of this multiplication process is what we refer to as creating the 'element address'.

      To calculate an element address, you could manually multiply out the fields yourself. While that's possible, i'm sure we're all too lazy for that, so of course there's an easier way. And that is by placing the square brackets around any normal array() access. This instructs PB to return the Element Address, rather than the content of this element.


Example #1,

  
; Create a 2d array called MyArray()
  Dim MyArray(100,200)
  
; read the value at 25,70 within MyArray()
  Print "Value:"+Str$(MyArray(25,70))
  
; Tell PB to calc the element address of this array() access
; rather than the retrieve that value at of this element.
  Print "Element Address:"+Str$([MyArray(25,70)])
  
  
  Sync
  WaitKey
  




Example #2

      This Example takes the above it bit further. Here we're manually writing data into our array by grabbing the arrays base pointer (it's address oin memory) then adding the structure size to that and adding on the element address that we wish to read/write to. This is basically an emulation of what occurs every time you manipulate array data.

  
; Create a 2d array called MyArray()
  Dim MyArray(100,200)
  
; read the value at 25,70 within MyArray()
  Print "Value:"+Str$(MyArray(25,70))
  
; Tell PB to calc the element address of this array() access
; rather than the retrieve that value at of this element.
  Print "Element Address:"+Str$([MyArray(25,70)])
  
  
; The following shows how you can calc the raw address (in memory)
; of any element within an array, then write data into.
  
; Get the Address of the first byte of this array in memory
  ArrayAddress=GetArrayPtr(MyArray())
  
; Skip Pass the Header structure of in the array data
  ArrayAddress=ArrayAddress+pbarraystruct_size
  
; Get the Element address at index (25,70) within MyArray()
  ElementAddress = [MyArray(25,70)] * 4
  
; Poke the value 123456 into this cell
  PokeInt ArrayAddress+ElementAddress, 123456
  
  
; display this element using the normal array index method
  Print "Value:"+Str$(MyArray(25,70))
  
  
  Sync
  WaitKey
  




Top






Do I have to calculate the Element Address for 1D arrays ?


     No, if you're dealing with a 1D array, then in this case, the element address and the index will correspond perfectly. So there's really no need to calculate element address when your dealing with 1D arrays.




Top






How do use these Element Addresses & Delta with the array commands ?


      While Most (if not all) the array commands in PB require you nominate the address of the element you wish to alter/copy/search from, we also have to provide them with delta/modulo. This value represents how (what direction and step size) the command moves moves through the array.

      Lets have a look at a bit look of an example. Imagine we have a 2D array of integer values (Table(10,20) and lets assume we wish to copy the row of elements at (10,0) to (5.0) . While we could happily write for next loop and run through the array and do the copy manually, that's really not very efficient as it places a lot of stress on the back the of PB runtime, in particular when copying a lot of elements. So this would present us with an ideal situation to use the "CopyArrayCells" command..

      While most of the code in the example bellow is for setting up and displaying the data, all were really interested in is how we need to setup CopyArrayCells in roder to move the data we want. Which we'll go through not.

      First we calculate the starting element address. Since we wish to copy a row data at row 10, we set our starting index to (10,0) in the table array.

; calc the address of the starting element
  SrcElementAddress = [Table(10,0)]
  


Next we calculate the change in the source address during the copy, the element delta. You can think of the delta as stepping values that PB is adding to both the source and destination element address during the copy. So if copy had a starting element address set at (5,10) and our delta was (0,1), then after one copy loop (during the CopyArrayCells process) the source element address would at index (5,11), then after 2 loops it'd be (5,12) etc etc..

So to copy the row we only in your array, we only want the 2nd dimension to change and since our starting address is set to start at element 0 in the second dimension we'll need to step forward (positively) by a delta of (0,1)

  
; Calc the Delta (direction) the src should move when copying
  SrcElementAddressDelta = [Table(0,1)]
  


Next we calculate the destination element address. This time we want it copy the data into this array at row 9, 0

  
; Calc the Destination Element Address
  DestElementAddress = [Table(9,0)]
  


  
; Calc the Delta (direction) the dest should move when copying
  DestElementAddressDelta = [Table(0,1)]
  


      Now we call the CopyArrayCells command to do the physical work for us. Since the command can copy between pretty much any array, you are required to tell it both the source and destination arrays. So it knows where to get the get from and where to put it.

  
  CopyArrayCells Table(),SrcElementAddress,SrcElementAddressdelta,_
  Table(),DestElementAddress,DestElementAddressdelta,_
  21 ; Number of elements to copy
  




Example #3,


  
  
; Dimension our array
  Dim Table(10,20)
  
  
  
; Fill a row 10 with random values between 0 and 100
  FillRowWithRandomNumbers(10,100)
  
; Dump the array contents to the screen
  ShowArray()
  
  
  
  
; ============================
; Copy Row 10 to row 9
; ============================
  
  
; calc the address of the starting element
  SrcElementAddress = [Table(10,0)]
  
; Calc the Delta (direction) the src should move when copying
  SrcElementAddressDelta = [Table(0,1)]
  
; Calc the Destination Element Address
  DestElementAddress = [Table(9,0)]
  
; Calc the Delta (direction) the dest should move when copying
  DestElementAddressDelta = [Table(0,1)]
  
  CopyArrayCells Table(),SrcElementAddress,SrcElementAddressdelta,_
  Table(),DestElementAddress,DestElementAddressdelta,_
  21 ; Number of elements to copy
  
  
  
; Dump the array contents to the screen
  ShowArray()
  
  
  Sync
  WaitKey
  
  
  
Function FillRowWithRandomNumbers(Rowindex,RandomValueRange)
  For lp=0 To GetArrayElements(Table(),2)
     Table(RowIndex,lp)=Rnd(RandomValueRange)
  Next
EndFunction
  
  
Function ShowArray()
  Print "Array State"
  For lp=0 To GetArrayElements(Table(),1)
     ShowRow(lp)
  Next
  Print ""
EndFunction
  
Function ShowRow(Rowindex)
  For lp=0 To GetArrayElements(Table(),2)
     t$=t$+Str$(Table(Rowindex,lp))+","
  Next
  Print TrimRight$(t$,",")
EndFunction
  
  







Example #4,


  
  
  
; Dimension our array
  Dim Table(10,10)
  
  
; Fill a row 10 with random values between 0 and 100
  FillRowWithRandomNumbers(00,100)
  
  
  
; calc the address of the starting element
  SrcAddress = [Table(0,0)]
  
; Calc the Delta (direction) the src should move when copying
  SrcDelta = [Table(0,1)]
  
  
  
; copy top row to bottom (backwards)
  CopyRow(SrcAddress,Srcdelta,[Table(10,10)],-[Table(0,1)])
  
; Copy Top row down the left hand side
  CopyRow(SrcAddress,Srcdelta,[Table(0,0)],[Table(1,0)])
  
  
; Copy Top row down the right hand side
  CopyRow(SrcAddress,Srcdelta,[Table(10,10)],-[Table(1,0)])
  
; Copy Top row across the table array
  CopyRow(SrcAddress,Srcdelta,[Table(10,10)],-[Table(1,1)])
  
  
  
; Dump the array contents to the screen
  ShowArray()
  
  
  Sync
  WaitKey
  
  
  
  
Function CopyRow(SrcAddress,Srcdelta,DestAddress,DestDelta)
  CopyArrayCells Table(),SrcAddress,Srcdelta,Table(),DestAddress,DestDelta,11
EndFunction
  
  
  
Function FillRowWithRandomNumbers(Rowindex,RandomValueRange)
  For lp=0 To GetArrayElements(Table(),2)
     Table(RowIndex,lp)=Rnd(RandomValueRange)
  Next
EndFunction
  
  
Function ShowArray()
  Print "Array State"
  For lp=0 To GetArrayElements(Table(),1)
     ShowRow(lp)
  Next
  Print ""
EndFunction
  
Function ShowRow(Rowindex)
  For lp=0 To GetArrayElements(Table(),2)
     t$=t$+Digits$( Table(Rowindex,lp) ,3)+","
  Next
  Print TrimRight$(t$,",")
EndFunction
  
  





Top






Can Element Delta's be negative ?


      No, since the delta is generated using the element address calculation and arrays don't allow negative indexes, then you can't use negative values in your delta address calculations either, you can however happily negate the result. So the limitation is easily overcome

      So while this is not possible

  
  Delta = [Myarray(0,-1) ]
  


This is,
  
  Delta = -[Myarray(0,1) ]
  







Top









 
Related Info: ClearArrayCells | CopyArrayCells | Dim | FindArrayCell | SearchHighestArrayCell | SearchLowestArrayCell :
 


(c) Copyright 2002 - 2024 - Kevin Picone - PlayBASIC.com