ПОНЯТНО О Visual Basic NET (том 2)

Выход из цикла с помощью If


Бесконечный цикл. Начнем с привычного. Задача: При помощи цикла печатать такие текст и числа:

Начало счета   3  5  7  9  11  13  15 . . .

Для краткости я во многих программах не буду показывать строки объявлений, заголовков и завершения процедур, а также строку, импортирующую класс Debug. Так что останется одна «суть». Не обращайте также пока внимания на непонятные слова (Do…Loop) в заголовках таблиц, эти слова понадобятся чуть позже. Вот вариант программы. Я назвал его нулевым:

0 ВАРИАНТ     (Do …. Loop)

        Write("Начало счета   ")

        f = 3

m:    Write(f & "  ")

        f = f + 2



 GoTo m

Выход из цикла. Теперь вопрос: как нам запрограммировать завершение работы цикла, чтобы он не выполнялся бесконечно? Для этого нужно применить оператор  GoTo  внутри оператора If.

Задача: При помощи цикла напечатать такие текст и числа:

Начало счета   3  5  7  9  11  13  15 . . . . 329  331  333   Конец счета

Для удобства отладки изменим условие задачи – напечатать:

Начало счета  3  5  7  9  Конец счета

Вы уже достаточно опытны в программировании, чтобы догадаться, что программа для измененного условия будет копией программы для исходного, за исключением одного числа.

Вот 4 варианта программы. Первый – самый простой, а остальные нам понадобятся в дальнейшем. Все 4 варианта делают одно и то же, они очень похожи, но чем-то и отличаются. Вот в этом отличии вам и надо разобраться, иначе не будет понятен дальнейший материал.

Создайте проект с 4 кнопками и выполните в пошаговом режиме все 4 варианта:

1 ВАРИАНТ     (Do …. Loop While)

2 ВАРИАНТ    (Do …. Loop Until)

        Write("Начало счета   ")

        f = 3

m:    Write(f & "  ")

        f = f + 2

        If f <= 9 Then GoTo m

 Write("Конец счета")

        Write("Начало счета   ")

        f = 3

m1:  Write(f & "  ")

        f = f + 2

        If f > 9 Then GoTo m2 Else GoTo m1

m2:  Write("Конец счета")

<
Вот в каком порядке выполняются операторы программы 1 варианта:
Write("Начало счета")       f=3       Write(f & "  ") {печатается3}       f=f+2  {f становится равным 5}        If f<=9 Then GoTo m      Write(f& "  ") {печ. 5}      f=f+2  {f = 7}       If f<=9 Then GoTo m      Write(f & "  ") {печ. 7}         f=f+2  {f = 9}       If f<=9 Then GoTo m         Write(f & "  ") {печ. 9}           f=f+2 {f = 11}          If f<=9 Then GoTo m            Write("Конец счета")
Здесь оператор GoTo m выполняется три раза. На четвертый раз условие f<=9 оказывается ложным и поэтому выполняется не GoTo m, а следующий за If оператор Write("Конец счета"), то есть программа выходит из цикла и завершает свою работу.

3 ВАРИАНТ     (Do  While …. Loop)
4 ВАРИАНТ     (Do  Until …. Loop)
        Write("Начало счета   ")
        f = 3
m1:  If f <= 9 Then GoTo m3 Else GoTo m2
m3:  Write(f & "  ")
        f = f + 2
       GoTo m1
m2:  Write("Конец счета")
        Write("Начало счета   ")
        f = 3
m1:  If f > 9 Then GoTo m2 Else GoTo m3
m3:  Write(f & "  ")
        f = f + 2
        GoTo m1
m2:   Write("Конец счета")

Задача: Напечатать пары чисел -  0  1000      1  999      2  998 . . . . . . 1000  0.
Программа:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim f, s As Integer
        f = 0
m:    s = 1000 - f
        Write(f & " " & s & "     ")
        f = f + 1
        If f <= 1000 Then GoTo m
End Sub
Задание 25.          
А. Напечатать  1  2  3  4 . . . 99  100
Б. Напечатать  100  99 . . . 3  2  1
В. Напечатать  1  2  3  4 . . . 99  100  99 . . . 3  2  1


Задача «Таблицы Брадиса» или «Таблицы логарифмов». В те далекие времена, когда калькуляторов еще не было, были такие напечатанные в виде брошюрок таблицы для школьников и студентов, по которым они могли быстро посмотреть численные значения квадратов, логарифмов и других математических функций. Поставим задачу вычислить и напечатать таблицы Брадиса. На первый раз достаточно вычислить и напечатать с 6 десятичными знаками квадраты и логарифмы чисел  0.001  0.002  0.003  . . .  0.999  1.000. 
Программа:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Dim a, Квадрат, Логарифм As Decimal
        a = 0.001
m:    Квадрат = a ^ 2
        Логарифм = Math.Log(a)
        Debug.WriteLine(Format(a, "0.000") & "    " & Format(Квадрат, "0.000000")  _
& "    " & Format(Логарифм, "0.000000"))
        a = a + 0.001
        If a <= 1 Then GoTo m
End Sub
Почему я объявил a как Decimal, а не Double? Причина в незначительных погрешностях, которые допускает компьютер при действиях с десятичными дробями (о чем я уже писал). На моем компьютере при многократном прибавлении 0.001 значение a типа Double на некотором этапе переставало быть точным. Конкретнее, у меня получалось вот что:
0,682 + 0,001 = 0,683000000000001
Вследствие этого, при дальнейшем нарастании а последнее сложение было таким:
0,999000000000001 + 0,001 = 1,000000000000001
Легко видеть, что в этом случае для a=1 задание не выполняется, так как неправда, что
1,000000000000001 <=  1
Тип же Decimal, как я уже писал, обеспечивает абсолютную точность сложений и вычитаний.
Можно было обойтись и типом Double, но в этом случае оператор If пришлось бы чуть-чуть изменить, например, так:
If  a < 1.00001  Then  GoTo m
Задание 26.          
Для х=2700, 900, 300, 100 . . . и т.д. вычислять и печатать y=x/4 + 20  и  z=2y+0.23  до тех пор, пока yz не станет меньше  1/х.
Задание 27.          
Пусть движущееся изображение, описанное в 8.1.4, через некоторое время остановится.
Задание 28.             
Изображение, пройдя немного слева направо, поворачивает вниз и, пройдя немного, через некоторое время останавливается.

Содержание раздела