Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Алгоритмизация и программирование ч.2.doc
Скачиваний:
6
Добавлен:
24.09.2019
Размер:
7.68 Mб
Скачать

27

1. Разветвляющиеся вычислительные процессы

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

Оператор if обеспечивает передачу управления на одну из двух ветвей вычислений, а оператор case — на одну из произвольного числа ветвей. Рассмотрим сначала задачи с применением оператора if.

1.1 Условный оператор if

Формат оператора:

if выражение then оператор_1 [else оператор_2:]

Сначала вычисляется выражение, которое должно иметь логический тип. Как правило, в выражении используются знаки операций отношения (меньше <, больше >, равно =, не равно <>, меньше или равно <=, больше или равно >=)2. Если требуется проверить несколько условий, их объединяют знаками логических операций and (И), or (ИЛИ), xor (исключающее ИЛИ) и not (отрицание). Примеры логических выражений:

а < 2

( х <> 0 ) and ( у <> 0 )

Если выражение имеет значение true, выполняется первый оператор, иначе — второй (рис. 1.1). Ветвь else может отсутствовать. После выполнения операторов из соответствующей ветви управление передается оператору, следующему за условным оператором.

Рис. 1.1. Структурная схема условного оператора

Если по какой-либо ветви требуется выполнить не один, а несколько операторов, применяют блок (составной оператор). Блок обрамляется ключевыми словами begin и end:

if а=0 then begin х:=0; у:=0 end

else begin х:=1; у:=2 end;

Внутри условного оператора можно записать еще один условный оператор, например:

if а >= b then if а = b then с := 0 else с := 1 else с := 2;

Ключевое слово else всегда считается относящимся к ближайшему слову if, т.е.

if а >= b

then if а = b

then с := 0

else с := 1

else с := 2;

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

1.2 Оператор case

Оператор варианта (выбора) используется для реализации алгоритмов, имеющих приведенную на рис. 1.2 структуру. Решение о том, какой именно оператор выполнить, принимается после анализа значения выражения порядкового типа. Выполняется оператор (простой или составной), записанный после константы, с которой совпало значение выражения.

Рис. 1.2. Структурная схема оператора выбора

Чаще всего после ключевого слова case указывается имя переменной (это частный случай выражения). Если требуется выполнить одни и те же действия для нескольких констант, они записываются либо через запятую, либо с помощью операции диапазона (..).

Формат оператора:

case выражение of

константы_1 : оператор_1;

константы_2 : оператор_2;

. . .

константы_n : оператор_n;

[else : оператор]

end;

1.3 Примеры использования операторов if и case.

Пример 1.1. Написать программу, которая по введенному значению аргумента вычисляет значение функции, заданной в виде графика (рис. 1.3) на интервале [-3; 3].

Рис. 1.3. Функция, заданная в виде графика

Начинать решение даже простейшей задачи необходимо с четкого описания ее исходных данных и результатов. В данном случае это очевидно: исходными данными является вещественное значение аргумента х, который определен на интервале [-3; 3], а результатом — вещественное значение функции у. Поэтому для представления этих величин в программе следует выбрать тип real.

Перед написанием программы следует составить алгоритм ее решения — сначала в общем виде, а затем постепенно детализируя каждый шаг. Такой способ, называемый нисходящей разработкой, позволяет создавать простые по структуре программы.

Сначала запишем функцию в виде формул:

Примечание: Уравнение окружности радиуса R с центром в точке выглядит так:

. Уравнение прямой: .

Далее приведено описание алгоритма в словесной форме.

  1. Ввести значение аргумента х.

  2. Проверить, принадлежит ли оно области определения функции.

  3. Если не принадлежит, вывести диагностическое сообщение и завершить программу.

  4. Определить, какому интервалу из области определения функции принадлежит введенное значение, и вычислить значение функции у по соответствующей формуле.

  5. Вывести значение у.

Опишем четвертый пункт алгоритма более подробно:

  • Если аргумент х принадлежит интервалу [-3; -2), то .

  • Если аргумент х принадлежит интервалу [-2; 0), то .

  • Если аргумент х принадлежит интервалу [0; 1), то

  • Если аргумент х принадлежит интервалу [1; 3], то .

