Основы программирования (947332), страница 12
Текст из файла (страница 12)
3.20. Синтаксичеркаядиаграмма <Операторбезусловной передачиуправления>Целоебез знакаJ ИдентификаторметкиооРис. 3.21. Синтаксическая диаграмма<Объявление меток>69Часть 1. Основы алгоритмизации и процедурное программированиеЧаще всего проблема разработки структурного варианта алгоритма возникает при работе с поисковыми циклами.
Как уже упоминалось впараграфе 1.3, в таких циклах просматривают некоторые последовательности элементов, пока не будет обнаружен элемент с заданными характеристиками. Отличительной особенностью поискового цикла является то, что элемент с заданными характеристиками в последовательности может отсутствовать, следовательно, необходимо предусмотреть два варианта выхода из цикла: досрочный, когда нужный элемент найден, и обычный - по завершениипросмотра всех вариантов.Пример 3.8. Разработать программу, которая определяет первый отрицательный элемент последовательности значений функции sin х при заданных п, шаге h и диапазоне изменения х [а, Ь].Для получения требуемого результата необходимо последовательно вычислять значение функции и анализировать его знак. Количество элементовпоследовательности на заданном отрезке и с заданным ша( Начало Jгом можно определить, следо/ Ввод7вательно, для вычисления зна/a,b,h /чений функции можно использовать счетный цикл.
Дляn:=(b-a)/h+lконкретных вариантов исходх:=аных данных может оказаться,что такого элемента в задангК^1:=1,пл\ной последовательности нет.Следовательно, после завершения цикла необходимо выy:=sin(x)вести соответствующее сообщение. Неструктурный варидау<0ант алгоритма решения задачипоказан на рис. 3.22.нетБез преобразований этотВывод/x:=x+hвариант алгоритма можно реа/лизовать только с использоваIZZJbreakнием оператора goto, так какgotoЭлементон позволяет передать управне найденление в любое место програм/ ж1Гмы, а процедура break - только оператору, следующему по( Конец )сле цикла (пунктир на рис.3.22). Поэтому реализация сиспользованием break потреРис. 3.22. Схема алгоритма поиска первогоотрицательного элемента последовательности бует дополнительной проверки (найден ли элемен) на вы(пунктиром выделен поисковый цикл)г7073.
Управляющие операторы языкаВывод/аX, у///"Элемент1// ненайдену'бРис. 3.23. Варианты организации поискового цикла для реализации:д - с использованием процедуры break; б- структурный вариантходе ИЗ цикла, чтобы вывести сообщение о том, что элемент не найден, только в том случае, если он действительно не найден (рис. 3.23, а)Для построения структурного варианта алгоритма меняем вид цикла:вместо счетного цикла будем использовать цикл-до со сложным условием,объединяющим оба условия выхода. После выхода из цикла неизвестно, покакому из условий цикл завершился, поэтому в данном варианте алгоритматакже приходится проверять, найден нужный элемент или нет (рис.
3.23, б).Рассмотрим соответствующие варианты программ.Вариант с использованием о п е р а т о р а g o t o :Program ex;Var /, n: integer; x,y, a, b, h:real;Label konec;{объявляем метку}BeginWrite (*Введите a,b,h:');Readln(a,b,h);n:=round((b'a)/h-^I.5); {определяем количество элементов}x:=a;for i:=l to n dobeginy:=sin(x);71Часть 1. Основы алгоритмизации и процедурное программированиеify<0 thenbeginWnteLn(y== \y:8:6,' при л:= \x:6:3);goto копес; {управление передаем на конец программы после вывода сообщения о том, что элемент не найден}end;x:=x+h;end;WriteLnCЭлемент не найден,');копес:{место, куда передается управление}EndВариант с использованием п р о ц е д у р ыbreak:Program ex;var in:integer; x,y,a,b,h:real;BeginWrite (*Введите a,b,h:');Readln(a,b,h);n:=round((b-a)/h-^J.5); {определяем количество элементов}x:=a;for i:=l to n dobeginy:=sin(x);ify<0 thenbeginWriteLn(y= ',y:8:6,' при x= \x:6:3);break; {осуществляем досрочный выход из цикла}end;end;{место, куда будет передано управление при выполнении break}ify>-0 then WriteLn('Элемент не найден,');End.Структурный вариант:Program ex;var х,у, а, 6, h:real;BeginWrite СВведите a,b,h: *);Readln(a,b,h);x:=a'h;repeat72J.
Управляющие операторы языкаx:=x+h;y:=-sm(x);until (x+h>b) or (y<0); {комбинированное условие выхода из цикла}ify<0 then WnteLn(y= \ у:8:б, ' при л:=', х:6:3)else WriteLn(*Элемент не найден. *);EndРазрабатывая структурный вариант цикла, мы были вынуждены однозначно сформулировать условие выхода из цикла и точно определить признак, по которому делается вывод о том, найдено ли решение. В то время какреализация «естественного» варианта алгоритма с использованием goto илиbreak требует учета всех возможных последствий неструктурной передачиуправления.
Кроме того, при структурном варианте получена самая простаяпрограмма, что в соответствии с рекомендациями структурного программирования существенно сокращаетколичество возможных ошибок.Рассмотрим еще один пример,при разработке программы которого теоретически можно использовать оператор continue.Пример 3.9. Разработать программу, которая должна вводить исуммировать 10 целых чисел, непревышающих 50. При вводе отрицательного числа она должна выдавать предупреждение, игнорировать число и ожидать ввода правильного значения.В данном случае в программенельзя использовать счетный цикл,так как количество его повторенийзаранее неизвестно, поэтому используем итерационный цикл,конкретно цикл-пока.
Алгоритм решения задачи представлен нарис. 3.24. Этот алгоритм можетбыть реализован с использованиемоператора goto, процедуры continueили оператора ветвления if. Последний вариант является структур- Рис. 3.24. Схема алгоритма определенияным.суммы 10 чисел, не превышающих 5073Часть I, Основы алгоритмизации и процедурное программированиеРассмотрим эти варианты.Вариант с использованием о п е р а т о р аgoto:Program ex;Var i,s,a:integer;Label cycl;Begini:=J;s:=0;while i<=10 dobeginRead(a);ifa>50 thenbeginWriteLn('Число не должно превышать 50 *);goto cycl; {передача управления на конец цикла}end;s:=s-^a; {операторы, которые необходимо обойти}cycl: end;WriteLn(s);EndВариант с использованием п р о ц е д у р ыcontinue:Program ex;Uses crt;Var i,s,a:integer;Begini:^l;S:=0;while i<=10 dobeginRead(a);ifa>50 thenbeginWriteLn('Число не долэюно превышать 50*);continue; {передаем управление на следующую итерацию}end;s:^s^a;i:=i-^l;end;WriteLn(s);End743, Управляющие операторы языкаСтруктурныйвариант:Program ex;Uses crt;Var hs,a: integer;Begini:-l;S:^0;while i<=10 dobeginRead(a);ifa>50 thenWriteLn('Число не должно превышать 50*)elsebegins:=s-\ra;i:=^i+I;endend;WriteLn(s);EndСтруктурная реализация алгоритма в данном случае является самой простой.
Использование вариантов.с оператором goto и процедурой continue нецелесообразно. Примен(ение continue в аналогичных ситуациях может бытьоправдано только при большом количестве пропускаемых операторов.Еще один тип алгоритмов, для реализации которых неопытные программисты обычно используют оператор goto, можно продемонстрировать наследующем примере.Пример ЗЛО. Разработать программу, которая многократно вычисляетзначение функции по вводимому пользователем значению аргумента.
Послевыдачи результата программа должна спрашивать, нужно ли продолжить работу. Если необходимость продолжения работы существует, пользовательвводит «у», иначе - «п». Соответственно в первом случае работа с программой продолжается, а во втором - программа завершает работу.В основе программы лежит циклический процесс.
По типу это цикл-до(рис. 3.25), однако его достаточно часто пытаются реализовать с использованием goto. Чтобы не делать таких ошибок, необходимо запомнить следующее: если в схеме алгоритма присутствует возврат управления на уже выполненный фрагмент, то необходимо выделить цикл и соответственно определить условие выхода из цикла.75Часть L Основы алгоритмизации и процедурное программирование(Ниже представлена реализация алгоритма с использованием цикла-до.Начало j/г /Выводsin(x)////иродолжитьУ/у^"/Ввод/7/__t—/Program ex;Var x:real;ch:char;BeginrepeatWrite('Введите x: ');ReadLn(x); {ни в коем случае не Read, так какдалее идет ввод символа (см. параграф 2.6)}WriteLn(*Результат \ sin(x):8:4);WriteLn(*Пpoдoлэ^cumь? (у/п)*);ReadLn(ch);until ch= *п VEnd.Окончательно можно сделать следующие выводы.1.
Оператор безусловной передачи управленияgoto в программах на Borland Pascal желательно вообще не использовать. Если у вас получился неструктурРис. 3.25. Схеманыйалгоритм, при реализации требующий goto, поалгоритмапробуйтепреобразовать его в структурный. Такое огвычисленияраничениесвязано с тем, что использование goto, какзначения функцииправило, приводит к появлению в программе большого количества ошибок [3, 4, 9].2. Процедуры неструктурной передачи управления break и continue могут быть полезны, однако при их использовании необходимо четко представлять себе, куда будет передано управление. Цикл, в котором использованыэти процедуры - это место повышенной вероятности наличия ошибок. Ондолжен специально тестироваться.Процедуры Halt и Exit обычно используют для аварийного завершениясоответственно программы или подпрограммы, поэтому их присутствие впрограмме практически не влияет на ее структурность.Задания для самопроверкиЗадание 1.
Разработайте профамму, которая определяет сумму первых трехотрицательных чисел последовательности значений, рассчитанных по формуле у^ == X - sin X при заданных диапазоне [а,Ь] изменения х и шаге h.Задание 2, Разработайте программу, которая строит таблицу значений функцииу = (in х) / tg X при заданных диапазоне [а, Ь] изменения х и шаге h. Если значениефункции в очередной точке не существует, то в соответствующей строке таблицывыведите сообщение «значение не существует».764. СТРУКТУРНЫЕ ТИПЫ ДАННЫХДостаточно часто возникает необходимость программирования обработки однотипных данных: таблиц, текстов, множеств и т.д.