Delphi-int.ru: портал программистов

Вход Регистрация | Забыли пароль?

События

Сегодня:
Вопросы0    Ответы0    Мини-форумы0


Последние:
Вопрос09.08, 09:39 / #6696
Ответ29.03, 23:32 / #6682
Новости8 июля 2023


Сейчас онлайн:
На сайте — 9
На IRC-канале — 2

Ссылки

Выбор (ветвления)

Автор:
© Ерёмин А.А., 2007
Машинная программа выполняет то, что вы ей приказали делать, а не то, что бы вы хотели, чтобы она делала.
Номер урока:
14
 

Предисловие

Большинство примеров, которые были рассмотрены в предыдущих уроках, являлись программами с линейной структурой. Программы с линейной структурой являются простейшими и используются, как правило, для реализации обычных вычислений по формулам (или других аналогичных задач, назначение которых - последовательное выполнение некоторых команд). Основная характеристика линейных алгоритмов - инструкции выполняются последовательно, одна за другой.
Но линейных алгоритмов, как правило, недостаточно для реализации какой-то более сложной задачи. К примеру, требуется программа, запрашивающая у пользователя 2 числа и вычисляющая их частное (т.е. выполняющая деление одного числа на другое). Всё бы ничего, но если второе число будет нулём? В результате выполнения деления возникнет ошибка и программа экстренно закончит свою работу. Как же быть? В этом случае нужен другой алгоритм - алгоритм с ветвлениями.
Ветвления (выбор) используются для выбора одного из нескольких направлений дальнейшего хода программы. Для нашего примера перед делением будет выбор из двух направлений - если исходные данные верны (т.е. второе число - не 0), то выполняется деление и выдаётся результат; но если второе число - 0, то деление выполнено не будет, а взамен, к примеру, пользователю будет выдано сообщение об ошибке.
Мы рассмотрим два типа ветвления - с помощью условного оператора и оператора выбора.

1. Условный оператор

Условный оператор, который называется IF (англ. "если") используется для выбора одного из двух направлений хода программы. Выбор последовательности инструкций осуществляется во время выполнения программы в зависимости от выполнения условия.

Общий синтаксис условного оператора IF:

if {условие} then
  {последовательность команд}

THEN - англ. "в таком случае, тогда". Таким образом, строка вполне переводима и на русский язык: "Если условие выполняется, тогда сделать что-то..."

Здесь условие - выражение логического типа (логические выражения были рассмотрены нами ранее в уроке №10). Если выражение является истинным (True), т.е. условие выполняется, то выполняется последовательность команд, указанная после THEN. Если же условие не выполняется, данный блок пропускается. В случае, если команд, ассоциированных с условием, несколько, то они заключаются в BEGIN ... END:

if {условие} then
begin
  Команда 1;
  Команда 2;
  Команда 3
end;

Данную форму записи условного оператора можно назвать сокращённой. Есть и полная форма. Дело в том, что сокращённая форма позволяет выполнить блок команд при выполнении заданного условия, но при этом мы теряем из вида тот случай, когда условие не выполняется. Для нашего примера с делением чисел сокращённой формы недостаточно.

Полная форма даёт возможность указать две последовательности команд: одну - для случая, если условие выполняется, а другую - если не выполняется. Третьего не дано... Синтаксис:

if {условие} then
  {команды, если условие выполняется}
else
  {команды, если условие не выполняется}

ELSE - англ. "иначе, в противном случае": "Если условие выполняется, то сделать что-то, а в противном случае сделать что-то другое".
Аналогично, если требуется выполнить несколько команд, они заключаются в BEGIN ... END:

if {условие} then
begin
  {...}
  {команды, если условие выполняется}
  {...}
end
else
begin
  {...}
  {команды, если условие не выполняется}
  {...}
end;

Пример.

В качестве примера создадим программу расчёта сопротивления электрической цепи, состоящей из двух сопротивлений. Предоставим возможность выбора типа соединения - последовательное или параллельное.
Для начала создадим интерфейс. Разместим на форме 2 поля TEdit для ввода величин сопротивлений (Edit1, Edit2). Для выбора типа соединения разместим 2 TRadioButton с соответствующими надписями (RadioButton1, RadioButton2). Результат будем выводить в TLabel (Label1), а вычисления будем производить при нажатии на кнопку TButton (Button1). Получиться должно примерно следующее:

Интерфейс программы для расчёта сопротивления цепи

Далее дважды щёлкаем по кнопке и пишем обработчик.

procedure TForm1.Button1Click(Sender: TObject);
var R1,R2,R: Real;
begin
  R1:=StrToFloat(Edit1.Text);
  R2:=StrToFloat(Edit2.Text);
  if RadioButton1.Checked then
    R:=R1+R2
  else
    R:=(R1*R2)/(R1+R2);
  Label1.Caption:='Сопротивление цепи: '+FloatToStr(RoundTo(R,-2))+' Ом';
end;

Комментарии и пояснения:

1) В качестве исходных данных имеются 2 сопротивления - R1 и R2. Результирующее сопротивление - R. Для всех трёх переменных указан вещественный тип данных (Real), т.к. значения сопротивлений могут быть дробными числами.
2) Сначала мы заносим в переменные R1 и R2 числа, введённые в Edit1 и Edit2.
3) Далее мы применяем условный оператор, чтобы узнать, какой из двух TRadioButton выделен. Если выделен первый, то применяем формулу последовательного сопротивления (сумму): R = R1 + R2. Проверять, выделен ли второй, смысла нет, так как их всего 2 - если не выделен первый, значит выделен второй. Для параллельного сопротивления формула следующая: R = (R1 * R2) / (R1 + R2). Таким образом, в зависимости от выбранного типа соединения значение переменной R будет вычислено по соответстующей формуле.
4) Наконец, выполняется вывод результата в Label1. В приведённом коде использована функция RoundTo(). Эта функция округляет вещественное число до указанного знака после запятой. В данном случае округление ведётся до двух цифр. Это сделано для того, чтобы в Label1 не попал весь длинный ряд чисел после запятой, а попали все первые две цифры. Функция RoundTo() описана в модуле Math, с которым мы однажды работали. Этот модуль необходимо подключить, добавив его имя в uses (см. в самом начале модуля в редакторе кода):

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Math;

Запустим программу и проверим её работспособность.

Примечание: в примерах, показанных в данном уроке, фигурные скобки ("{" и "}") указаны всего лишь для удобства обозначения, что в конкретном месте кода программы должно что-то находиться - переменная, набор команд и т.д. В коде реальной программы данных скобок быть не должно!

2. Оператор выбора

Оператор выбора, который называется CASE, используется для выбора одного из нескольких направлений дальнейшего хода программы. Выбор последовательности инструкций осуществляется во время выполнения программы в зависимости от равенства значения переменной-селектора константе, указанной перед группой инструкций. В качестве переменной-селектора можно использовать переменную только перечислимого типа. Целое число (Integer) - перечислимый тип данных. Другим простым перечислимым типом данных является символьный тип (Char). Синтаксис оператора CASE:

case {переменная-селектор} of
  {константа_1}: {инструкции 1}
  {константа_2}: {инструкции 2}
  {...}
  else {инструкции, если ни одна константа не подошла}
end;

Работает оператор следующим образом: берётся значение переменной-селектора и последовательно сравнивается с каждой из констант. Если значения совпадают, то выполняются инструкции, указанные после данной константы. Если ни одна константа не совпала со значением переменной-селектора, но при этом указан блок else, то выполняются инструкции этого блока. Если блок else не указан, никаких команд выполнено не будет.
Обратите внимание, что после каждой константы ставится двоеточие (":").
Помимо одиночных констант можно указывать несколько констант через запятую, а также можно указывать диапазон, задав начальный и конечный элементы и разделив их двумя точками. Пример:

case a of
  1,2,3,4,5: {...}
  else {...}
end;

case a of
  1..5: {...}
  else {...}
end;

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

Пример программы с использованием оператора выбора.

Создадим программу, которая будет запрашивать ввод числа от 1 до 12 и выводить название времени года, которому принадлежит месяц с указанным номером.

Интерфейс прост: поле ввода (Edit1) и кнопка (Button1).

Обработчик кнопки таков:

procedure TForm1.Button1Click(Sender: TObject);
var Month: Integer;
begin
  Month:=StrToInt(Edit1.Text);
  case Month of
    1,2,12: ShowMessage('Зима');
    3..5: ShowMessage('Весна');
    6..8: ShowMessage('Лето');
    9..11: ShowMessage('Осень')
    else ShowMessage('Число должно быть от 1 до 12.')
  end
end;

Результат работы:

Результат работы программы

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

Заключение

