Язык Паскаль

Рассмотрение программы как цели грамматики языка Паскаль. Организация ввода исходных данных и вывода результирующей информации. Характеристика основных типов управления очередностью действий: последовательного, ветвящегося и циклического процессов.

Рубрика Программирование, компьютеры и кибернетика
Вид реферат
Язык русский
Дата добавления 17.02.2012
Размер файла 76,5 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Министерство образования и науки Украины

Национальный технический университет Украины "КПИ"

Факультет Информатики и вычислительной техники

Реферат: ЯЗЫК ПАСКАЛЬ

Киев 2011

1. Цель грамматики (программа)

Целью грамматики языка является программа. Эта конструкция в Паскале определяется следующим образом:

<программа>::= <заголовок программы>;

<блок>.

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

Одна из форм заголовка программы в Стандарте Паскаля несла смысловую нагрузку (связывала с именем программы имена используемых в ней файлов). Эта форма ниже не рассматривается, поскольку современными системами программирования заголовок программы вообще игнорируется, т. е. может быть опущен. Но делать этого не следует просто потому, что любой текст, в том числе и программа, должны иметь заголовок. Таким образом:

<заголовок программы> ::= program<имя программы>

<имя программы> ::= <идентификатор>

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

Блок в свою очередь определяется с помощью конструкций <список разделов описаний> и <раздел операторов>:

<блок> ::= <список разделов описаний>;

< раздел операторов >.

<список разделов описаний> ::= < раздел >

<список разделов описаний>:

< раздел >

< раздел > ::= < раздел меток >

< раздел констант >

< раздел типов>

< раздел переменных>

< раздел процедур и функций >

Знак "или" в конце правила означает, что раздел, а, следовательно, и список разделов описаний может быть пустым, т.е отсутствовать в тексте программы.

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

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

Конструкция <тип> здесь существенно упрощена и вводит понятие только так называемых стандартных (предопределенных или встроенных) простых типов переменных, значения которых могут быть целыми (Integer), вещественными (Real), булевскими (Boolean) или символьными (Char). Концепция типов данных в языке Паскаль будет подробно обсуждаться позднее.

< раздел переменных> ::= var < список описаний переменных>

< список описаний переменных> ::= <описание переменных>

< список описаний переменных>;

<описание переменных>

<описание переменных> ::= <список имен переменных> :

<тип>

<список имен переменных> ::= <имя переменной>

<список имен переменных>,

<имя переменной>

<тип> ::= Integer Real Boolean Char

<имя переменной> ::= <идентификатор>

Раздел операторов описывает действия, выполняемые программой. Его иногда называют телом программы. Конструкция раздела операторов выглядит следующим образом:

<раздел операторов> ::= begin

<список операторов>

end

<список операторов> ::= <оператор>

<список операторов>;

<оператор>

<оператор> ::= <оператор присваивания>

<составной оператор>

<оператор выбора>

<оператор цикла>

<оператор перехода>

<оператор присоединения>

<оператор процедуры>

Примером простейшей программы на языке Паскаль может служить программа:

program Prim; {заголовок программы с именем prim}

var {список разделов описаний; включает один раздел}

A : Integer; {описание переменной целого типа}

B : real; {описание переменной вещественного типа}

begin {начало раздела операторов}

A :=1; {первый оператор списка операторов}

B :=0.625; {оператор присваивания; по типу аналог предыдущего}

Write (A,B) {оператор процедуры вывода значений переменных}

end. {конец раздела операторов ; после end - точка}

Для пояснения текста программы использован комментарий. Назначение этой конструкции ясно из примера и заложено в самом названии.

<комментарий> ::= {<последовательность символов>}

(*<последовательность символов>*)

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

A:=1; {первый оператор списка операторов

B:=0.625; оператор присваивания; по типу аналог предыдущего},

в котором оператор B:=0.625 попал в текст комментария и, следовательно, транслятором не воспримется. Это обусловлено тем, что текст программы вообще воспринимается транслятором как одна строка. Пробелы и комментарии как разделители лексем, а также признаки конца строки (ln) могут встречаться один раз или повторяться многократно в любом месте текста программы и после выделения лексем транслятором игнорируются. В частности, выделение строк на экране видеотерминала или на печатающем устройстве носит чисто условный характер и связано только с ограниченными размерами изображения или разметкой текста для удобства чтения.

Ввод и вывод информации

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

