Тверской государственный университет
Опубликован: 13.09.2006 | Доступ: свободный | Студентов: 3491 / 369 | Оценка: 4.65 / 4.29 | Длительность: 30:37:00
Специальности: Программист, Менеджер
Лекция 8:

Операторы

< Лекция 7 || Лекция 8: 123456 || Лекция 9 >
Цикл For Next

Позволяет повторять группу операторов заданное число раз.

Синтаксис:

For счетчик_цикла = начало To конец [Step шаг]
тело цикла
Next [счетчик_цикла]

Здесь счетчик_цикла - это числовая переменная. В начале выполнения цикла она принимает значение, задаваемое числовым выражением начало. (Переменная счетчик_цикла не может иметь тип Boolean или быть элементом массива.) Числовое выражение конец задает заключительное значение счетчика цикла. Оно вычисляется до начала исполнения тела цикла и не меняется, даже если входящие в него переменные изменяют в теле цикла свои значения. Числовое выражение шаг необязательно. Его значение также вычисляется в начале цикла и прибавляется к счетчику цикла всякий раз, когда завершается выполнение тела цикла и вычисление достигает строки Next [счетчик_цикла]. Если шаг цикла явно не указан, по умолчанию он равен 1. тело цикла - это последовательность операторов, которая будет выполнена заданное число раз. При каком значении переменной счетчик_цикла происходит завершение цикла, зависит от знака параметра шаг. Если шаг положителен, цикл завершится, когда впервые выполнится условие:

счетчик_цикла > конец

Если шаг цикла отрицателен, условие его завершения:

счетчик_цикла < конец

Это условие проверяется перед началом выполнения цикла, а затем - после каждого прибавления шага к счетчику цикла в операторе Next. Если оно выполнено, управление передается на оператор, следующий за Next, нет - выполняются операторы из тела цикла. Завершить цикл For … Next можно и с помощью оператора Exit For. Такие операторы могут быть расположены в тех местах тела цикла, где требуется из него выйти, не дожидаясь выполнения условия завершения.

Примеры.

В нашем примере три вложенных цикла For … Next использованы для вычисления произведения двух целочисленных матриц, инициализированных случайными числами. Затем результирующая матрица проверяется на наличие в ней нулевого значения:

Public Sub For1()
	Dim A(1 To 5, 1 To 5) As Integer
	Dim B(1 To 5, 1 To 5) As Integer
	Dim C(1 To 5, 1 To 5) As Integer
	Dim I As Integer, J As Integer, K As Integer
	Dim Res As String
	' Инициализация матриц	A и B случайными числами в интервале [-10, +10]
	VBA.Randomize
	For I = 1 To 5
		For J = 1 To 5
			'Получение случайного числа Rnd и преобразование в целое
			A(I, J) = Int(21 * Rnd) - 10
		Next J
	Next I
	For I = 1 To 5
		For J = 1 To 5
			B(I, J) = Int(21 * Rnd) - 10
		Next J
	Next I
		
	'Вычисление произведения матриц
	For I = 1 To 5
		For J = 1 To 5
			C(I, J) = 0
			For K = 1 To 5
					C(I, J) = C(I, J) + A(I, K) * B(K, J)
			Next K
		Next J
	Next I
		
	Res = "No"
	C(2, 2) = 0
	'Проверка на нулевое значение
	For I = 1 To 5
		For J = 1 To 5
			If C(I, J) = 0 Then
					Debug.Print "Индексы: ", I, J
					Res = "Yes"
					Exit For
			End If
		Next J
	Next I
	Debug.Print Res
End Sub
7.4.

Обратите внимание, оператор выхода Exit For прекращает выполнение только внутреннего цикла, так что проверка на ноль будет осуществляться в каждой строке матрицы, независимо от существования нулей в предыдущих строках. Сделаем еще несколько замечаний по поводу оператора For Next:

  • По окончании цикла счетчик цикла сохраняет свое значение в момент выхода и его можно использовать, например, для анализа преждевременного выхода из цикла. Заметим, что в большинстве языков программирования значение счетчика цикла считается неопределенным по завершении цикла.
  • В операторе Next можно не указывать имя переменной, задающей счетчик, это имя подразумевается по умолчанию, как завершающее последний открытый оператор For. Однако и эту возможность не следует использовать. Рекомендуем всегда явно указывать имя счетчика в операторе Next.
  • Допускается менять значение счетчика в теле цикла. Этого не следует делать никогда. К сожалению, система не следит за этим и допускает подобные безобразия. Этот цикл никогда не завершится:
Public Sub For2()
	Dim A(1 To 5) As Integer
	Dim i As Integer
	For i = 5 To 1 Step -1
		A(i) = i
		i = i + 1
	Next i
		
End Sub

Обычно попытка изменить значение счетчика цикла в его теле означает, что вместо цикла For…Next следовало бы применить цикл другого вида, например Do…Loop.

Цикл Do...Loop

Повторяет блок операторов, пока заданное условие является истинным или пока оно не станет истинным.

Синтаксис:

Имеется четыре варианта синтаксиса этого цикла. В двух первых вариантах условие проверяется в начале цикла:

Do [{While | Until} условие]
тело цикла
Loop

В других двух вариантах условие проверяется в конце цикла:

Do
тело цикла
Loop [{While | Until} условие]

