Using Arrays

Using Arrays

Before we get to generic syntax, it makes sense to begin with the simplest collection: the array. An array is an indexed collection of objects, all of the same type (all ints, all strings, and so on). C# provides native syntax for the declaration of arrays. To picture a one-dimensional array, imagine a series of mailboxes, all lined up one after the other, as shown in Figure. Each mailbox can hold exactly one object (letter, box, and so on). Each mailbox also has a number, so you can identify which item is in which box. Unlike real-world mailboxes, though, all the mailboxes must hold the same kind of object; you declare the type of object that the mailboxes will hold when you declare the array.

An array of five integers

The important thing about arrays is that you can treat the entire array (the set of mailboxes) as a single entity, with a single name. As you'll see, using loops, you can easily perform an operation on every element within an array in turn.

Declaring Arrays

Declare a C# array with the following syntax:

    type[] array-name;

For example:

    int[] myIntArray;

You are not actually declaring an array. Technically, you are declaring a variable (myIntArray) that will hold a reference to an array of integers. As always, we'll use the shorthand and refer to myIntArray as the array, knowing that what we really mean is that it is a variable that holds a reference to an (unnamed) array.

The square brackets ([]) tell the C# compiler that you are declaring an array, and the type specifies the type of the elements it will contain. In the previous example, myIntArray is an array of integers.

Instantiate an array using the new keyword. For example:

    myIntArray = new int[5];

This statement creates and intializes an array of five integers, all of which are initialized to the value zero.

It is important to distinguish between the array itself (which is a collection) and the elements held in the array (which can be of any type, so long as all the elements in the array are the same type). myIntArray is the array (or, more accurately, the variable that holds the reference to the array); its elements are the five integers it holds.

C# arrays are reference types, created on the heap. Thus, the array to which the variable myIntArray refers is allocated on the heap. The elements of an array are allocated based on their own type. Because integers are value types, the elements in myIntArray will be value types, and thus all the elements will be created inside the block of memory allocated for the array.

The block of memory allocated to an array of reference types will contain references to the actual elements, which are themselves created on the heap in memory separate from that allocated for the array.

Understanding Default Values

When you create an array of value types, each element initially contains the default value for the type stored in the array (see Figure). The statement:

    myIntArray = new int[5];

creates an array of five integers, each of whose value is set to 0, which is the default value for integer types.

Unlike arrays of value types, the reference types in an array are not initialized to their default value. Instead, the references held in the array are initialized to null. If you attempt to access an element in an array of reference types before you have specifically initialized the elements, you will generate an exception.

Assume you have created a Button class. Declare an array of Button objects with the following statement:

    Button[] myButtonArray;

and instantiate the actual array like this:

    myButtonArray = new Button[3];

You can shorten this to:

    Button[] myButtonArray = new Button[3];

This statement does not create an array with references to three Button objects. Instead, this creates the array myButtonArray with three null references. To use this array, you must first construct and assign the Button objects for each reference in the array. You can construct the objects in a loop that adds them one by one to the array, as you'll see later in the chapter.

Accessing Array Elements

You can access the elements of an array using the index operator ([]). Arrays are zero-based, which means that the index of the first element is always zeroin this case, myArray[0].

The Length property of the array tells you how many objects the array holds. Therefore, objects are indexed from 0 to Length-1.

Figure illustrates the array concepts covered so far. In this example, a class named Tester creates an array of Employees and an array of integers, populates the Employee array, and then prints the values of both.

Working with an array

using System;
namespace Learning_CSharp

   // a simple class to store in the array
   public class Employee

      public Employee(int empID)
         this.empID = empID;
      public override string ToString( )
         return empID.ToString( );
      private int empID;
   public class Tester
      static void Main( )
         int[] intArray;
         Employee[] empArray;
         intArray = new int[5];
         empArray = new Employee[3];

         // populate the arrays
         for (int i = 0;i<intArray.Length;i++)
            intArray[i] = i*2;

         for (int i = 0;i<empArray.Length;i++)
            empArray[i] = new Employee(i+1005);

         // output array values
         Console.WriteLine("intArray values:");
         for (int i = 0;i<intArray.Length;i++)
            Console.WriteLine(intArray[i].ToString( ));

         Console.WriteLine("\nemployee IDs:");
         for (int i = 0;i<empArray.Length;i++)
            Console.WriteLine(empArray[i].ToString( ));

The output looks like this:

    intArray values:

    employee IDs:

The example starts with the definition of an Employee class that implements a constructor that takes a single integer parameter. Employee implements the ToString( ) method to print the value of the Employee object's employee ID.

The test method declares and then instantiates a pair of arrays. Initially, the integer array is automatically filled with integers whose value is set to 0, but then you populate it with a for loop. The loop has a counter, i, and you iterate through the loop by setting each element of the array as the index value (i) increases. You set the value in intArray with this statement:

    intArray[i] = i*2;

The first time through the loop, i is equal to 0, and intArray[0] is set to 0*2, which is 0. The next time through, i is 1, and the second element (intArray[1]) is set to the value 2 (1*2). The loop runs until i is equal to intArray.Length, at which point it stops. Note that i is equal to intArray.Length - 1 on the last time through the loop, which is the index of the last element in the array.

It's not hard to remember that arrays start at 0, but it can be tricky to remember that the highest index is actually one less than Length. When you use a loop to iterate through your array, always make sure that your condition for ending the loop is counter < Array.Length, not counter <= Array.Length.

C# is smarter than its C++ and C ancestors; if you do try to write past the end of the array, rather than trampling on random memory, you'll get an "IndexOutOfRange" exception, which will help you find the error quickly and reliably.

In any case, you want always to be on the lookout for what programmers call the "off-by-one" error. A famous example of this is the fence-post error. Imagine you are building a picket fence, where each horizontal board is one foot long. How many uprights do you need to build a 10-foot fence?[*]

[*] It is tempting to say 10 uprights for a 10-foot fence. But how many do you need for a one-foot fence? You need two, one on each end of the one-foot board. For a two-foot fence, you need three. You always need that extra upright, and so for a 10-foot fence, you need 11 uprights. Watch out for off-by-one errors; they come up a lot.

The Employee array contents must be constructed by hand, because the values of reference types are not initialized when the array is created (the array is filled with null values). You assign values to the elements of empArray the same way you did intArray, with a for loop. This time, though, you have to create a new Employee object to add to each index in the array

Finally, the contents of the arrays are displayed to ensure that they are filled as intended, using the same for loop technique. The five integers print their value first, followed by the three Employee objects.

 Python   SQL   Java   php   Perl 
 game development   web development   internet   *nix   graphics   hardware 
 telecommunications   C++ 
 Flash   Active Directory   Windows