инфа учебное пособие (єўхсэюх яюёюсшх)

Посмотреть архив целиком

83




ВВЕДЕНИЕ


"... недостойно совершенства человеческого подобно рабам тратить часы на вычисления."

Лейбниц


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

Созданием языков программирования занимаются в большинстве случаев очень квалифицированные специалисты, часто группы программистов, а иногда даже международные коллективы. Однако подавляющее большинство языков программирования умирало, едва родившись. Лишь к немногим из них был проявлен интерес, и буквально единицы получили действительно широкое распространение. К таким "счастливым" языкам принадлежит язык Паскаль, разработанный Никлаусом Виртом в 1968-1971гг. в Цюрихском Институте информатики (Швейцария). Первоначальная цель разработки языка диктовалась необходимостью инструмента "для обучения программированию как системной дисциплине". Однако очень скоро обнаружилась чрезвычайная эффективность языка Паскаль в самых разнообразных приложениях: от решения небольших задач численного характера до разработки сложных программных систем компиляторов, баз данных, операционных систем и т.д. Существуют многочисленные реализации языка практически для всех машинных архитектур; разработаны десятки диалектов и проблемно-ориентированных расширений языка Паскаль; обучение программированию и научно-технические публикации часто базируются на этом языке.

Для того чтобы хорошо овладеть программированием, необходимо знать, что такое компьютер. Слово "компьютер" означает "вычислитель", т.е. устройство для вычислений. Потребность в автоматизации обработки данных, в том числе вычислений, возникла очень давно. Многие тысячи лет назад для счета использовались счетные палочки, камешки и т.д. В дальнейшем стали использовать счеты. В 1642 г. Блез Паскаль разработал устройство, механически выполняющее сложение чисел, а в 1673 г. Готфрид Вильгельм Лейбниц сконструировал арифмометр, позволяющий механически выполнять четыре арифметических действия. В в. математик Чарльз Беббидж попытался построить вычислительное устройство, которое должнобыло выполнять вычисления без участия человека, т.е. уметь исполнять программы. Но осуществить эту мечту удалось ученым только в ХХ в., когда для построения вычислительных устройств стали использовать электромеханические реле. С 1943 г. группа специалистов под руководством Джона Мочли и Преспера Экерта в США начала конструировать вычислительную машину на основе электронных ламп. Машина работала достаточно быстро, но для задания её программы приходилось в течение нескольких часов или даже нескольких дней соединять провода. Вот тогда и стали конструировать машину, которая могла бы хранить программу в своей памяти. К этой работе был привлечен знаменитый математик Джон фон Нейман, который ясно и просто сформулировал основные принципы функционирования универсальных вычислительных устройств. Первый компьютер, в котором воплощены принципы фон Неймана, был построен в 1949 г. английским исследователем Морисом Уилксом. С той поры компьютеры стали гораздо более мощными, но подавляющее большинство из них работает в соответствии с принципами фон Неймана.

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

Рис. 1

процессор, осуществляющий арифметические и логические операции, а также организующий процесс выполнения программ;

запоминающее устройство, или память для хранения программ и данных;

внешние (периферийные) устройства для ввода/вывода информации.

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

На рис.1 одинарные линии показывают управляющие связи, двойные информационные.

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

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

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

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

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

Совокупность программных средств можно разделить на три категории:

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

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

  • инструментальные системы (системы программирования), обеспечиващие создание новых программ для компьютера.

Рассмотрим некоторые системные программы. Одной из важнейших системных программ является операционная система. Операционная система это программа, которая загружается при включении компьютера. Она осуществляет диалог с пользователем, управление компьютером, его ресурсами (оперативной памятью, местом на дисках и т.д.), запускает другие (прикладные) программы на выполнение. Операционная система обеспечивает пользователю и прикладным программам удобный способ общения (интерфейс) с устройствами компьютера. Для компьютеров типа IBM PC чаще всего используется операционная система MS DOS, UNIX, OS/2.

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

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


  1. ЭТАПЫ РЕШЕНИЯ ЗАДАЧИ НА ЭВМ


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

