Мощь одномерных массивов
Внутри скобок мы можем писать не только числа, но и переменные, и выражения. От этого программа сразу станет с непривычки менее понятной, однако приобретет необыкновенную мощь.
Привыкаем к переменным и выражениям в качестве индексов. Сначала мы должны привыкнуть к переменным и выражениям в качестве индексов. Вот три эквивалентных варианта программы, распечатывающей длины удавов. Вы должны без компьютера убедиться, что все три варианта распечатают одно и то же.
Private Sub Button6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button6.Click
Dim dlina() As Integer = {0, 500, 400, 600}
Debug.WriteLine(dlina(1))
Debug.WriteLine(dlina(2))
Debug.WriteLine(dlina(3))
End Sub
Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click
Dim dlina() As Integer = {0, 500, 400, 600}
Dim i As Integer
i = 1
Debug.WriteLine(dlina(i))
i = 2
Debug.WriteLine(dlina(i))
i = i + 1
Debug.WriteLine(dlina(i))
End Sub
Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click
Dim dlina() As Integer = {0, 500, 400, 600}
Dim i As Integer = 1
Dim k As Integer = 10
Debug.WriteLine(dlina(i))
Debug.WriteLine(dlina(k - 8))
i = 2
k = 1
Debug.WriteLine(dlina(k + i))
End Sub
Мощи здесь пока не видно, увидите чуть позже.
Вопрос: Продолжаем привыкать. Не подходя к компьютеру, ответьте, что напечатает следующая процедура:
Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
Dim a(100), i As Integer
i = 2 : a(3) = 10 : a(i) = 100 : a(i + 6) = a(i) + a(5 - i) : i = 0 : Debug.WriteLine(a(i + 3) + a(2) + a(i + 8))
End Sub
Ответ: 220
Хорошо бы вы получили правильный ответ самостоятельно. Если не смогли получить, значит вы не понимаете чего-то важного или просто невнимательны. В этом случае читайте пояснение:
Первая ступенька: i = 2 ®a(3) = 10 ®a(2) = 100 ®a(2 + 6) = a(2) + a(5 - 2) ®i = 0 ®Debug.WriteLine( a(0 + 3) + a(2) + a(0 + 8))
Вторая ступенька: i = 2 ®a(3) = 10 ®a(2) = 100 ®a(8) = a(2) + a(3) ®i = 0 ®Debug.WriteLine( a(3) + a(2) + a(8))
Третья ступенька: i = 2 ®a(3) = 10 ®a(2) = 100 ®a(8) = 110 ®i = 0 ®Debug.WriteLine( 10 + 100 + 110)
Цикл – мощное оружие при работе с массивами. Теперь решим задачу про суммарную длину удавов в предположении, что удавов не 3, а 1000:
Private Sub Button9_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button9.Click
Dim Число_удавов As Integer = 1000
'Верхняя граница индекса может быть выражена переменной величиной:
Dim dlina(Число_удавов) As Integer
Dim summa, i As Integer
'Вводим с клавиатуры длины тысячи удавов, хоть это и утомительно и никто так не делает.
'Здесь на первом выполнении цикла i=1 и поэтому компьютер вводит число в ячейку dlina(1),
'на втором - i=2 и поэтому компьютер вводит число в ячейку dlina(2) и т.д.
For i = 1 To Число_удавов
dlina(i) = InputBox("Введите длину " & i & "-го удава")
Next
'Определяем суммарную длину тысячи удавов:
summa = 0
For i = 1 To Число_удавов
summa = summa + dlina(i)
Next
Debug.WriteLine(summa)
End Sub
Отлаживая эту программу, возьмите, конечно, вместо числа 1000 какое-нибудь маленькое число.
Пример. Продолжаем привыкать к индексам. Решим еще одну задачу. Дан ряд из 10 произвольных чисел: a(1), a(2), ... , a(10). Подсчитать и напечатать суммы каждой из восьми троек стоящих рядом чисел.
первая тройка: a(1)+a(2)+a(3)
вторая тройка: a(2)+a(3)+a(4)
третья тройка: a(3)+a(4)+a(5)
......
восьмая тройка: a(8)+a(9)+a(10)
Вот программа:
Private Sub Button10_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button10.Click
Dim a() As Integer = {0, 5, 3, 4, 0, 20, 10, 23, 2, 9, 1000}
Dim i As Integer
For i = 1 To 8
Debug.WriteLine(a(i) + a(i + 1) + a(i + 2))
Next
End Sub
Вот что она напечатает:
Следующие два задания очень важны, так как это ваши первые задания по массивам.
Задание 102.
Напишите с использованием массива программу вычисления среднегодовой температуры. Подсчитайте также количество теплых дней в году (когда температура выше 20 градусов). Узнайте, каким по порядку идет самый жаркий день. (Для отладки в компьютере годом можно считать неделю.)
Задание 103.
Вычислить и распечатать первые 139 чисел Фибоначчи.
Двумерные массивы
Поясним суть двумерных массивов на простом примере. Пусть на целом ряде метеостанций, расположенных в разных точках земного шара, в течение многих дней измеряли температуру воздуха. Показания термометров свели в таблицу. Ограничимся для экономии места тремя станциями и четырьмя днями.
1-й день | 2-й день | 3-й день | 4-й день | |
Метеостанция 1 | -8 | -14 | -19 | -18 |
Метеостанция 2 | ||||
Метеостанция 3 |
Требуется (в порядке возрастания трудности):
1) Распечатать температуру на 2-й метеостанции за 4‑й день и на 3-й метеостанции за 1‑й день.
2) Распечатать показания термометров всех метеостанций за 2‑й день
3) Определить среднюю температуру на 3-й метеостанции
4) Распечатать всю таблицу
5) Распечатать, в какие дни и на каких метеостанциях температура была в диапазоне 24-26 градусов тепла
Для этого обозначим показания термометров при помощи индексированной переменной с двумя индексами по следующей схеме:
t(1,1) | t(1,2) | t(1,3) | t(1,4) |
t(2,1) | t(2,2) | t(2,3) | t(2,4) |
t(3,1) | t(3,2) | t(3,3) | t(3,4) |
Первый индекс в скобках обозначает номер строки (метеостанция), второй – номер столбца (день) прямоугольной таблицы. Такую таблицу математики называют матрицей.
В памяти отводим массив из ячеек типа Integer под значения индексированной переменной t. Будем называть его двумерным массивом:
Dim t (3, 4) As Integer
Аналогично одномерному массиву, первый индекс здесь будет меняться не от 1 до 3, а от 0 до 3, а второй – от 0 до 4. Таким образом в памяти будет отведен следующий массив ячеек:
t(0,0) | t(0,1) | t(0,2) | t(0,3) | t(0,4) |
t(1,0) | t(1,1) | t(1,2) | t(1,3) | t(1,4) |
t(2,0) | t(2,1) | t(2,2) | t(2,3) | t(2,4) |
t(3,0) | t(3,1) | t(3,2) | t(3,3) | t(3,4) |
Мы просто не будем пользоваться верхней строкой и левым столбцом.
Программа:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim t(3, 4) As Integer
Dim i, j, s As Integer
'Зададим значения элементов массива примитивным присваиванием:
t(1, 1) = -8 : t(1, 2) = -14 : t(1, 3) = -19 : t(1, 4) = -18
t(2, 1) = 25 : t(2, 2) = 28 : t(2, 3) = 26 : t(2, 4) = 20
t(3, 1) = 11 : t(3, 2) = 18 : t(3, 3) = 20 : t(3, 4) = 25
'Выполняем 1 пункт задания:
Debug.WriteLine(t(2, 4) & " " & t(3, 1))
'А теперь распечатаем второй столбец массива (2 пункт задания):
Debug.Write("Второй столбец: ")
For i = 1 To 3 : Debug.Write(t(i, 2) & " ") : Next
Debug.WriteLine("") 'Переводим строку
'Определим среднее значение элементов третьей строки (3 пункт задания):
i = 3
s = 0
For j = 1 To 4 : s = s + t(i, j) : Next
Debug.WriteLine("Средняя температура равна " & s / 4)
'Распечатаем всю таблицу (4 пункт задания):
For i = 1 To 3
For j = 1 To 4
Debug.Write(t(i, j) & " ")
Next j
Debug.WriteLine("") 'Переводим строку
Next i
'Распечатаем станции и дни с температурой 24-26 градусов (5 пункт задания):
For i = 1 To 3
For j = 1 To 4
If t(i, j) >= 24 And t(i, j) <= 26 Then Debug.WriteLine("Станция " & i & " день " & j)
Next j
Next i
End Sub
Вот что напечатает эта программа:
20 11
Второй столбец: -14 28 18
Средняя температура равна 18,5
-8 -14 -19 -18
25 28 26 20
11 18 20 25
Станция 2 день 1
Станция 2 день 3
Станция 3 день 4
Инициализация двумерного массива. Вместо фрагмента, объявляющего массив и задающего его значения присваиванием:
Dim t(3, 4) As Integer
t(1, 1) = -8 : t(1, 2) = -14 : t(1, 3) = -19 : t(1, 4) = -18
t(2, 1) = 25 : t(2, 2) = 28 : t(2, 3) = 26 : t(2, 4) = 20
t(3, 1) = 11 : t(3, 2) = 18 : t(3, 3) = 20 : t(3, 4) = 25
можно использовать более короткую запись:
Dim t ( , ) As Integer = { {99, 99, 99, 99, 99} , {99, -8, -14, -19, -18} , {99, 25, 28, 26, 20} , {99, 11, 18, 20, 25} }
Разберемся в ней. Верхние границы индексов не указываются, но запятая в круглых скобках остается, чтобы было понятно, что массив двумерный, а не одномерный. Чисел в фигурных скобках нужно столько, чтобы заполнить столбцы 0,1,2,3,4 и строки 0,1,2,3. Каждую строку берем в свои фигурные скобки и отделяем от других строк запятой. Весь массив снаружи «обнимается» дополнительной парой фигурных скобок. Ненужные нам нулевую строку и нулевой столбец я заполнил числами 99, а мог бы и любыми другими, так как в программе мы их не используем.
Задание 104.
Вычислить разницу между максимальной и минимальной температурой во всей таблице.
Какие бывают массивы
Массивы бывают не только числовые, но и строковые и типа Date и многие прочие. Например:
Dim s(50) As String
Это означает, что в каждой из 51 ячеек должно находиться не число, а произвольная строка. А объявление
Dim DT(10) As Date
означает, что в каждой из 11 ячеек должна находиться дата.
Пример. Вот элементарный пример использования строкового массива:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim s(50) As String
s(21) = "Привет"
s(22) = s(21) + " всем!!!"
Debug.WriteLine(s(22))
Debug.WriteLine(Len(s(21)))
End Sub
Вот что напечатает эта программа:
Привет всем!!!
Пример. Вот пример работы с массивами других типов:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim b(30, 6) As Boolean
Dim DT(10) As Date
b(2, 3) = False
b(5, 0) = Not b(2, 3)
Debug.WriteLine (b(5, 0))
DT(2) = #1/15/2003 11:59:42 PM#
DT(0) = DT(2).AddDays(10)
If b(5, 0) Then Debug.WriteLine (DT(0))
End Sub
Вот что напечатает эта программа:
True
25.01.2003 23:59:42
Еще пример:
Enum типРуль
вверх
влево
вниз
вправо
End Enum
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
Dim Руль(300) As типРуль
Руль(200) = типРуль.влево
Руль(220) = Руль(200) + 1
Debug.WriteLine(Руль(220))
End Sub
Вот что напечатает эта программа:
вниз
Бывают массивы, состоящие из структур, объектов, но о них мы поговорим позже.
Многомерные массивы. Массивы могут быть одномерные, двумерные, трехмерные, четырехмерные и т.д.: