Introduction to Programming Using Visual Basic 2005, An (6th Edition)
7.1. Creating and Accessing ArraysA variable (or simple variable) is a name to which Visual Basic can assign a single value. An array variable is a collection of simple variables of the same type to which Visual Basic can efficiently assign a list of values. Consider the following situation: Suppose that you want to evaluate the exam grades for 30 students. Not only do you want to compute the average score, but you also want to display the names of the students whose scores are above average. You might place the 30 pairs of student names and scores in a text file and run the program outlined: Private Sub btnDisplay_Click(...) Handles btnDisplay.Click Dim student1 As String, score1 As Double Dim student2 As String, score2 As Double Dim student3 As String, score3 As Double . . Dim student30 As String, score30 As Double 'Analyze exam grades Dim sr As IO.StreamReader = IO.File.OpenText("SCORES.TXT") student1 = sr.ReadLine score1 = CDbl(sr.ReadLine) student2 = sr.ReadLine score2 = CDbl(sr.ReadLine) . . student30 = sr.ReadLine score30 = CDbl(sr.ReadLine) sr.Close() 'Compute the average grade . . 'Display names of above average students . . End Sub This program is going to be uncomfortably long. What's most frustrating is that the 30 Dim statements and 30 pairs of statements reading from the file are very similar and look as if they should be condensed into a short loop. A shorthand notation for the many related variables would be welcome. It would be nice if we could just write For i As Integer = 1 To 30 studenti = sr.ReadLine scorei = CDbl(sr.ReadLine) Next Of course, this will not work. Visual Basic will treat studenti and scorei as two variables and keep reassigning new values to them. At the end of the loop, they will have the values of the thirtieth student. Declaring an Array Variable
Visual Basic provides a data structure called an array that lets us do what we tried to accomplish in the loop. The variable names, similar to those in the preceding program, will be student(0), student(1), student(2), student(3), ..., student(29) and score(0), score(1), score(2), score(3), ..., score(29)
We refer to these collections of variables as the array variables student() and score(). The numbers inside the parentheses of the individual variables are called subscripts, and each individual variable is called a subscripted variable or element . For instance, student(3) is the fourth subscripted variable of the array student(), and score(20) is the 21st subscripted variable of the array score(). The elements of an array are assigned successive memory locations. Figure 7.1 shows the memory locations for the array score(). Figure 7.1. The array score().
Array variables have the same kinds of names as simple variables. If arrayName is the name of an array variable and n is an Integer literal, variable, or expression, then the declaration statement Dim arrayName(n) As varType reserves space in memory to hold the values of the subscripted variables arrayName(0), arrayName(1), arrayName(2), ..., arrayName(n). The value of n is called the upper bound of the array. The number of elements in the array,n+1, is called the size of the array. The subscripted variables will all have the same data type; namely, the type specified by varType. For instance, they could be all String variables or all Integer variables. In particular, the statements Dim score(29) As Double Dim score(29) As Double
declare the arrays needed for the preceding program. Values can be assigned to individual subscripted variables with assignment statements and displayed in text boxes and list boxes just as values of ordinary variables. The default initial value of each subscripted variable is the same as with an ordinary variable; that is, the keyword Nothing for String types and 0 for numeric types. The statement Dim score(29) As Double
sets aside a portion of memory for the Integer array score() and assigns the default value 0 to each element. The statements score(0) = 87 score(1) = 92
assign values to the zeroth and first elements. The statements For i As Integer = 0 To 2 lstBox.Items.Add(score(i)) Next
then produce the following output in the list box: 87 92 0 As with an ordinary variable, an array declared in the Declarations section of the Code window is class-level. That is, it will be visible to all procedures in the form, and any value assigned to it in a procedure will persist when the procedure terminates. Array variables declared inside a procedure are local to that procedure and cease to exist when the procedure is exited. Example 1. |
The following program creates a string array consisting of the names of the first four Super Bowl winners. Figure 7.2 shows the array created by the program. Figure 7.2. The array teamName() of Example 1.
Private Sub btnWhoWon_Click(...) Handles btnWhoWon.Click Dim teamName(3) As String Dim n As Integer 'Place Super Bowl Winners into the array teamName(0) = "Packers" teamName(1) = "Packers" teamName(2) = "Jets" teamName(3) = "Chiefs" 'Access array n = CInt(mtxtNumber.Text) txtWinner.Text = teamName(n - 1) End Sub
[Run, type 2 into the masked text box, and click the button.] |
The Load Event Procedure
In Example 1, the array teamName was assigned values within the btnWhoWon_Click event procedure. Every time the button is clicked, the values are reassigned to the array. This manner of assigning values to an array can be very inefficient, especially in programs with large arrays where the task of the program (in Example 1, looking up a fact) may be repeated numerous times for different user input. When, as in Example 1, the data to be placed in an array are known at the time the program begins to run, a more efficient location for the statements that fill the array is in the form's Load event procedure. The Load event occurs automatically when the form is loaded into memory, before it becomes visible on the screen. The header and End Sub statements for the Load event procedure are placed in the Code window when you double-click on the form. A typical header looks like
Private Sub frmName_Load(...) Handles MyBase.Load
The keyword MyBase is similar to the Me keyword and refers to the form being loaded. Example 2 uses the frmBowl_Load procedure to improve on Example 1.
Example 2.
The following improvement on Example 1 makes teamName () a class-level array and assigns values to the elements of the array in the frmBowl_Load procedure: Dim teamName(3) AsString Private Sub btnWhoWon_Click(...) Handles btnWhoWon.Click Dim n As Integer n = CInt(mtxtNumber.Text) txtWinner.Text = teamName(n - 1) End Sub Private Sub frmBowl_Load(...) HandlesMyBase.Load 'Place Super Bowl Winners into the array teamName(0) = "Packers" teamName(1) = "Packers" teamName(2) = "Jets" teamName(3) = "Chiefs" End Sub |
Like ordinary variables, array variables can be declared and assigned initial values at the same time. A statement of the form
Dim arrayName() As varType = {value0, value1, value2, ..., valueN}
declares an array having upper bound N and assigns value0 to arrayName(0), value1 to arrayName(1), value2 to arrayName(2), ..., and valueN to arrayName(N). For instance, in Example 4, the Dim statement and frmBowl_Load event procedure can be replaced by the single line
Dim teamName() As String = {"Packers", "Packers", "Jets", "Chiefs"}
The GetUpperBound Method
The value of arrayName.GetUpperBound(0) is the upper bound of the array. For instance, in Example 1, the value of teamName.GetUpperBound(0) is 3.
ReDim Statement
After an array has been declared, its size (but not its type) can be changed with a statement of the form
ReDim arrayName(m)
where arrayName is the name of the already declared array and m is an Integer literal, variable, or expression. Note: Since the type cannot be changed, there is no need for an "As dataType" clause at the end of the ReDim statement.
Visual Basic allows you to declare an array without specifying an upper bound with a statement of the form
Dim arrayName() As varType
Later, the size of the array can be stipulated with a ReDim statement.
The ReDim statement has one shortcoming: It causes the array to lose its current contents. That is, it resets all String values to Nothing and resets all numeric values to 0. This situation can be remedied by following ReDim with the word Preserve. The general form of a ReDim Preserve statement is
ReDim Preserve arrayName(m)
Of course, if you make an array smaller than it was, data in the eliminated elements will be lost.
Example 3. (This item is displayed on pages 313 - 314 in the print version)
The following program reads the names of the winners of Super Bowl games from a file and places them into an array. The user can type a team's name into a text box and then display the numbers of the Super Bowl games won by that team. The user has the option of adding winners of subsequent games to the array of winners. The program uses the text file SBWINNERS.TXT whose lines contain the names of the winners in order. That is, the first four lines of the file contain the names Packers, Packers, Jets, and Chiefs. Dim teamName() AsString Dim upperBound As Integer Private Sub frmBowl_Load(...) HandlesMyBase.Load Dim sr As IO.StreamReader = IO.File.OpenText("SBWINNERS.TXT") Dim name As String, numLines As Integer 'Count number of lines in the file and assign it minus one to upperBound numLines = 0 Do While (sr.Peek <> -1) name = sr.ReadLine numLines += 1 Loop upperBound = numLines -1 sr.Close() 'Specify the title bar of the form Me.Text = "First " & upperBound + 1 & " Super Bowls" 'Specify the caption of the Next Winner button btnNextWinner.Text = "Add Winner of Game " & upperBound + 2 'Specify the size of the array and fill it with the entries of the file ReDim teamName(upperBound) sr = IO.File.OpenText("SBWINNERS.TXT") For i As Integer = 0 To upperBound teamName(i) = sr.ReadLine Next sr.Close() End Sub
[Run, type "49ers" into the text box, and press the Display button. Then, feel free to add subsequent winners. Your additions will be taken into account when you next press the Display button.] |
Using an Array as a Frequency Table
An array can be used as either a checklist or a frequency table, as in the next example.
Example 4.
The following program requests a sentence as input and records the frequencies of the letters occurring in the sentence. The first element of the array charCount() holds the frequency with which the letter A occurs in the sentence, and so on. Recall that the function Asc associates each character with its position in the ANSI table. Private Sub btnAnalyze_Click(...) Handles btnAnalyze.Click 'Count occurrences of the various letters in a sentence Dim index As Integer Dim sentence, letter As String Dim charCount(25) As Integer 'Examine and tally each letter of the sentence sentence = (txtSentence.Text).ToUpper For letterNum As Integer = 1 To sentence.Length letter = sentence.Substring(letterNum - 1, 1) If (letter >= "A") And (letter <= "Z") Then index = Asc(letter) - 65 'The ANSI value of "A"is 65 charCount(index) += 1 End If Next 'List the tally for each letter of alphabet lstCount.Items.Clear() For i As Integer = 0 To 25 letter = Chr(i + 65) If charCount(i) > 0 Then lstCount.Items.Add(letter & " " & charCount(i)) End If Next End Sub
[Run, type a sentence into the text box, and press the button.] |
Comments
Using a subscript greater than the upper bound of an array is not allowed. For instance, the following lines of code produce the error dialog box shown immediately thereafter:
Dim trees() As String = {"Sequoia", "Redwood", "Spruce"} txtBox.Text = trees(5)
If arrayOne() and arrayTwo() have been declared with the same data type, then the statement
arrayOne = arrayTwo
makes arrayOne() an exact duplicate of arrayTwo(). It will have the same size and contain the same information.
An array can require a large block of memory. After the array is no longer needed, the statement
Erase arrayname
can be executed to release all memory allocated to the array.
Practice Problems 7.1
1. | Write code to declare an array with upper bound 10 and place the names of the five Great Lakes into the first five elements. Use one or two lines of code. |
2. | In Example 3, rewrite the btnDisplay_Click event procedure so that only the first Super Bowl won by the requested team is displayed. The loop should terminate when the team is found. |
3. | When should arrays be used to hold data? |
Exercises 7.1
1. | What is the size of an array whose upper bound is 100? |
2. | What is the upper bound of an array whose size is 100? |
In Exercises 3 through 12, determine the output displayed when the button is clicked.
3. |
Private Sub btnDisplay_Click(...) Handles btnDisplay.Click Dim num As Integer = 2 Dim spoon(num) As String spoon(0) = "soup" spoon(1) = "dessert" spoon(2) = "coffee" txtOutput.Text = "Have a "& spoon(num - 1) & " spoon." End Sub |
4. | Private Sub btnDisplay_Click(...) Handles btnDisplay.Click Dim a(20) As Integer a(5) = 1 a(10) = 2 a(15) = 7 lstOutput.Items.Add(a(5) + a(10)) lstOutput.Items.Add(a(5 + 10)) lstOutput.Items.Add(a(20)) End Sub |
5. | Dim sq(5) As Integer Private Sub btnDisplay_Click(...) Handles btnDisplay.Click Dim t As Integer For i As Integer = 0 To 5 sq(i) = i * i Next lstOutput.Items.Add(sq(3)) t = 3 lstOutput.Items.Add(sq(5 - t)) End Sub |
6. | Dim fh(3) As String Private Sub btnDisplay_Click(...) Handles btnDisplay.Click Dim n As Integer Dim sr As IO.StreamReader = IO.File.OpenText("HORSEMEN.TXT") For i As Integer = 0 To 3 fh(i) = sr.ReadLine Next (Assume that the four lines of the file HORSEMEN.TXT contain the following entries: Miller, Layden, Crowley, Stuhldreher.) |
7. | Dim s(3) As Integer Private Sub btnDisplay_Click(...) Handles btnDisplay.Click Dim t As Integer Dim sr As IO.StreamReader = IO.File.OpenText("DATA.TXT") t = 0 For k As Integer = 0 To 3 s(k) = CInt(sr.ReadLine) t += s(k) Next txtOutput.Text = CStr(t) sr.Close() End Sub (Assume that the four lines of the file DATA.TXT contain the following entries: 3, 5, 2, 1.) |
8. | Dim a(3), b(3) As Integer Dim c(3) As Double Private Sub btnDisplay_Click(...) Handles btnDisplay.Click Dim sr As IO.StreamReader = IO.File.OpenText("DATA.TXT") For i As Integer = 0 To 3 a(i) = CInt(sr.ReadLine) b(i) = CInt(sr.ReadLine) Next sr.Close() For i As Integer = 0 To c.GetUpperBound(0) c(i) = a(i) * b(i) lstOutput.Items.Add(c(i)) Next End Sub
(Assume that the eight lines of the file DATA.TXT contain the following entries: 2, 5, 3, 4, 1, 3, 7, 2.) |
9. | Private Sub btnDisplay_Click(...) Handles btnDisplay.Click 'Compare the values of two chess pieces Dim chess() As string = {"king", "queen", ""} chess(2) = "rook" ReDim Preserve chess(6) chess(3) = "bishop" txtOutput.Text = "A "& chess(2) & " is worth more than a "_ & chess(3) End Sub |
10. | Dim grade(1) As Double Private Sub btnDisplay_Click(...) Handles btnDisplay.Click Dim average As Double ReDim grade(3) grade(2) = 70 grade(3) = 80 average = (grade(0) + grade(1) + grade(2) + grade(3)) / 4 txtOutput.Text = "Your average is "& average End Sub Private Sub frmGrades_Load(...) Handles MyBase.Load grade(0) = 89 grade(1) = 91 End Sub |
11. | Dim score() As Double = {71, 68, 69} Private Sub btnDisplay_Click(...) Handles btnDisplay.Click 'Find the sum of four scores Dim total As Double ReDim Preserve score(3) score(3) = 72 total = score(0) + score(1) + score(2) + score(3) txtOutput.Text = "Your total is "& total & "." End Sub |
12. | Dim band() As String = {"soloist", "duet", "trio", "quartet"} Private Sub btnDisplay_Click(...) Handles btnDisplay.Click Dim num As Integer ReDim Preserve band(9) band(4) = "quintet" band(5) = "sextet" band(6) = InputBox("What do you call a group of 7 musicians?") num = CInt(InputBox("How many musicians are in your group?")) txtOutput.Text = "You have a "& band(num - 1) & "." End Sub
(Assume that the first response is septet and the second response is 3.) |
In Exercises 13 through 18, identify the errors.
13. | Dim companies(100) As String Private Sub frmFirms_Load(...) Handles MyBase.Load Dim recCount Integer Dim sr As IO.StreamReader = IO.File.OpenText("FIRMS.TXT") recCount = CInt(sr.ReadLine) ReDim companies(recCount - 1) As String For i As Integer = 0 To recCount - 1 companies(i) = sr.ReadLine Next sr.Close() End Sub
|
(Assume that the file FIRMS.TXT contains a list of companies and the first line of the file gives the number of companies.)
14. | Dim p(100) As Double Private Sub btnDisplay_Click(...) Handles btnDisplay.Click For i As Integer = 0 To 200 p(i) = i / 2 Next End Sub |
15. | Dim a(10) As Integer Private Sub btnDisplay_Click(...) Handles btnDisplay.Click Dim sr As IO.StreamReader = IO.File.OpenText("DATA.TXT") For i As Integer = 0 To 8 a(i) = CInt(sr.ReadLine) Next sr.Close() For k As Integer = 0 To 8 a(k) = a(5 - k) Next End Sub
(Assume that the nine lines of the file DATA.TXT contain the following entries: 1, 2, 3, 4, 5, 6, 7, 8, 9.) |
16. | Private Sub btnDisplay_Click(...) Handles btnDisplay.Click Dim films() As String = {"Gladiator", "Titanic"} lstOutput.Items.Add(films) End Sub |
17. | Private Sub btnDisplay_Click(...) Handles btnDisplay.Click Dim amount(2) As Integer = {7, 11, 14} Dim total As Integer = 0 For i As Integer = 0 To 2 total += amount(i) Next txtOutput.Text = CStr(total) End Sub |
18. | Private Sub frmNames_Load(...) Handles MyBase.Load Dim recCount As Integer Dim sr As IO.StreamReader = IO.File.OpenText("DATA.TXT") recCount = CInt(sr.ReadLine) ReDim names(recCount - 1) As String For i As Integer = 0 to recCount - 1 names(i) = sr.ReadLine Next sr.Close() End Sub
(Assume that the four lines of the file DATA.TXT contain the following entries: 3, Tom, Dick, Harry.) |
19. | Assuming that the array river() is as follows, fill in the empty rectangles to illustrate the progressing status of river() after the execution of each program segment: temp = river(0) river(0) = river(4) river(4) = temp
temp = river(0) For i As Integer = 0 To 3 river(i) = river(i + 1) Next river(4) = temp
|
20. | Assuming the array cat() is as follows, fill in the empty rectangles (on the next page) to show the final status of cat() after executing the nested loops: For i As Integer = 0 To 2 For j As Integer = 0 To 3 - i If cat(j) > cat(j + 1) Then temp = cat(j) cat(j) = cat(j + 1) cat(j + 1) = temp End If Next Next
Dim gap As Integer = 2 Do While gap <= 1 Do doneFlag = True For i As Integer = 0 To 3 - gap If cat(i) > cat(i + gap) Then temp = cat(i) cat(i) = cat(i + gap) cat(i + gap) = temp doneFlag = False End If Next Loop Until doneFlag = True gap = CInt(gap / 2) Loop
|
21. | The subscripted variables of the array a() have the following values: a(0) = 4, a(1) = 6, a(2) = 3, a(3) = 1, a(4) = 2, a(5) = 5, a(6) = 8, a(7) = 7. Suppose i = 2, j = 4, and k = 5. What values are assigned to n when the following assignment statements are executed?
|
22. | The array monthName() holds the following three-character strings: monthName(0)="Jan", monthName(1)="Feb", ..., monthName(11)="Dec"
|
23. | Modify the program in Example 3 to display "Never Won a Super Bowl" if the specified team has never won a Super Bowl game. |
24. | Modify the program in Example 3 so that the text file SBWINNERS.TXT is only read once. |
In Exercises 25 through 36, write a line of code or program segment to complete the stated task.
25. | Suppose the Integer array quantities() has been declared with an upper bound of 100 and data have been placed into several elements of the array. Write one line of code that will restore the values of all the elements to their default value of 0. | ||||||||||||||||||||||||||||||
26. | Write code to declare an array of size 20 and place the names Jerry, George, Elaine, and Kramer into the first four elements. Use one or two lines of code. | ||||||||||||||||||||||||||||||
27. | Declare the string array marx() with upper bound 3 so that the array is visible to all parts of the program. Assign the four values Chico, Harpo, Groucho, and Zeppo to the array before any buttons are pressed. | ||||||||||||||||||||||||||||||
28. | Declare the string array stooges() to have size 3 so that the array is local to the event procedure btnStooges_Click. Assign the three values Moe, Larry, and Curly to the array as soon as the button is clicked. | ||||||||||||||||||||||||||||||
29. | The arrays a() and b() have been declared to have upper bound 4, and values have been assigned to a(0) through a(4). Store these values in array b() in reverse order. | ||||||||||||||||||||||||||||||
30. | Given two arrays of type Double, p() and q(), each with upper bound 20, compute the sum of the products of the corresponding array elements, that is, p(0)*q(0) + p(1)*q(1) + p(2)*q(2) + ... + p(20)*q(20) | ||||||||||||||||||||||||||||||
31. | Display the values of the array a() having upper bound 29 in five columns, like the following:
| ||||||||||||||||||||||||||||||
32. | A list of 20 digits, all between 0 and 9, is contained in a text file. Display the frequency of each digit. | ||||||||||||||||||||||||||||||
33. | Compare two arrays a() and b() of size 10 to see if they hold identical values, that is, if for all i from 0 through 9. | ||||||||||||||||||||||||||||||
34. | Calculate the sum of the entries with odd subscripts in an integer array a() of size 10. | ||||||||||||||||||||||||||||||
35. | Twelve exam grades are stored in the array grades(). Curve the grades by adding 7 points to each grade. | ||||||||||||||||||||||||||||||
36. | Read 10 digits contained in a text file into an array and then display three columns in a list box as follows: column 1 should contain the original 10 digits, column 2 should contain these digits in reverse order, and column 3 should contain the averages of the corresponding digits numbers in columns 1 and 2. | ||||||||||||||||||||||||||||||
37. | Thirty scores, each lying between 0 and 49, are given in a text file. Write a program that uses these scores to create an array frequency() as follows: frequency102 = # of scores < 10 frequency112 = # of scores such that 10 < = score < 20 frequency122 = # of scores such that 20 < = score < 30 frequency132 = # of scores such that 30 < = score < 40 frequency142 = # of scores such that 40 < = score < 50 The program should then display the results in tabular form as follows:
| ||||||||||||||||||||||||||||||
38. | Write a program that asks the user for a month by number and then displays the name of that month. For instance, if the user inputs 2, the program should display February. Hint: Create an array of 12 strings, one for each month of the year. | ||||||||||||||||||||||||||||||
39. | The file USPRES.TXT contains the names of the 43 U.S. Presidents in the order they served. Write a program that places the names in an array, supplies all presidents having a requested first name, and supplies all presidents for a requested range of numbers. The following is one possible outcome: | ||||||||||||||||||||||||||||||
40. | The file COLORS.TXT contains the names of the colors of Crayola®[*] crayons in alphabetical order. Write a program to read the colors into an array and then display the colors beginning with a specified letter. The program should declare an array with upper bound 50 and then increase the size of the array by 10 elements whenever it runs out of space to store the colors. One possible outcome is the following: [*] Crayola® is a registered trademark of Binney & Smith. | ||||||||||||||||||||||||||||||
41. | An anagram of a word or phrase is another word or phrase that uses the same letters with the same frequency. Punctuation marks and spaces are ignored. Write a program that requests two words or phases as input and determines if they are anagrams of each other. (Test the program with the pair of phrases DWIGHT DAVID EISENHOWER and HE DID VIEW THE WAR DOINGS.) |
Solutions to Practice Problems 7.1
1. | Two possible answers are as follows: Dim lakes() As String = {"Huron", "Ontario", "Michigan", _ "Erie", "Superior", "", "", "", "", "", ""} Dim lakes() As String = {"Huron", "Ontario", "Michigan", _ "Erie", "Superior"} ReDim Preserve lakes(10) |
2. | This task consists of searching through an array and is carried out just like the task of searching a text file for a specified item. Replace the For loop with the following code: Do While (teamName(i) <> txtName.Text) And (i > upperBound) i += 1 Loop If teamName(i) = txtName.Text Then lstGamesWon.Items.Add(i + 1) End If
|
3. | Arrays should be used when
|
Категории