Здесь условие является числовым или строковым выражением со значениями True или False. Вообще оно необязательно. Значение Null условия трактуется как False. Тело цикла - это последовательность операторов, которая будет выполняться, пока условие остается истинным, если перед ним стоит ключевое слово While или пока оно остается ложным - в вариантах цикла с ключевым словом Until. Таким образом, циклы вида While условие эквивалентны циклам вида Until Not условие. Кроме того, в тело цикла может входить оператор Exit Do, выполнение которого сразу прекращает цикл и передает управление оператору, непосредственно следующему за Loop. В случае нескольких вложенных циклов Do … Loop оператор Exit Do завершает лишь самый внутренний цикл, в теле которого он расположен.

Примеры.

В нашем примере реализованы три варианта поиска по образцу с проверкой условия в начале цикла, в конце цикла и в середине цикла для варианта поиска по образцу с барьером:

Public Sub Loop1()
	Const Size = 5
	Dim X() As Integer
	Dim i As Integer
	Dim Found As Boolean
	Const pat = 7
	'Инициализация случайными числами в интервале [1 - 10]
	ReDim X(1 To Size)
	Randomize
	For i = 1 To Size
		X(i) = Int(11 * Rnd)
	Next i
		
	'Поиск по образцу с проверкой в начале цикла
	i = 1: Found = False
	Do While (i <= Size) And (Not Found)
		If X(i) = pat Then
			Found = True
		Else: i = i + 1
		End If
	Loop
	If Found Then
		Debug.Print "Найден образец!"
	Else: Debug.Print "Образец не найден!"
	End If
		
	'Поиск по образцу с проверкой в конце цикла
	i = 1: Found = False
	Do
		If X(i) = pat Then
			Found = True
		Else: i = i + 1
		End If
	Loop Until Found Or (i = Size + 1)
	If Found Then
		Debug.Print "Найден образец!"
	Else: Debug.Print "Образец не найден!"
	End If
		
	'Поиск с барьером
	ReDim Preserve X(1 To Size + 1)
	X(Size + 1) = pat
	i = 1
	Do
		If X(i) = pat Then Exit Do
		i = i + 1
	Loop
	If i = Size + 1 Then
		Debug.Print "Образец не найден!"
	Else: Debug.Print "Образец найден!"
	End If
End Sub
7.5.
Цикл While...Wend

Повторяет выполнение последовательности операторов, пока заданное условие не станет ложным.

Синтаксис:

While	условие
тело цикла
Wend

Здесь условие и тело цикла такие же, как и для цикла Do…Loop. Только для этого вида цикла не предусмотрен оператор выхода Exit. Фактически цикл While…Wend - частный случай цикла Do…Loop - оставлен в языке для совместимости с предыдущими версиями.

Цикл For Each...Next

Повторяет заданную последовательность операторов для каждого элемента массива или набора.

Синтаксис:

For Each элемент In группа
тело цикла
Next [элемент]

Здесь элемент - переменная, которая пробегает в качестве значений элементы коллекций или массива. Для коллекций элемент может быть переменной типа Variant, переменной типа Object или переменной (объектом) некоторого класса. В случае цикла по массиву элемент обязан быть переменной типа Variant. Группа - это имя набора объектов (чаще всего это коллекция объектов) или массива, для элементов которых выполняется цикл. Цикл не применим для массивов, тип элементов которых определен пользователем, так как такие элементы не могут быть значениями переменной типа Variant. В таких массивах можно использовать цикл вида For … Next. Тело цикла - последовательность операторов, выполняемая для каждого элемента набора или массива, - может содержать операторы Exit For, позволяющие прервать выполнение цикла и передать управление оператору, следующему за Next (обычно такой выход происходит при выполнении некоторого условия, проверяемого в операторе If…Then…Else ). Указывать переменную элемент после ключевого слова Next не обязательно, но желательно.

Примеры.

В примере создается коллекция, число элементов которой и сами элементы выбираются случайным образом. Затем эта коллекция копируется в динамический массив, размерность которого увеличивается в процессе копирования. На последнем этапе массив распечатывается. Циклы типа For …Each прекрасно работают в подобных ситуациях:

Public Sub ForEach1()
	Dim X As New Collection
	Dim Y() As Integer
	Dim item As Variant
	Dim i As Integer, Size As Integer
		
	'Инициализация коллекции
	Randomize
	Size = Int(21 * Rnd)
	For i = 1 To Size
	    X.Add Int(11 * Rnd)
	Next i
		
	'Копирование коллекции в динамический массив
	Size = 1
	For Each item In X
		ReDim Preserve Y(1 To Size)
		Y(Size) = item
		Size = Size + 1
	Next item
	
	'Печать элементов динамического массива
	For Each item In Y
		Debug.Print item
	Next item
End Sub

Кроме рассмотренных управляющих операторов VBA содержит доставшиеся в наследство от прежних версий операторы перехода по метке GoTo, перехода по метке с возвратом GoSub...Return и условные операторы перехода по меткам On...GoSub и On...GoTo. Мы никогда не пользуемся этими операторами.

< Лекция 7 || Лекция 8: 123456 || Лекция 9 >
полина есенкова
полина есенкова
Дмитрий Вологжин
Дмитрий Вологжин
Добрый день, прошел тесты с 1 по 9, 10 не сдал, стал читать лекцию и всё пройденные тесты с 1 по 9 сбросились, когда захотел пересдать 10 тест.