По такому алгоритму можно практически «один в один» написать программу:

program calc_fun;

var x, y: real;

begin

writeln ('Введите значение аргумента:');

readln(x);

if (x<-3) or (x >3) then begin

writeln ('Значение должно принадлежать [-3;3]');

exit

end;

if x < -2 then y := -2 * x - 5;

if (x>=-2) and ( x<0 ) then y:=-sqrt(1-sqr(x + 1)) - 1;

if (x>=0) and (x<1) then y:=x-1;

if x>=1 then y:= sqrt(1-sqr(x-2));

writeln ('Для x= ', x:3:2, ' значение функции y=', y:3:2)

end.

Обратите внимание на запись условий, содержащих два сравнения. Начинающие часто записывают такие условия, просто воспроизводя математическую формулу, то есть как а < х < Ь. Ошибка состоит в том, что операции отношения (< >, ==, <, >, ! =) являются бинарными, то есть должны иметь два операнда. И если мы хотим проверить два условия (а < х и х < Ь), то и операций должно быть две.

Поскольку необходимо, чтобы эти условия выполнялись одновременно, они объединены с помощью операции логического И (and), то есть выражение принимает вид (a<x) and (x<b). Заключать каждое условие в круглые скобки необходимо потому, что логические операции имеют более высокий приоритет, чем операции отношения. При отсутствии скобок сначала будет предпринята попытка выполнить операцию х and х2, что вряд ли соответствует нашему замыслу.

Первый и последний условные операторы записаны без двойных условий, потому что проверка того, что аргумент находится в диапазоне [-3; 3], выполнена раньше.

Стандартная процедура exit обеспечивает выход из программной единицы, в которой она записана.

Тестовые примеры для этой программы должны включать по крайней мере по одному значению аргумента из каждого интервала, а для проверки граничных условий — еще и все точки перегиба (если это кажется вам излишним, попробуйте в условиях «забыть» знак =, а затем ввести значения х, равные -2 и 0).

Структурная схема вычисления значения функции приведена на рис. 1.4.

Рис. 1.4. Алгоритм вычисления значения функции

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

if x < -2 then y := -2 * x - 5

else if x < 0 then y := -sqrt( 1 - sqr(x + 1)) - 1

else if x < 1 then y := x - 1

else y := sqrt( 1 - sqr(x - 2));

Этот вариант вычисления значения функции иллюстрирует рис.

Сравним между собой структурные схемы двух вариантов фрагментов программы (см. рис. 1.4 и 1.5). Во втором варианте проверка на принадлежность аргумента очередному интервалу выполняется только в том случае, если х не входит в предыдущий интервал. Программа получилась более компактной, более эффективной, но, возможно, менее наглядной. В отличие от предыдущей версии, порядок следования условных операторов имеет здесь большое значение.

Рис. 1.5. Второй вариант вычисления значения функции

Пример 1.2. Написать программу, реализующую калькулятор на четыре арифметических действия (+, −, /, *)

Исходными данными для этой программы являются два вещественных операнда и знак операции, представляющий собой символ. Алгоритм работы программы очевиден: в зависимости от значения введенного знака операции выполнить соответствующее действие над операндами.

program calculator;

var

a, b, resiltat: real;

operac : char;

begin

writeln( 'Введите первый операнд: ');

readln(a);

writeln( 'Введите операцию: ');

readln(operac);

writeln('Введите второй операнд: ');

readln(b);

case operac of

'+' : resiltat:=a+b;

'-' : resiltat:=a-b;

'/' : resiltat:=a/b;

'*' : resiltat:=a*b;

else begin

writeln( ' Недопустимая операция ');

exit end;

end;

writeln( ' resiltat=', resiltat:10:2);

end.

Обратите внимание на то, что если по какой-либо ветви требуется записать не один, а несколько операторов, они заключаются в блок с помощью ключевых слов begin и end.

Хотя наличие слова else не обязательно, рекомендуется всегда обрабатывать случай, когда значение выражения не совпадает ни с одной из констант. Это облегчает поиск ошибок при отладке программы.