ARRAYS: SOME QUESTIONS AND ANSWERS

by F. Ho; edited by Renee Gentry
=====================================================================

The information below has been gathered from notes developed within the
Support Department.  They appear in Question/Answer format.
  
**************
  
Q: How is memory allocated for arrays?
A: Memory is allocated "dynamically"
          
For example:
              
If an array of 100 elements has been declared, a pointer is set from
the memvar area to a small chunk of memory area where a reference to
the array elements are kept. This array area is 22 bytes wide times
the number of elements long.  (See figure 1)
  
If the values in the array elements are of type NUMERIC, they are
stored within this area in their respective storage element area.
(See figure 2)
  
If the values were of type CHARACTER, a pointer is set from the
storage element area of that array to any contiguous area of memory
that can hold that string. (See figure 3)


Figure 1:
 
             memvar area
          ------------------                 22 bytes
         |                  |               <--long-->
          ------------------               |-----------|
         |                  |              |-----------|      
          ------------------               |-----------|   Array(100)
         |                  |              |-----------|      |
          ------------------               |-----------|      |
         |  Array(100)      | -----------> |-----------|      
          ------------------               |-----------|
         |                  |              |-----------|
                                         |         |
                 


Figure 2:

 
                22 bytes long
             ------------------  
            |  1)              |            Array(2) = 75
             ------------------             Array(3) = 40
           |  2)  75          |
   |         ------------------ 
Array(100)  |  3)  40          |
   |         ------------------ 
   |        |  4)              |
            ------------------ 
            |                  |
                               
                
 
 
Figure 3:

                                                  ---------------
                22 bytes long               ---> | "Hello There" |
             ------------------            |      ---------------
            |  1)              | ----------
             ------------------         
           |  2)  75          |      
   |         ------------------           Array(1) = "Hello There"
Array(100)  |  3)  40          |          Array(4) = "Waz Happenin?"
   |         ------------------ 
   |        |  4)              | -----
            ------------------       | 
            |                  |      |         -----------------
                                     ------> | "Waz Happenin?" |
                                                -----------------


**************  

Q: How do arrays respond to the TYPE() function?
A:
    i.  a TYPE() done on an array name will return "A" for "Array"
        e.g.
            - declare ARRAY[10]
            - ? type("ARRAY")             - * will return "A"
  
  

   ii.  a TYPE() done on an array element will return "U" for 
        "Undefined" - regardless of any values assigned to it
        e.g.
            - ARRAY[1] = 25
            - ARRAY[2] = "Hello"
            - ? type("ARRAY[1]")          - * will return "U"
            - ? type("ARRAY[2]")          - * will return "U"


   iii. on the other hand, if the array elements are assigned to
        variables, a TYPE() function done on the respective variable
        will return the appropriate type:
        e.g.
            - ARRAY[1] = 25
            - ARRAY[2] = "Hello"
            - A = ARRAY[1] 
            - B = ARRAY[2]
            - ? type("A")                 - * will return "N" 
            - ? type("B")                 - * will return "C"

**************

Q: How would you collapse a declared array?
A: Like all other variables, you can:
    
   1 - RELEASE the array   e.g. release ARRAY
   2 - assign it a false value e.g. ARRAY = .F.
  *3 - if the array was declared in a lower procedure, a return to 
       the higher calling procedure destroys out the array

**************

Q: How would you create a 2-dimensional array in Clipper?
  
A: First, a background note on how arrays are actually "declared"
   or "dimensioned" by any computer languages:

   - When one issues the commands:
                           
                DIM ARRAY(10)       - in BASIC
                DECLARE ARRAY[10]   - in CLIPPER
  
      a single array dimension of 10 elements is allocated.


   - Or when one issues the command:

                DIM ARRAY(3,5) - in BASIC for a two-dimensional array

     a SINGLE array of 15 (3*5) elements is allocated.  The only 
     thing that makes it work like it is two-dimensional is a 
     built-in function in BASIC that does the proper POSITIONAL-
     ALLOCATION for the element concerned.

     This "position-allocator" function is what's missing in Clipper.
     But, you can get around this by making your own UDF which 
     accomplishes the same thing.



Below is an example on how to declare a 2-dimensional array:

        clear
        declare ARRAY[3*5]       && or declare ARRAY[15]

        ARRAY[DIM2(2,3)] = "TEST"     && DIM2 is our pos-alloc function

        ? ARRAY[DIM2(2,3)]            && should print "TEST"
        quit


        function DIM2                 && our position-allocator function
        parameters X,Y
        return(((X - 1) * 5) + Y)


The above can be generalized as:

        clear
        ITEMS = 3
        ELEMENTS = 5
        declare ARRAY[ITEMS * ELEMENTS]

        ARRAY[DIM2(2,3)] = "TEST"

        ? ARRAY[DIM2(2,3)]
        quit

        function DIM2
        parameters X,Y
        return(((X - 1) * ELEMENTS) + Y)


The above declaration will set up a single dimensional array of 15 
elements:

        ARRAY  01
               02
               -
               -
               -
               14
               15

But the POS-ALOC function can make it access the table as if it were:

                   1    2    3
                  --------------
        ARRAY 1  | 01 | 06 | 11 |
                  --------------
              2  | 02 | 07 | 12 |
                  --------------
              3  | 03 | 08 | 13 |
                  --------------
              4  | 04 | 09 | 14 |
                  --------------
              5  | 05 | 10 | 15 |
                  --------------

So that, the command:

        ARRAY[DIM2(2,3)] = "TEST"

will store "TEST" at location:

        ARRAY[DIM2(2,3)]

               or

        ARRAY[(((2-1) * 5) + 3)]

               or

        ARRAY[8]


**************
Note:
  
You CANNOT do a GET into an unitialized array.  Doing so will return a
runtime error message of "Type conflict in subscript" ,or it will
just go right through the read.

        @ 12,12 get ARRAY[1]        && invalid
        read


Workaround:

        XX = ARRAY[1]
        @ 12,12 get XX
        read


or, at least initialize the array element you want to do a GET on:

        ARRAY[1] = space(10)
        @ 12,12 get ARRAY[1]
        read

--End:ARRAYS.TXT  