Ввод информации осуществляется с помощью оператора процедуры Read, после которого в круглых скобках указывается имя переменной или параметр. Этой переменной будет присвоено значение, вводимое с клавиатуры. Набор на клавиатуре сопровождается при этом "эхо-сигналом", т.е. на экране видеотерминала появляется изображение вводимых символов (в некоторых системах программирования есть средства, позволяющие отключить эхо). Например, оператор Read(X) означает, что после набора на клавиатуре последовательности символов 0.255 выполниться действие X:=0.255. Последовательность операторов Read(A); Read(B); Read(C) может быть заменена одним - Read(A,B,C). Как в первом, так и во втором случае необходимо выполнить одни и те же действия - ввести три значения переменных.

Разновидностью оператора read является оператор ReadLn. Он используется без параметров и "устанавливает" маркер экрана в начало новой строки (действия, подобные возврату каретки пишущей машинки). Таким образом, оператор ReadLn(A,B,C) эквивалентен последовательности Read(A); Read(B); Read(C); ReadLn. При этом ReadLn - обязательно последний.

Вывод информации на экран видеотерминала осуществляется с помощью оператора Write. Существует также его разновидность Writeln. Параметром этого оператора может быть имя переменной или выражение. В обеих случаях на экран будет выведено значение переменной или результата выражения, который будет предварительно вычислен. Кроме того, параметром может быть конструкция <строка>, т. е. последовательность символов, взятая в кавычки. В последнем случае на экран будет выведена сама последовательность символов без каких-либо изменений. Например, Write(X) обеспечит вывод на экран значения переменной X, а Write(`X') - вывод символа X.

Последовательность операторов write можно заменять одним оператором по тем же правилам, что и последовательность операторов read. Так оператору WriteLn (`Корни равны ',Re+Im,' и `,Re - Im) соответствует последовательность операторов:

Write (`Корни равны ');

Write (Re+Im);

Write (` и `);

Write (Re - Im);

WriteLn;,

а оператору WriteLn (`Комплексные корни равны ',Re,'+I `,Im,' и `,Re,' -i`,Im) соответствует последовательность:

Write (`Комплексные корни равны ');

Write (Re);

Write ('+I `);

Write (Im);

Write (`и `);

Write (Re);

Write (' -I`);

Write (Im);

WriteLn;

Если предположить что Re=3.0 , а Im=5.0 , то в первом случае результатом вывода будет строка на экране:

корни равны 8.0 и -2.0

а во втором:

комплексные корни равны 3.0+i5.0 и 3.0-i5.0.

Относительно процедур ввода-вывода можно сделать еще одно существенное замечание. Оператор Read переводит машину в режим ожидания ввода с клавиатуры. В этот момент на экране виден только мигающий курсор (маркер), если экран предварительно очищен или такой же курсор в конце текста сообщений предыдущего диалога (результатов предыдущего вывода). В этом случае полезной оказывается подсказка о том, чего ожидает машина. Для этого в тексте программы оператору Read должен предшествовать оператор Write, с помощью которого такая подсказка и выводится на экран. Например, перед вводом значения аргумента вычисляемой функции желательно оформить подсказку вида

Write (` Введите аргумент функции x= ');

и только после этого записать соответствующий оператор ввода

Read (X);

2. Концепция действия

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

следование, при котором действия выполняются в соответствии с порядком их следования в тексте программы (в дальнейшем такой процесс будет называться последовательным или линейным);

ветвящийся процесс, соответствующий принятию решения, при котором последовательность действий определяется некоторым условием;

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

Последовательный процесс

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

Соответствующая оператору присваивания синтаксическая конструкция имеет вид:

<оператор присваивания>::= < левая часть >:=< правая часть >

< левая часть> ::= < имя переменной>

< правая часть> ::= <выражение>

<выражение> ::= <терм>

+<терм>

- <терм>

not <терм>

<выражение>

<аддитивная операция>

<терм >

<терм> ::= <множитель>

<простое выражение>

<мультипликативная операция>

<множитель>

<множитель>::= <переменная>

<константа без знака>

(<выражение>)

<переменная> ::= <имя переменной>

<константа без знака> ::= <число без знака>

<аддитивная операция> ::= +-or

<мультипликативная операция> ::= /divmodand

Конструкцией выражения предусмотрена запись в правой части оператора присваивания обычной формы алгебраического выражения (в том числе и его скобочных форм), с незначительными отличиями:

знаки операций должны соответствовать нотации языка;

запрещено использование надстрочных и подстрочных символов;

отсутствуют операции возведения в степень и извлечения корня.

Кроме того, при записи операторов присваивания вместо привычного знака равенства используется операция установки равенства или присваивания (:=). При этом следует учесть, что выполняться с ожидаемым результатом оператор присваивания будут только в том случае, когда значения всех переменных в правой части уже определены.

Составной оператор. Составной оператор является простейшей формой структурирования последовательности действий, т.е. позволяет объединить некоторые действия и рассматривать их в дальнейшем, как единое целое (один оператор):

<составной оператор> ::= begin <список операторов> end

Роль этой конструкции, в основном, сводится к упрощению последующих синтаксических определений (см ниже).

Используя конструкцию составной оператор, можно уточнить определение <блок>:

<блок> ::= <список разделов описаний><составной оператор>

Ветвления

Условный оператор. Ветвящийся вычислительный процесс в алгебраической форме описывается как:

или

что соответственно читается как "если a<0, то а положить равным а2, иначе а/2 ". или для второго выражения - "если a<0, то а положить равным а2 ". В противном случае здесь ничего не нужно делать, поскольку а не изменяет своего значения. На языке блок-схем алгоритмов это можно представить соответственно Рис. 2.1.а. и 2.1.б.

Для описания ветвлений используется синтаксическая конструкция, называемая оператором выбора:

<оператор выбора>:= <условный оператор>

<оператор варианта>

Оператор варианта используется для описания множественных ветвлений и будет рассматриваться позднее. Конструкция условного оператора имеет вид:

<условный оператор>::= if <условие> then <оператор>

else <оператор>

if <условие> then <оператор>

Спецификация абстракции настолько наглядна, что не требует пояснений если воспользоваться переводом с английского (if - если, then - то, else - иначе). Приведенные выше примеры в виде условных операторов могут быть записаны как:

if A<0 then A:=A*A else A:=A/2 ,

или второй вариант:

if A<0 then A:=A*A.

Для уточнения конструкции требуется определить "условие":

<условие>:: = <выражение>

<выражение><операция отношения>

<выражение>

В каком случае выражение представляет собой "условие", а также смысл операций not, or и and поясняются после описания булевского типа.

Теперь для практического использования условных операторов осталось ответить на два не вполне очевидных вопроса. Первый из них связан с тем, что в соответствии с правилом после символов then и else можно записать только один оператор. Это ограничение вызвано следующим: если использовать список операторов вместо одного оператора, то возникнет неоднозначность и для ее устранения потребуется дополнительная разметка текста. Последнее утверждение иллюстрируется с помощью Рис.2.2.

Первая из блок-схем (Рис.2.2.а) соответствует "короткому" оператору, который в тексте программы будет выглядеть так: ...;S1; if I<N then S2;S3;S4;... (здесь и на рисунке содержательная часть оператора заменена символом S и его порядковым номером). Если условие истинно, то никакой неопределенности нет. Операторы будут выполняться в последовательности ... S1, S2, S3, S4,... Если условие ложно, то в соответствии с блок-схемой должна выполняться последовательность ... S1, S4,... Однако, фрагмент программы не содержит информации о том, какое количество операторов после символа then нужно пропустить. Не содержится в нем и информация о том, с какого оператора нужно продолжать последовательность, т.е. определить ее вид невозможно.

Аналогичная ситуация возникает и для Рис.2.2.б. Только теперь она относится к последовательности операторов, расположенных после символа else, поскольку предыдущая часть последовательности всегда находится между символами then и else. Действительно, фрагмент текста программы ... S1; if i<n then S2 else S3; S4; S5;... не содержит признаков, позволяющих определить последовательность выполнения операторов при истинном условии.

Проблема неоднозначности в языке Паскаль легко устраняется с помощью конструкции <составной оператор>. Поскольку составной оператор есть один оператор, спецификация условного оператора не будет нарушена при использовании после символов then и else списка операторов произвольной длины, заключенного между символами begin и end.

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

Второй тип неоднозначности при использовании условных операторов возникает в том случае, когда они "вложены" друг в друга, т.е. когда после then следует еще один условный оператор. Например, в случае

if I<N then if A<E then A :=A/2 else I :=I+1

невозможно определить, к какому из условных операторов относится цепочка else I=I+1. Действительно, если вложенным считать подчеркнутый оператор, то можно рассмотреть два варианта:

if I<N then if A<E then A :=A/2 else I:=I+1 или

if I<N then if A<E then A :=A/2 else I:=I+1

Эту неоднозначность можно устранить, если использовать операторные скобки (begin ... end), заключая в них каждый "вложенный"оператор. Такой прием всегда может быть использован, поскольку не нарушает правил грамматики. Однако для таких ситуаций в языке обычно принимается соглашение о том, что else принадлежит ближайшему if, т.е правильным следует считать второй вариант разбора. Кроме того, тщательный подбор и минимизация условий часто вообще позволяют избавиться от вложенных условных операторов.

В качестве примера использования условных операторов рассматривается один из возможных вариантов программы решения квадратного уравнения ax2 + bx +c =0.

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

Если а=0 и b=0, уравнение или тавтологично (с=0), или противоречиво (с0). В этом случае должно быть предусмотрено сообщение о том, что уравнение вырождено.

Если а=0 и b 0, имеется один корень со значением -с/b.

Если а 0 и с=0, имеются два корня -b/a и 0.

В других случаях уравнение имеет вид ax2 + bx +c =0 (все коэффициенты не равны нулю), или ax2+c =0 (а 0 и с 0), и для вычисления корней можно использовать формулу

.

Величина d= b2 - 4ac есть дискриминант уравнения. Если d 0, то имеются два вещественных корня, возможно равных, иначе - корни комплексные. Поэтому формула в "чистом" виде неудобна для вычисления корней. Ее нужно реализовать последовательно, сначала вычислив величину -b/2a, затем дискриминант и (в зависимости от условия d 0) значения самих корней.

С учетом сказанного выше программа решения квадратного уравнения примет вид program Prim2_1.

Кроме известных конструкций, в программе при вычислении переменной Im в правой части оператора присваивания использована цепочка символов Sqrt(Abs(D)/2A). Это стандартные (встроенные в систему программирования) функции Sqrt и Abs. Стандартная функция Abs "возвращает" переменной с именем функции абсолютное значение аргумента, указанного в скобках, а функция Sqrt - значение квадратного корня. В рассматриваемом случае аргументом функции Sqrt является взятое в круглые скобки выражение, в которое входит функция Abs(D).

program Prim2_1;

var

A,B,C,D,Re,Im : Real;

begin

Writeln (`Введите коэффициенты квадратного уравнения');

Write (`A= `);

Read (A);

Write (` B= `);

Read (B);

Write (` C= `);

Read (C);

if (A=0) and (B=0)

then

WriteLn(`Уравнение вырождено')

else

begin

if A=0

then

writeln (`Единственный корень равен ', C/B)

else

begin

if C=0

then

WriteLn (`Корни равны ', B/A,' и `,0);

else

begin

Re:= B/2A;

D:=BB4AC;

Im:=Sqrt(Abs(D)/2A);

if D >=0

then

WriteLn (`Корни равны ',Re+Im, и `,Re -Im)

else

WriteLn (`Комплексные корни равны ',Re,'+I `,Im,'

и', Re,' - I`,Im)

end

end

end

end.{Prim2_1}

С учетом тестирования различных вариантов сочетания значений коэффициентов A, B и C, значения которых указаны в скобках, результаты будут выведены в виде строк:

Уравнение вырождено (A=0 B=0 C=7);

Единственный корень равен -0.250000 (A=0 B=1 C=4);

Корни равны -1.500000 и 0 (A=2 B=3 C=0);

Корни равны -2.000000 и -3.000000 (A=1 B=5 C=6);

Комплексные корни равны 5.000000+i*0.866025 и -5.000000-i*0.866025

(A=1 B=1 C=1).

Однако в одном случае эта программа может дать неточные результаты Если B2 намного больше, чем 4AC то дискриминант примерно равен B2 и один из корней будет иметь очень малое значение. Вычисление меньшего корня производится при вычитании двух чисел, которые примерно равны. Это может привести к потере значения, попавшего в область "машинного нуля". Поэтому лучше сначала вычислить больший корень X1, а затем определить меньший из отношения X2=C/(A*X1).

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

<оператор варианта> ::= case <выражение> of <список ветвлений>

end

<список ветвлений> ::= <вариант>

<список ветвлений>;<вариант>

<вариант> ::= <список меток > : <оператор>

<список меток > ::= <метка > <список меток >,<метка>

<метка> ::= <константа скалярного типа >

Последнее правило здесь определяет лексему "метка". Это определение в дальнейшем будет уточняться. С помощью оператора варианта из списка вариантов для исполнения выбирается тот оператор, метка которого равна текущему значению селектора. Если такой метки нет в списке меток, действие оператора не определено. Порядок операторов в списке ветвлений произвольный, но каждая из меток должна быть уникальной. В качестве примера, иллюстрирующего применение оператора варианта, ниже приведена схема программы оформления "диалогового меню", которое позволяет по желанию пользователя выбрать вариант продолжения работы программы. При этом переменная C является выражением, значение которого определяет вариант.

var

C : Integer;

begin

Write (`Введите номер варианта(1-3)');

case C of

1: begin

. . . . . {вычисления по варианту 1}

end;

2: begin

. . . . . {вычисления по варианту 2}

end;

3: begin

. . . . . {вычисления по варианту 3}

end;

end; {case}

end;

Повторы (циклы)

Как уже упоминалось, операторы цикла позволяют описать повторяющийся процесс. Действия, которые повторяются, принято называть телом цикла. В общем случае количество повторений тела цикла должно быть каким-либо способом задано. Иначе такой процесс будет бесконечным.

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

Основным способом проверки возможного окончания цикла является определение функции f(x) (X - множество переменных программы) такой, что f(X) 0 удовлетворяет условию окончания, а также доказательства того, что эта функция убывает. Простейшим видом такой функции является обычный счетчик, т.е. функция вида i:=i-1 или i:=i+1 (единица вычитается или прибавляется после каждого повторения). В первом случае убывает некоторое начальное значение i (например, n) до некоторого конечного значения (например,1). Тогда условием завершения цикла будет i 1 и количество повторений будет равно n. Во втором случае счет можно начать с i равного 1 и убывать будет разность между текущим значением i и конечным значением n, проверка которой на меньше-равно нулю равнозначна проверке условия i n. Переменную i в этом случае называют параметром цикла, а сам цикл, в котором она используется циклом с параметром. При этом для большинства языков программирования, и языка Паскаль в том числе, принято следующее соглашение: начальное и конечное значения параметра цикла нельзя переопределять в теле цикла и после естественного выхода из цикла значение параметра не определено, т.е. использовать его значение для дальнейших вычислений нельзя. Циклу с параметром соответствуют блок-схемы алгоритмов, приведенные на Рис. 2.3.а,б. При этом Рис. 2.3.а соответствует циклу с предусловием, а Рис. 2.3.б - циклу с постусловием.

Особенностью цикла с предусловием является то, что его тело может не выполниться ни разу (условие проверяется до входа в тело цикла). Для цикла с постусловием, наоборот, характерно то, что его тело обязательно выполниться хотя бы один раз. Поэтому при использовании операторов цикла нужно знать, каким образом организована проверка этого условия.

Кроме того, как уже упоминалось, для определения условия завершения совсем не обязательно использовать функцию счета. Эту роль может выполнять значение любой переменной или выражения. Важно только то, что это значение должно изменяться при выполнении тела цикла.

Абстракция <оператор повтора> в стандарте Паскаля представлена мощной и гибкой конструкцией, состоящая из трех альтернатив:

<оператор повтора> ::= <оператор for>

<оператор repeat>

<оператор while>

Среди альтернатив, заданных правилом, оператор for является циклом с параметром и проверкой условия окончания до входа в тело цикла; оператор repeat (повторять) - цикл с постусловием; оператор while (пока) - цикл с предусловием.

Правила, определяющие конструкцию цикла for, имеют вид:

<оператор for> ::= for <параметр цикла> := <список цикла>

do <оператор>

<список цикла> ::= <начальное значение> to

<конечное значение>

<начальное значение> downto

<конечное значение>

<начальное значение> ::= <выражение>

<конечное значение> ::= <выражение>

<параметр цикла> ::= <имя>

Первая из альтернатив списка цикла соответствует увеличению параметра цикла на единицу и только на единицу от начального и вплоть до конечного значения, а вторая - уменьшению параметра на единицу. Естественно, что в первом случае тело цикла не будет выполняться, если начальное значение будет больше конечного значения, а во втором - наоборот. Примером использования обеих форм этого оператора могут служить два варианта программы вычисления степенной функции вида S=XY при условии y 0.

program Prim2_2;

var

I,Y : Integer;

X,S : Real;

begin

Write (`Введите аргумент степенной функции X= ');

ReadLn (X);

Write (`Введите показатель степени');

readLn (Y);

S :=1;

for I :=1 to Y do

S :=S*X;

WriteLn (X,' в степени ',Y,' равно `,S)

end. {Prim2_2}

program Prim2_3;

var

i,Y : Integer;

X,S : Real;

begin

Write (`Введите аргумент степенной функции х= ');

ReadLn (X);

Write (`Введите показатель степени');

ReadLn (Y);

S :=1;

for i :=Y downto 1 do

S :=S*X;

WriteLn (X,' в степени ',Y,' равно `,S)

end. {Prim2_3}

Согласно синтаксичесическому определению телом цикла for может служить только один оператор. Однако эта проблема уже рассматривалась. Если в качестве тела цикла должен использоваться список операторов, достаточно заменить его конструкцией <составной оператор>.

Следующей конструкцией оператора повтора является <оператор repeat>:

<оператор repeat> ::= repeat <список операторов> until <условие>

Смысл конструкции очевиден. Достаточно прочесть ее стилизованный русский перевод: "повторять действия, предписанные списком операторов до выполнения условия". Телом цикла в этом случае является список операторов между ограничителями (зарезервированными словами) repeat и until. Выход из цикла определяется достижением истинности условия.

Попытка использовать этот цикл в программе вычисления степенной функции хорошо иллюстрирует его особенности. Во-первых, это цикл без параметра, а условием окончания цикла при вычислении степенной функции служит явно заданная функция счета. Поэтому счетчик нужно организовать искусственно, используя для этого вспомогательную переменную, например, i. Во-вторых, это цикл с постусловием, что создает неудобства при Y=0, т.е. в случае, когда начальное значение Y=1 должно сразу использоваться как результат. Текст такой программы приведен ниже.

program Prim2_4;

var

I,Y : Integer;

X,S : Real;

begIn

Write (`Введите аргумент степенной функции х= ');

ReadLn (X);

Write (`Введите показатель степени');

ReadLn (Y);

S:=1;

I:=1;

if Y<>0 then

repeat

S:=S*X;

I:=I+1

untIl I>=Y;

WrIteLn (X,' в степени ',Y,' равно `,S)

end. {Prim2_4}

Другим примером использования цикла repeat служит программа вычисления функции sin(x). Функция вычисляется с помощью разложения ее в ряд вида: sin(x)=x1/1! - x3/3! + x5/5! - x7/7! - ... (количество суммируемых членов ряда определяется точностью - e). В процессе вычисления очередной член (pi) определяется по формуле pi= - pi=1 * x2 /(I * (I - 1)). При этом учитывается, что члены ряда индексируются с шагом 2, т.е. i=1,3,5, , и в качестве начальных установок используются i:=3, s:=x, p:=x, x2:=x*x. Перменная s является "накопителем" текущей суммы членов ряда, а условием окончания процесса является проверка вида "очередной член по абсолютной величине меньше заданной точности", т. е. pi < e.

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

Program Prim2_5;

var

I : Integer;

E,X,P,S : Real;

begin

Write (`Введите аргумент функции Sin(x), x= ');

ReadLn (X);

Write (`Введите точность e=');

ReadLn (E);

S :=X;

P :=X;

X2 :=X*X;

I :=3;

repeat

P :=-P*X2/(I*(I-1));

S :=S+P;

I:=I+2

until Abs(P)<E;

WriteLn ('Sin (', X, ') = `, S)

end. {Prim2_5}

Оператор while по сути мало чем отличается от repeat, если не принимать во внимание то, что это цикл с предусловием. Его конструкция имеет вид:

<оператор while> ::= while <условие > do <оператор >

Соответствующие оператору действия можно описать следующей инструкцией: "пока условие истинно - выполнять тело цикла". Телом цикла здесь так же может быть только один оператор, который при необходимости можно сделать составным. В качестве примеров использования цикла while ниже приводятся две программы (program prim2_6 и program prim2_7), реализующие вычисление уже знакомых функций S=XY и Sin(X).

При разборе первой программы следует обратить внимание на то, что перед циклом не проверяется на равенство нулю значение показателя степенной функции (из текста исключен условный оператор). Цикл while - цикл с предусловием, поэтому в случае Y=0 его тело выполняться не будет, и в данном случае он предпочтительнее цикла repeat. Однако, применение этого цикла, по прежнему, требует искусственного введения функции счета повторов. Во втором случае, цикл while не имеет никаких преимуществ перед циклом repeat и рекомендации в пользу одного из них будут не оправданы.

В заключение нельзя не отметить, что операторы повтора - это достаточно "капризная" конструкция с точки зрения оценки их вычислительной сложности. Действительно, одно "лишнее" действие в теле цикла или затраты на проверку не минимизированного условия в операторах repeat и while будут повторяться многократно. Поэтому, как тело цикла, так и условие в общем случае требуют тщательной минимизации.

program Prim2_6;

var

I,Y : Integer;

X,S : Real;

begin

Write (`Введите аргумент степенной функции х= ');

ReadLn (X);

Write (`Введите показатель степени');

ReadLn (Y);

S :=1;

I :=1;

while I<Y do

begin

S :=S*X;

I :=I+1

end;

WriteLn (X,' в степени ',Y,' равно `,S)

end. {Prim2_6}

program Prim2_7;

var

I : Integer;

E,X,p,S : Real;

begin

Write (`Введите аргумент функции Sin(x), х= ');

ReadLn (X);

Write (`Введите точность e= ');

ReadLn (E);

S :=X;

p :=X;

X2 :=X*X;

i :=3;

while abS(P)> E do

begin

P :=-P*X2/(I*(I-1));

S :=S+P;

I :=I+2

end;

WriteLn ('Sin(',x,') = `,S)

end. {Prim2_7}

3. Оператор безусловного перехода

Оператор безусловного перехода (просто оператор перехода или оператор goto) указывает, что продолжение программы должно начинаться с того оператора, перед которым стоит метка. Такой оператор называется помеченным. Меткой является целое число без знака (не более 4 разрядов). Определение конструкции оператора goto имеет вид:

<оператор goto> ::= goto <метка>

<метка> ::= <целое без знака>

В связи с этим требуется доопределение конструкции <помеченный оператор>:

<помеченный оператор> ::= <метка> : <оператор>

Любая метка должна быть описана в разделе меток:

<раздел меток> ::= label <список меток>

<список меток> ::= <метка><список меток>, <метка>

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

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

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

В языке Паскаль имеется достаточное количество конструкций, которые являются своеобразными "ограничителями" на неоправданное применение "мощности", т.е. позволяют не использовать оператор goto (это - условный оператор, циклы while, repeat, процедуры). Поэтому оператор перехода следует применять только в исключительных ситуациях. Такой ситуацией является, например, аварийный выход из тела цикла, однако даже для этих случаев в конкретных реализациях языка предусмотрена альтернативная по имени инструкция (break, exit).

В связи с этим, ниже рассматриваются два варианта программы, вычисления с помощью которой при желании пользователя должны повторяться, т. е. требуется переход в начало раздела операторов. Возврат при положительном ответе (Y) на вопрос с подсказкой "Повторить вычисления? Y -да, N - нет" можно осуществить с помощью оператора goto 1, где меткой 1: будет помечен первый оператор программы. В втором случае для этих целей используется цикл repeat, поскольку повторение всей программы - это цикл с постусловием (его тело должно выполниться хотя бы один раз).

program PrimV1;

var

F : Char;

. . .

begin

1: I :=1; {помеченный первый оператор}

. . . {другие операторы тела программы}

Write (`Повторить вычисления? Y -да, N - нет');

Read (F);

if F=`Y' or `y' or `Н' or `н' then

goto 1

end. {PrimV1}

program primV2;

var

F : Char;

. . .

begin

repeat

. . . {операторы тела программы, включая первый - I :=1;}

Write (`Повторить вычисления? Y -да, N - нет');

Read (F);

until F=`Y' or `y' or `Н' or `н' then

end. {PrimV2}

Цепочка символов, определяющая условие опператора if, явяется "защитой от дурака", т. e. позволяет в ответ на запрос программы нажать клавишу Y вне зависимости от состояния регистра клавивтуры (латынь, кирилица, верхний или нижний регистры).

4. Упражнения

Напишите различные варианты программ, реализующих вычисление степенной функции для значений Y в интервалах [1,n], [0,n] и [-n,n], применяя различные варианты операторов цикла (таких программ может быть более двух десятков). Попытайтесь сформулировать критерии для сравнения написанных программ и оцените качество программ по этим критериям.

2. Упорядочите запись условного оператора, используя обычную "лесенку"

if A<B then if C<D then X :=1

else if A<B then if C<D then X := 2

else X :=3

else if A<D then if B<C then X :=4

else X :=5

else X :=6

else X :=7;

Установите, нет ли в этом операторе избыточных или противоречивых условий. Напишите оператор, имеющий тот же результат, но проминимизируйте условия. Попробуйте заменить этот условный оператор на оператор case.

Опишите блок-схемы алгоритмов, которые являлись предметом упражнений пункта 3 предыдущего раздела, в виде программ, используя уже знакомые конструкции языка.

Модифицируйте программу вычисления корней квадратного уравнения так, чтобы при условии 4ac < e* d2 больший по величине корень х1 вычислялся первым, а затем второй корень по формуле х2=c/(a* х1).

Напишите программу, которая определит все способы размена 1 рубля с помощью монет достоинством 1, 2, 5, 10, 25, 50 копеек.

6. Напишите программу для генерации случайных чисел в диапазоне [0/..MaxInt]. Для этого необходимо взять любое целое число, возвести его в квадрат и вычесть из результата некоторую константу со значением в этом же диапазоне. Затем полученный результат снова возвести в квадрат и т. д. Определите при каком значении константы генератор имеет лучшие характеристики (не "вырождается", возвращая постоянное значение, и не вызывает переполнения разрядной сетки.

язык паскаль управление последовательный

Размещено на Allbest.ru


Подобные документы

  • Общая характеристика языков программирования. Описание языка Паскаль: основные субъекты языка; структура Паскаль-программы; типизация и объявление данных. Операторы присваивания и выражения. Структурные операторы, организация ветвлений и циклов.

    дипломная работа [276,6 K], добавлен 26.01.2011

  • Элементарные конструкции языка ПАСКАЛЬ: имена, числа и строки. Стандартные типы данных. Организация ввода и вывода данных с терминального устройства. Разработка программы, изменяющей первоначальную матрицу по заданной схеме и выводящей ее на экран.

    курсовая работа [68,6 K], добавлен 09.07.2015

  • Описание конструкций языка программирования Паскаль, обеспечивающих ветвление. Организация циклических процессов. Создание программы для ввода последовательности вещественных чисел до появления 0, расчет среднего арифметического данной последовательности.

    лабораторная работа [189,8 K], добавлен 17.04.2012

  • Логические конструкции в системе программирования Паскаль. Команды языка программирования, использование функций, процедур. Постановка и решение задач механики в среде системы Паскаль. Задачи статики, кинематики, динамики решаемые с помощью языка Паскаль.

    курсовая работа [290,9 K], добавлен 05.12.2008

  • Создание приложения, исполняющего трансляцию программы из языка Паскаль в язык Си: разработка алгоритма реализации задачи, описание необходимых констант, переменных, функций и операторов, представление листинга программы и распечатка результатов.

    курсовая работа [305,9 K], добавлен 03.07.2011

  • Разработка программы для решения системы обыкновенных дифференциальных уравнений на базе языка программирования Паскаль АВС. Чтение исходных данных из внешнего файла. Вывод исходных данных и результатов на дисплей и во внешний файл. Суть метода Ейлера.

    реферат [126,1 K], добавлен 12.01.2012

  • Выбор метода проектирования транслятора с языка Паскаль на язык Си, разработка и кодирование алгоритма программы. Использование допустимых операторов в исходном тексте, определение типов переменных и синтаксиса логических и арифметических выражений.

    курсовая работа [1,0 M], добавлен 03.07.2011

  • Лингвистическая концепция языка Паскаль. Интегрированная инструментальная оболочка. Основы построения программ на ТП 7.0. Алфавит языка и специфика использования символов. Простые типы данных: константы и переменные. Циклические конструкции и операции.

    курсовая работа [284,6 K], добавлен 02.07.2011

  • Основные сведения о системе программирования Турбо Паскаль. Структура программы на Паскале и ее компоненты. Особенности и элементы языка Турбо Паскаль. Порядок выполнения операций в арифметическом выражении, стандартные функции и оператор присваивания.

    лекция [55,7 K], добавлен 21.05.2009

  • Разработка программы, создающей и управляющей базой данных, ее реализация на языке Turbo Pascal. Организация алгоритма программы. Вывод информации и возможность добавления информации в базу данных. Поиск информации в базе данных по заданному значению.

    курсовая работа [26,7 K], добавлен 19.06.2010

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.