Часть
1. Основы Visual Basiс
|
||||||
15.10.2004 | ||||||
Глава
3.
|
||||||
Переменные.
Инструкция Option Explicit.
Инструкция If. Таймер. |
||||||
Переменные. Инструкция Option Explicit. |
Все, пора поговорить о переменных. Перегружать информацией я тебя не буду, но минимум знать надо.
Очень желательно,
чтобы программа начиналась с инструкции Option Explicit
в секции General. Эта инструкция заставляет программиста явно объявлять переменные.
При ее отсутствии всякое слово, не противоречащее синтаксису VB, может быть
переменной.
Что происходит, если мы не используем инструкцию Option Explicit? А то, что
мы вообще можем не объявлять переменные. Это ведь здорово! А вот и нет! А почему
нет, видно из следующего:
При отсутствии Option Explicit, если нам нужна новая переменная, мы просто вводим
ее в код программы, например,
NewChislo=7
и опс, Visual Basic уже
подсуетился и зарезервировал для переменной памяти, причем зарезервировал по
полной программе - максимально. Дело в том, что если явно не задавать тип переменнной,
VB считает переменную типом Variant, так как такая переменная может содержать
почти любые данные: и целые, и дробные, и строковые. Зато и памяти эта переменная
использует очень много. Если же мы явно объявим переменную и зададим ее тип
сообразно с нашими потребностями, то рациональное использование памяти - на
лицо.
Если тебя это соображение не убедило, то представим ситуацию, когда ты повторно
используешь свою переменную для, например, изменения ее значения. И при этом
делаешь опечатку (а опечаток делается очень много), пропускаешь букву h:
NewCislo=NewCislo+1
Для Visual Basic в этом никакой ошибки нет. Он при компиляции быстренько резервирует
память под новую переменную NewCislo, считая ее типом Variant и у него никаких
проблем. Проблемы у тебя. И критичные. Во-первых, ты имеешь ненужную переменную
NewCislo со значением 1, о которой ты знать не знаешь. Во-вторых, если ты ожидаешь,
что значение твоей начальной переменной NewChislo увеличилось на 1 и стало 8,
то это совершенно напрасно. А вот ожидать, что результат выполнения твоей программы
даст непредсказуемый результат можно смело.
Иное дело, если ты использовал инструкцию Option Explicit. В этом случае, при
запуске программы, Visual Basic тут же найдет новую необъявленную переменную
и остановит выполнение программы на строке с ошибкой.
Если я тебя убедил, тогда, чтобы не писать инструкцию Option Explicit в каждом
новом проекте, нажми кнопку “Инструменты” (Tools), выбери “Опции” и в окрывшемся
окне на вкладке “Редактор” поставь галочку напротив надписи “Требовать определение
переменной”, потом OK. Теперь, всякий раз при создании нового проекта (но только
нового, в старые эту инструкцию надо прописывать в (General) вручную.), VB сам,
автоматически, будет прописывать Option Explicit.
Любое слово, кроме зарезервированных VB, можно сделать именем переменной. Но начинаться имя должно с буквенного символа. Например Peremenaia, Ima1, X, LastNumber, z001. Не надо использовать в именах математические операторы. И нельзя объявлять две переменные с одинаковыми именами. В принципе, для удобства чтения кода и солидности существуют определенные рекомендованные правила (что-то вроде стандартов) написания имен переменных. Но, так как использование этих правил - сугубо личное дело каждого, я их придерживаться не буду. Если охота, поищи в Интернете что-нибудь про Венгерское соглашение, Венгерскую нотацию или соглашение Реддика.
Итак, при явном объвлении переменной очень желательно явно задавать ее тип. В крайне редких случаях, когда тип хранимых данных в переменной заранее неизвестен, используется как раз тип Variant. В Visual Basic наиболее часто используются следующие типы данных (а соответственно переменных):
Long ‘длинное целое число со знаком от –2 147 483 648 до 2 147 483 647
Integer ‘целое число со знаком от –32 768 до 32767
String ‘строка символов
Boolean ‘логическое, принимает два значения или “True” (Истина) или “False” (Ложь)
Пока что нам этого хватит. Если интересно, то перечень типов данных, поддерживаемые VB, можно посмотреть здесь.
Теперь, где и как их объявлять. Если ты объявишь переменную в теле процедуры объекта, например кнопки, то доступна она будет только в этой процедуре. В другой, скажем, кнопке, ее использовать нельзя. Чтобы переменную использовать во всей форме, надо объявить ее в разделе деклараций (это в самом верху кода – (General) – (Declarations). Для этих случаев можно использовать инструкцию Dim. Ну, а чтоб она была доступна во всей программе (в разных, например, формах) она должна быть объявлена в стандартном модуле с ключевым словом Public. Но модулей мы пока не создавали и оставим это до поры в стороне. Ну вот, на первое время этого о переменных хватит. Чтобы было совсем понятно, вот пример объявления переменных:
Option
Explicit
Dim MyStream As
String
Dim K14 As Long
Dim Flag As Boolean
Dim Numder As Integer
Private Sub Form_Load()
Dim Flag2 As Boolean
Dim m99little As String
End Sub
Таймер. Программа “Часики”. |
Теперь разберем использование
нового объекта - Timer (таймера). Слева, где компоненты формы, они же
инструменты-элементы, нарисован такой будильничек. Это таймер и есть. Он всегда
невидимый, но нужный элемент. Всего их одновременно можно использовать около
30 штук. Но нам такое количество таймеров не надо.
Создадим новый exe-проект и поместим один таймер на форму. На основе его мы
сделаем сейчас маленькие часики. В свойствах этого таймера поставьте следующие
установки:
Enabled – False (по умолчанию True) означает, что таймер выключен
Interval – 1000 (время, в миллисекундах, через которое таймер срабатывает, если конечно включен). Таймер будет срабатывать каждые 1000 мск, т.е. каждую секунду, как в нормальных часах.
Кроме того, нам понадобятся три лейбла: Label1 для секунд, Label2 для минут и Label3 – сами догадайтесь для чего. Правильно, для часов. Все.
Изменим свойства лейблов следующим образом:
Alignment – 2-Центровка
(Это чтоб цифры были по центру лейблов)
BorderStyle – 1-Фиксировано (это чтоб размер формы нельзя было изменить)
Caption – 00 (на всякий случай, т.е. значение лейблов изначально будет
“00”)
Нажми Font и выбери размер шрифта 14, а начертание – полужирное. После этого
подбери подходящий размер окон Лейблов, чтобы цифры в них выглядели симпатично.
Должно получиться как на рис.8.
Рисунок 8.
Создадим процедуру Form_Load .
Option
Explicit
Private
Sub
Form1_Load()
Затем в теле процедуры, как у всякой приличной программы, меняем заголовок формы.
Form1.Caption = "Часики"
Дальше, для того, чтобы наши часы сразу показывали текущее время, надо его взять из компьютера. Чтобы получить системное время, есть функция Time (Label1.Caption=Time). Но она дает полное время одной строкой (16:23:42). Нам тогда придется выбирать из нее секунды, минуты и часы, чтобы распихать по свои лейблам. А чтобы этого не делать, можно взять готовые функции, которые предоставят нам это все по частям:
Label1.Caption = Second(Time) 'стало быть секунды
Label2.Caption = Minute(Time) 'ну, минуты
Label3.Caption = Hour(Time) ' и часы
Теперь, при запуске того, что мы наваяли, у нас будет показываться текущее время. Это, конечно, прогресс, но вот только часики-то стоят. Трясти монитор не стоит, они от этого не пойдут, а вот запустить таймер одной простой строчкой мы сможем:
Timer1.Enabled = True
Вот она, булева алгебра (ну еще не алгебра, но уже кое-что). То есть Timer1.Enabled может быть либо включен (True), либо выключен (False). На этом процедура Form1_Load() закончена:
End Sub
Чтобы получить хоть какие-нибудь блага от запущенного таймера и заставить наши часики ходить, создадим процедуру, которая будет исполняться при наступлении события срабатывания таймера. Событие это у таймера единственное и называется тоже .Timer. Возникает оно в тот момент, когда таймер досчитывает до предела, установленного в свойстве Interval и соответственно сбрасывается на ноль.
Private Sub Timer1_Timer()
Наши секунды должны увеличиваться на одну за каждое срабатывание таймера. Поэтому пишем счетчик, который будет увеличивать значение наших секунд на единицу при каждом срабатывании таймера:
Label1.Caption = Label1.Caption + 1
И вот мы вплотную подошли к проблеме условного оператора (а лучше инструкции) If, без которого - никуда. Суть этой инструкции в том, что он позволяет при неком создавшемся условии производить изменения в ходе программы в зависимости от этого условия.
Инструкция условия If. |
Этоу инструкцию можно использовать
в блоковой форме: полном (развернутом) виде и неполном (без строк ElseIf),
а также в одну строку.
В полном виде в блоковой форме синтаксис этой инструкции будет выглядеть следующим
образом:
If Условие1
Then
группа операторов1
ElseIf Условие2 Then
группа операторов2
..............
ElseIf УсловиеN Then
группа операторовN
Else
Последняя группа операторов
End If
Условие представляет из себя оператор, значение
которого может принимать True (Истина) или
False (Ложь). Например, если Условие1
представляет из себя выражение X>1, то оно истинно, если X
равно 2, то оно ложно при значении X равном 1. Если Условие1
истинно, то выполняется группа операторов1, остальные группы
операторов не выполняются, если даже в каких-нибудь последующих ветках УсловиеN
истинно. Если Условие1 ложно, то группа
операторов1 не выполняется, а производится проверка Условие2
в следующей ветке ElseIf. И опять же, если Условие2
истинно, то выполняется группа операторов2, последующие группы операторов
не выполняются и их условия не проверяются. В противном случае происходит переход
к следующей ветке ElseIf. Если ни в одной ветке
нет истинных операторов, выполняется последняя группа операторов вне
зависимости от каких-либо условий. Логическая схема инструкции If представлена
в таблице:
If Условие1 Then | ElseIf
Условие2 Then |
ElseIf
УсловиеN Then |
...
|
Else |
||||
группа операторов1 |
группа операторов2 |
группа операторовN |
...
|
последняя |
||||
|
||||||||
End If |
Наиболее часто инструкция
If используется в блоковой форме в неполном (усеченном) виде. В этом случае
строки ElseIf отсутствуют:
If Условие
Then
группа операторов1
Else
группа операторов2
End If
В этом случае, если Условие - истинно, то
выполняется группа операторов1, а если нет, то группа операторов2.
Также довольно часто возникает необходимость в зависимости от условия выполнить
один оператор. Тогда Инструкция If может использоваться одной строчкой, без
строки End If.
If Условие
Then
Оператор1 Else
Оператор2
или еще короче
If Условие
Then
Оператор1
Все очень просто. Это вообще
мой любимый оператор (куда удобнее и универсальней, чем Select... Case).
А теперь применим знание этого оператора на практике. Чтобы
у нас показания времени в нашей программе «Часики» до десятка были с ноликами
01, 02, 03, а не 1, 2, 3 мы проверяем условие, меньше ли двух длина числа, записанного
в лейбле. Если да, то прибавляем впереди нолик. Для этого используем функцию
Len("строка"), которая определит число символов в строке. Если
в строке, например, 2 символа, то Len даст число 2. У нас получится:
If
Len(Label1.Caption) <
2 Then Label1.Caption = "0" & Label1.Caption
‘для первого лейбла
Но ведь и при загрузке системного
времени в процедуре Form1_Load нам тоже нужна такая проверка. Не будем же мы
переписывать одно и тоже в двух разных процедурах. Мы сделаем свою общую процедуру
и будем обращаться к ней по мере необходимости. Назовем ее, к примеру, Zero.
В конце нашей программы на свободном месте набираем на клавиатуре новую процедуру:
Private Sub
Zero()
If Len(Label1.Caption) < 2 Then
Label1.Caption = "0" & Label1.Caption
If Len(Label2.Caption) < 2 Then
Label2.Caption = "0" & Label2.Caption
If Len(Label3.Caption)< 2 Then
Label3.Caption = "0" & Label3.Caption
End Sub
Таким образом, у нас теперь есть своя собственная процедура, которая называется Zero. Никаких событий для ее выполнения нет и, чтобы она работала, ее нужно пробудить из нужного места программы, для чего просто пишем ее имя Zero. А нужные эти места находятся в последней строчке в процедурах Form1_Load() и Timer1_Timer(), прямо (перед End Sub).
Ну вот, с ноликами все в порядке, зато часы не работают. В подпрограмме Timer1_Timer() у нас всего один оператор. Чтобы часы работали, как настоящие, нам надо, чтобы, когда секунд становилось больше 59, они обнулялись, при этом минуты увеличивались бы на один. Используя оператор If это сделать очень легко:
If
Label1.Caption > 59
Then
Label1.Caption = "0"
Label2.Caption = Label2.Caption + 1
End If
'То же самое для Лейбла2:
If Label2.Caption > 59 Then
Label2.Caption = "0"
Label3.Caption = Label3.Caption + 1
End If
Аналогично для Label3 . Нам надо, чтоб, при значении часов больше 23 часов, Label3 показывал не 24, а ноль:
If
Label3.Caption > 23
Then Label3.Caption = "0"
Теперь ставим ссылочку на нашу процедуру проверки ноликов Zero :
Zero
И готово, т.е.
End
Sub
Вот полный листинг того,
что получилось. Кто хочет, может скачать исходник примера вверху страницы.
Option
Explicit
Private
Sub
Form_Load()
Form1.Caption = "Часики"
Label1.Caption = Second(Time)
Label2.Caption = Minute(Time)
Label3.Caption = Hour(Time)
Timer1.Enabled = True
Zero
End Sub
Private
Sub Timer1_Timer()
Label1.Caption = Label1.Caption + 1
If Label1.Caption > 59 Then
Label1.Caption = "0"
Label2.Caption = Label2.Caption + 1
End If
If Label2.Caption > 59 Then
Label2.Caption = "0"
Label3.Caption = Label3.Caption + 1
End If
If Label3.Caption > 23 Then Label3.Caption
= "0"
Zero
End Sub
Private
Sub Zero()
If Len(Label1.Caption) < 2 Then
Label1.Caption = "0" & Label1.Caption
If Len(Label2.Caption) < 2 Then
Label2.Caption = "0" & Label2.Caption
If Len(Label3.Caption) < 2 Then
Label3.Caption = "0" & Label3.Caption
End Sub
Теперь вот что. Тебе надо
самостоятельно разобраться с другой программой – «Однорукий бандит». Если сможешь
- будешь программировать, если нет, читай все сначала. Я даю исходник с подробнейшими-преподробнейшими
комментариями. Скачай его здесь.
«Однорукий
бандит» - имитация работы известного аппарата для азартных игр. В трех Лейблах
отображаются меняющиеся цифры от 1 до 7. Для работы с ними используются три
переменные Number. Их изменение управляется тремя таймерами. Первоначально интервалы
у таймеров одинаковы – 10 мск. В трех переменных Zamedlenie генерируются случайные
числа.
Zamedlenie1 = Int(Rnd
* 20) + 10
Работает это так. Rnd генерирует псевдослучайное число от 0 до 1. На двадцать умножаем, чтобы получить целую часть числа (можно умножать на что угодно, но не меньше 10, а то не получится целая часть). Функция Int отбрасывает дробную часть. Прибавляем в конце 10, чтобы исключить значение 0, а то таймер не остановится. Т.е., если Rnd генерирует, например, число 0,156, то
Zamedlenie1= Округляем (0,156*20) + 10 = 3 + 10 = 13. Очень просто.
При каждом срабатывании таймераувеличивается его интервал на значение замедления, пока интервал не становится больше 300 (это задано программно: Timer1.Interval > 300
После этого таймер выключается. Чтобы узнать, все ли таймеры выключились, я использую переменную Flag, которая накапливает в себе количество выключившихся таймеров. Когда Flag=3, считаем, что все три таймера закончили работу (а так оно и есть) и начинаем обрабатывать результаты (подпрограмма Raschet()). Изначальный капитал игрока хранится в переменной Summa, которая при различных выигрышах изменяется на сумму трех переменных Bonus, а при проигрыше на переменную BonusMinus. Почему ее значение отрицательное? Просто мне так захотелось, хотя это, конечно,совершенно необязательно. В Лейблах 4 и 5 выводятся всякие прикольные надписи, в зависимости от результата игры. Ну и кроме того, чтобы во время работы таймеров кнопка не нажималась, она, по состоянию переменной FlagClick, либо позволяет запустить таймеры, либо меняет свою надпись.
После того, как капитал игрока исчерпан, мы переходим к процедуре прекращения игры EndOfGame(), и в ней кнопка блокируется. Дальнейшая игра при этом невозможна.
В этой программе мы впервые объявляем переменные. Ничего в этом сложного нет. Главное, чтоб тип переменной приблизительно соответствовал нашим надобностям. Просто посмотри, как это деляется.
Ну вот, практически и все. Остальное ты должен додумать сам. Удачи.
|
Copyright
|