next up previous
Next: Stacks Up: Data Structures Previous: Example: Bubble Sort

2D Arrays

A two-dimensional array is a table with R rows and C columns, written R x C. An element of the array is specified by [r,c], where r is the row and c is the column. The figure below illustrates a 3 x 4 array with the elements labelled by row and column.

tabular163

The number of elements in an array equals the number of rows, R, times the number of columns, C. In C, arrays begin with an index of 0, thus the declaration:

char A_2D[R,C];

creates an array containing R*C elements. The index of the last row is R-1 and the index of the last column is C-1.

If the row and column indices do not begin at zero, as in the Pascal declaration:

A_2D:   array[first_row .. last_row,
              first_col .. last_col] of char;

then the number of elements in the array is given by:

number_of_elements = 
    ( last_row - first_row + 1) (last_col - first_col + 1).

A two-dimensional array in SAL is declared as:

A_2D:   <type>  initial_value:number_of_elements

where <type> is either .byte or .word. If the size of the array elements is not a byte or a word, then the array size is:

array_size = ( number_of_elements ) ( size_of_element ),

where size_of_element is 1 for a byte array and 4 for an integer array. An equivalent SAL declaration for the array is:

A_2D:   .space  <array_size>

In this declaration, <array_size> must be an integer constant.

The memory arrays m[] and M[] are one-dimensional. A two-dimensional array is an array of one-dimensional arrays. In row-major order, a two-dimensional array is stored as an array of rows in the memory array. The ordering of the elements for a 3 x 4 array is shown below:

tabular188

In the Pascal and C programming languages, arrays are stored in row-major order. In FORTRAN, arrays are stored in column-major order as an array of columns. The ordering of the elements for the same 3 x 4 array in column-major order is shown below:

tabular202

Whether an array is stored in row-major or column-major order depends on the implementation chosen by the compiler or the assembly language programmer.

The address of an element in a 2D array stored in row-major (column-major) order is computed by skipping entire rows (columns) to reach the address of the desired row (column) and then computing the address of the desired element in the row (column).

For a byte array in row-major order, element A_2D[r,c] is given by

tabular215

Consider the 3 x 4 C array declared as:

char A_2D[3,4];

The number of elements in the array is:

number_of_elements = (2 - 0 + 1) (3 - 0 + 1) = 12

A SAL declaration for the array is:

A_2D:   .byte   0:12

or

A_2D:   .space  12

The address of element [1,3] is calculated using row-major ordering:

tabular221

In a row-major array with elements of size size_of_element, element A_2D[r,c] is given by:

tabular225

For column-major order, the row and column terms in the formula are reversed:

tabular231

Consider a 10 x 10 integer array declared in C as:

int A_2D[10,10];

A SAL declaration for this array is:

A_2D:   .word   0:100   # 100 element integer array

or

A_2D:   .space  400     # 100 element integer array

The first declaration initializes all the array elements to 0, as shown below:

tabular237

The following code changes the elements in the third column to 1's, as shown below:

tabular246

#
#       SAL code to initialize a 10 x 10 integer array to 0,
#       except the third column, which is set to 1's.
#       Array is stored in row-major order.
#
        .data
A_2D:   .word   0:100   # 100 element integer array
C:      .word           # column index
R:      .word           # row index
Base:   .word           # base address of array
I:      .word           # address of element [R,C]
NRows:  .word   10      # number of elements in a column
NCols:  .word   10      # number of elements in a row
Size:   .word   4       # size of the elements
        .text
__start:
        move    R, 0    # initialize row index
        move    C, 2    # initialize column index
        la      Base, A_2D      # load base address of array
Loop:   beq     R, NRows, Next  # if R > NRows, done
        mul     I, R, NCols     # skip R rows
        add     I, I, C         # skip C columns
        mul     I, I, Size      # multiply by element size
        add     I, I, Base      # add base address to element address
        move    M[I], 1 # A_2D[R,C] := 1
        add     R, R, 1 # increment row index
        b       Loop
Next:   # more code goes here

Note that the difference between the addresses of elements [r+1,c] and [r,c] is given by:

tabular237

When performing array operations down a column (row), a more efficient address computation is to simply increment the array index by the number of elements in a row (column) times the size of the elements.


next up previous
Next: Stacks Up: Data Structures Previous: Example: Bubble Sort

CS 301 Class Account
Wed Nov 3 15:29:25 AST 1999