· Define new terms
· Explain how to setup and use arrays
· Describe the different types of arrays
· Explain how arrays and loops work together
· Describe the methods and properties of the string class
Imagine collecting information about a group of students. A programmer could build a Student class with all the information about a student. There would be room for the student's name, address, birthday, and other information. The program could then declare an object, with its own name, for each student. Each student's information would have to be processed individually. A programmer would have to have a complete set of code for every declared Student object. This would become tedious very quickly. It would be much easier if a collection could be created that could be processed using a loop. Fortunately, C# like most programming languages supports collections like what you need.
Arrays are collections of objects . All objects in an array must be the same type. Arrays may have a single dimension or multiple dimensions. Think of a single dimension array as a line of boxes that all hold the same type of information. The line of boxes has a single name. Each box in the line is numbered. Someone might be given directions to find an item in a specific box in a specific line of boxes. This is how arrays work. An array has a name that identifies the whole list of items. Each item in the array is identified by a number called an index.
Arrays are declared and constructed in two steps. First, a variable is declared as an array of a type. Second, the length of the array is specified and space is allocated for it on the heap. The keyword new is used to construct the array on the heap. The lines below declare and construct an integer array with 25 elements.
int [] iData;
iData = new int [25];
This creates an array of 25 elements whose indexes range from zero to 24. Array index values start at zero. It is important to remember that the highest index value is one less then the total number of elements in the array.
The declaration and construction of an array can be combined in one statement. The statements above can be combined as follows.
int [] iData = new int [25];
Once an array has been allocated, each element in the array must have a value assigned to it. The C# compiler will not allow a program to read from any variable, including an element in an array, unless a value has been assigned.
Individual elements in an array are addressed by using subscripts. A subscript is an integer value that identifies an element in an array. This subscript is enclosed in square brackets. The following line of code sets a value in the third element in the array iData.
iData[2] = 5;
Remember that C# indexes start at zero so the subscript for the third element is two. Subscripts can be integer literals, variables with integer values or even equations or methods that have integer results.
Arrays can be initialized when they are declared. The following code declares an array, allocates space for it and specifies initial values.
int [] testArray = new int[] {1,2,3,4,5,6,7,8,9,0};
The compiler counts the number of data points and allocates the amount of space required. TestArray will have ten elements. The value of testArray[0] is one. The range of values in array elements is dependent on the class type of the array. The size of the array in elements is unrelated to how large or small a value can be stored in the array.
When an array of a reference type is created, each element in the array must be allocated using the new keyword. This will call a constructor for the element and set an initial value. For example, an array of Dice objects might be declared and initialized using the following code.
Dice [] myDie = new Dice [10];
for(int q=0; q<10; q++)
{
myDie[q] = new Dice(6);
}
Attempting to access an element in a reference array before the individual elements have been allocated will result in a run-time error.
There are times when a row of boxes is not enough. You might need several rows of boxes places one on top of another. C# supports this using multidimensional arrays. There are two kinds of multidimensional arrays: rectangular and jagged.
Rectangular arrays are arrays where each row is the same length. The subscripts that address an element in a rectangular array are separated by a comma inside square brackets. The following code declares a rectangular array and sets the value in the first element in the array.
int [,] array2d = new int [5,5];
array2d[0,0] = 125;
A program can also set initial values in a multidimensional array when it is declared. The following code declares and initializes a 3 by 3 array.
int [,] array3by = new int [,] {
{1,2,3},
{5,6,7},
{25,67,99}
};
A jagged array is an array of arrays. In this case, each row may be a different length. The syntax for declaring jagged arrays is different from rectangular arrays.. The array is declared first. After the array is declared, the number of rows is declared. After the number of rows is declared the length of each row must be declared individually. The following code declares a jagged array of three rows and copies a value into the last element.
int [][] jag; // Declare the array
jag = new int [3][]; // Allocate three rows
jag[0] = new int [3]; // First row has 3 elements
jag[1] = new int [4]; // Second row has 4 elements
jag[2] = new int [5]; // Third row has 5 elements
jag[1][4] = 254;
Notice that each dimension in a jagged array has its own set of square brackets for subscripts. This is an important difference between rectangular and jagged arrays.
An array is an object of the array class. As with other classes, the array class has a number of methods and properties that make using them easier. The methods and properties in this chapter fall into two categories - public instance and public static. Public instance methods and properties are related to a specific object. These methods and properties are accessed using a reference to an object. Public static methods are related to the class as a whole. Static methods are referenced using the class name.
Length is an instance property. When used with an array, the length property returns the length of the array in members. For example, the code below displays the number 25 because a five by five two-dimensional array has 25 elements.
int [,] myArray = new int [5,5];
Console.WriteLine("myArray has {0} elements", myArray.Length);
The length property is often used to control loops that process the elements in a single dimension array. The code below adds the elements of an integer array.
total = 0;
for (int j=0;j < testArray.Length; j++)
{
total += testArray[j];
}
Length is a read-only property and cannot be set to a new value.
The rank property, an instance property, holds the number of dimensions of an array. A single dimensioned array has a rank of one. Jagged arrays are considered an array of arrays. The rank property of a jagged array is always one.
Rank, as with length, is helpful when writing general-purpose methods that will accept arrays of different lengths and dimensions.
GetLength is an instance method that returns the length, in elements, of a dimension in an array. This method returns a one-based result. In other words, a zero-based array with a lower bound of zero and an upper bound of nine has a length of ten elements. The GetLength method takes a single parameter that indicates the dimension whose length is returned. The following code demonstrates this method.
int [,,] wild = new int [2,3,4];
Console.WriteLine("Dimension one = {0} two = {1} three = {2} ", wild.GetLength(0), wild.GetLength(1), wild.GetLength(2));
for (int k = allAges.GetLowerBound(0); k <= allAges.GetUpperBound(0); k++)
Console.WriteLine("Item {0} = {1} ",k,allAges[k]);
Initial is an instance method that can only be used with value classes. Value classes include the predefined types such as int, double and bool. Initialize uses the default constructor of the value type to set an initial value for each element in the array. The code below will set each element in the array allAges to zero.
int [] allAges = new int[15];
allAges.Initialize();
This method sets all elements to the same, default, value. This method can only be used on value types that have constructors. Reference types, such as classes, should not use this method. Reference types should use loops to initialize elements on an array.
BinarySearch is used to search for a specific item in a sorted, single dimensioned array. The array is searched using a binary search algorithm. Binary searches only word correctly if the array is in sorted order. The system does not check to make sure the array is sorted. The results of a search of an unsorted array are unpredictable, No error will be generated but items in the array will often not be found.
The most basic form of the BinarySearch method accepts an array and an object to search for in the array. Another overloading of this method accepts a starting and ending index between the array and object parameters. These starting and ending indexes limit the search to that range in the array.
The BinarySearch method returns an integer value that hold either the index of the item in the array if the item is found or a negative number if the item is not found. The absolute value of the negative number, if the item is not found, is the index of the item that would follow the search item if it were in the array.
BinarySearch is a static method in the Array class. This means that the array to be sorted is passed as a parameter to the method that references the class name.
The following sample code searches an array of strings for a specific word. If the word is found its index is displayed. If the word is not found, an error message is displayed.
object oFind = (object) "come";
int index = Array.BinarySearch(sWords, oFind);
if (index >=0)
{
Console.WriteLine ("The word is in element {0}", index);
}
else
Console.WriteLine("The word {0} was not found", oFind);
The Reverse method, a static method, can be used to reverse the sequence of all or part of a single dimensioned array. An entire array is reversed by passing its name for the Reverse method. The following code reverses the order of an array.
int [] rList = new int[] {1,2,3,4,5,6,7,8};
Console.WriteLine("Before Reverse");
DisplayArray(rList);
Array. Reverse(rList);
Console.WriteLine("After Reverse");
DisplayArray(rList);
public static void DisplayArray(Array aList)
{
foreach (int p in aList)
{
Console.Write("{0} ",p);
}
Console.WriteLine();
}
The output for this code is as follows:
Before Reverse
1 2 3 4 5 6 7 8
After Reverse
8 7 6 5 4 3 2 1
The Reverse method can also be used with a start index and the number of elements to be reversed. The first parameter in the Reverse method is the array to reverse. The second parameter is the index to start the reverse. This is zero based so the value zero will start at the first element and one would indicate the second element. The third parameter specifies the number of elements to reverse. This value is a count and not the ending index. For example, the call V Array.Reverse(rList,2,4) reverses four elements starting with element 2, the third element in a zero based array. The following code with sample output shows how this works.
int [] rList = new int[] {1,2,3,4,5,6,7,8};
Console.WriteLine("Before Reverse");
DisplayArray(rList);
Array.Reverse(rList,2,4);
Console.WriteLine("After Reverse");
DisplayArray(rList);
Before Reverse
1 2 3 4 5 6 7 8
After Reverse
8 7 6 5 4 3 2 1
The Sort method is a static member that puts the elements of an array in order. All elements of the specified array are included in the basic sort. The following code shows an example of the Sort method followed by output from the sample code.
int [] rList = new int[] {10,2,13,45,15,6,17,81,25,72};
Console.WriteLine("Before Sort");
DisplayArray(rList);
Array.Sort(rList);
Console.WriteLine("After Sort");
DisplayArray(rList);
Before Sort
10 2 13 45 15 6 17 81 25 72
After Sort
2 6 10 13 15 17 25 45 72 81
The Sort method uses the IComparable interface for the array type. Arrays of a user written class can be sorted if they implement the IComparable interface. Chapter 9 explains how to implement interfaces such as IComparable.
For loops and while loops can obviously be used to process arrays. These loops can be used to initialize all the members on an array, return values from each member or both read and change values. By using the Length property of the array a for loop can easily be set up to process a whole array. If you wanted to add up all the elements in an array, you could use code like the following:
for (int j=0;j < testArray.Length; j++)
{
total += testArray[j];
}
Console.WriteLine("The total of testArray is {0}",total);
C# includes a special looping statement that makes this process even easier however.
The foreach loop will handle all the setup and processing information for dealing with an array. The foreach loop will execute for each and every member of the array. All the programmer has to tell the program is what array to process.
The following code adds all the values in an array called testArray. An iteration variable, called "K" in this example, of the array type is declared and associated with the array. The loop will be executed as many times as needed to process the whole array. Each time the loop executes, K will refer to the next element in the array.
foreach (int K in testArray)
{
total += K;
}
Console.WriteLine("The total of testArray is {0}",total);
The iteration variable in the foreach statement refers to an element in the actual array. Foreach loops can be used to process collections of any type C# uses. All references to K will use values from testArray, but should not be used to change the contents of the array to avoid unpredictable side effects
The iteration variable in the foreach loop must be the declared the same type as the elements of the array. No subscripts are required to access the currently processed element in the array. The loop may access other elements of the array but those accesses must use the full array name including subscripts.
Foreach loops are most often used to process all of the elements in a collection. The break statement can be used to exit a foreach loop as it can be used in a for or while loop. The continue statement can also be used with foreach loops.
The string class represents a string of characters. While not an array is the usual sense, a string is sometimes thought of as an array of characters. There is a different set of properties and methods for strings and arrays though both have a length property. The length property returns the number of characters in a string. An individual character in a C# string can be accessed using an index value. This is similar to addressing an element in an array. For example, the following code will display the third character in the string. Indexing for strings is zero-based as in an array.
Console.WriteLine("Third letter is {0}",inString[2]);
The value of length is always one greater then the largest legal index value. Attempting to access beyond the length of the string will throw and ArgumentException.
The string class is sealed and other classes may not be derived from it. Classes may include string data however.
String Literals
String literals are often used to initialize string objects. String literals are collections of characters inside a set of quotation marks. Strings are enclosed by double quote marks ( " ) while char literals are enclosed in single quotes ( ' ). This is an important distinction to the compiler and attempting to use double quotes for a char or single quotes for a string will generate an error.
The slash character ( \ ) has a special meaning inside a string. This character starts an escape sequence and indicates that the character that follows it is to be treated special. These escape sequences are frequently used in output to the Console object. Some of these codes are listed in the table below.
|
Escape Sequence |
Description |
|
\' |
Single quote |
|
\" |
Double quote |
|
\0 |
Null |
|
\a |
Alert (bell) |
|
\n |
New Line |
|
\r |
Carriage return |
|
\t |
Tab |
If you wish to include a \ in your string there are two options. One option is to double the slash ( \\ ) so that the first slash indicated that the next slash is for real. The other method is to use a special kind of literal called a verbatim string. These strings are indicated by an ampersand ( @ ) in front of the opening quotation mark. All characters inside the quotation marks of a verbatim string are used as specified. Along with slashes, linefeeds and other characters that normally cause a break in a string are permitted. The following shows a string object being initialized with a verbatim string literal.
string fName = @"C:\testing.txt";
String manipulation is an important part of data processing. C# supports a number of useful methods that make searching, changing, comparing and otherwise using string data easy. The next few sections explain some of the methods supported by the string class.
The CompareTo method is used to compare a string variable or constant to a string object. This method returns an integer value that indicates which value is greater. If the two strings have the same value, CompareTo returns a zero. If the source string has a higher alphabetic value then the parameter object, CompareTo returns a one. A negative one is returned if the parameter object has a higher value then the source string. The following code shows a string literal being compared to a source variable named aWord.
int rtn = aWord.CompareTo("aaa")
The CompareTo method is used by the array class Sort method to sort arrays of strings.
The addition operator is overloaded for the string class to support concatenation. Concatenation is the process of adding one string to another. The following code creates a new string that has two string added to each other.
string newString = oldString + "ing";
The Equals method returns a Boolean value that indicates if a source and parameter string object have the same value. The comparison operator (==) is overloaded for the string class and can be used to compare the value of two strings. The following code examples demonstrate the Equals method.
if (aWord.Equals(myString))
{
. . .
}
is equivalent to
if (aWord == myString)
{
. . .
}
The IndexOf method is used to search a string for the first occurrence of a string, character or array of characters. This method returns an integer value that holds the index of the starting location of the string if it is found. A -1 is returned if the search string is not found. The following code returns the index of the first "o" in the inString string.
int x = inString.IndexOf("o")
A second, optional, integer parameter specifies the index position in the string. The following code returns the index of the first occurrence of "o" after the third character in the string.
int x = inString.IndexOf("o",2)
The Insert method is used to add characters in the middle of a string. This method takes two parameters: an integer value that indicates where to insert the string; a string to insert into the original string. The following code creates a new string that inserts " and " between Jack and Jill. The resulting string is "Jack and Jill."
string oldString = "JackJill";
string newString = oldString.Insert(4," and ");
The PadLeft and PadRight methods add spaces or a specified character to a string to create a string of a specified length. The PadLeft method places the original string at the right of the output string by adding leading spaces or characters. The PadRight places the original string at the left of the new string by adding trailing spaces or characters.
The following code adds leading spaces to the first string and trailing dashes to the second string.
string testing = "word";
Console.WriteLine("->{0}<-->{1}<-", testing.PadLeft(10), testing.PadRight(10,'-'));
The resulting output would be:
-> word<-->word------<-
The split method creates an array of strings by splitting the existing string based of an array of characters that is passed to the method. This method is useful for processing information in a string where each piece of information is separated by one or more common characters. For example, a data that uses slashes to separate month, day and year or names separated by commas.
The following code splits a sentence into an array of words by using the space character as a split character.
string inString ="Now is a good time.";
char [] spc = new char [] {' '};
string [] aWords = inString.Split(spc);
The Substring method returns a specified part of an existing string. This method differs from using the index of a string in that it can return a string of characters while the index returns a single character.
This method has two overloads. When used with one parameter, this method will return a string that includes all the characters from the indicated starting position until the end of the string. If two integer parameters are given, Substring will return the number of characters specified in the second parameter starting at the location indicated by the first parameter. It is important to understand that the second parameter is the number of characters and not the index of the last character to copy.
The ToLower and ToUpper methods returns a string with all letters set to lower or upper case. These methods are often used to set a string to a known case so that comparisons may be made easier or to guarantee that characters are presented in an appropriate state. The following code ensures that a name is displayed formatted as capital letter first followed by all lower case letters.
Console.WriteLine("{0}{1}", myName.ToUpper()[0], myName.Substring(1).ToLower());
Arrays hold several values of the same type. Each value is identified by a number or expression that evaluates to a number that is referred to as an index. Arrays may hold either value or reference types. Reference arrays are initialized by a constructor when space for the element is allocated using the new keyword.
Single dimensioned arrays are similar to a row of storage locations. Arrays may be created with multiple dimensions similar to a grid (two dimensions) or a box (three dimensions). The indexes of rectangular arrays, where all the rows or columns are the same length, are enclosed in a single set of square brackets.
Jagged arrays are arrays of arrays. The length of difference rows in jagged arrays may be different from each other. Jagged arrays have each dimensions indexes in its own set of square brackets.
C# provides a number of static and instance methods and properties to help use arrays.
The instance property Length holds the number of elements in an array. Instance methods include: Rank which returns the number of dimensions of an array; GetLength which returns the number of elements in a dimension of an array; GetLowerBound and GetUpperBound which return the starting and ending index values of an array; and Initialize which set all values in an array to their default value.
The static arrays are characteristic of the Array class and specific array names are passed into the class for processing. Instance arrays refer to a specific array. The static methods include: BinarySearch for searching sorted arrays; Reverse for reversing the contents of an array; Sort for putting the contents of an array in order.
The foreach loop can be used to process each element in an array without specifying the start or ending index. The foreach loop uses a non-indexed reference to each element in the array that is used to process that information inside the loop.
The string class holds strings of characters. Special string class methods can be used to manipulate the information in a string. Strings have a length property and are indexed similarly to arrays.
1. How many different types of values can be in one array?
2. What form of loop is designed to process all the elements of an array?
3. Describe the difference between calling instance and static methods?
4. What method is used to search a sorted array for a specific element?
5. Describe the differences between a rectangular array and a jagged array?
6. What property of an array can be read to find the number of elements in an array?
7. What types of expressions may be used as array indexes?
8. What instance method can be used to set starting values for value type arrays?
9. Describe the differences between the GetLength method and the Length property?
10. How is the index range of an array related to the values the array can hold?
Concatenation Concatenation is the process of adding one string to another.
Element An element of an array is a specific piece of information in the array. Each element is a separate value but all elements of an array are the same type.
Index A number that indicates which of several values in an array to use.
Parallel Arrays Two or more arrays of the same length that sort related information. The information in a location or index in one array is related to the information in the other arrays that have the same location or index.
Subscript A subscript is the index value of an array element as it is used in a statement. The subscript appears inside a set of square brackets.
Projects
The game is played on a collection of cells. Each cell has eight neighboring cells. Each cell either is occupied by a “life” or is empty. The state of a cell for a new generation is determined by a few simple rules.
· If a life has no neighbors or only one, it dies of loneliness.
· If a life has four or more neighbors, it dies of overcrowding.
· If a life has either two or three neighbors, it survives to the next generation.
· If a cell has no life in it but has exactly three neighbors, a new life is born.
Create a program to allow a user to set up a game board with initial life values and generate new generations of the board.
· Month the driver was born (two characters including a leading zero if needed)
· The first and last letter of the driver’s family name
· The first letter of the driver’s first name
· The year the driver was born (last two characters of a four digit year)
· The day of the month the driver was born (two characters including a leading zero if needed)
· A final character that is usually a one. This is used in cases where two people would otherwise have the same number. You will use a one in your program.
Your task is to write a program that will ask for and read in a person’s first and last name and their birthday. It will then display that person’s license number. The number for John Doe, born July 4, 1976 would look like:
07DEJ76041
Note that the letters are case sensitive, thus in all uppercase. This is important because the user will enter some letters as lowercase. The program will have to make sure that lowercase letters are converted to uppercase letters.