- •6.1. Объекты – экземпляры класса 11
- •6.2. Графические объекты. Рисуем и пишем. 22
- •Глава 7. Разветвляющиеся программы 45
- •Глава 8. Циклические программы 94
- •Глава 9. Отладка программы 133
- •Глава 10. Типичные приемы программирования 144
- •10.3.1. Пример 154
- •Глава 11. Процедуры и функции 167
- •11.3. Области видимости переменных 208
- •11.4. Функции 222
- •11.5. Переменные и параметры объектного типа 239
- •Глава 12. Графика – 2 259
- •Глава 13. Работа с таймером, временем, датами 320
- •Глава 14. Работа с мышью и клавиатурой 392
- •Глава 15. Массивы, рекурсия, сортировка 440
- •Глава 16. Разные звери в одном ковчеге 479
- •Объекты – экземпляры класса
- •Понятие объекта, как экземпляра класса
- •Создаем объекты из класса
- •Невидимый код в окне кода – Windows Form Designer generated code
- •Удобство визуального программирования
- •Класс – это программа
- •Невидимые объекты
- •Графические объекты. Рисуем и пишем.
- •Класс Graphics
- •Первая нарисованная линия
- •Рисуем отрезки, прямоугольники, круги, эллипсы
- •Рисуем дуги, сектора и закрашенные фигуры
- •Рисуем на нескольких элементах управления
- •Переменные и выражения вместо чисел
- •Методы, «придирчивые» к типу параметров
- •Разветвляющиеся программы
- •Что такое выбор (ветвление)
- •Условный оператор If или как компьютер делает выбор
- •Разбираем оператор If на примерах
- •Правила записи однострочного оператора If
- •Еще примеры и задания
- •Случайные величины
- •Функции Rnd и Randomize
- •Проект «Звездное небо».
- •Многострочный If
- •Разбираем многострочный If на примерах
- •Правила записи многострочного If
- •If условие Then операторы ElseIf операторы
- •Ступенчатая запись программы
- •Вложенные операторы If. Логические операции и выражения
- •Вложенные операторы If
- •Логические операции And, Or, Not
- •Логические выражения
- •Логический тип данных Boolean
- •Оператор варианта Select Case
- •Улучшаем калькулятор
- •Проверка ввода чисел в текстовое поле
- •Запрет деления на ноль
- •Ставим пароль на калькулятор
- •Функция MsgBox
- •Циклические программы
- •Оператор перехода GoTo. Цикл. Метки
- •Цикл с GoTo. Метки
- •Зацикливание
- •Примеры
- •Движение объектов по экрану
- •Выход из цикла с помощью If
- •Операторы цикла Do
- •Оператор Do …. Loop
- •Оператор Do …. Loop While
- •Оператор Do …. Loop Until
- •Оператор Do While …. Loop
- •Оператор Do Until …. Loop
- •Разница между вариантами операторов Do
- •Примеры и задания
- •Оператор Exit Do
- •Оператор цикла While …End While
- •Оператор цикла For
- •Объясняю For на примерах
- •Шаг цикла
- •Синтаксис и работа оператора For
- •Оператор Exit For
- •«Мыльные пузыри» и другие шалости
- •Используем в рисовании переменные величины
- •Отладка программы
- •Типичные приемы программирования
- •Вычисления в цикле
- •Роль ошибок в программе
- •Счетчики и сумматоры
- •Счетчики
- •Сумматоры
- •Вложенные операторы
- •Вложенные циклы – «Таблица умножения»
- •Вложенные циклы – «Небоскреб»
- •Поиск максимума и минимума
- •Процедуры и функции
- •Процедуры
- •Понятие о процедурах пользователя
- •Пример процедуры пользователя
- •Понятие о процедурах с параметрами
- •Пример процедуры с параметрами
- •Вызов процедур из процедуры пользователя
- •Операторы Stop, End и Exit Sub
- •Проект «Парк под луной»
- •Задание на проект
- •От чисел – к переменным
- •От переменных – к параметрам
- •Делим задачу на части
- •Программируем части по-отдельности
- •Серп молодого месяца или «в час по чайной ложке»
- •Земля, пруд, три дерева и два фонаря
- •Ряд деревьев
- •Ряд фонарей и аллея
- •Два способа программирования
- •Области видимости переменных
- •Создание, инициализация и уничтожение переменных
- •Области видимости переменных
- •Зачем нужны разные области видимости
- •Область видимости – блок
- •Статические переменные
- •Функции
- •Передача параметров по ссылке и по значению
- •Из чего состоит тело процедуры. Выражения
- •Функции
- •Константы
- •Переменные и параметры объектного типа
- •Переменные объектного типа
- •Параметры объектного типа
- •Соответствие типов
- •Соответствие объектных типов
- •Неопределенные параметры, произвольное число параметров
- •Что такое методы
- •Пользуемся подсказкой, чтобы узнать объектные типы
- •Параметры методов
- •Графика – 2
- •Точки и прямоугольники
- •Прямоугольник
- •Использование Точки и Прямоугольника в графических методах
- •Собственные перья, кисти и шрифты
- •Создаем собственные перья. Конструктор
- •Создаем собственные кисти
- •Работа с картинками
- •Картинка, как свойство Image элемента управления
- •Растровая и векторная графика
- •Рисуем картинки
- •Размер и разрешение картинок
- •Метод DrawImage и его варианты
- •Метод RotateFlip объекта Bitmap
- •Метод Save объекта Bitmap
- •Рисуем в памяти
- •Перерисовка картинок, фигур и текста
- •Текстурная кисть
- •Работа с цветом
- •Системные цвета
- •Функция FromArgb
- •Прозрачность
- •Как узнать цвет точки на фотографии
- •Преобразования системы координат
- •Встроенный графический редактор vb
- •Работа с таймером, временем, датами
- •Тип данных DateTime (Date)
- •Переменные и литералы типа DateTime
- •Свойства и методы структуры DateTime
- •Свойства и методы модуля DateAndTime
- •Значения строкового параметра для функций работы с датами:
- •Форматирование даты и времени
- •Перечисления
- •Рамка (GroupBox), панель (Panel) и вкладка (TabControl)
- •Рамка (GroupBox)
- •Панель (Panel)
- •Вкладка (TabControl)
- •Проект «Будильник-секундомер»
- •Постановка задачи
- •Делим проект на части
- •Делаем часы
- •Занимаемся датой
- •Занимаемся днем недели
- •Делаем будильник
- •Делаем секундомер
- •Рисуем бордюры вокруг рамок
- •Полный текст программы «Будильник-секундомер»
- •Недоработки проекта
- •Таймер и моделирование
- •Анимация
- •Суть анимации
- •Движем объекты
- •«Движем» свойства объектов
- •Мультфильм «Летающая тарелка»
- •Мультфильм «Человечек»
- •Работа с мышью и клавиатурой
- •Фокус у элементов управления
- •Работа с мышью
- •Основные события, связанные с мышью
- •Подробности событий мыши. Класс MouseEventArgs
- •Две задачи: Глаз-ватерпас и Мышка-карандаш
- •Работа с клавиатурой
- •Событие KeyPress. Класс KeyPressEventArgs. Структура Char
- •События KeyDown и KeyUp. Класс KeyEventArgs
- •Проект – Гонки (игра)
- •Постановка задачи
- •Делим проект на части
- •Первая часть – рисуем поле для гонки
- •Вторая часть – управляем машиной
- •Третья часть – Поведение машины, организация счетчиков и пр.
- •Недоработки проекта
- •Гонки двух автомобилей
- •Задания на проекты
- •Часть III. Программирование на vb – второй уровень
- •Массивы, рекурсия, сортировка
- •Переменные с индексами
- •Одномерные массивы
- •Основы работы с одномерными массивами
- •Мощь одномерных массивов
- •Двумерные массивы
- •Какие бывают массивы
- •Использование массивов при программировании игр
- •Массивы как объекты
- •Массивы как параметры
- •Массивы элементов управления
- •Индукция. Рекурсия
- •Сортировка
- •Простая сортировка
- •Метод пузырька
- •Разные звери в одном ковчеге
- •Коллекции
- •Создание коллекции, методы коллекции
- •Оператор цикла For Each
- •Коллекции, принадлежащие контейнерам
- •Структуры
- •Оператор With
- •Алфавитный указатель
- •Специально для http://all-ebooks.Com
Из чего состоит тело процедуры. Выражения
Тело процедуры состоит из операторов Dim и остальных операторов. Остальные операторы выполняются по порядку.
Из чего состоят операторы? Они могут включать в себя блоки других операторов, как это делают, например, операторы If и Do. Они могут включать в себя выражения.
Мы знаем с вами уже три вида выражений: арифметические (их значение – число), строковые (их значение – текстовая строка) и логические (они принимают одно из двух значений: True или False).
Выражение, стоящее отдельно, само по себе, встречаться не может. Выражения всегда являются частью операторов. Выражения мы встречаем справа (не слева!) от знака равенства в операторе присваивания, в условиях тех же операторов If и Do, внутри скобок при обращении к методам и функциям.
В простейшем случае выражение – это литерал:
Фрагмент |
Где тут выражения |
a = 0 |
0 |
b = -7 |
-7 |
s = "Привет" |
"Привет" |
В простом случае выражение – это переменная:
a = c |
c |
w = s |
s – строковое выражение |
В обычном случае выражение – это литералы и переменные, соединенные знаками арифметических и других операций. В выражения входят скобки, а также математические и другие функции:
d = a + 1 |
Здесь три выражения: a, 1 и a+1 |
w = s & "ик" |
Здесь три выражения: s, "ик" и s & "ик" |
Debug.WriteLine(b - 3) |
Здесь три выражения: b, 3 и b-3 |
b = Len(w) |
Здесь два выражения: w и Len(w) |
b = a * (Len(w) – Rnd()) |
Выражение a * (Len(w) – Rnd()) и в нем 5 выражений |
If c + 9 > a Then |
Логическое выражение c+9>a, состоящее из двух арифметических |
Функции
Философия. Мы с вами уже сталкивались со стандартными функциями (например, Len(w), Abs(c+200) и др.). Стандартная функция – это некая скрытая программа, которая принимает свои параметры, указанные в скобках, в качестве исходных данных (аргументов), что-то делает с ними и в результате получает одну величину, которая и является значением функции. Много примеров функций вы найдете в Error: Reference source not found и по всей книге.
Когда мы видим оператор
b = a * (Len(w) – Abs(c+200))
то говорим, что при выполнении этого оператора компьютер обращается к функциям Len и Abs. А само упоминание этих функций в тексте оператора называем обращениями к этим функциям, чтобы отличить их от объявлений функций, которые являются солидными программами для вычисления значений этих функций, только скрытыми от нас. Здесь полная аналогия с обращением к процедуре пользователя. Обращение к процедуре – это коротенький оператор, а объявление процедуры может состоять из многих строк.
Обратите внимание, что обращения к стандартным функциям встречаются обычно в выражениях. Редко кто пишет отдельные операторы такого вида:
Len(w)
Abs(c + 20)
Да это и понятно. Ведь в этом случае неизвестно, как использовать вычисленную величину функции. Действительно, ну вот мы вычислили длину строки, а куда ее девать, как приспособить для какого-нибудь дела? Поэтому пишут так:
b = Len(w)
Здесь все понятно: мы в дальнейшем можем использовать, переменную b, которая несет в себе вычисленную величину функции, как хотим. Или, скажем, так:
Debug.WriteLine(Abs(c + 20))
Здесь тоже от абсолютной величины польза была: мы ее напечатали.
Сейчас я хочу, чтобы мы подошли к осознанию необходимости и удобства обладания собственными функциями – функциями пользователя. Функции пользователя вы создаете тогда, когда вам недостаточно функций из библиотеки классов .NET Framework. Например, вы хотите иметь функцию, аргументами которой были бы длины двух сторон прямоугольника, а значением – периметр этого прямоугольника. Но позвольте! – скажете вы – Мы только что создали процедуру, которая делает именно это, да еще и площадь вычисляет! Зачем нам нужна еще какая-то функция? А затем, что функция в данном случае удобнее и естественнее в использовании. Вы увидите, что удобнее создать и использовать две функции: Периметр и Площадь, чем одну процедуру. И не забывайте, кстати, что единую функцию Периметр_Площадь создать нельзя, так как функция может иметь только одно значение.
Пример 1. Вспомним задачу из 11.4.1: «Известны стороны двух прямоугольников. Нужно напечатать периметр того прямоугольника, чья площадь больше.» Приведу целиком программу решения этой задачи, но уже с использованием не процедуры, как в 11.4.1, а функций:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim A1, B1 As Integer 'Две стороны 1 прямоугольника
Dim A2, B2 As Integer 'Две стороны 2 прямоугольника
A1 = 10 : B1 = 50
A2 = 20 : B2 = 30
If Площадь(A1, B1) > Площадь(A2, B2) Then WriteLine(Периметр(A1, B1)) _
Else WriteLine(Периметр(A2, B2))
End Sub
Function Периметр(ByVal Сторона1 As Integer, ByVal Сторона2 As Integer) As Integer
Return 2 * Сторона1 + 2 * Сторона2
End Function
Function Площадь(ByVal Сторона1 As Integer, ByVal Сторона2 As Integer) As Integer
Площадь = Сторона1 * Сторона2
End Function
Пояснения. Оператор
If Площадь(A1, B1) > Площадь(A2, B2) Then WriteLine(Периметр(A1, B1)) _
Else WriteLine(Периметр(A2, B2))
содержит в себе два обращения к функции Площадь и два обращения к функции Периметр. Он хорош своей естественностью и понятностью. Действительно, он практически повторяет условие задачи:
«ЕСЛИ площадь первого прямоугольника больше площади второго,
ТО печатай периметр первого прямоугольника,
ИНАЧЕ печатай периметр второго».
Терминология. Как же устроены наши функции? Сначала о терминологии, которая очень похожа на терминологию процедур.
Все операторы, из которых состоит функция, без заголовка и конечной строки, будем называть телом функции. А вместе с этими строками – объявлением функции. Как видите, тела наших функций очень коротенькие, всего из одного оператора. Но операторов может быть сколько угодно, как и в процедуре.
Когда VB в процессе выполнения программы натыкается на функцию Периметр, он ищет в программе объявление функции с именем Периметр и начинает выполнять тело этой функции. Этот процесс называется вызовом функции или обращением к функции . Говорят также, что управление передается функции. После выполнения тела функции VB возвращается к выполнению программы. Говорят, что управление возвращается к программе. Про значение функции говорят, что функция возвращает это значение в программу.
Отличия функций от процедур. Вы видите, что объявление функции очень похоже на объявление процедуры. Но функция в отличие от процедуры обладает некоторыми свойствами переменной величины. Объявление функции отличается от объявления процедуры следующими элементами:
В заголовке функции мы пишем не Sub (процедура), а Function (функция)
В заголовке функции после скобок с параметрами должен быть указан тип значения функции (так как у нас это численное значение имеет смысл площади или периметра, то я выбрал в обоих случаях Integer).
Внутри тела функции ей хотя бы раз должно быть присвоено какое-нибудь значение. Именно это значение функция и будет возвращать. Присвоение можно делать двумя способами:
Обычным оператором присваивания, в котором слева от знака равенства стоит имя функции, как если бы это была не функция, а обычная переменная (у нас этим занимается оператор Площадь = Сторона1 * Сторона2).
При помощи специального оператора Return (у нас этим занимается оператор Return 2 * Сторона1 + 2 * Сторона2).
В конечной строке мы пишем не End Sub (конец процедуры), а End Function (конец функции)
Напомню еще раз, что обращение к функции отличается от обращения к процедуре. Если обращение к процедуре – самостоятельный оператор, то обращение к функции – это обычно составная часть выражения.
Пример 2. Рассмотрим другой пример функции. Ее параметр (аргумент) – строка. Значение функции – та же строка, повторенная столько раз, сколько символов (букв) в исходной строке. Например, если параметр – «уж», то функция – «ужуж», параметр – «Вена», функция – «ВенаВенаВенаВена». Если длина параметра превышает 8 символов, значение функции таково – «Вы задали слишком длинное слово».
Вот программа:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim S As String
S = TextBox1.Text
TextBox1.Text = Размноженное_слово(S)
End Sub
Function Размноженное_слово(ByVal Slovo As String) As String
Dim i, Длина_слова As Integer
Длина_слова = Len(Slovo)
If Длина_слова > 8 Then
Return "Вы задали слишком длинное слово"
Else
Размноженное_слово = ""
For i = 1 To Длина_слова
Размноженное_слово = Размноженное_слово & Slovo
Next
End If
End Function
Пояснения. Здесь мы пишем в текстовом поле слово и щелчком по кнопке тут же получаем в том же текстовом поле результат – размноженное слово.
Посмотрим на объявление функции. В заголовке мы видим, что как параметр функции, так и сама функция имеют тип String. Процедуры и функции, как вы уже видели, могут содержать кроме параметров также и обычные локальные переменные (в нашем случае это i и Длина_слова). Тело функции состоит из нескольких операторов.
Механика работы этой функции проста. Переменная Размноженное_слово накапливает в себе слова, как сумматор сумму. Роль плюса играет знак &. На каждой итерации второй из двух операторов присваивания удлиняет Размноженное_слово на Slovo. А итераций столько, сколько букв в слове. «Обнуляет сумматор» оператор
Размноженное_слово = ""
Роль нуля исполняет пустая строка "" длиной в 0 символов.
Для возврата значений применяется в одном месте оператор Return и в двух местах – оператор присваивания Размноженное_слово = . . .. Не запутаемся ли? – Значение одно, операторов – три. Спрашивается, какой из этих операторов в действительности вернет значение? Чтобы ответить на этот вопрос, вам нужно знать, что
между операторами Return и присваивания, используемыми для возврата значения функции, имеется существенное различие. А именно: наткнувшись на оператор Return, компьютер выполняет его и на этом немедленно прекращает выполнение функции, возвращаясь в программу, ее вызвавшую. Ничего подобного при выполнении оператора присваивания не происходит – компьютер продолжает выполнять тело функции дальше.
Если вы внимательно разберете текст этой или любой другой функции, то увидите, что вернет значение оператор, последний по времени выполнения (а не в порядке записи). Какой именно? Все зависит от длины слова. Если оно длиннее 8 букв, то значение вернет оператор Return. Если его длина – от 1 до 8 букв, то второй из двух операторов присваивания. Если вы ничего не введете в текстовое поле, то – первый.
Обязательно прогоните программу в пошаговом режиме. Вам будет любопытно наблюдать, как постепенно удлиняется Размноженное_слово.
Побочный эффект. В теле функции можно писать сколько угодно любых операторов. А почему бы в таком случае не попытаться убить двух зайцев и не вычислять в теле функции Площадь еще и периметр? Ну и что, что он не будет возвращаемым значением функции! Зато тогда можно было бы обойтись одной функцией. Попробуем:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim A1, B1, П1 As Integer 'Две стороны и периметр 1 прямоугольника
Dim A2, B2, П2 As Integer 'Две стороны и периметр 2 прямоугольника
A1 = 10 : B1 = 50
A2 = 20 : B2 = 30
If Площадь(A1, B1, П1) > Площадь(A2, B2, П2) Then WriteLine(П1) Else WriteLine(П2)
End Sub
Function Площадь(ByVal Сторона1 As Integer, ByVal Сторона2 As Integer, ByRef Периметр As Integer) _
As Integer
Площадь = Сторона1 * Сторона2
Периметр = 2 * Сторона1 + 2 * Сторона2
End Function
Что мы выиграли и что проиграли? Сэкономили две строчки кода, но пришлось вводить дополнительные переменные и параметр. А самое главное – проиграли в простоте, единообразии и понятности. Функция получилась довольно нелепая.
Если функция кроме возвращаемого значения вычисляет что-то еще побочное, что мы используем в программе, то говорят, что функция имеет побочный эффект. Побочные эффекты довольно часто используются в программировании. Например, среди функций из библиотеки классов .NET Framework довольно много таких, возвращаемое значение которых никого не интересует, а интересует именно побочный эффект. Поэтому обращение к функции разрешено писать не только в выражениях, но и отдельным оператором. Например, так:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim A1, B1, П1 As Integer 'Две стороны и периметр прямоугольника
A1 = 10 : B1 = 50
Площадь(A1, B1, П1)
Debug.WriteLine(П1)
Math.Abs(-20)
End Sub
Как я уже упоминал, от площади в этом примере толк есть, а от абсолютной величины – нет.
Напишите функцию с двумя строковыми параметрами. Функция должна выдать длину той строки, которая короче.