Arrays Overview


An array is a collection of variables of the same type referred to by a single, common name. Arrays can have more than one dimension. While C# arrays are similar to arrays in other languages (such as C++) they have one important distinguishing feature - they are implemented as class objects. Several important advantages are gained by implementing arrays as class objects. For example, arrays can be garbage collected.

1 Dimensional Arrays

A 1 dimensional array is a continguous list of related variables. To declare a 1 dimensional array in C#, the following syntax is adopted.

type[] array-name = new type[size];

The type is the type of each item in the array. The array-name is the name by which the array is accessed. The portion

type[] array-name
of the above syntax declares an array reference and it is subsequently initialized via the new operator. The new operator specifies the size of the array. From this it is apparent that in C# arrays are dynamically allocated.

To allocate an array of 10 integers, the following syntax may be adopted.

int[] iarray = new int[10];

This may be separated into two components as follows:

int[] iarray;
iarray = new int[10];

where the array reference declaration is separated from the dynamic allocation.

A simple example that uses arrays to take the average of 10 floating point values is shown below.

// Average - Averaging an Array of Doubles

using System;

class Arrays
{
    static void Main()
    {
        double[] darray = new double[10];

        darray[0] = .5;
        darray[1] = 1.5;
        darray[2] = 2.5;
        darray[3] = 3.5;
        darray[4] = 4.5;
        darray[5] = 5.5;
        darray[6] = 6.5;
        darray[7] = 7.5;
        darray[8] = 8.5;
        darray[9] = 9.5;

        double average=0;

        for (int i = 0; i < darray.Length; i++)
            average += darray[i];

        average /= darray.Length;

        Console.WriteLine("Average = " + average);
    }
}

The array of doubles is called darray. An array of 10 doubles is dynamically allocated and each element of the array is individually initialized. A for loop is then used to sum the array and subsequently the sum is divided by the number of elements; thereby yielding the average. The property Length is used to perform the calculation. This property yields the number of elements in the array.

Perhaps a more mentally taxing activity is to use arrays to calculate prime numbers. A formula for prime numbers has eluded mathematicians to date, but it is possible to generate primes from an array. The larger the number of required primes, the bigger the array that is used. An array of booleans is used. Below is the program that generates primes up to 100.

// Sieve - A Sieve of Prime Numbers

using System;

enum Primes
{
    Size = 100
}

class Program
{
    static void Main()
    {
         bool[] primes = new bool[(int)Primes.Size];

         primes[0] = false; primes[1] = false;

         for (int i = 2; i < (int)Primes.Size; i++)
             primes[i] = true;

         int Limit = (int)Math.Sqrt((double)Primes.Size);

         for (int j = 2; j < Limit; j++)                          // starting with 2 step along the array
             if (primes[j])                                       // if a prime is found...
                 for (int k = 2; k * j < (int)Primes.Size; k++)   // use a loop to knock out all its multiples
                     primes[k * j] = false;

         for (int l = 1; l < (int)Primes.Size; l++)  // now print out what is left - the primes
             if (primes[l]) Console.WriteLine(l);

     }
}

The program produces the following printout.

2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97

At the top of the program, an enumeration is used to define the constant that specifies the size of the array to be used. Although enumerations have not yet been covered, their use is fairly intuitive so it should be clear from the program what is going on. Note that it is good form to proceed in this way because the program can be adjusted to print out all primes up to 1000 (say) by changing just one line. Using enumerations for symbolic constants is a very good idea in general, even when type casting is required (as it is above).

An array of booleans is declared and allocated with the following statement.

bool[] primes = new bool[(int)Primes.Size];

The enumerator Primes.Size determines how many bools are allocated and how many primes are calculated. Zero and one are set to be false (non-prime) manually. Then initially, all numbers from 2 up to the limit are flagged as prime (set to true). Those that are not prime will then be systematically set to false in what follows.

A loop starting at 2 and proceeding to the square root of the array size is then entered. This loop takes each prime and knocks out its multiples - because they are non-prime. A nested loop is used to knock out the multiples of each prime. When the outer loop finishes, only primes are left in the array. Finally, a loop is then used on the array to signal which elements are prime.