Условный оператор IF и оператор выбора CASE позволяют создавать ветвления в программах, т.е. выполнять различные действия в зависимости от заданного условия. Отличие их друг от друга состоит в том, что IF используется для единственного выбора, а CASE - для множественного. Очевидно, что данные операторы могут быть вложены друг в друга (например, в одном из блоков оператора CASE может быть использован IF). При написании какой-либо сравнительно сложной программы без ветвлений не обойтись.

Автор: Ерёмин А.А.

Статья добавлена: 21 сентября 2007

Следующая статья: Обучающий курс. 15. Подводим промежуточный итог »

Рейтинг статьи: 4.55 Голосов: 11 Ваша оценка:

Зарегистрируйтесь/авторизируйтесь,
чтобы оценивать статьи.


Статьи, похожие по тематике

 

Для вставки ссылки на данную статью на другом сайте используйте следующий HTML-код:

Ссылка для форумов (BBCode):

Быстрая вставка ссылки на статью в сообщениях на сайте:
{{a:114}} (буква a — латинская) — только адрес статьи (URL);
{{статья:114}} — полноценная HTML-ссылка на статью (текст ссылки — название статьи).

Поделитесь ссылкой в социальных сетях:


Комментарии читателей к данной статье

antoca
Репутация: +1

antoca (9 августа 2010, 17:57):

"Если да, то как можно сравнить число с логическим значением, коим является"

Число можно сравнивать с логическим значением, да ты сам это писал несколько страниц назад. Ошибки нет.
Dj_smart
Репутация: нет

Dj_smart (18 ноября 2009, 15:18):

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

if (a+b>c) or (a+c>b) or (b+c>a) then ...
Andrush
Репутация: нет

Andrush (18 ноября 2009, 02:36):

if (a+b>c)and(b+c>a)and(a+c>b)
я так делал
Ерёмин А.А.
Репутация: +40

Ерёмин А.А. (13 октября 2009, 19:25):

a,b,с - числа? Если да, то почему к ним применяются логические операции?
p - число? Если да, то как можно сравнить число с логическим значением, коим является "(a or c or b)"?
Ham_ele_on
Репутация: -1

Ham_ele_on (13 октября 2009, 16:34):

разобрался, но видимо не до конца
if (a>(c+b))or(c>(a+b))or(b>(c+a))or(s<=0)or(p<=(a or c or b))
then MessageDlg('недопустимые значения',mtinformation,[mbOk],0);
как правильно должна записываться фраза в последних скобках (p<=(a or c or b))
пробовал по разному, всё равно выдаёт ошибку и компиляция не происходит.
скажите , что я НЕ прочитал...ткните носом
Ham_ele_on
Репутация: -1

Ham_ele_on (13 октября 2009, 08:11):

спасибо, разобрался.
Ерёмин А.А.
Репутация: +40

Ерёмин А.А. (13 октября 2009, 06:56):

А вы приоритеты расставьте - сначала ведь должны выполниться больше/меньше, а только затем OR. Вот и заключите маленькие условия в скобки.
Ham_ele_on
Репутация: -1

Ham_ele_on (12 октября 2009, 23:03):

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

if a>b then ShowMessage('a>b')else
if b>a then ShowMessage('b>a') else
if c>(a and b) then ShowMessage('c>a и b');
здесь ошибка в последней строке.

if a>b OR b>c then Close;
здесь тоже выдаёт ошибку
nightly
Репутация: нет

nightly (20 апреля 2009, 13:31):

Я хорошенько подумал и понял,что был не прав.
Ерёмин А.А.
Репутация: +40

Ерёмин А.А. (20 апреля 2009, 09:43):

Если сомневаетесь в работоспособности примера - скопируйте и попробуйте.

Что касается "если поменять местами их названия" - а вы часто так делаете? Боюсь, если надписи кнопок "Расчёт" и "Выход" поменять местами, результат тоже будет неожиданный.
nightly
Репутация: нет

nightly (19 апреля 2009, 22:18):

Мне кажется,что в статье есть следующая ошибка:
при расчете сопротивления вы выбираете 1 из radiobutton`ов.Но!Как компилятор узнает,какому именно radiobutton`у соответствет,к примеру,последовательное сопротивление????Ведь, если поменять местами их названия, то правильно программа работать уже не будет!Здесь следует использовать не radiobutton`ы, а RadioGroup.

Оставлять комментарии к статьям могут только зарегистрированные пользователи.