В общем случае решение задачи на ЭВМ можно разбить на следующие этапы:

  • постановка задачи;

  • разработка алгоритма;

  • составление программы;

  • трансляция программы;

  • отладка и выполнение программы;

  • анализ результатов.

Слово "алгоритм" произошло от имени узбекского математика Аль Хорезми, который в IX в. разработал правила четырех арифметических действий над числами в десятичной системе счисления. Примерами алгоритмов могут служить врачебные и кулинарные рецепты, способы решения квадратных и дифференциальных уравнений.

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

Алгоритм должен обладать следующими основными свойствами:

  • детерминированность (определенность) при заданных исходных данных обеспечивается однозначность искомого результата;

  • массовость пригодность для задач данного типа при исходных данных, принадлежащих заданному подмножеству;

  • результативность реализуемый вычислительный процесс выполняется за конечное число этапов с выдачей осмысленного результата;

  • дискретность разбиение на отдельные этапы, выполнение которых не вызывает сомнений.

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


  1. Графический СПОСОБ ОПИСАНИЯ АЛГОРИТМОВ


Одним из самых трудоемких этапов решения задачи на ЭВМ является разработка алгоритма. Человечество разработало эффективный алгоритм завязывания шнурков на ботинках. Многие дети с пятилетнего возраста могут это делать. Но дать чисто словесное описание этого алгоритма без картинок и демонстрации - очень трудно.

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

Рассмотрим два способа: графический и с помощью языков программирования.

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

Таблица 1

Геометрическая фигура

Назначение

1

2

Начало и завершение алгоритма, прерывание процесса обработки данных или выполнения программы.

a выбирается из ряда 5,10,15мм и т.д. ,а b=1,5a или 2a


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


Выбор направления выполнения алгоритма или программы в зависимости от некоторых переменных условий

Окончание табл. 1

1

2


Ввод-вывод преобразование данных в форму, пригодную для обработки или регистрации результатов обработки



Вызов подпрограммы: функции или процедуры


Текст, поясняющий выполняемую операцию или группу операций. Располагается справа от геометрической фигуры


Внутристраничный соединитель, указывающий связь между прерванными линиями потока


Межстраничный соединитель, указывающий связь между прерванными линиями потока, помещенными на разных листах




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



По своей структуре различают следующие типы алгоритмов: линейные, разветвляющиеся и циклические. В линейных схемах алгоритмов все предписания выполняются одно за другим. Например, алгоритм вычисления длины окружности по известной площади круга (рис.2). В разветвляющихся схемах алгоритмов для конкретных исходных данных выполняются не все заданные предписания. Однако какие именно предписания будут выполняться, конкретно определяется в процессе выполнения алгоритма в результате проверки некоторых условий. Разветвляющийся алгоритм всегда избыточен. Примером разветвляющегося алгоритма является алгоритм, приведенный на рис.3 и определяющий, пройдет ли график функции y=3x+4 через точку с координатами x1,y1.


Рис. 4



Рис. 3


Рис. 2




Циклическим алгоритмом называется такой алгоритм, в котором можно выделить многократно повторяющуюся последовательность предписаний, называемую циклом. Для таких алгоритмов характерно наличие параметра цикла, которое перед входом в цикл имеет начальное значение, а затем изменяется внутри цикла. Имеется также предписание о проверке условия окончания цикла. Применение циклов сокращает текст алгоритма и, в конечном итоге, длину программы. Примером циклического алгоритма может служить алгоритм, приведенный на рис.4 и определяющий факториал натурального числа n. В этом алгоритме введена дополнительная переменная i, которая является параметром цикла и изменяется от начального значения 1 до конечного значения n c шагом 1. На каждом шаге итерации искомая величина f умножается на переменную цикла. В реальных задачах, как правило, сочетаются все три типа алгоритмов. Способ описания алгоритма с помощью алгоритмического языка подробно рассматривается в следующем разделе.


  1. ПРОГРАММИРОВАНИЕ НА ЯЗЫКЕ турбо-ПАСКАЛЬ

    1. ЛИНЕЙНЫЕ ПРОГРАММЫ

      1. СТРУКТУРА ПРОГРАММЫ


Чтобы иметь представление о том, как программируют на языке Турбо-Паскаль, приведем пример программы pr1, определяющей сумму двух чисел:

program pr1;

var a,b,result: integer;

begin

a:=2;

b:=3;

result:=a+b;

writeln(result);

end.

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

Структура программы на языке Турбо-Паскаль в общем случае выглядит следующим образом:

  • заголовок программы;

  • описательная часть;

  • операторная часть.

Заголовок программы представляется так:

program <имя программы>;

Cлово program является зарезервированным (ключевым), т.е. не может использоваться для каких-нибудь иных целей.

<имя программы> это правильный идентификатор. Идентификаторы (или имена) используются в программе и для обозначения переменных, меток, типов, процедур и функций, констант. На имена (идентификаторы) накладываются некоторые ограничения. Важным ограничением при выборе идентификаторов является невозможность использования ключевых слов, например program или var. Идентификатор должен начинаться с буквы и может содержать буквы латинского алфавита, цифры и знаки подчеркивания. Длина идентификатора может быть любой, но значащими являются первые 63 символа. Имена могут нести смысловую нагрузку, как, например, result, но могут и не нести. Использование осмысленных имен предпочтительнее, так как это делает программу более простой для понимания. В идентификаторах, как и во всей программе на Турбо-Паскале, игнорируется разница в высоте букв.

Описательная часть программы может содержать несколько разделов:

1) раздел меток;

2) раздел констант;

3) раздел типов;

4) раздел переменных;

5) раздел процедур и функций.

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

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

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

Вторая строка описательная часть, содержащая в данном случае только описание переменных. Описание переменных всегда начинается с ключевого слова var и указывает имена переменных и их тип.

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

Рассмотрим подробнее описания переменных и операторы, необходимые для написания линейной программы.


      1. ОПИСАНИЕ ПЕРЕМЕННЫХ


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


Рис. 5

Диапазон возможных значений целых типов зависит от их внутреннего представления, которое может занимать один, два или четыре байта. В табл.2 приводятся названия целых типов, длина их внутреннего представления в байтах и диапазон возможных значений. Целые типы относятся к так называемым порядковым типам. Для порядковых типов характерно то, что такие типы имеют конечное число возможных значений и эти значения можно каким-либо образом упорядочить и каждому значению поставить в соответствие целое число. К любому порядковому типу применима функция ord(x), которая возвращает порядковый номер применима функция ord(x), которая возвращает порядковый номер значения выражения х. Для целых типов ord(x) возвращает само же значение х. К порядковым типам можно также применить функции pred(x) и succ(x). Функция pred(x) возвращает значение, которое соответствует порядковому номеру ord(x)-1, а функция succ(x) ord(x)+1.


Таблица 2

Целые типы


Длина, байт

Название типа

Диапазон значений

1

byte

от 0 до 255

1

shortint

от -128 до 127

2

word

от 0 до 65535

2

integer

от -32768 до 32767

4

longint

от -2147483648 до 2147483647


Над целыми числами выполняются операции:

"+" сложение; "*" умножение;" / " деление;

"-" вычитание; div целочисленное деление;

mod получение остатка от целочисленного деления.

Например, 5div2 дает результат 2, 6div2 дает 3, 5mod2 дает 1, а 6mod3 0.

В табл.3 содержатся основные встроенные процедуры и функции, применяемые к целым типам. В квадратных скобках указывается необязательный параметр.


Таблица 3

Встроенные процедуры и функции для обработки

данных целого типа


Обращение

Реализуемое действие

abs(x)

Возвращает модуль х

dec(x[,i])

Уменьшает значение х на i, при отсутствии i на 1

inc(x[,i])

Увеличивает значение х на i, при отсутствии i на 1

odd(i)

Возвращает true, если i - нечетное число, false - четное

random(w)

Возвращает псевдослучайное число, равномерно распределенное на интервале[0,w-1]

sqr(x)

Возвращает квадрат аргумента

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

1.36 1.36e0

0.0013 1.3e-3

123.123 1.23123e2

В разделе описания переменных данные вещественного типа можно описать так:

var a,b: real;

c,d: single;

k: double;

l,m,n: extended;

Таблица 4

Вещественные типы


Длина,

байт

Название

Диапазон десятичного порядка

Количество значащих цифр

4

single

от -45 до +38

от 7 до 8

6

real

от -39 до +38

от 11 до 12

8

double

от -324 до +308

от 15 до 16

10

extended

от -4951 до +4932

от 19 до 20

8

comp

от до

от 19 до 20

В табл.5 приведены встроенные функции и процедуры для обработки данных вещественного типа.

Таблица 5

Встроенные функции для обработки данных

вещественного типа


Обращение

Реализуемое действие

abs(x)

Модуль аргумента

arctan(x)

Àрктангенс (радианы)

frac(x)

Дробная часть числа

int(x)

Целая часть числа

ln(x)

Натуральный логарифм

pi

=3.14159...

random

Псевдослучайное число, принадлежащее интервалу[0,1]

randomize

Инициализация датчика псевдослучайных чисел

sqrt(x)

Корень квадратный

sqr(x)

Квадрат аргумента

sin(x)

Синус(радианы)

сos(x)

Косинус(радианы)

exp(x)

Экспонента

      1. ОПЕРАТОР ПРИСВАИВАНИЯ


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

<переменная>:=выражение.

необходимо учесть, что переменная и выражение должны быть одного типа. Например, если переменные описаны следующим образом:

var

x,y : integer;

a,b : real;

то можно записать операторы присваивания

x:=x+5;

y:=x;

a:=b;

b:=5.33*x+y/2;

Как уже говорилось, тип переменной позволяет не только устанавливать длину ее внутреннего представления, но и контролировать те действия, которые осуществляются над ней в программе. Контроль за использованием переменных еще на этапе компиляции программы важное преимущество Турбо-Паскаля, повышающее его надежность. В Турбо-Паскале почти не возможны автоматические преобразования типов. Исключение сделано только в отношении констант и переменных типа integer, которые можно использовать и в выражениях типа real, т.е. для описанных выше переменных оператор x:=a будет неверным из-за невозможности преобразования вещественного типа к целому. В то же время, оператор a:=x будет верным.

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


      1. ПРОЦЕДУРЫ ВВОДА И ВЫВОДА


Ввод/вывод связан с обменом информацией между оперативной памятью и внешними устройствами. Здесь рассмотрены процедуры ввода/вывода: read, readln, write, writeln, использующие стандартные файлы ввода/вывода. Стандартным файлом ввода является клавиатура, а вывода экран. Для ввода данных с клавиатуры применяются процедуры:

read (<список ввода>);

readln (<список ввода>);

Список ввода это последовательность из одной или более переменных типа char, string, а также любого целого или вещественного типа. При вводе числовых переменных процедура read вначале выделяет подстроку во входном потоке по следующему правилу: все ведущие пробелы, символы табуляции и маркеры конца строки пропускаются, выделяется первый значащий символ, признаком конца подстроки является любой из вышеперечисленных символов или символ конец файла. Выделенная таким образом подстрока рассматривается как символьное представление числовой константы, которое преобразуется в соответствии с типом переменной, и полученное значение присваивается переменной. Если значащих символов в строке нет, а список ввода еще не исчерпан, то автоматически осуществляется переход к новой строке. Процедура readln идентична процедуре read за исключением того, что после считывания последней переменной, оставшаяся часть строки пропускается, так что следующее обращение к read или readln начнется с первого символа новой строки. Кроме того, процедуру readln можно вызывать без параметров, что приведет к пропуску всех символов текущей строки. Рассмотрим следующий фрагмент программы:

var a,b,c,d:real;

begin ... read(a,b,c,d); ... end.

Пусть, требуется ввести числа 1,3;13,3;76,8;125,0. Информация набирается в виде:

1.3 13.3 76.8 125.0

на одной или нескольких строках. В результате выполнения процедуры read переменной а присвоится значение 1.3, переменной b значение 13.3, с 76.8, d 125.0. Если же ввод производится с помощью двух процедур:

readln(a,b,c);read(d);

числа, соответствующие a,b,c, набираются на одной строке, а число, соответствующее d, на другой.

Для вывода данных на экран используются процедуры:

writeln(<список ввода>);

write(<список ввода>);

Список вывода может содержать одно или несколько выражений типа char, string, boolean, а также любого целого или вещественного типа. Отличие процедуры writeln от write состоит лишь в том, что в процедуре write курсор остается на той же строке экрана за последним выведенным символом, а в writeln курсор переходит на начало следующей строки. Предположим, что переменные a,b,c описаны как целые и имеют соответственно значения 132, 25, -37. После выполнения процедур

writeln(a,b);write(c);

a и b будут напечатаны на одной строке, а с на другой:

13225

-37

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

writeln(a:3,b:5,c:4);

В этом случае при печати под значение переменной a отводится 3 позиции, b 5 позиций, под с 4 позиции, т.е. будет выведено 132 25 -37.

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

writeln('a=',a:1,'b=',b:2,'c=',c:3);

В последнем примере используется возможность вывода строк символов, при этом будет напечатано:

a=132b=25c= -37

Пусть переменные d, e, f описаны как вещественные и имеют соответственно значения 13,13;123,45;-987,654. Результатом работы оператора

writeln('d=',d:5:2,'e=',e:8:3,'f=',f:8:2);

будет строка

d=13.13e= 123.450f= -987.65

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

writeln('d=',d:10,' e=',e:9,' f=',f);

d= 1.313E+01 e= 1.23Е+02 f=-9.8765000000E+02


      1. ПРИМЕР ЛИНЕЙНОЙ ПРОГРАММЫ


Теперь, когда мы познакомились с операторами, необходимыми для составления линейной программы, рассмотрим еще один пример такой программы. Пусть дано два числа a и b длины сторон прямоугольника. Найти площадь s и периметр p прямоугольника. На рис.6 представлена графическая схема алгоритма решения данной задачи, а программа приведена в примере pr2.

Рис. 6


program pr2 ;

var

a,b,s,p:real;

begin

writeln('Введите длины стоpон пpямоугольника:');

read(a,b);

s:=a*b;

p:=(a+b)*2;

writeln('Площадь = ',s:5:3);

writeln('Пеpиметp = ',p:5:3);

end.

В этой программе все операторы выполняются последовательно друг за другом. Выполнение программы начинается с вызова процедуры вывода writeln, которая выводит на экран подсказку "Введите длины сторон прямоугольника:", что обеспечивает удобный интерфейс с пользователем. Вызов процедуры read приводит к прерыванию программы до тех пор, пока пользователь не введет два числа. Далее вычисляются площадь и периметр прямоугольника и выводятся результаты на экран.


    1. РАЗВЕТВЛЯЮЩИЯСЯ ПРОГРАММЫ


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

На рис.7 приведена графическая схема алгоритма, а программа в примере pr3.


Рис. 7



program pr3;

var

x,y:real;

begin

writeln('Введите x:');

readln(x);

if x>0

then

y:=x*x*x+3

else

y:=x*sin(x);

writeln(y);

end.

В этой программе впервые встречается условный оператор и служит для выбора формулы вычисления y в зависимости от введенного значения x.



      1. УСЛОВНЫЙ ОПЕРАТОР


Условный оператор служит для ветвлений в программе и имеет следующий синтаксис:

if <условие> then <оператор1> else <оператор2>.

Здесь if, then, else ключевые слова (перев. с англ. если, то, иначе соответственно);

<условие> логическое выражение типа сравнения (например, a>b, c<=d, f=1), логическому типу посвящен следующий раздел пособия;

<оператор1> и <оператор2> любой оператор Турбо-Паскаля. Оператор работает следующим образом: если условие истинно, то выполняется <оператор1> и управление передается на следующий за условным оператор; если условие ложно, то выполняется <оператор2> и управление передается на следующий за условным оператор. Таким образом, всегда выполняется один из двух операторов: либо из ветви then, либо из ветви else.

Кроме вышеприведенной формы условного оператора, существует сокращенная форма условного оператора, в которой отсутствует ветвь else:

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

Оператор работает следующим образом: если условие истинно, то выполняется <оператор1> и управление передается на следующий за условным оператор; если условие ложно, то управление сразу передается на следующий за условным оператор. Таким образом, в зависимости от условия <оператор1> либо выполняется, либо не выполняется.

Рассмотрим фрагменты схем алгоритмов и соответствующие им фрагменты программ.



if a>b then

max:=a

else

max:=b;




if k>0 then

s:=s+k;





if a>b then

if a>c then

max:=a

else max:=c;


if a>b then

if a>c then

max:=a

else max:=c

else

if b>c then

max:=b

else max:=c;

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

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

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


      1. СОСТАВНОЙ ОПЕРАТОР


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




if c>0 then

begin

s:=s+c;

k:=k+1

end

else

c:=c-1;

if n

begin

n:=n+1;

m:=m-1;

end

else

begin

n:=n-1;

m:=m+1;

end;


Здесь следует обратить внимание на правила употребления точки с запятой:

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

каждый оператор в теле программы завершается точкой с запятой, если сразу за ним не следуют ключевые слова end, else или until;

после определенных ключевых слов, таких, как then, else, begin, var, const, никогда не ставится точка с запятой.

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


      1. ЛОГИЧЕСКИЙ ТИП


Турбо-Паскаль позволяет обрабатывать данные не только числового типа, но и других типов, например логического. Для обозначения логического типа используется ключевое слово boolean. Булевы (логические) переменные могут иметь одно из двух значений: true (истина) или false (ложь). Булевский тип является порядковым типом и упорядочен так, что false < true. По сравнению с типом real, который допускает миллионы различимых значений, может показаться, что тип boolean имеет ограниченную область применения. Однако, как это ни странно, именно ограниченность диапазона значений булевых переменных придает булевым выражениям их значимость.

Булевы выражения могут принимать несколько различных форм. Во-первых, они могут быть просто константами true (истина) или false (ложь). Оператор присваивания, использующий эту форму, аналогичен арифметическому оператору. Например, пусть переменные a и b логического типа:

var a,b:boolean;

тогда можно написать операторы:

a:=true;

b:=false.

Булевы выражения можно использовать для проверки отношений между двумя переменными: a>b,c<=d,k=m и т.д. Таким образом, условие в условном операторе является выражением логического типа. Кроме того, булевы выражения могут конструироваться с помощью булевых операций. Эти операции образуют инструментальный фундамент булевой логики, алгебры логики, разработанной в ХIХв. математиком Джорджем Булем. Рассмотрим три основные булевы операции.

Операция and логическое пересечение ( умножение, операция "и"). Выражение a and b дает значение true только в том случае, если a и b имеют значения true, в остальных случаях false:

true and true = true

true and false = false

false and false = false

Операция or логическое сложение (объединение, операция "или"). Выражение a or b дает значение false в том и только в том случае, если a и b имеют значения false, в остальных случаях результат true:

true or true = true

true or false = true

false or false = false

Операция not отрицание (операция "не"). Выражение not a имеет значение, противоположное значению a:

not true = false

not false = true

Эти операции полезны, если нужно проверить сложное условие:





if (a>b) and (a>c)

then max:=a;







if (x=y) or (x=z)

then z:=y;


      1. Оператор case


Оператор case предназначен для организации выбора из множества различных вариантов. В общем случае оператор case выглядит следующим образом:

case <выражение> of <список выбора> else <оператор> end;

Здесь case, of, else, end ключевые слова (пер. с англ.: выбор, из, иначе, конец);

<выражение> выражение любого порядкового типа;

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

<значение> константа или константное выражение того же типа, что и <выражение>;

<оператор> любой оператор Турбо-Паскаля, в том числе и составной.

Работа оператора начинается с вычисления <выражения>. Значение этого выражения является критерием для выбора из нескольких вариантов. Если полученное значение выражения совпадает с одной из констант, то выполняется тот оператор, которому предшествует эта константа. Если такой константы не обнаруживается, то выполняется оператор следующий за ключевым словом else. Ветвь else может отсутствовать, и в этом случае управление передается оператору следующему за оператором case.

Ниже приведены примеры, демонстрирующие работу оператора выбора.

program pr4;

var n:integer;

begin

writeln('Введите число');

read(n);

case n mod 2 of

1: writeln(n,'- нечетное');

0: writeln(n,'- четное');

end;

end.

Следующая программа по номеру месяца определяет время года.

program pr5;

var month: integer;

begin

writeln('Введите число - номеp месяца');

read(month);

case month of

12,1,2: writeln(month,' - зимний месяц');

3,4,5: writeln(month,' - весенний месяц');

6,7,8: writeln(month,' - летний месяц');

9,10,11: writeln(month,' - осенний месяц');

else writeln('Пpо это мне неизвестно!');

end;

end.

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

program pr6;

var

op: char ;{Арифметическая операция}

x,y,z: real;{Операнды и результат}

begin

write('x,y=');

readln(x,y);

write('Введите аpифметическую опеpация:');

readln(op);

case op of

'*': begin z := x* y; writeln('z=',z);end;

'/': begin z := x/ y; writeln('z=',z);end;

'+': begin z := x+y; writeln('z=',z);end;

'-': begin z := x- y; writeln('z=',z);end;

else writeln('Увы! Это не аpифметическая опеpация.' );

end;

end.


      1. Оператор перехода


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

Безусловный переход приводит к передаче управления из одного места в программе в другое. Структура оператора перехода следующая:

goto <метка>

Здесь goto ключевое слово (англ.: перейти на [метку]).

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

...............

label m,1,loop;

begin

.........

goto 1;

m: .........

goto loop;

1: ............

goto m;

Метка, описанная в программе, обязательно должна использоваться. Метка, описанная в функции или процедуре, должна использоваться в той функции или процедуре, в которой она описана.


      1. ПРИМЕР РАЗВЕТВЛЯЮЩЕЙСЯ ПРОГРАММЫ


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

Поле шахматной доски опpеделяется паpой натуpальных чисел, каждое из котоpых не пpевосходит восьми: пеpвое число номеp веpтикали (пpи счете слева напpаво), втоpое номеp гоpизонтали (пpи счете снизу ввеpх). Даны натуpальные числа k,l,m,n, каждое из котоpых не пpевосходит восьми. Требуется выяснить, являются ли поля (k,l) и (m,n) полями одного цвета.

Прежде чем приступать к составлению алгоритма и программы, необходимо внимательно рассмотреть шахматную доску и прийти к выводу, что поля будут иметь одинаковый цвет, если сумма номеров горизонтали (k+l) и вертикали (n+m) того и другого поля будет четной или того (k+l) и другого (n+m) поля нечетной. Схема алгоритма приведена на рис.8, a программа на языке Турбо-Паскаль - в примере pr7.

program pr7;

var k,l,n,m:byte;

begin

writeln('Введите кооpдинаты полей k,l,n,m: ');

read(k,l,n,m);

if odd(k+l) and odd(n+m) or not odd(k+l) and not odd(n+m)

then writeln('Поля одного цвета ')

else writeln('Поля pазного цвета ');

end.


Рис. 8

Следует заметить, что приоритет операции not выше, чем and, а приоритет операции and выше, чем or. Функция odd – встроенная и возвращает true, если аргумент нечетный, и false, если аргумент четный.


      1. ТИП ДИАПАЗОН


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

var

a,b:1900..2000;

с: 'a'..'z';

Для переменных a и b базовым является целый тип, для с символьный. Сначала указывается нижняя граница, затем верхняя (при этом нижняя граница не должна быть больше верхней). Попытки присвоить переменной ограниченного типа значение, не входящее в заданный диапазон, приведет к возникновению ошибки при счете. Таким образом, введение ограниченных типов перекладывает проверку допустимости значений с программиста на ЭВМ. К переменным типа диапазон применимы все операции и стандартные функции, которые допустимы с переменными соответствующего порядкового типа. Теперь, в свете вышеприведенных сведений, программа про шахматное поле будет следующей:

program pr8;

var k,l,n,m: 1..8;

begin

writeln('Введите кооpдинаты полей k,l,n,m: ');

read(k,l,n,m);

if odd(k+l) and odd(n+m) or not odd(k+l) and not odd(n+m)