В.Г. Абрамов, Н.П. Трифонов, Г.Н. Трифонова - Введение в язык Паскаль (1107618), страница 27
Текст из файла (страница 27)
Специальные указания оператору ЭВМ (в случае необходимости).Вся эта информация так или иначе необходима для документированияпрограммы, и самым подходящим местом для ее размещения являетсясама программа, которая в этом случае получается "самодокументированной".5.4. Пример разработки и оформления программыВ качестве иллюстрации метода пошаговой детализации и оформленияпрограммы рассмотрим пример учебного характера, в котором используются только рассмотренные до сих пор возможности языка Паскаль.П р и м е р 5.1. Разработать и составить паскаль-программу, в которойне используются функции, для вычисления_ ( \\т\ при т < 10,I \ [ т при т > 10,где целое т удовлетворяет условию 3 т ~ 1к < 3 т , к — заданное целоечисло.
Значение х/^Гвычислять с точностью е = 10~7.Общую схему программы представим в виде трех последовательныхблоков:1. Ввод и печать значения к.2. Вычисление у по заданным правилам.3. Печать значения у.Реализация на паскале блоков 1 и 3 в данном случае очевидна, так чтодальнейшей детализации подлежит только блок 2.Из анализа условия на значение т видно, что это есть наименьшее целоенеотрицательное число, для которого З т > Аг.Учитываяэто обстоятельство,а также заданные правила вычисления у, блок 2 можно детализироватьследующим образом:1012.1. Найти наименьшее целое т > 0 такое, что Зт > к.2.2. i f т < 1 0 then2.2.1. Вычислить у - 1 \т\else2.2.2. Вычислить .у = у / тС учетом этой детализации схема программы примет вид:1.
Ввод и печать значения к.2.1. Найти наименьшее целое т > 0 такое, что Зт > к.2.2. if т < 10 then2.2.1. Вычислить у = \jm\else2.2.2. Вычислить^ =\fm3. Печать значения у.(далее мы не будем выписывать полную схему программы после каждогоочередного шага детализации).Займемся теперь детализацией выделенных более мелких блоков 2.1,2.2.1 и 2.2.2.Для блока 2.1 можно предложить следующий алгоритм.
Примем предварительно т = 0, г = 3° ~ 1. Затем будем последовательно домножать г на3, а значение т увеличивать на единицу. Как только текущее значение гвпервые превзойдет значение к, будет получено нужное значение т:2.1.1.г : = 1; т: = 0 ;2.1.2. while / - < & d obegin г: =r * 3 ; т = т + 1 endТеперь блок 2.1. фактически записан на паскале, так что дальнейшая егодетализация не требуется.Блок 2.2.1 проще всего реализовать следующим образом:2.2.1.1. Вычислить р = т\2.2.1.2. Вычислить у = 1 /рРеализация блока 2.2.1.2 очевидна, а для вычисления р = т\ предварительноположим р = 1, а затем последовательно домножим р на 1, 2,...
' т :2.2.1.2.1. р := 1;2.2.1.2.2. f o r / := 1 to т do р := р * /'Теперь осталось детализировать блок 2.2.2. Для вычисления у = \[хвоспользуемся итерационным методом Ньютона, который был рассмотренв гл. 4 :+1)= у(п1 +_ j,("))/2,п = 0,1,2,...который сходится при любом начальном приближении v < - 0 '.Для нашего случая в качестве начального приближения примел= т/2, а итерационный процесс будем продолжать до тех пор, но к;очередная учтенная поправка v ^ = ( х / у ^ - у ^ ) / 2 по модулю не окажется меньше е:2.2.2.1.
у :=т/2\;1022.2.2.2. r e p e a t .v: = ( m / y - y ) l2;у : = y +u;if v < 0 t h e n и := — v;u n t i l и < epsТеперь д е т а л и з а ц и я а л г о р и т м а доведена д о у р о в н я т р е б о в а н и й я з ы к ап а с к а л ь и м о ж н о п е р е х о д и т ь к записи т е к с т а п а с к а л ь - п р о г р а м м ы , к о н ц е н т р и р у я с в о е в н и м а н и е н а п р а в и л а х записи п р о г р а м м ы н а э т о м я з ы к е :{Пример 5.1. Громыко В.И. Ф-т ВМК МГУ.
25.10.86.Иллюстрация метода пошаговой детализации!program ЫАГДЕТ (i nput., output);{eps-точность вычисления квадратного корня]с on st ер в*» IE—7$var k,p,m,r,i:integer;у,v: real;begin{ввод и печать значения k>read(k) ; writeln<_ k=', t;);{вычисление у no заданным правилам}{найти наименьшее целое m такое, что 3**m>k>r:=l;т:=0;while r<k dobegin r:=r*3; т:=т+1 end;{выбор правила вычисления у }if т<10 thenbegin{вычисление р=ш!>ps=l 5•for i: = l to m do p:=p*i;{вычисление y=l/p>y:=l/pend{значение у вычислено по первому правилу}else{извлечение корня из т сТОЧНОСТЬЮeps>begin{начальное приближение у0=т/2}у: =т/2;103repeatv:=(m/y-y)/2; y:=y+v;if v<0 then v:=-vuntil v<epsend;{значение у вычислено no второму правилу){вывод результата}writ.eln('_ у= , у)end.ГЛАВА6СКАЛЯРНЫЕ ТИПЫ ЗНАЧЕНИЙ:ПЕРЕЧИСЛИМЫЕ И ОГРАНИЧЕННЫЕДо сих пор мы имели дело со стандартными скалярными типами значений,которые определены самим я з ы к о м и которые не могут вводитьсяв употребление (в частности, описываться) в паскаль-программе.Однако, как мы уже знаем, паскаль предоставляет программисту возможность вводить в употребление и другие, удобные для него типы значений.В данной главе мы рассмотрим простейшие из таких типов значений —п е р е ч и с л и м ы е и о г р а н и ч е н н ы е типы.
Оба эти класса типовотносятся к скалярным типам, поскольку каждое из значений этих типовсостоит из единственного данного (т.е. является тривиальной структуройданных) — точно так же, как и любое значение стандартного типа.6.1. Перечислимые типыВ случае стандартных типов значений мы имели дело с такими понятиями,как "целое число", "вещественное число", "литера" и "логическое значение", подразумевая под каждым таким понятием определенное множествоего частных случаев. В алгоритмическом языке каждому из этих понятийсопоставляется некоторый тип значений, а множеству частных случаевкаждого понятия — соответствующее множество значений этого типа.Однако на практике нам приходится иметь дело с самыми различнымипонятиями, каждое из которых включает в себя свое множество частныхслучаев. Например, понятие " м е с я ц года" (или просто " м е с я ц " )объединяет в себе в качестве частных случаев месяцы с именами январь,февраль, ..., декабрь; понятие "день" (недели) — дни с именами понедельник, вторник, ..., воскресенье: понятие "цвет радуги" — цвета с именамикрасный, оранжевый, ..., фиолетовый; понятие " ф р у к т ы " — некоторый набор интересующих нас плодов, например с именами яблоко, груша, персик,айва и т.д.
и т.п.При решении на ЭВМ задач, связанных с использованием понятий подобного рода, их отдельные частные случаи иногда кодируют в цифровой форме путем отображения на целые числа. Например, месяцы в году можнозакодировать последовательными целыми числами от 1 до 12; так же можно поступить с днями недели, цветами радуги и т.д. В этом случае в записиалгоритма вместо явного указания нужного частного случая понятияуказывается его код. Ясно, что при этом снижается наглядность записи105алгоритма, затрудняется его понимание и проверка.
Например, встретивв тексте программы условиеi-f b=9 t h e nневозможно сразу понять, о чем здесь идет речь: то ли о сравнении целочисленной переменной b (являющейся, например, счетчиком числа повторенийцикла) с целым числом 9, то ли выясняется, не девятый ли месяц года(т.е. сентябрь) представляет значение переменной b и т.д. Так что для понимания или проверки правильности такой записи приходится по ходу делавспоминать (или выяснять), что же по существу решаемой задачи представляет собой переменная b и что именно закодировано целым числом 9.Если же по своему существу переменная b представляет какой-то месяцгода и нужно проверить, является этот месяц сентябрем или нет, то гораздоудобнее было бы не прибегать к кодировке, а записать это условие в естественной форме:i-f Ь = с е н т я е р ь thenДля достижения такой естественности и наглядности записи алгоритмарешения задачи, в которой используются подобного рода понятия, целесообразно каждому из них также сопоставить некоторый тип, определяющийсвое множество конкретных допустимых значений, каждое из которых ибудет представлять отдельный частный случай этого понятия.
При этомв качестве таких значений — для избежания кодировки — естественнопринять обычные названия (имена) этих частных случаев. Конечно, для значений подобных типов довольно трудно определить какие-то специальныеоперации, например аналоги арифметических операций над числами —в подавляющем большинстве случаев бывает достаточно операцийсравнения.Исходя из указанных выше соображений, в паскале и предусмотреныперечислимые типы значений, которые относятся к скалярным типам.В языке имеется только один стандартный перечислимый тип — таковымявляется тип boolean.
Наряду с ним программист имеет возможностьвводить в употребление свои, удобные для него перечислимые типы.Любой нестандартный тип значений должен быть определен в программе, с помощью задания типа. В случае перечислимого типа это заданиесинтаксически определяется следующей метаформулой:< задание перечислимого типа > : : = ( < имя > {, < имя >})Имена, перечисленные через запятую в круглых скобках, являются константами определяемого типа, а их набор, перечисленный в скобках, иявляется множеством значений этого типа. Значения перечислимого типасчитаются перенумерованными, начиная с нуля, в порядке их перечисления.Пример задания перечислимого типа:(понедельник, вторник, среда, четверг, пятница, суббота, воскресенье)Множество значений этого типа состоит из семи элементов — имен, перечисленных в круглых скобках.
Эти имена являются константами определен106ного здесь типа, причем имеет место соотношениепонедельник < вторник < среда < ... < воскресенье,значение понедельник имеет порядковый номер 0, значение вторник —порядковый номер 1 и т.д.Напомним, что большинство определяемых в программе типов (в томчисле и рассматриваемый здесь перечислимый тип) можно ввестив употребление двумя способами.При первом из них новый тип вводится в употребление с помощьюописания этого типа (в разделе типов), где определяемому типу даетсясвое имя:< описание типа >:: = < имя типа > = < задание типа > |{ имя типа > = < имя типа >Альтернатива <имя типа) = ( и м я типа) этой метаформулы говорито том, что новый тип можно определить путем указания имени ранееопределенного (или стандартного) типа.