Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП.docx
Скачиваний:
2
Добавлен:
26.04.2019
Размер:
271.22 Кб
Скачать

ооп

1 алгоритм. свойства алгоритмов. формы записи.

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

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

  • линейные алгоритмы;

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

  • циклические алгоритмы.

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

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

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

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

общепринятыми способами записи являются графическая запись с помощью блок-схем и символьная запись с помощью какого-либо алгоритмического языка.

2 графический способ записи алгоритмов. обозначения основных блоков

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

3 псевдокод. пример записи алгоритма, основанного на паскале

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

4 словесный способ записи алгоритмов. пример алгоритма перевода вещественного числа из системы с основанием p в систему с основанием q

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

 вещественное число, в общем случае содержащее целую и дробную часть, всегда можно представить в виде суммы целого числа и правильной дроби. поскольку в предыдущем шаге проблема записи натуральных чисел в различных системах счисления уже была решена, можно ограничить рассмотрение только алгоритмами перевода правильных дробей. введем следующие обозначения: правильную дробь в исходной системе счисления p будем записывать в виде0,yp, дробь в системе q – 0,yq, а преобразование – в виде 0,yp  0,yq. последовательность рассуждений весьма напоминает проведенную ранее для натуральных чисел. в частности, это касается рекомендации осуществлять преобразование через промежуточный переход к 10-й системе, чтобы избежать необходимости производить вычисления в "непривычных" системах счисления, т.е. 0,yp 0,y10  0,yq. это, в свою очередь, разбивает задачу на две составляющие: преобразование 0,yp  0,y10 и 0,y10 0,yq, каждое из которых может рассматриваться независимо.

    алгоритмы перевода 0,y10  0,yq выводится путем следующих рассуждений. если основание системы счисления q, простая дробь содержит n цифр и bk – цифры дроби (1 k  n, 0  bk  q–1), то она может быть представлена в виде суммы:

 (5)

    часть дроби от разряда i до ее конца обозначим  i и примем  n = bn/q (очевидно,  1 = 0,yq); тогда в (5) легко усматривается рекуррентное соотношение:

 (6)

    если вновь позаимствовать в pascal’е обозначение функции – на этот раз trunc, которая производит округление целого вещественного числа путем отбрасывания его дробной части, то следствием (6) будут соотношения, позволяющие находить цифры новой дроби:

bi = trunc(q· i),

i+1 = q· i - trunc(q· i) (7)

    соотношения (7) задают алгоритм преобразования 0,y10  0,yq:

  1. умножить исходную дробь в 10-й системе счисления на q, выделить целую часть – она будет первой цифрой новой дроби; отбросить целую часть;

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

  3. записать дробь в виде последовательности цифр после нуля с разделителем в порядке их появления в п (1) и (2).

    блок-схема алгоритма представлена на рисунке 1. цикл перевода заканчивается либо в том случае, когда окажется i+1 = 0, либо последовательность действий повторится наперед заданное число раз (значение константы ex), которое совпадает с количеством значащих цифр в дробной части.

рис.1. блок-схема алгоритма

5 типы языков программирования

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

  1. машинные языки

  2. языки ассемблера

  3. языки высокого уровня (алгоритмические, логические, ооя)

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

конструкции машинного языка интерпретируются непосредственно аппаратурой.

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

язык высокого уровня - согласно гост 19781-90 - язык программирования, понятия и структура которого удобны для восприятия человеком.

языки высокого уровня отражают потребности программиста, но не возможности системы обработки данных.

6 язык ассемблера. пример программы для ibm pc.

язы́к ассе́мблера — язык программирования низкого уровня, мнемонические команды которого (за редким исключением) соответствуют инструкциям процессора вычислительной системы. трансляция программы в исполняемый машинный код производится ассемблером (от англ. assembler — сборщик) — программой-транслятором, которая и дала языку ассемблера его название.

000

rd #40

загрузка параметров первого массива

001

wr r1

002

rd #11

003

wr r2

004

call m

вызов подпрограммы

005

wr r6

сохранение результата

006

rd #54

загрузка параметров второго массива

007

wr r1

008

rd #7

009

wr r2

010

call m

вызов подпрограммы

011

wr r7

сохранение результата

012

rd #63

загрузка параметров третьего массива

013

wr r1

014

rd #3

015

wr r2

016

call m

вызов подпрограммы

017

add r7

вычисление среднего арифметического

018

add r6

019

div #3

020

out

вывод результата

021

hlt

стоп

022

m: rd @r1

загрузка первого элемента в r3

023

wr r3

024

l2: rd @r1+

чтение элемента и модификация адреса

025

wr r4

определение, является ли число отрицательным

026

sub #0

027

jns l1

переход к циклу, если число не отрицательно

028

ret

возврат к основной программе

029

l1: jrnz r2,l2

цикл

030

rd r3

чтение результата в асс

031

ret

возврат к основной программе

7 теорема структурного программирования. пример в программных кодах

теорема бёма — якопини — положение структурного программирования, согласно которому любой исполняемый алгоритм может быть преобразован к структурированному виду, то есть такому виду, когда ход его выполнения определяется только при помощи трёх структур управления: последовательной (англ. sequence), ветвлений (англ. selection) и повторов или циклов (англ. repetition, cycle).

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

  • например:

подпрограмма 1 /* последовательное выполнение инструкций 1, 2 ..n…...*/

инструкция 1; инструкция 2; ... инструкция n; конец подпрограммы 1.

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

  • например:

подпрограмма 2 /* ветвлений – выбор инструкции согласно условию */ если условие 1 то инструкция 1; /* выполняется, если истинно условие 1 */

если условие 2 то инструкция 2; /* выполняется, если истинно условие 2 */ ... иначе инструкция n; /* выполняется, если не ни одно из условий не является истинным */ . конец подпрограммы 2.

3. в циклах инструкции повторяются до тех пор пока не изменится некое условие, например значение логической переменной.

  • например:

подпрограмма 3 /* цикл */ пока условие n выполнить инструкция n /* цикл повторяется пока верно условие n */ инструкция n + 1 /* выход из цикла по нарушению условия n */ конец подпрограммы 3

8 базовые алгоритмические структуры

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

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

характерной особенностью базовых структур является наличие в них одного входа и одного выхода.

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

школьный алгоритмический язык

язык блок-схем

действие 1 действие 2 . . . . . . . . . действие n

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

    pascal    

язык блок-схем

1. if-then

если условие

  то действия

все

2. if-yhen-else

если условие

  то действия 1

  иначе действия 2

все

3. case

выбор

  при условие 1: действия 1

  при условие 2: действия 2

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

  при условие n: действия n

все

4. case-else

выбор

  при условие 1: действия 1

  при условие 2: действия 2

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

  при условие n: действия n

  иначе действия n+1

все

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

школьный алгоритмический язык

язык блок-схем

цикл типа while-do. предписывает выполнять тело цикла до тех пор, пока выполняется условие, записанное после слова пока.

нц пока условие

  тело цикла

  (последовательность действий)

кц

цикл типа for-do. предписывает выполнять тело цикла для всех значений       некоторой переменной (параметра цикла) в заданном диапазоне.     

нц для i от i1 до i2

  тело цикла

  (последовательность действий)

кц

9 классификация языков программирования в зависимости от степени детализации предписаний

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

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

• машинные;

• машинно-оpиентиpованные (ассемблеpы);

• машинно-независимые (языки высокого уровня).

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

языки высокого уровня делятся на:

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

• логические (prolog, lisp и др.), которые ориентированы не на разработку алгоритма решения задачи, а на систематическое и формализованное описание задачи с тем, чтобы решение следовало из составленного описания;

• объектно-ориентированные (object pascal, c++, java и др.), в основе которых лежит понятие объекта, сочетающего в себе данные и действия над нами. программа на объектно-ориентированном языке, решая некоторую задачу, по сути описывает часть мира, относящуюся к этой задаче. описание действительности в форме системы взаимодействующих объектов естественнее, чем в форме взаимодействующих процедур.

10 преимущества алгоритмических языков относительно машинных

сложность машинных программ ограничивалась способностью программиста одновременно мысленно отслеживать последовательность выполняемых операций и местонахождение большого количества данных

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

основные преимущества таковы:

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

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

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

  • требуемые операции задаются с помощью общепринятых математических обозначений;

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

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

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

11 компоненты алгоритмического языка. примеры

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

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

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

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

12 основные понятия в алгоритмических языках

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

        1. имена (идентификаторы) - употpебляются для обозначения объектов пpогpаммы (пеpеменных, массивов, функций и дp.).

        2. опеpации. типы операций:

  • аpифметические опеpации + , - , * , / и дp. ;

  • логические опеpации и, или, не;

  • опеpации отношения < , > , <=, >= , = , <> ;

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

        1. данные - величины, обpабатываемые пpогpаммой. имеется тpи основных вида данных: константы, пеpеменные и массивы

  • константы - это данные, которые зафиксированы в тексте программы и не изменяются в процессе ее выполнения.

пpимеpы констант: 

  1. числовые 7.5, 12;

  2. логические да (истина), нет (ложь);

  3. символьные "а", "+";

  4. литеpные "abcde", "информатика", "" (пустая строка).

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

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

          1. выpажения - пpедназначаются для выполнения необходимых вычислений, состоят из констант, пеpеменных, указателей функций (напpимеp, exp(x)), объединенных знаками опеpаций.

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

    различают выражения арифметические, логические и строковые.

    • арифметические выражения служат для определения одного числового значения. например, (1+sin(x))/2. значение этого выражения при x=0 равно 0.5, а при x=p/2 - единице.

    • логические выражения описывают некоторые условия, которые могут удовлетворяться или не удовлетворяться. таким образом, логическое выражение может принимать только два значения - "истина" или "ложь" (да или нет). рассмотрим в качестве примера логическое выражение x*x + y*y < r*r , определяющее принадлежность точки с координатами (x,y) внутренней области круга радиусом r c центром в начале координат. при x=1, y=1, r=2 значение этого выражения -"истина", а при x=2, y=2, r=1 - "ложь".

    • значения строковых (литерных) выражений - текcты. в них могут входить литерные константы, литерные переменные и литерные функции, разделенные знаком операции сцепки. например, а + в означает присоединение строки в к концу строки а. если а = "куст ", а в = "зеленый", то значение выражения а+в есть "куст зеленый".

          1. операторы (команды). оператор - это наиболее крупное и содержательное понятие языка: каждый оператор представляет собой законченную фразу языка и определяет некоторый вполне законченный этап обработки данных. в состав опеpатоpов входят:

    • ключевые слова;

    • данные;

    • выpажения и т.д.

    • операторы подpазделяются на исполняемые и неисполняемые.неисполняемые опеpатоpы пpедназначены для описания данных и стpуктуpы пpогpаммы, а исполняемые - для выполнения pазличных действий (напpимеp, опеpатоp пpисваивания, опеpатоpы ввода и вывода, условный оператор, операторы цикла, оператор процедуры и дp.).

    13 основные стандартные функции в алгоритмических языках

    cтандартные функции языка - это такие часто употребляемые функции, которые заранее запрограммированы и встроены в транслятор языка.

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

    обращение

    тип аргумента

    тип результата

    примечание

    abs(x)

    real, integer

    тип аргумента

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

    arctan(x)

    real, integer

    real

    арктангенс (значение в радианах)

    cos(x)

    real, integer

    real

    косинус, угол в радианах

    exp(x)

    real, integer

    real

    экспонента

    frac(x)

    real

    real

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

    int(x)

    real, integer

    real

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

    ln(x)

    real, integer

    real

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

    pi

    нет

    real

    3,141592653

    sin(x)

    real, integer

    real

    синус, угол в радианах

    sqr(x)

    real, integer

    тип аргумента

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

    sqrt(x)

    real, integer

    real

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

    random

    нет

    real

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

    random(i)

    integer

    integer

    псевдослучайное число в интервале [0, i]

    round(x)

    real

    integer

    округление до ближайшего целого

    trunc(x)

    real

    integer

    отбрасывание дробной части числа

    14 структурированное программирование и его история

    следующий шаг был сделан в 1954 году, когда был создан первый язык высокого уровня — фортран (англ. fortran - formula translator). языки высокого уровня имитируют естественные языки, используя некоторые слова разговорного языка и общепринятые математические символы. эти языки более удобны для человека, с помощью них, можно писать программы до нескольких тысяч строк длиной. однако легко понимаемый в коротких программах, этот язык становился нечитаемым и трудно управляемым, когда дело касалось больших программ. решение этой проблемы пришло после изобретения языков структурного программирования (англ. structured programming language), таких как алгол(1958), паскаль(1970), си(1972).

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

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

    также создавались функциональные (аппликативные) языки (пример: lisp — англ. list processing, 1958) и логические языки (пример: prolog — англ. programming in logic, 1972).

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

    15 язык turbo pascal как инструмент структурированного программирования

    16 транслятор. компилятор. интерпретатор

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

    трансляторы реализуются в виде компиляторов или интерпретаторов. с точки зрения выполнения работы компилятор и интерпретатор существенно различаются.

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

    интерпретатор (англ. interpreter — истолкователь, устный переводчик) переводит и выполняет программу строка за строкой.

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

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

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

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

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

    17 примеры записей арифметических и логических выражений на языке паскаль

    арифметические:

    знак

    операция

    -

    вычитание

    +

    сложение

    *

    умножение

    /

    деление

    div

    целочисленное деление

    mod

    остаток от деления

    x*col-7*(g-u+5)

    s/t/y-y+8*(u/7-5-g)*(u-8.78)

    5.89+6*(y+7*u*(t+6))

    5 mod g (в этом выражении ищется остаток от деления 5 на g.)

    g div 2 (в этом выражении вычисляется результат от деления g на 2.)

    логические:

    а

    в

    not a

    a and b

    a or b

    a xor b

    true

    true

    false

    true

    true

    false

    true

    false

    false

    false

    true

    true

    false

    true

    true

    false

    true

    true

    false

    false

    true

    false

    false

    false

    (a and b)or(b and not c)

    (a xor b) and ( a or c) xor (not h)

    18 лексика языка turbo pascal. примеры

    символы из алфавита языка используются для построения базовых элементов pascal-программ - лексем. лексема - минимальная единица языка, имеющая самостоятельный смысл.  в turbo pascal имеются следующие классы лексем: 1. служебные (зарезервированные) слова. это ограниченная группа слов, построенных из букв. каждое служебное слово представляет собой неделимое образование, смысл которого фиксирован в языке. служебные слова нельзя использовать в качестве имен, вводимых программистом (т.е. в качестве идентификаторов переменных, констант и т.д.). все 55 служебных слов языка представлены ниже.

    absolute

    array

    and

    asm

    assembler

    begin

    case

    const

    constructor

    destructor

    div

    downto

    else

    end

    external

    file

    for

    forward

    function

    goto

    if

    implementation

    in

    inline

    interface

    interrupt

    label

    mod

    nil

    not

    object

    of

    or

    packed

    private

    procedure

    program

    record

    repeat

    set

    shl

    shr

    string

    then

    to

    type

    unit

    until

    uses

    var

    virtual

    while

    with

    xor

     

    заметим, что синтаксис языка turbo pascal на самом деле допускает использование некоторых служебных слов в качестве идентификаторов (к числу таких слов относятсяassembler, external, forward, interrupt, private, virtual). строго говоря, эти слова называются в языке директивами. однако в целях большей ясности программ использование директив в качестве идентификаторов не рекомендуется.

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

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

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

    index index index

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

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

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

    ; : = ( .

     в текстах pascal-программ допускаются фрагменты пояс­нительного характера -комментарии. наличие комментари­ев не изменяет смысл программы и не влияет на ее выполне­ние.

    19 грамматика языка turbo pascal. примеры

    1.текст программы состоит из трех составных частей. это заголовок, описания, операторы. заголовок программы содержит имя программы. для версии eth необходимо дополнительно указать источник и приемник данных для работы программы - файлы для ввода и вывода информации. по умолчанию файл input связан с клавиатурой компьютера, а файл output - с экраном монитора. в turbo pascal заголовок имеет декоративное значение и использовать его не обязательно.

    2. описания - это символьные конструкции для описания свойств объектов программы. все объекты программы надо обязательно указать в этой части программы. операторы - это символьные конструкции для описания действий над объектами программы. операторы должны находиться между словами begin и end. эти слова считаются скобками.

    3. в одной строке текста можно размещать несколько операторов или описаний. поэтому между операторами надо обязательно ставить символ-разделитель. для разделения операторов используется символ точка с запятой ( ; ). после последнего оператора разделитель ставить не обязательно.

    4. малые и большие буквы считаются эквивалентными (равнозначными). имя любого объекта в записи программы может содержать только буквы латинского алфавита, цифры и символ подчеркивания ( _ ). имя не может начинаться с цифры. никакие другие типы символов в записи имен не разрешаются.

    program имя(ввод,вывод);

    program echo(input,output);

    описания;

    var n: integer;

    begin

    begin

    оператор;

    write('число?');

    оператор;

    read(n);

    оператор

    write(n)

    end.

    20 операторы ввода\вывода данных в turbo pascal

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

         сначала операторы ввода (форматы операторов): read(<список ввода>); readln(<список ввода>);

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

         разница между работой процедур read и readln (от read line) состоит в следующем: после выполнения read значение следующего данного считывается с этой же строчки, а после выполнения readln - с новой строки.

         для вывода информации в паскале также есть две команды: write(<список вывода>); writeln(<список вывода>);

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

         приведем пример использования операторов ввода и вывода:

    program inteface; var    r,s : real; begin    write('введите радиус круга ');      {печать на экране просьбы о вводе}    readln(r);                                        {ввод значения в переменную r с клавиатуры}    s:=4*arctan(1)*sqr(r);           {вычисление площади круга (pr2)}    writeln('площадь круга радиусом ',r,' равна ',s) end.

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

    21 структурные и простые операторы turbo pascal. примеры

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

    метка - это последовательность цифр в диапазоне от 0 до 9999 или идентификатор.

    существует два основных вида операторов: простые операторы и структурные операторы.

    Простые операторы:

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

    Оператор присваивания

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

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

    приведем некоторые примеры операторов присваивания:

    x := y + z

    done := (i >= 1) and (i < 100);

    huel := [blue, succ(c)];

    i := sqr(j) - i * k;

    Присваивания объектного типа

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

    Операторы процедуры

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

    приведем некоторые примеры операторов процедур:

    transpose(a,n,m);

    fin(name,address);

    Операторы перехода

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

    при использовании оператора перехода должны соблюдаться следующие правила:

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

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

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

    Структурные операторы

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

    Составные операторы

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

    приведем пример составного оператора:

    begin

    z := x;

    x := y;

    y := z;

    end;

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

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

    Оператор условия (if)

    синтаксис оператора if можно представить следующим образом:

    в выражении должен получаться результат, имеющий стандартный булевский тип. если результатом выражения является истинное значение (true), то выполняется оператор, следующий за ключевым словом then.

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

    синтаксическая неоднозначность, возникающая в конструкции:

    if e1 then e2 else e3 разрешается путем следующей интерпретации этой конструкции:

    if e1 then

    begin

    if e2 then

    s1

    else

    s2

    end

    примечание: в предшествующем операторе else двоеточие не указывается.

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

    оператор варианта (case)

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

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

    приведем некоторые примеры оператора варианта:

    case operator of

    plus: x := x+y;

    minus: x := x-y;

    times: x := x*y;

    end;

    Оператор цикла

    оператор цикла задает повторное выполнение определенных операторов.

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

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

    Оператор цикла с постусловием (repeat)

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

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

    приведем примеры оператора цикла с постусловием:

    repeat

    write('введите значение (0..9):');

    readln(i);

    until (i >= 0) and (i <= 9);

    Операторы цикла с предусловием (while)

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

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

    примерами операторов цикла с предусловием могут служить следующие операторы:

    while i > 0 do

    begin

    if odd(i) then z := z * x;

    i := i div 2;

    x := sqr(x);

    end;

    Операторы цикла с параметром (for)

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

    в качестве управляющей переменной должен использоваться идентификатор переменой (без какого-либо квалификатора), который обозначает переменную, объявленную локальной в блоке, в котором содержится оператор for. управляющая переменная должна иметь перечислимый тип. начальное и конечное значения должны иметь тип, совместимый по присваиванию с перечислимым типом.

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

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

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

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

    если принять во внимание эти ограничения, то оператор for v := expr1 to expr2 do body; эквивалентен оператору:

    begin

    temp1 := expr1;

    temp2 := expr2;

    if temp1 <= temp2 then

    begin

    v := temp1;

    body;

    while v <> temp2 do

    begin

    v := succ(v);

    body;

    end;

    end;

    end;

    и оператор цикла: for v := expr1 downto exp2 do body; эквивалентен операторам:

    begin

    temp1 := expr1;

    temp2 := expr2;

    if temp1 >= temp2 then

    begin

    v := temp1;

    body;

    while v <> temp2 o

    begin

    v := pred(v);

    body;

    end;

    end;

    end;

    где temp1 и temp2 - вспомогательные переменные, тип которых совпадает с основным типом переменной v и которые не встречаются в другом месте программы.

    приведем примеры оператора цикла с параметром:

    for i := 2 to 63 do

    if data[i] > max then max := data[i]

    for i := 1 to 10 do

    for j := 1 to 10 do

    begin

    x := 0;

    for k := 1 to 10 do

    x := x + mat1[i,k]*mat2[k,j];

    mat[i,j] := x;

    end;

    Оператор with

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

    возьмем следующее описание:

    type

    tdate = record

    day : integer:

    month : integer;

    year : integer:

    end;

    с учетом данного описания приведем пример оператора with:

    with orderdate do

    if month = 12 then

    begin

    month := 1;

    year := year + 1

    end else

    month := month + 1;

    это эквивалентно следующему:

    if orderdate.month = 12 then

    begin

    orderdate.month := 1;

    orderdate.year := tdate.year + 1

    end

    else

    date.month := tdate.month + 1;

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

    допустим описаны следующие переменные:

    type

    tpoint = record

    x,y: integer;

    end;

    var

    x: point;

    y: integer;

    в этом случае и к x, и к y можно обращаться, как к переменной или как к полю записи. в операторе:

    with x do

    begin

    x := 10;

    y := 25;

    end;

    x между ключевыми словами with и dо относится к переменной типа указатель, а в составном операторе x и y ссылаются на x.x и y.y.

    оператор:

    with v1,v2,...vn do s;

    эквивалентен операторам:

    with v1 do

    with v2 do

    ...

    with vn do

    s;

    в обоих случаях, если vn является полем и v1, и v2, то она интерпретируется как v2.vn, а не как v1.vn.

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

    22 типы данных. классификация

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

    v  базовые:

    ø  порядковые

    §  целые

    §  символьные

    §  логические

    ø  вещественные

    ø  указатели

    v  конструируемые

    ø  структурированные

    §  массивы

    §  множества

    §  записи

    §  файлы

    ø  указатели

    ø  строки

    ø  процедурные

    ø  объекты

    ø  перечисляемые

    базовые типы данных – типы, определяемые в языке программирования

    конструируемы типы данных – типы данных, которые создаются программистом

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

    Порядковые типы данных

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

    Целые типы данных

    тип данных

    количество бит

    диапазон

    shortint

    byte

    integer

    word

    longint

    8

    8

    16

    16

    32

    -128..127

    0..255

    -32768..32767

    0..65535

    -2147483648..2147483647

    -27..27-1

    0..28-1

    -215..215

    0..216-1

    -231..231-1

    тип   данных longint следует использовать для огромных расчетов и не следует использовать в обычных программах. позже я расскажу о действиях и функциях (процедурах), применяемым к порядковым типам данных, но скажу, что особенными для этих типов данных являются операции div и mod.операция div – это операция целочисленного деления, то есть результатом будет целая часть от деления целого числа на целое. операция mod – это операция остатка отделения, т.е она вернет делимое минус делитель умноженное на целую часть.

    Символьные типы данных

    символьный тип данных это тип char. очевидно, что переменная типа char можно присвоить значение в виде символьной константы, например c:=’a’.но символьный тип данных может иметь значения, задающиеся кодам в таблице ascii-кодов, то есть, то, что приведено в первом примере может быть c:=#65. 65 – ascii код символа а. теперь понятно, почему символьный тип данных – это порядковый тип данных, потому что мы можем любой символ заменить числом в диапазоне 0..255, а все числа идут по определенному порядку.

    Логический тип данных

    логический тип данных имеет всего два значения и кодируется одни битом его значения true и false, 1 и 0 соответственно истина и ложь.

    рассмотрю перечисленные операции. конъюнкция – логическое и или еще ее называют логическим умножением, таблица истинности приведена ниже.

     

    x

    y

    x and y

    0

    0

    0

    0

    1

    0

    1

    0

    0

    1

    1

    1

    дизъюнкция -  логическое или, иначе ее называют логическим сложением. в языке программирования паскаль обозначается or.таблица истинности приведена ниже.

    x

    y

    x or y

    0

    0

    0

    0

    1

    1

    1

    0

    1

    1

    1

    1

    еще есть операция инверсии, в которой все делается в обратную сторону: 0 меняется на 1, 1 меняется на 0.

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

    Функции и процедуры, применяемые к порядковым типам данных

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

    сначала рассмотрим функции:

    ord(x) - возвращает порядковый номер значения переменной x (относительно того типа, к которому принадлежит переменная х).

    pred(x) - возвращает значение, предшествующее х (к первому элементу типа неприменима).

    succ(x) - возвращает значение, следующее за х (к последнему элементу типа неприменима).

     теперь процедуры:

    inc(x) – оператор инкремента, возвращает значение x:=x+1

    inc(x,k) - возвращает значение x:=x+k.

    dec(x) – оператор декремента, возвращает значение x:=x-1.

    dec(x,k) - возвращает значение x:=x-k.

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

    Вещественные типы данных

    как и с целочисленными типами данных, вещественные тип данных это не только тип real.вещественные типы данных приведены в таблице ниже.

    тип

    количество байт

    диапазон (абсолютной величины)

    single

    real

    double

    extended

    comp

    4

    6

    8

    10

    8

    1.5*10-45..3.4*1038

    2.9*10-39..1.7*1038

    5.0*10-324..1.7*10308

    3.4*10-4932..1.1*104932

    -263+1..263-1

    из этой таблици видно, что тип real – самый оптимальный для использования, так как имеет достаточно большой диапазон значений, но при этом занимает не так много памяти, а тип extended надо использовать лишь для  астрономических  расчетов и не использовать в обычных программах. к этим типам данных применяются все арифметические операции кроме операций div и mod, еще применяются операции преобразования типов данных.

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

    23 простые типы данных в turbo pascal. примеры

    к простым типам относятся порядковые и вещественные типы.

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

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

    идентификатор

    длина (байт)

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

    операции

    целые типы

    integer

    2

    -32768..32767

    +, -, /, *, div, mod, >=, <=, =, <>, <, >

    byte

    1

    0..255

    +, -, /, *, div, mod, >=, <=, =, <>, <, >

    word

    2

    0..65535

    +, -, /, *, div, mod, >=, <=, =, <>, <, >

    shortint

    1

    -128..127

    +, -, /, *, div, mod, >=, <=, =, <>, <, >

    longint

    4

    -2147483648..2147483647

    +, -, /, *, div, mod, >=, <=, =, <>, <, >

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

    real

    6

    2,9x10-39 - 1,7x1038

    +, -, /, *, >=, <=, =, <>, <, >

    single

    4

    1,5x10-45 - 3,4x1038

    +, -, /, *, >=, <=, =, <>, <, >

    double

    8

    5x10-324 - 1,7x10308

    +, -, /, *, >=, <=, =, <>, <, >

    extended

    10

    3,4x10-4932 - 1,1x104932

    +, -, /, *, >=, <=, =, <>, <, >

    логический тип

    boolean

    1

    true, false

    not, and, or, xor, >=, <=, =, <>, <, >

    символьный тип

    char

    1

    все символы кода ascii

    +, >=, <=, =, <>, <, >

    24 структурированные типы данных в turbo pascal. примеры

    структурированные типы

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

    4.2.1. Массивы

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

    4.2.2. Записи

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

    структура объявления типа записи такова:

    <имя типа> = record <сп.полей> end

    здесь <имя типа> - правильный идентификатор;

    record, end - зарезервированные слова (запись,конец); <сп.полей> - список полей; представляет собой последовательность разделов записи, между которыми ставится точка с запятой.

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

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

    4.2.3. Множества

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

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

    пример определения и задания множеств:

    type

    digitchar= set of '0'..'9';

    digit = set of 0. .9;

    var

    sl,s2,s3 :digitchar;

    s4,s5,s6 :digit;

    begin

    .....

    s1:=['1','2','3'];

    s2:=['3','2','1'];

    s3:=['2','3'];

    s4:=[0..3,6];

    s5:=[4,5];

    s6:=[3..9];

    .....

    end.

    в этом примере множества s1 и s2 эквивалентны, а множество s3 включено в s2 , но не эквивалентно ему.

    над множествами определены следующие операции:

    * пересечение множеств;

    + объединение множеств;

    - разность множеств;

    = проверка эквивалентности; возвращает true, если оба множества эквивалентны;

    <> проверка неэквивалентности; возвращает true, если оба множества неэквивалентны;

    <= проверка вхождения; возвращает true, если первое множество включено во второе;

    >= проверка вхождения; возвращает true, если второе множество включено в первое;

    in проверка принадлежности; в этой бинарной операции первый элемент - выражение, а второй - множество одного и того же типа; возвращает true , если выражение имеет значение, принадлежащее множеству:

    3 in s6 возвращает true;

    2*2 in s1 возвращает false.

    дополнительно к этим операциям можно использовать две процедуры. include - включает новый элемент во множество. exclude - исключает элемент из множества.

    4.3. Строки

    тип string (строка) в турбо паскале широко используется для обработки текстов. он во многом похож на одномерный массив символов array[o..n] of char, однако, в отличие от последнего, количество символов в строке-переменной может меняться от 0 до n, где n - максимальное количество символов в строке. значение n определяется объявлением типа string [n] и может быть любой константой порядкового типа, но не больше 255 . турбо паскаль разрешает не указывать n, в этом случае длина строки принимается максимально возможной, а именно n=255 .

    строка в турбо паскале трактуется как цепочка символов. к любому символу в строке можно обратиться точно так же, как к элементу одномерного массива array [0..n] of char.

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

    concat(s1 [,s2, ... , sn]) - функция типа string; возвращает строку, представляющую собой сцепление строк-параметров si, s2, ..., sn.

    copy(st, index, count) - функция типа string; копирует из строки st count символов, начиная с символа с номером index.

    delete (st, index, count) - процедура; удаляет соunt символов из строки st, начиная с символа с номером index.

    insert (subst, st, index) - процедура; вставляет подстроку subst в строку st, начиная с символа с номером index.

    length (st) - функция типа integer; возвращает длину строки st.

    pos (subst, st) - функция типа integer; отыскивает в строке stпервое вхождение подстроки subst и возвращает номер позиции, с которой она начинается; если подстрока не найдена, возвращается ноль.

    str(x [; width [: decimals] ], st) - процедура; преобразует число x любого вещественного или целого типов в строку символов st так, как это делает процедура writeln перед выводом; параметры width и decimals, если они присутствуют, задают формат преобразования: width определяет общую ширину поля, выделенного под соответствующее символьное представление вещественного или целого числа x, a decimals - количество символов в дробной части (этот параметр имеет смысл только в том случае, когда х- вещественное число).

    val(st, x, code) - процедура; преобразует строку символов st во внутреннее представление целой или вещественной переменной x, которое определяется типом этой переменной; параметр code содержит ноль, если преобразование прошло успешно, и тогда в x помещается результат преобразований, в противном случае он содержит номер позиции в строке st, где обнаружен ошибочный символ, и в этом случае содержимое х не меняется;

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

    25 тип – массив. примеры

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

    type имя_типа = array [тип индекса] of тип_элемента

    type mas = array [1..10] of real

    color = array [byte] of mas

    active = array [menu] of boolean

    в первом операторе описан тип массива из вещественных элементов, которые нумеруются от 1 до 10. во втором операторе элементами массива являются массивы типа mas, а нумеруются они в пределах, допустимых для типа byte, т.е. от 0 до 255. в третьем в качестве индекса использовано имя из раздела «перечисляемый тип данных», а сами элементы могут принимать значения true или false.

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

    размещение массива в памяти происходит до выполнения программы, поэтому при описании индекса можно применять только константы или константные выражения. использовать для этого переменные нельзя!

    обычно при описании массива верхняя граница его индекса задается в виде именованной константы:

    const n =6;

    type intmas = array [1..n] of integer;

    c массивами в целом можно выполнять только одну операцию: присваивание. все остальные действия выполняются с отдельными элементами массива.

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

    инициализация массивов. можно присвоить значения элементам массива до начала выполнения программы. это делается так же, как и для простых переменных, - в разделе описания констант:

    const a: intmas = (0,5, -7,100,15,1);

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

    26 тип – запись. примеры

    в программах часто возникает необходимость логического объединения данных. однотипные данные организуются в массивы, а для объединения разнотипных данных предназначен типе «запись». он вводится с помощью ключесвого слова record. элементы записи называются полями.

    type имя_типа = record

    описание 1-го поля записи;

    описания 2-го типа записи;

    описание n-го поля записи»

    end;

    поля записи могут быть любого типа, кроме файлового.

    type goods = record

    name=: string [20];

    price=: real;

    number=: integer;

    end

    переменные типа “запись» описываются обычным образом. можно задавать описание типа при описании переменной, создавать массивы из записей, записи из массивов и т.д.

    есть 2 способа доступа к полю записи: либо с помощью конструкции имя_записиюимя_поля, либо с использованием оператора присоединения with:

    g1.price:=200

    with g1 do begin

    price:=200; number:=10

    end.

    оператор with удобнее использовать, если требуется обращаться к нескольким полям одной и той же записи.

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

    program store;

    const max_n = 100;

    case

    str20 = string[20];

    goods = record

    name=:str20;

    price=:real;

    number=:integer;

    end;

    var stock: array[1..max_n] of goods;

    i,j,len: integer;

    name: str20;

    found: boolean;

    f:text;

    begin

    assign(f,’stock.txt’); reset(f);

    i;+1;

    while not eof(f) do begin

    with stock[i] do readln(f,name,price,number);

    inc(i);

    if i>max_n then begin

    writeln (‘переполнение массива’); exit end;

    end;

    while true do begin

    writeln (‘введите наименование:’); readln(name);

    len:= length(name);

    if len = 0 then break;

    for j:= len + 1 to 20 do name:= name + ‘ эж

    found:=false;

    for j:=1 to i-1 do begin

    if name <> stock[j].name then continue;

    with stock[j] do writeln (name:22, price:7:2, number:5);

    found:=true;

    break;

    end;

    if not found then writeln(‘товар не найден’);

    end;

    end.

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

    const g: goods = (name:’boots’; price:200; number:10);

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

    type contact = record

    name:string[40];

    tel:string[15];

    case i:integer of

    0: (post:string[20]);

    1: (date:string[10]; code:word);

    end.

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

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

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

    type

    figure = (rect, triangle, circle);

    shape = record;

    x,y:real;

    case kind: figure of

    rect: (height, width,:real);

    triangle: (x2,y2,x3,y3:real);

    circle: (radius:real);

    end;

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

    type shape = record

    x,y:real;

    case integer of

    0: (height, width,:real);

    1: (x2,y2,x3,y3:real);

    2: (radius:real);

    end;

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

    27 тип – множество. примеры

    множественный тип данных в языке паскаль соответствует математическому представлению о множествах: это ограниченная совокупность различных элементов. множество создается на сонове элементов базового типа – это может быть перечисляемый тип, интервальный или byte. в множестве не может быть более 256 элементов, а их порядковые номера должны лежать в пределах от 0 до 255.

    множество описывается с помощью служебных слов set of.

    type имя_типа = set of базовый_тип

    примеры описания:

    type caps = set of ‘a’..’z’;

    colors = set of (red, green, blue);

    numbers = set of byte;

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

    var oct: set of 0..7;

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

    Константа вида [ ] означает пустое множество.

    Тип «множество» задает набор всех возможных подмножеств его элементов, включая пустое. Если базовый тип, на котором строится множесвто, имеет k элементов, то число подмножеств, входящих в это множество, равно 2k.

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

    var b: 1..3;

    Эта переменная может принимать три различных значения 1,2 или 3. Переменная m типа «множество».

    var m: set of 1..3

    может принимать 8 различных значений

    [ ] [1] [2] [3] [1,2] [1,3] [2,3] [1,2,3]

    Порядок перечисления элементов базового типа в константах не имеет значения

    Операции над множествами

    Величины множественного типа не могут быть элементами списка ввода-вывода. Допустимые операции над множествами

    Знак

    Название

    Математическая запись

    Результат

    :=

    Присваивание

    +

    объединение

    U

    множество

    *

    Пересечение

    множество

    -

    Дополнение

    \

    множество

    =

    Тождественность

    =

    логический

    <>

    Нетождественность

    логический

    <=

    Содержится в

    логический

    >=

    Содержит

    логический

    in

    принадлежность

    логический

    Операции над множествами в соновном соответствуют операциям, определенным в теории множеств. Объединение множеств А и В – это множество, состоящее из всех элементов, принадлежащих А и В. Пересечение множеств А и В – множество, состяощее из элементов, принадлежащих одновременно А и В. Дополнение множеств А и В – множество, состоящее из элементов множества А, не принадлежащих В.

    Тождественность множеств А и В означает, что эти множества совпадают, нетождественность – не совпадают. Множество А содержится в множестве В, если все элементы А принадлежат В. Множество А содержит множество В, если все элементы В принадлежат А.

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

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

    type Caps = set of ‘A’ .. ‘Z’;

    var a,b,c: Caps;

    begin

    a:= [‘A’, ‘U’..’Z’];

    b:=[‘M’..’Z’];

    c:=a; {присваивание}

    c:=a+b; {объединение, результат [‘A’,’M’..’Z’]}

    c:=a*b; {пересечение, результат [‘U’..’Z’]}

    c:=b-a; {вычитание, результат [‘M’..’T’]}

    c:=a-b; {вычитание, результат [‘A’]}

    if a=b then writeln (‘тождественны’); {не выполнится}

    if a<>b then writeln (‘не тождественны’); {выполнится}

    if c<=a then writeln (‘c содержится в a’); {выполнится}

    ifNin b then writeln (‘ в b есть N’); {выполнится}

    end.

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

    Является ли введенной символ цифрой:

    var c:char;

    if c in [‘0’..’9’] then…

    В гонках участвуют 30 машин со стартовыми номерами от 101 до 130. Проводится 5 заездов по 6 машин. Программа формирует состав заездов случайным образом.

    program race;

    var cast, lap: set of 100..130;

    i,j,n: byte;

    begin

    randomize;

    cast:=[];

    for i:=1 to 5 do begin

    write (i, ‘-й заезд’);

    lap:=[];

    for j:= 1 to 6 do begin

    repeat

    n:= random (30) +101;

    until not 9n in lap) and not (n in cast);

    lap:= lap +[n];

    write (n:4);

    end;

    cast:= cast+lap;

    writeln;

    end;

    end.

    28 Тип - строка. примеры

    Строки используются для хранения последовательностей символов. В Паскале существуют 3 типа строк:

    • стандартные (string)

    • определяемые программистом на основе string

    • строки в динамической памяти

    Строка типа string может содержать до 255 символов. Под каждый символ отводится по 1 байту, в котором хранится код символа. Еще один байт отводится под фактическую длину строки. Т.о., в памяти под одну переменную типа string всегда отводится 256 байт.

    Для коротких строк использовать стандартную строку неэффективно, поэтому в язык введена возможность самостоятельно задавать максимальную длину строки

    Str4 = string[4];

    Здесь описан собственный тип данных с именем str4. Переменная этого типа занимает в памяти 5 байт.

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

    Примеры описания:

    Const n=15

    Var s: string {строка стандартного типа}

    S1: str4 {строка типа str4, описанного выше}

    S2: string [n] {описание типа задано при описании переменной}

    Инициализация строк, как и переменных других типов, выполняется в разделе описания констант

    const s3: string[15] = ‘shooshpanchik’;

    Внутреннее представление строки s3:

    S3:string [15]

    13

    s

    h

    o

    o

    s

    h

    p

    a

    n

    c

    h

    i

    k

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

    s2:= ‘shooshpanchik’;

    s1:= s2; {в s1 будут помещены символы “shoo”}

    Строки можно склеивать (сцеплять) между собой с помощью операции конкатенации, котороая обозначается знаком +

    s1:= ‘ком’;

    s2:= s1+’пот’; {результат – “компот”}

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

    Имя строки может использоваться в процедурах ввода-вывода:

    readln (s1,s2);

    write (s1);

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

    К отдельному символу строки можно обращаться как к элементу массива символов, например s1[4]. Символ строки совместим с типом char, их можно использовать в выражениях одновременно:

    s1[4]:= ‘X’; writeln (s2[3]+s2[5]+’r’);

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

    Функция Concat(s1,s2..sn) возвращает строку, являющуюся слиянием строк s1,s2..sn. Ее действие аналогично операции конкатенации.

    Функция Copy(s,start,len) возвращает подстроку длиной len, начинающуюся с позиции start строки s. Параметры len и start должны быть целого типа.

    Процедура Delete(s,start,len) удаляет из строки s, начиная с позиции start, подстроку длиной len.

    Процедура Insert(subs,s,start) вставляет в строку s подстроку subs, начиная с позиции start/

    Функция Length(s) возвращает фактическую длину строки s, результат имеет тип byte.

    Функция Pos(subs,s) ищет вхождение подстроки subs в строку s и возвращает номер первого символа sums в s или 0, если subs не содержится в s.

    Процедура Str(x,s) преобразует числовое значение x в строку s, при этом для x может быть задан формат, как в процедурах вывода write и writeln.

    Процедура Val)s,x,errcode) преобразует строку s в значение числовой переменной x, при этом строка s должна содержать символьное представление числа. В случае успешного преобразования переменная errcode равна 0. Если же обнаружена ошибка, то errcode будет содержать номер позиции первого ошибочного символа, а значение x не определено.

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

    program censor;

    var s,str: string[10];

    f:text;

    i,dl:integer;

    begin

    assign(f,’primer.txt’); reset(f);

    writeln(‘какую последовательность заменять?’); readln(s);

    dl:=length(s);

    while not eof(f) do begin

    readln(f,str);

    i:=1;

    while i<>0 do begin

    i:=pos(s,str);

    if i<>0 then begin

    delete(str,i,dl);

    insert(‘…’,str.,i);

    end;

    end;

    writeln(str);

    end;

    close(f);

    end.

    29 Типфайл. Примеры

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

    Файловые типы языка Паскаль бывают стандартные и определяемые программистом. Стандартными являются текстовый файл (text) и бестиповой файл (file).

    Описание их в программе:

    var ft:text;

    fb:file;

    Программист может определить файл, состоящий из элементов определенного типа. Такой файл называется компонентным или типизированным:

    var fc: file of <тип_компонент>

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

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

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

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

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

    Для понимания сути работы с файлами полезно разделить их по признаку наличия или отсутствиия преобразования информации при выполнении чения-записи и по способу доступа

    Файл

    текстовый

    бестиповой

    Компонентный

    преобразование

    +

    -

    -

    Прямой доступ

    -

    +

    +

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

    Primer.pas’ – имя файла в текущем каталоге

    D:\pascal\input.txt’ – полное имя файла

    CON’ ‘NUL’ ‘COM1’ ‘PRN’ – имена устройств

    Для организации ввода-вывода в программе необходимо выполнить следующие действия:

    1. Объявить файловую переменную

    2. Связать ее с физическим файлом

    3. Открыть файл для чтения и/или записи

    4. Выполнить операции ввода-вывода

    5. Закрыть файл

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

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

    Механизм буферизации позволяет более быстро и эффективно обмениваться информацией с внешними устройствами.

    В Паскале есть подпрограммы, применяемые для файлов любог типа, а также подпрограммы для работы с определенными типами файлов

    Подпрограммы для работы со всеми типами файлов

    Процедуры

    assign(var f;filename:string);

    Связывает логический файл f с физическим файлом, имя которого задано в строке filename. Если путь к файлу не задан, предполагается, что он находится в текущем каталоге.

    close(var f)

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

    erase(var f)

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

    rename(var f;newname:string)

    Переименовывает физический файл на диске, связанный с логическим файлом f. Переименование возможно после закрытия файла.

    reset(var f)

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

    rewrite(var f)

    Открывает логический файл f для записи данных (открывает выходнйо файл). После успешного выполнения этой процедуры файл готов к записи в него первого элемента. Если физический файл, с которым связана переменная f, чуществовал ранее, он очищается, т.е вся информация из него теряется. Если файл не существовал, он создается

    Функции

    eof(var f):Boolean

    Возвращает значение true, если при чтении достигнут конец файла. Это означает, что прочитан последний элемент в файле или что файл после открытия оказался пуст.

    I0result: integer

    Возвращает целое число, соответствующее коду последней ошибки ввода-вывода. При номральной завершении операции функция вернет значение 0. Значение функции I0result необходимо присваивать какой-либо переменной, т.к. при каждом вызове функция обновляет свое значение. Функция I0result работает только при выключенном режиме проверки ошибок ввода-вывода, т.е. с ключом компиляции {$I-}.

    Текстовые файлы

    Тексовый файл представляет собой последовательность строк символов переменной длины. Каждая строка заканчивается символами перевода строки и возврата каретки (их коды 13 и 10). Эти символы вставляются в физический файл при нажатии клавиши Enter. При чтении файла эти символы не вводятся в переменные в программе, а воспринимаются как разделитель.

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

    append(var f)

    Для чтения из текстового файла применяются процедуры:

    read (f, список)

    readln (f, [список])

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

    Для ввода с клавиатуры определено стандартное имя файла INPUT, а для вывода на экран – OUTPUT. Эти файлы отличаются от обычных тем, что их нельзя открывать и закрывать, поскольку это делается автоматически и их имена можно не указывать при обращении к процедурам ввода и вывода.

    Процедуры записи в текстовый файл:

    write(f, список)

    writeln(f, [список])

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

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

    flush(var f:text)

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

    settextbuf(var f:text; var buf; bufsize:word)

    Процедура служит для увеличения или уменьшения буфера ввода-вывода текстового файла f. Размер буфера для текстовых файлов по умолчанию равен 128 байт. Увеличение буфера сокращает количество обращений к диску. Рекомендуется изменять размер буфера до открытия файла. Буфер файла начнется с первого байта переменной buf. Размер буфера задается в необязательном параметре budsize. Если параметр отсутствует, размер буфера определяется длиной переменной buf.

    seekEof (var f:text):Boolean

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

    seekEoln (var f:text):boolean

    Функция возвращает значение true, если до конца строки остались только пробелы.

    Бестиповые файлы

    Бестиповые файлы предназанчены для хранения участков оперативной памяти на внешних носителях. После описания файловой переменной

    var имя: file;

    ее требуется связать с физическим файлом с помощью процедуры assign. Чтение и запись производятся через буфер порциями равными размеру буфера. Размер буфера, отличающийся от стандартного (128байт), можно задать с помощью второго параметра процедур reset и rewrite при открытии файла.

    reset(var f:file; bufsize:word)

    Размер буфера должен находиться в пределах от 1 байта до 64 Кбайт.

    Собственно чтение и запись выполняются с помощью процедур blockread и blockwrite

    blockread(var f:file; var x:count; var num: word)

    Процедура blockread считывает в переменную x количесвто блоков count. Длина блока равна размеру буфера. Значение count должно быть больше или равно 1, за одно обращение нельзя ввести больше 64Кбайт. Поскольку при вводе никаких преобразований данных не выполняется, имеет значение только адрес начала области памяти и ее длина, поэтому тип переменной x не указывается.

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

    Процедура blockwrite записывает в файл количесвто блоков, равно count, начиная с адреса, заданного переменной x. Длина блока равна длине буфера. Необязательный параметр num возвращает число успешно записанных боков (неудача может произойти, например, из-за переполнения или сбоя диска).

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

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

    program create_bfile;

    var buf: array[1..4] of real;

    f_in:text;

    f_out:file;

    i,k: integer

    name_in, name_out: string;

    begin

    {$i-}

    writeln (‘введите имя входного файла’); readln (name_in);

    assign(f_in,name_in);

    reset (f_in);

    if I0result <>0 then begin

    writeln (‘файл ‘,name_in, ‘не найден’); exit end;

    writeln (‘введите имя выходного файла ‘); readln(name_out);

    assign(f_out, name_out);

    rewrite (f_out, sizeof(real)*4);

    {$i+}

    i:=0;

    while not eof(f_in) do begin

    inc(i);

    read(f_in,buf[i]);

    if i=4 then begin

    blockwrite (f_out,buf,1); i:=1; end;

    end;

    if i<>o then begin

    for k:=i+1 to 4 do buf[k]:=0;

    blockwrite (f_out, buf,1);

    end;

    close (f_in); close (f_out);

    end.

    Компонентные файлы

    Компонентные файлы применяются для хранения однотипных элементов в их внутренней форме представления. Тип компонент задается после ключевых слов file of.

    var имя: file of тип_компонент;

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

    type mas=array[1..100] of real;

    var a,b: mas;

    f: file of mas;

    begin

    assign(f,’some_file.dat’); rewrite(f);

    write(f,a,b);

    close(f);

    end.

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

    Из текстового файла прочитать пары вещественных чисел, считая первое вещественной, а второе – мнимой составляющей комплексного числа, и записать их в файл комплексных чисел

    program tip_file;

    type

    complex=record

    d,m:real;

    end

    var x:complex;

    f1:text;

    f2:file of complex;

    i:byte;

    begin

    assign(f1,’tipfile.dat’); reset(f1);

    assign(f2,’tipfile.res’); rewrite(f2);

    while not eof(f1) do begin

    read(f1,x.d,x.m); write(f2,x);

    end;

    close(f10; close(f2);

    Прямой доступ

    При последовательном доступе чтение или запись очередного элемента файла возможны только после аналогичной операции с предыдущим элементом. Например, чтобы получить n-й элемент файла, требуется считать n-1 элементов. Бестиповые и компонентные файлы состоят из блоков одинакового размера. В бестиповом файле размер блока равен длине буфера, а в компонентном – длине компоненты. Это позволяет применить к таким файлам прямой доступ, при котором операции выполняются с заданным блоком. Прямой доступ применяется только для физических файлов, расположенных на дисках.

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

    Стандартные подпрограммы, используемые для реализации прямого доступа

    filepos(var f):longint

    Функция возвращет текущую позицию в файле f. Для только что открытого файла текущей позицией будет 0. После чтения или записи первого блока текущая позиция станет равно 1. После прочтения последней записи функция возвратит количесвто блоков в файле.

    filesize (var f):longint

    Функция возвращает количество блоков в открытом файле а

    seek(var f; n:longint)

    процедура выполняет установку текущей позиции в файле (позиционирование). В параметре n задается нмоер блока, к которому будет выполняться обращение. Блоки нумеруются с 0. Например, чтобы работать с четвертым блоком, необходимо задать значение n равное 3. Процедура seek работает с открытыми файлами.

    truncate(var f)

    процедура устанавливает в текущей позиции признак конца файла и удаляет все последующие блоки.

    Программа, которая выводит на экран заданную по номеру запись из файла, сформирвоанного в программе create_bfile:

    program ger_bfile;

    var buf:array[1..4] of real;

    f:file;

    i,k:integer;

    filename:string;

    begin

    {$i-}

    writeln(‘введите имя входного файла: ‘); readln(filename);

    assign(f,filename);

    reset(f,sizeof(real)*4);

    if i0result <>0 then begin

    writeln(‘файл ‘, filename, ‘не найден’); exit end;

    {$i+}

    while true do begin

    write(‘введите номер записи или -1 для окончания’);

    readln(k);

    if (k>filesize(f)) or (k<0) then begin

    writeln(‘такой записи в файле нет’); exit end;

    seek(f,k);

    blockread(f,buf,1);

    for i:=1 to 4 do write(buf[i]:6:1);

    end;

    close(f);

    end.

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

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

    30 Процедуры передачи управления. Примеры

    В Паскале есть несколько стандартных процедур, изменяющих последовательность выполнения операторов:

    • break - завершает выполнение цикла, внутри которого записана;

    • continue - выполняет переход к следующей итерации цикла;

    • exit - выходит из программы или подпрограммы, внутри которой записана;

    • halt - немедленно завершает выполнение программы.

    program ch;

    const MaxIter = 500; { максимальное количество итераций }

    var x, eps : double; { аргумент и точность }

    c, y : double; { член ряда и его сумма }

    n : integer; { номер члена ряда }

    done : boolean; { признак достижения точности }

    begin

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

    readln(x, eps);

    done := true;

    c := 1; y := c; { первый член ряда и нач. значение суммы }

    n := 0;

    while abs(c) > eps do begin

    c := c * sqr(x) /(2 * n + 1)/(2 * n + 2);

    { очередной член ряда }

    y := y + c; { добавление члена ряда к сумме }

    inc(n);

    if n > MaxIter then begin { аварийный выход из цикла }

    writeln('Ряд расходится!');

    done := false; break

    end

    end;

    if done then

    writeln('Для аргумента ', x, ' значение функции: ', y, #13#10,

    'вычислено с точностью', eps, ' за ', n, ' итераций');

    readln;

    end.

    Оператор Go to

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

    Использование оператора безусловного перехода оправдано, как правило, в двух случаях:

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

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

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

    31 Совместимость типов

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

    • оба типа одинаковые

    • оба типа вещественные

    • оба типа целочисленные

    • один тип является поддиапазоном другого

    • оба типа являются отрезками одного и того же основного типа

    • оба типа являются множественными типами с совместимыми базовыми типами

    • один тип является строковым типом, другой – строковым или типом pchar

    • один тип – pointer, другой – любой тип указателя

    • один тип – pchar, другой – символьный массив с нулевой базоу вида array[0..X] of char (только при разрешении расширенного синтаксиса директивой {$X+}

    • оба типа являются указателями идетичных типов (только при разрешении расширенного синтаксиса директивой {$X+})/

    • оба типа являются процедурными с идентичными типами результатов, одинаковым числом параметров и соответствием между параметрами

    32 Совместимость по присваиванию

    Этот вид совместимости требуется при присваивании значений, например в операторе присваивания или при передаче значений в подпрограмму

    Значение типа Т1 является совместимым по присваиванию с типом Т2 (т.е. допустим оператор Т1:=Т2), если выполняется одно из следующих условий:

    • Т1 и Т2 – тождественные типы (кроме файловых или типов, содержащих элементы файлового типа).

    • Т1 и Т2 – совместимые порядковые типы, при этом значения типа Т2 попадают в диапазон возможных значений Т1.

    • Т1 и Т2 – вещественные типы, при этом значения типа Т2 попадают в диапазон возможных значений Т1.

    • Т1 – вещественный тип, а Т2 – целочисленный

    • Т1 и Т2 – строковые типы

    • Т1 – строковый тип, а Т2 – символьный (char)

    • Т1 и Т2 – совместимые множественные типы, при этом все значения типа Т2 попадают в диапазон возможных значений Т1

    • Т1 и Т2 – совместимые типы указателей

    • Т1 – тип char, а Т2 – строковая константа (только при разрешении расширенного синтаксиса директивой {$X+}

    • Т1 – тип char, а Т2 – символьный массив с нулевой базой array[0..n] of char (только при разрешении расширенного синтаксиса директивой {$X+}

    • Т1 и Т2 – совместимые процедурные типы

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

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

    33 Подпрограммы. Процедуры и функции. Примеры записи на Turbo Pascal

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

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

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

    inc(i); writeln(a, b, c); { вызовы процедур }

    y := sin(x) + 1; { вызов функции }

    Внутри подпрограмм можно описывать другие подпрограммы. Они доступны только из той подпрограммы, в которой они описаны. Рассмотрим правила описания подпрограмм.

    Процедуры

    Структура процедуры аналогична структуре основной программы:

    procedure имя [(список параметров)]; { заголовок }

    разделы описаний

    begin

    раздел операторов

    end;

    Пример 1

    Найти разность средних арифметических значений двух вещественных массивов из 10 элементов.

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

    program dif_average;

    const n = 10;

    type mas = array[1 .. n] of real;

    var a, b : mas;

    i : integer;

    dif, av_a, av_b : real;

    procedure average(x : mas; var av : real); {1}

    var i : integer;

    begin

    av := 0;

    for i := 1 to n do av := av + x[i];

    av := av / n;

    end; {2}

    begin

    for i := 1 to n do read(a[i]);

    for i := 1 to n do read(b[i]);

    average(a, av_a); {3}

    average(b, av_b); {4}

    dif := av_a - av_b;

    writeln('Разность значений ', dif:6:2)

    end.

    Описание процедуры average расположено в строках с {1} по {2}. В строках, помеченных цифрами {3} и {4}, эта процедура вызывается сначала для обработки массива а, затем - массива b. Эти массивы передаются а качестве аргументов. Результат вычисления среднего арифметического возвращается в главную программу через второй параметр процедуры.

    Функции

    Описание функции отличается от описания процедуры незначительно:

    function имя [(список параметров)] : тип; { заголовок }

    разделы описаний

    begin

    раздел операторов

    имя := выражение;

    end;

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

    Найти разность средних арифметических значений двух вещественных массивов из 10 элементов.

    program dif_average1;

    const n = 3;

    type mas = array[1 .. n] of real;

    var

    a, b : mas;

    i : integer;

    dif : real;

    function average(x : mas) : real; {1}

    var i : integer; {2}

    av : real;

    begin

    av := 0;

    for i := 1 to n do av := av + x[i];

    average := av / n; {3}

    end;

    begin

    for i := 1 to n do read(a[i]);

    for i := 1 to n do read(b[i]);

    dif := average(a) - average(b); {4}

    writeln('Разность значений ', dif:6:2)

    end.

    Оператор, помеченный комментарием {1}, представляет собой заголовок функции. Тип функции определен как вещественный, потому что такой тип имеет среднее арифметическое элементов вещественного массива. Оператор {3} присваивает вычисленное значение имени функции. В операторе {4} функция вызывается дважды: сначала для одного массива, затем для другого.

    34 Глобальные и локальные переменные

    В IBM PC-совместимых компьютерах память условно разделена на так называемые сегменты. Адрес каждого байта составляется из номера сегмента и смещения относительно его начала.

    Длина адресов сегмента и смещения - 16 бит, поэтому размер сегмента не может превышать 216 байт (64K). При вычислении адреса байта в оперативной памяти адрес сегмента сдвигается на 4 двоичных разряда влево, и к нему прибавляется смещение. Таким образом, длина адреса составляет 20 бит, и с помощью него можно адресовать память объемом 220 байт (1 мегабайт).

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

    Адреса сегментов хранятся во время выполнения программы в сегментных регистрах: CS – адрес сегмента кода, DS – адрес сегмента данных, SS – адрес сегмента стека.

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

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

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

    ВНИМАНИЕ Подпрограмму надо писать таким образом, чтобы вся необходимая для ее использования информация содержалась в ее заголовке.

    35 Структура исполняемой программы в ОП

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

    Программа на языке Pascal состоит из строк. Набор текста программы осуществляется с помощью встроенного редактора текстов системы программирования Turbo Pascal или любого другого редактора. В первом случае программа может после выхода из редактора (при нажатии клавиши F10) в главное меню компилироваться и выполняться; во втором случае программу следует записать в файл и затем вызвать для компиляции и выполнения в интегрированной среде программирования Turbo Pascal.

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

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

    Можно рассмотреть следующую схему:

    – зарезервированные слова program, procedure, function пишутся строчными буквами;

    – имена констант, переменных, процедур, функций начинаются с прописных букв;

    – операторы записываются только строчными буквами;

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

    Такая схема записи создает условия для лучшего понимания программы и значительно более быстрого обнаружения в ее тексте ошибок. Следует учитывать, что максимальный размер программы на Pascal ограничен. Компилятор позволяет обрабатывать программы и библиотечные модули, в которых объем данных и генерируемый машинный код не превышают 64 Кбайт каждый. Если программа требует большего количества памяти, следует использовать библиотечные модули (.TPU-файлы) или оверлейные структуры.

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

    Синтаксически программа состоит из необязательного заголовка и блока.

    Блок может содержать в себе другие блоки. Блок состоит из двух частей: описательной и исполнительной. Первая часть может отсутствовать, без второй блок не имеет смысла. Блок, который не входит ни в какой другой блок, называется глобальным. Если глобальный блок содержит другие блоки, то они называются локальными. Глобальный блок — это основная программа, он должен присутствовать в любом случае. Локальные блоки — это процедуры и функции, их присутствие необязательно. Объекты программы (типы, переменные, константы и т. д.) тоже называются глобальными и локальными. Областью действия объектов является блок, в котором они описаны, и все вложенные в него блоки.

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

    Исходя из этого можно записать структуру программы следующим образом: 

    Program ... ; { Заголовок программы }

    Uses ... ; { Подключение модулей }

    Label ... ; { Раздел объявления меток }

    Const ... ; { Раздел объявления констант }

    Type ... ; { Раздел объявления новых типов }

    Var ... ; { Раздел объявления переменных }

    Procedure ... ; { Описание своих процедур }

    Function ... ; { Описание своих функций }

    Begin { начало основной программы }

    ...;

    { Операторы }

    ...;

    End.

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

    ПРИМЕР : Простейшая программа.

    program prim_1; { демонстрация структуры программы}

    {эта программа не требует никаких объявлений и описаний}

    begin

    write('Привет! Вот мы и начали.') (* эта строка текста появится на экране *)

    end.

    36 Виды параметров подпрограмм

    Список параметров, то есть величин, передаваемых в подпрограмму и обратно, содержится в ее заголовке. Для каждого параметра обычно задается его имя, тип и способ передачи. Либо тип, либо способ передачи могут не указываться.

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

    В Паскале четыре вида параметров:

    • значения;

    • переменные;

    • константы;

    • нетипизированные параметры.

    Кроме того, по другим критериям можно выделить особые виды параметров:

    • открытые массивы и строки;

    • процедурные и функциональные параметры;

    • объекты.

    Параметры-значения

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

    имя : тип;

    Например, передача в процедуру Р величины целого типа записывается так:

    procedure P(x : integer);

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

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

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

    Например, если в вызывающей программе описаны переменные

    var x : integer;

    c : byte;

    y : longint;

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

    P(x); P(c); P(y); P(200); P(x div 4 + 1);

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

    Параметры-переменные

    Признаком параметра-переменной является ключевое слово var перед описанием параметра:

    var имя : тип;

    Например, передача в процедуру Р параметра-переменной целого типа записывается так:

    procedure P(var x : integer);

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

    ВНИМАНИЕ При вызове подпрограммы на месте параметра-переменной может находиться только ссылка на переменную точно того же типа.

    Проиллюстрируем передачу параметров-значений и параметров-переменных на примере.

    ar a, b, c, d, e : word;

    procedure X(a, b, c : word; var d : word);

    var e : word;

    begin

    c := a + b; d := c; e := c;

    writeln ('Подпрограмма:');

    writeln ('c = ', c, ' d = ', d, ' e = ', e);

    end;

    begin

    a := 3; b := 5;

    x(a, b, c, d);

    writeln ('Главная программа:');

    writeln ('c = ', c, ' d = ', d, ' e = ', e);

    end.

    Результаты работы этой программы приведены ниже:

    Подпрограмма:

    c = 8 d = 8 e = 8

    Главная программа:

    c = 0 d = 8 e = 0

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

    Параметры-константы

    Параметр-константу можно узнать по ключевому слову const перед описанием параметра:

    const имя : тип;

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

    Например, передача в процедуру Р параметра-константы целого типа записывается так:

    procedure P(const x : integer);

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

    Параметры составных типов (массивы, записи, строки) предпочтительнее передавать как константы, потому что при этом не расходуется время на копирование и место в стеке.

    Результаты работы процедуры следует передавать через параметры-переменные, результат функции - через ее имя.

    Нетипизированные параметры

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

    procedure P(const a, b; var y);

    Есть одно важное ограничение: передать-то их можно, а вот делать с ними в подпрограмме что-либо до тех пор, пока они не приведены к какому-то определенному типу, все равно нельзя!

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

    Function EQ(const x, y; size : word) : boolean;

    type mas_byte = array[0 .. MaxInt] of byte;

    var n : integer;

    begin

    n := 0;

    while (n < size) and (mas_byte(x)[n] = mas_byte(y)[n]) do inc(n);

    EQ := n = size;

    end;

    В эту функцию фактически передаются только адреса начала расположения в памяти двух переменных, поэтому необходим еще один параметр: длина сравниваемых величин в байтах (параметр size). Единственный способ выяснить, равны ли две величины, размер которых заранее не известен - их побайтное сравнение, поэтому оба параметра приводятся к типу mas_byte, объявленному в функции. При описании массива используется стандартная константа MaxInt, в которой хранится максимальное значение для величин типа integer, то есть 32767.

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

    var a, b : array [1 .. 10] of byte; x: real; c: string;

    Следующие обращения к функции EQ будут корректны:

    EQ(a, b, sizeof(a)) { сравнение двух массивов }

    EQ(a[2], b[5], 4) { сравнение 2-5 элементов массива "a" с 5-8 элементами

    массива "b", соответственно }

    Открытые массивы и строки

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

    procedure P(a : array of real);

    Элементы массива нумеруются с нуля. Номер максимального элемента в массиве можно определить с помощью функции High.

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

    function max_el(const mas : array of integer) : integer;

    var i, max : integer;

    begin

    max := mas[0];

    for i := 0 to High(mas) do

    if mas[i] > max then max := mas[i];

    max_el := max;

    end;

    Для передачи в подпрограмму по адресу строк любой длины используется либо специальный тип OpenString, называемый открытой строкой, либо тип string при включенном режиме {$P+} (по умолчанию этот режим выключен).

    Пример передачи строк в подпрограмму:

    type s20 = string[20];

    var s1 : string[40];

    s2 : string[10];

    procedure P(const x : s20; y : string; var z : openstring);

    ...

    begin

    ... P(s2, s1, s1); ...

    end.

    37 Примеры передачи двух основных видом параметров подпрограмм. Их отличие

    38 Рекурсивные подпрограммы. Пример функции n!

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

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

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

    Простой пример рекурсивной функции - вычисление факториала. Чтобы получить значение факториала числа n, требуется умножить на n факториал числа (n - 1). Известно также, что 0! = 1 и 1! = 1.

    function fact(n : byte) : longint;

    begin

    if (n = 0) or (n = 1) then fact := 1

    else fact := n * fact(n - 1);

    end;

    Рассмотрим, что происходит при вызове этой функции при n = 3. В стеке отводится место под параметр n, ему присваивается значение 3 и начинается выполнение функции. Условие в операторе if ложно, поэтому управление передается на ветвь else. Для вычисления выражения n * fact(n - 1) требуется повторно вызвать функцию fact. Для этого в стеке отводится новое место под параметр n, ему присваивается значение 2, и выполнение функции начинается сначала. В третий раз функция вызывается со значением параметра, равным 1, и вот тут-то становится истинным выражение (n = 0) or (n = 1), поэтому происходит возврат из подпрограммы в точку вызова, то есть на выражение n * fact(n - 1) для n = 2. Результат выражения присваивается имени функции и передается в точку ее вызова, то есть в то же выражение, только теперь происходит обращение к параметру n, равному 3.

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

    39 Модули. Описание модулей. Использование модулей

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

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

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

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

    Описание модулей

    Исходный текст каждого модуля хранится в отдельном файле с расширением .pas. Общая структура модуля:

    unit имя; { заголовок модуля }

    interface { интерфейсная секция модуля }

    { описание глобальных

    элементов модуля

    (видимых извне) }

    implementation { секция реализации модуля }

    { описание локальных

    (внутренних) элементов

    модуля }

    begin { секция инициализации }

    { может отсутствовать }

    end.

    ВНИМАНИЕ Имя файла, в котором хранится модуль, должно совпадать с именем, заданным после ключевого слова unit.

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

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

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

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

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

    Для сохранения скомпилированного модуля на диске требуется установить значение пункта Destination меню Compile в значение Disk. Компилятор создаст файл с расширением .tpu.

    Пример описания модуля. Оформим в виде модуля подпрограмму вычисления среднего арифметического значения элементов массива.

    unit Average;

    interface

    const n = 10;

    type mas = array[1 .. n] of real;

    procedure average(x : mas; var av : real);

    implementation

    procedure average(x : mas; var av : real);

    var i : integer;

    begin

    av := 0;

    for i := 1 to n do av := av + x[i];

    av := av / n;

    end;

    end.

    Использование модулей

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

    program example;

    uses Average, Graph, Crt;

    ...

    Поиск модулей выполняется сначала в библиотеке исполняющей системы, затем в текущем каталоге, а после этого - в каталогах, заданных в диалоговом окне Options/Directories.

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

    40 Стандартные модули Turbo Pascal

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

    Модуль System

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

    Модуль Crt

    Модуль предназначен для организации эффективной работы с экраном, клавиатурой и встроенным динамиком. При подключении модуля Crt выводимая информация посылается в базовую систему ввода-вывода (ВIОS) или непосредственно в видеопамять.

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

    Рис. 1

    Под каждый символ отводится два байта: один байт занимает ASCII-код символа, другой байт хранит атрибуты символа: его цвет, цвет фона и признак мерцания (рис. 1). Можно получить восемь различных цветов фона и 16 цветов символов.

    Модуль Crt позволяет:

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

    • открывать на экране окна прямоугольной формы и выполнять вывод в пределах этих окон;

    • очищать экран, окно, строку и ее часть;

    • обрабатывать ввод с клавиатуры;

    • управлять встроенным динамиком.

    Работа с экраном

    Текущие цвета символа и фона задаются с помощью процедур TextColor и TextBackGround и действуют на следующие за ними процедуры вывода. Вывод выполняется в текущую позицию курсора. Для ее изменения служит процедура GotoXY.

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

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

    Программа "угадай число".

    program luck;

    uses crt;

    const max = 10;

    var

    i, k, n : integer;

    begin

    clrscr; { очистить экран }

    randomize; i := random(max); { загадать число }

    window(20, 5, 60, 20); { определить окно }

    TextBackGround(Blue); { цвет фона - синий }

    clrscr; { залить окно фоном }

    TextColor(LightGray); { цвет символов - серый }

    k := -1; { счетчик попыток }

    GotoXY(12, 5); writeln(' Введите число : ');

    repeat { цикл ввода ответа }

    GotoXY(20, 9); { установить курсор }

    readln(n); { ввести число }

    inc(k);

    until i = n;

    window(20, 22, 60, 24); { определить окно результата }

    TextAttr := 2 shl 4 + 14; { желтые символы за зеленом фоне }

    clrscr; { залить окно фоном }

    GotoXY(6, 2); { установить курсор }

    writeln(' Коэффициент невезучести : ', k / max :5:1);

    readkey; { ждать нажатия любой клавиши }

    TextAttr := 15; { белые символы на черном фоне }

    clrscr; { очистить после себя экран }

    end.

    Работа с клавиатурой

    Модуль Crt позволяет работать с управляющими клавишами и комбинациями клавиш. Нажатие каждой клавиши преобразуется либо в ее ASCII-код, либо в так называемый расширенный код (scan-код) и записывается в буфер клавиатуры, из которого затем и выбирается процедурами ввода. Под каждый код отводится два байта. Если нажатие клавиш соответствует символу из набора ASCII, в первый байт заносится код символа. Если нажата, к примеру, клавиша курсора, функциональная клавиша или комбинация клавиш с CTRL или ALT, то первый байт равен нулю, а во втором находится расширенный код, соответствующий этой комбинации.

    Для работы с клавиатурой модуль Crt содержит функции ReadKey и KeyPressed.

    Модули Dos и WinDos

    Модули Dos и WinDos содержат подпрограммы, реализующие возможности операционной системы MS-DOS - например, переименование, поиск и удаление файлов, получение и установку системного времени, выполнение программных прерываний и так далее. Эти подпрограммы в стандартном Паскале не определены. Для поддержки подпрограмм в модулях определены константы и типы данных.

    Модуль Dos использует строки Паскаля, а WinDos - строки с завершающим нулем.

    Модуль Graph

    Модуль обеспечивает работу с экраном в графическом режиме.

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

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

    Модуль Graph обеспечивает:

    • вывод линий и геометрических фигур заданным цветом и стилем;

    • закрашивание областей заданным цветом и шаблоном;

    • вывод текста различным шрифтом, заданного размера и направления;

    • определение окон и отсечение по их границе;

    • использование графических спрайтов и работу с графическими страницами.

    В отличие от текстового режима, в графическом курсор невидим.

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

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

    Структура графической программы

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

    • подключение модуля Graph;

    • перевод экрана в графический режим;

    • установку параметров изображения;

    • вывод изображения;

    • возврат в текстовый режим.

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

    program lines;

    uses Graph, Crt; { 1 }

    const

    grDriver : integer = Detect;

    size = 40;

    s2 = size div 2;

    s4 = size div 4;

    margin = 40;

    var

    grMode : integer;

    ErrCode: integer;

    HalfX, HalfY : integer;

    x, y, x1, y1, x2, y2, i : integer;

    begin

    randomize;

    { ---------------------------инициализация графики ----- }

    InitGraph(grDriver, grMode, 'd:\tp\bgi'); { 2 }

    ErrCode := GraphResult; { 3 }

    if ErrCode <> GrOK then begin

    writeln('Ошибка графики: ', GraphErrorMsg(ErrCode));

    exit end;

    { ------------------------------------ вывод линий ----- }

    HalfX := GetMaxX div 2; { 4 }

    HalfY := GetMaxY div 2;

    x := HalfX; x1:= x;

    y := HalfY; y1:= y;

    for i := 1 to 450 do begin { 5 }

    x2 := round(cos(0.05 * i) * HalfY) + HalfX;

    y2 := round(sin(0.02 * i) * HalfY) + HalfY;

    if (i mod 10) = 0 then SetColor(random(15) + 1);

    Line(x1, y1, x2, y2);

    Line(x, y, x2, y2);

    x1 := x2; y1 := y2;

    delay(5);

    end;

    { --------------------------- формирование спрайта ----- }

    SetColor(Cyan);

    x := margin; y := x;

    Circle(x + s2, y + s2, s2);

    SetFillStyle(InterLeaveFill, Green); { 6 }

    FillEllipse(x + s4,y + s4, s4, s4 div 2);

    FillEllipse(x + 3 * s4,y + s4, s4, s4 div 2);

    SetLineStyle(SolidLn, 0, ThickWidth); { 7 }

    Line(x + s2, y + s4, x + s2, y + s2);

    SetColor(Red);

    Arc(x + s2, y + s2, 200, 340, s4);

    Getmem(image, imagesize(x, y, x + size, y + size)); { 8 }

    GetImage(x, y, x + size, y + size, image^); { 9 }

    PutImage(x, y, image^, XorPut);

    { ------------------ вывод движущегося изображения ----- }

    while x < GetMaxX - margin - size do begin { 10 }

    PutImage(x, y, image^, XorPut);

    delay(20);

    PutImage(x, y, image^, XorPut);

    inc(x, 5);

    end;

    PutImage(x, y, image^, XorPut);

    { ----------------------------------- вывод текста ----- }

    SetColor(Cyan);

    SetTextStyle(GothicFont, HorizDir, 4); { 11 }

    OuttextXY(HalfX + margin, HalfY - margin, 'The end');

    readln;

    CloseGraph { 12 }

    end.

    Графическая библиотека подключается в операторе 1. В графический режим экран переводится в операторе 2 вызовом процедуры InitGraph. Ей надо передать три параметра: номер графического драйвера (grDriver), его режим grMode и путь к каталогу, в котором находятся драйверы.

    Если параметр grDriver равен константе Detect, заданной в модуле Graph, выбор режима выполняется автоматически.

    Если графический режим выбирался автоматически, для позиционирования изображений на экране необходимо получить доступное количество точек по X и по Y с помощью функций GetMaxX и GetMaxY (оператор 4). В данной программе с помощью этих функций формируются координаты центра экрана.

    В цикле (оператор 5) выводится серия линий с небольшой задержкой. Цвет линий изменяется случайным образом через каждые 10 итераций.

    Следующий фрагмент программы демонстрирует работу с графическими спрайтами, которые применяются для вывода движущихся изображений. Для увеличения скорости отрисовки изображение формируется один раз, после чего заносится в память с помощью процедуры GetImage (оператор 9). Объем памяти, необходимый для размещения спрайта, определяется с помощью процедуры ImageSize, выделение памяти выполняет процедура GetMem (оператор 8).

    При формировании изображения использована процедура установки стиля закраски SetFillStyle (оператор 6). Он используется процедурой рисования закрашенного эллипса FillEllipse. Стиль линии, задающий повышенную толщину линии, устанавливается процедурой SetLineStyle (оператор 7). Этот стиль действует при выводе отрезка (Line) и дуги (Arc).

    Для вывода спрайта используется процедура PutImage. Ее четвертый параметр задает способ сочетания выводимого изображения и фона. Операция исключающего ИЛИ (она задается константой XorPut), примененная дважды, позволяет оставить неизменным фон, по которому движется изображение (цикл 10).

    Перед выводом текста устанавливается его стиль (оператор 11). Стиль текста состоит из имени шрифта, его расположения (горизонтальное или вертикальное) и масштаба. В модуле Graph имеется один растровый шрифт и несколько векторных. Каждый символ растрового шрифта определяется точечной матрицей 8 х 8, символ векторного шрифта задается набором кривых.

    В конце программы восстанавливается исходный режим экрана (оператор 12).

    Модуль Strings

    Модуль предназначен для работы со строками, заканчивающимися нуль-символом, то есть символом с кодом 0 (их часто называют ASCIIZ-строки). Модуль содержит функции копирования, сравнения, слияния строк, преобразования их в строки типа string, поиска подстрок и символов.

    В модуле System определен тип pChar, представляющий собой указатель на символ (^Char). Этот тип можно использовать для работы со строками, заканчивающимися #0. Эти строки располагаются в динамической памяти, и программист должен сам заниматься ее распределением.

    Кроме того, для хранения ASCIIZ-строк используются массивы символов с нулевой базой, например:

    var str : array[0 .. 4000] of char;

    p : pChar;

    Массивы символов с нулевой базой и указатели на символы совместимы.

    41 Модуль Turbo Pascal - System

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

    42 Модуль Turbo Pascal - Crt

    Модуль предназначен для организации эффективной работы с экраном, клавиатурой и встроенным динамиком. При подключении модуля Crt выводимая информация посылается в базовую систему ввода-вывода (ВIОS) или непосредственно в видеопамять.

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

    Рис. 1

    Под каждый символ отводится два байта: один байт занимает ASCII-код символа, другой байт хранит атрибуты символа: его цвет, цвет фона и признак мерцания (рис. 1). Можно получить восемь различных цветов фона и 16 цветов символов.

    Модуль Crt позволяет:

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

    • открывать на экране окна прямоугольной формы и выполнять вывод в пределах этих окон;

    • очищать экран, окно, строку и ее часть;

    • обрабатывать ввод с клавиатуры;

    • управлять встроенным динамиком.

    Работа с экраном

    Текущие цвета символа и фона задаются с помощью процедур TextColor и TextBackGround и действуют на следующие за ними процедуры вывода. Вывод выполняется в текущую позицию курсора. Для ее изменения служит процедура GotoXY.

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

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

    Программа "угадай число".

    program luck;

    uses crt;

    const max = 10;

    var

    i, k, n : integer;

    begin

    clrscr; { очистить экран }

    randomize; i := random(max); { загадать число }

    window(20, 5, 60, 20); { определить окно }

    TextBackGround(Blue); { цвет фона - синий }

    clrscr; { залить окно фоном }

    TextColor(LightGray); { цвет символов - серый }

    k := -1; { счетчик попыток }

    GotoXY(12, 5); writeln(' Введите число : ');

    repeat { цикл ввода ответа }

    GotoXY(20, 9); { установить курсор }

    readln(n); { ввести число }

    inc(k);

    until i = n;

    window(20, 22, 60, 24); { определить окно результата }

    TextAttr := 2 shl 4 + 14; { желтые символы за зеленом фоне }

    clrscr; { залить окно фоном }

    GotoXY(6, 2); { установить курсор }

    writeln(' Коэффициент невезучести : ', k / max :5:1);

    readkey; { ждать нажатия любой клавиши }

    TextAttr := 15; { белые символы на черном фоне }

    clrscr; { очистить после себя экран }

    end.

    Работа с клавиатурой

    Модуль Crt позволяет работать с управляющими клавишами и комбинациями клавиш. Нажатие каждой клавиши преобразуется либо в ее ASCII-код, либо в так называемый расширенный код (scan-код) и записывается в буфер клавиатуры, из которого затем и выбирается процедурами ввода. Под каждый код отводится два байта. Если нажатие клавиш соответствует символу из набора ASCII, в первый байт заносится код символа. Если нажата, к примеру, клавиша курсора, функциональная клавиша или комбинация клавиш с CTRL или ALT, то первый байт равен нулю, а во втором находится расширенный код, соответствующий этой комбинации.

    Для работы с клавиатурой модуль Crt содержит функции ReadKey и KeyPressed.

    43 Модуль Turbo Pascal - Graph

    Модуль обеспечивает работу с экраном в графическом режиме.

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

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

    Модуль Graph обеспечивает:

    • вывод линий и геометрических фигур заданным цветом и стилем;

    • закрашивание областей заданным цветом и шаблоном;

    • вывод текста различным шрифтом, заданного размера и направления;

    • определение окон и отсечение по их границе;

    • использование графических спрайтов и работу с графическими страницами.

    В отличие от текстового режима, в графическом курсор невидим.

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

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

    Структура графической программы

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

    • подключение модуля Graph;

    • перевод экрана в графический режим;

    • установку параметров изображения;

    • вывод изображения;

    • возврат в текстовый режим.

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

    program lines;

    uses Graph, Crt; { 1 }

    const

    grDriver : integer = Detect;

    size = 40;

    s2 = size div 2;

    s4 = size div 4;

    margin = 40;

    var

    grMode : integer;

    ErrCode: integer;

    HalfX, HalfY : integer;

    x, y, x1, y1, x2, y2, i : integer;

    begin

    randomize;

    { ---------------------------инициализация графики ----- }

    InitGraph(grDriver, grMode, 'd:\tp\bgi'); { 2 }

    ErrCode := GraphResult; { 3 }

    if ErrCode <> GrOK then begin

    writeln('Ошибка графики: ', GraphErrorMsg(ErrCode));

    exit end;

    { ------------------------------------ вывод линий ----- }

    HalfX := GetMaxX div 2; { 4 }

    HalfY := GetMaxY div 2;

    x := HalfX; x1:= x;

    y := HalfY; y1:= y;

    for i := 1 to 450 do begin { 5 }

    x2 := round(cos(0.05 * i) * HalfY) + HalfX;

    y2 := round(sin(0.02 * i) * HalfY) + HalfY;

    if (i mod 10) = 0 then SetColor(random(15) + 1);

    Line(x1, y1, x2, y2);

    Line(x, y, x2, y2);

    x1 := x2; y1 := y2;

    delay(5);

    end;

    { --------------------------- формирование спрайта ----- }

    SetColor(Cyan);

    x := margin; y := x;

    Circle(x + s2, y + s2, s2);

    SetFillStyle(InterLeaveFill, Green); { 6 }

    FillEllipse(x + s4,y + s4, s4, s4 div 2);

    FillEllipse(x + 3 * s4,y + s4, s4, s4 div 2);

    SetLineStyle(SolidLn, 0, ThickWidth); { 7 }

    Line(x + s2, y + s4, x + s2, y + s2);

    SetColor(Red);

    Arc(x + s2, y + s2, 200, 340, s4);

    Getmem(image, imagesize(x, y, x + size, y + size)); { 8 }

    GetImage(x, y, x + size, y + size, image^); { 9 }

    PutImage(x, y, image^, XorPut);

    { ------------------ вывод движущегося изображения ----- }

    while x < GetMaxX - margin - size do begin { 10 }

    PutImage(x, y, image^, XorPut);

    delay(20);

    PutImage(x, y, image^, XorPut);

    inc(x, 5);

    end;

    PutImage(x, y, image^, XorPut);

    { ----------------------------------- вывод текста ----- }

    SetColor(Cyan);

    SetTextStyle(GothicFont, HorizDir, 4); { 11 }

    OuttextXY(HalfX + margin, HalfY - margin, 'The end');

    readln;

    CloseGraph { 12 }

    end.

    Графическая библиотека подключается в операторе 1. В графический режим экран переводится в операторе 2 вызовом процедуры InitGraph. Ей надо передать три параметра: номер графического драйвера (grDriver), его режим grMode и путь к каталогу, в котором находятся драйверы.

    Если параметр grDriver равен константе Detect, заданной в модуле Graph, выбор режима выполняется автоматически.

    Если графический режим выбирался автоматически, для позиционирования изображений на экране необходимо получить доступное количество точек по X и по Y с помощью функций GetMaxX и GetMaxY (оператор 4). В данной программе с помощью этих функций формируются координаты центра экрана.

    В цикле (оператор 5) выводится серия линий с небольшой задержкой. Цвет линий изменяется случайным образом через каждые 10 итераций.

    Следующий фрагмент программы демонстрирует работу с графическими спрайтами, которые применяются для вывода движущихся изображений. Для увеличения скорости отрисовки изображение формируется один раз, после чего заносится в память с помощью процедуры GetImage (оператор 9). Объем памяти, необходимый для размещения спрайта, определяется с помощью процедуры ImageSize, выделение памяти выполняет процедура GetMem (оператор 8).

    При формировании изображения использована процедура установки стиля закраски SetFillStyle (оператор 6). Он используется процедурой рисования закрашенного эллипса FillEllipse. Стиль линии, задающий повышенную толщину линии, устанавливается процедурой SetLineStyle (оператор 7). Этот стиль действует при выводе отрезка (Line) и дуги (Arc).

    Для вывода спрайта используется процедура PutImage. Ее четвертый параметр задает способ сочетания выводимого изображения и фона. Операция исключающего ИЛИ (она задается константой XorPut), примененная дважды, позволяет оставить неизменным фон, по которому движется изображение (цикл 10).

    Перед выводом текста устанавливается его стиль (оператор 11). Стиль текста состоит из имени шрифта, его расположения (горизонтальное или вертикальное) и масштаба. В модуле Graph имеется один растровый шрифт и несколько векторных. Каждый символ растрового шрифта определяется точечной матрицей 8 х 8, символ векторного шрифта задается набором кривых.

    В конце программы восстанавливается исходный режим экрана (оператор 12).

    44 Структура графической программы в Turbo Pascal

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

    • подключение модуля Graph;

    • перевод экрана в графический режим;

    • установку параметров изображения;

    • вывод изображения;

    • возврат в текстовый режим.

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

    program lines;

    uses Graph, Crt; { 1 }

    const

    grDriver : integer = Detect;

    size = 40;

    s2 = size div 2;

    s4 = size div 4;

    margin = 40;

    var

    grMode : integer;

    ErrCode: integer;

    HalfX, HalfY : integer;

    x, y, x1, y1, x2, y2, i : integer;

    begin

    randomize;

    { ---------------------------инициализация графики ----- }

    InitGraph(grDriver, grMode, 'd:\tp\bgi'); { 2 }

    ErrCode := GraphResult; { 3 }

    if ErrCode <> GrOK then begin

    writeln('Ошибка графики: ', GraphErrorMsg(ErrCode));

    exit end;

    { ------------------------------------ вывод линий ----- }

    HalfX := GetMaxX div 2; { 4 }

    HalfY := GetMaxY div 2;

    x := HalfX; x1:= x;

    y := HalfY; y1:= y;

    for i := 1 to 450 do begin { 5 }

    x2 := round(cos(0.05 * i) * HalfY) + HalfX;

    y2 := round(sin(0.02 * i) * HalfY) + HalfY;

    if (i mod 10) = 0 then SetColor(random(15) + 1);

    Line(x1, y1, x2, y2);

    Line(x, y, x2, y2);

    x1 := x2; y1 := y2;

    delay(5);

    end;

    { --------------------------- формирование спрайта ----- }

    SetColor(Cyan);

    x := margin; y := x;

    Circle(x + s2, y + s2, s2);

    SetFillStyle(InterLeaveFill, Green); { 6 }

    FillEllipse(x + s4,y + s4, s4, s4 div 2);

    FillEllipse(x + 3 * s4,y + s4, s4, s4 div 2);

    SetLineStyle(SolidLn, 0, ThickWidth); { 7 }

    Line(x + s2, y + s4, x + s2, y + s2);

    SetColor(Red);

    Arc(x + s2, y + s2, 200, 340, s4);

    Getmem(image, imagesize(x, y, x + size, y + size)); { 8 }

    GetImage(x, y, x + size, y + size, image^); { 9 }

    PutImage(x, y, image^, XorPut);

    { ------------------ вывод движущегося изображения ----- }

    while x < GetMaxX - margin - size do begin { 10 }

    PutImage(x, y, image^, XorPut);

    delay(20);

    PutImage(x, y, image^, XorPut);

    inc(x, 5);

    end;

    PutImage(x, y, image^, XorPut);

    { ----------------------------------- вывод текста ----- }

    SetColor(Cyan);

    SetTextStyle(GothicFont, HorizDir, 4); { 11 }

    OuttextXY(HalfX + margin, HalfY - margin, 'The end');

    readln;

    CloseGraph { 12 }

    end.

    Графическая библиотека подключается в операторе 1. В графический режим экран переводится в операторе 2 вызовом процедуры InitGraph. Ей надо передать три параметра: номер графического драйвера (grDriver), его режим grMode и путь к каталогу, в котором находятся драйверы.

    Если параметр grDriver равен константе Detect, заданной в модуле Graph, выбор режима выполняется автоматически.

    Если графический режим выбирался автоматически, для позиционирования изображений на экране необходимо получить доступное количество точек по X и по Y с помощью функций GetMaxX и GetMaxY (оператор 4). В данной программе с помощью этих функций формируются координаты центра экрана.

    В цикле (оператор 5) выводится серия линий с небольшой задержкой. Цвет линий изменяется случайным образом через каждые 10 итераций.

    Следующий фрагмент программы демонстрирует работу с графическими спрайтами, которые применяются для вывода движущихся изображений. Для увеличения скорости отрисовки изображение формируется один раз, после чего заносится в память с помощью процедуры GetImage (оператор 9). Объем памяти, необходимый для размещения спрайта, определяется с помощью процедуры ImageSize, выделение памяти выполняет процедура GetMem (оператор 8).

    При формировании изображения использована процедура установки стиля закраски SetFillStyle (оператор 6). Он используется процедурой рисования закрашенного эллипса FillEllipse. Стиль линии, задающий повышенную толщину линии, устанавливается процедурой SetLineStyle (оператор 7). Этот стиль действует при выводе отрезка (Line) и дуги (Arc).

    Для вывода спрайта используется процедура PutImage. Ее четвертый параметр задает способ сочетания выводимого изображения и фона. Операция исключающего ИЛИ (она задается константой XorPut), примененная дважды, позволяет оставить неизменным фон, по которому движется изображение (цикл 10).

    Перед выводом текста устанавливается его стиль (оператор 11). Стиль текста состоит из имени шрифта, его расположения (горизонтальное или вертикальное) и масштаба. В модуле Graph имеется один растровый шрифт и несколько векторных. Каждый символ растрового шрифта определяется точечной матрицей 8 х 8, символ векторного шрифта задается набором кривых.

    В конце программы восстанавливается исходный режим экрана (оператор 12).

    45 Этапы решения задач с помощью компьютера

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

    1. Постановка задачи:

      • сбоp инфоpмации о задаче;

      • фоpмулиpовка условия задачи;

      • опpеделение конечных целей pешения задачи;

      • определение формы выдачи результатов;

      • описание данных (их типов, диапазонов величин, структуры и т.п. ).

    2. Анализ и исследование задачи, модели:

      • анализ существующих аналогов;

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

      • pазpаботка математической модели;

      • разработка структур данных.

    3. Разработка алгоритма:

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

      • выбор формы записи алгоритма (блок-схемы, псевдокод и др.);

      • выбоp тестов и метода тестиpования;

      • проектирование алгоритма.

    4. Пpогpаммиpование:

      • выбор языка программирования;

      • уточнение способов организации данных;

      • запись алгоpитма на выбpанном языке пpогpаммиpования.

    5. Тестиpование и отладка:

      • синтаксическая отладка;

      • отладка семантики и логической стpуктуpы;

      • тестовые pасчеты и анализ pезультатов тестиpования;

      • совершенствование пpогpаммы.

    6. Анализ результатов решения задачи и уточнение в случае необходимости математической модели с повторным выполнением этапов 2 — 5.

    7. Сопровождение программы:

      • доработка программы для решения конкретных задач;

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

    46 Технология структурного программирования. Критерии качества программы

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

    Были сформулированы основные принципы проектирования и реализации программного обеспечения:

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

    • Собственно структурное программирование, рекомендующее определенные структуры алгоритмов и стиль программирования

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

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

    Декомпозиция программы с использованием метода пошаговой детализации выполняется следующим образом

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

    • Последовательности подзадач, например, ввод данных, преобразование данных, вывод данных

    • Альтернативы подзадач, например, добавление записей к файлу или их поиск

    • Повторения подзадачи, например, циклически повторяемая обработка данных

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

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

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

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

    2.     Надежность- способность программы безотказно выполнять определенные функции при заданных условиях в течение заданного периода времени.

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

    4.     Эффективность- отношение уровня услуг, предоставляемых пользователю к объему используемых ресурсов (времени, памяти)

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

    6.     Переносимость- способность программного продукта быть перенесенным из одной среды в другую (в частности, с одной аппаратной архитектуры на другую)

    7.     Добротность- программа должна быть добротно и рационально организована, не слишком переусложнена.

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

    47 Этапы создания структурной программы

    N

    Этапы программирования

    Выполнение

    1.

    Постановка задачи

    Составить программу для вычисления площади круга радиусом R.

    2.

    Математическое описание

    Расчетная формула: S=πR2

    3.

    Разработка алгоритма (структограммы)

    Описание R,S

    Ввод R

    Расчет S=πR2

    Вывод S

    4.

    Написание программы

    Program P1; { программа вычисления площади круга}

    Var r,S:real; {Описание переменных}

    Begin

    Read(R); {в этом месте программа останавливается, для ввода числового значения R}

    {R:=4;}{другой вариант ввода исходных данных}

    S:=3.14*Sqr(R); {расчет}

    {S:=Pi*sqr(R);} {другой вариант расчета}

    Writeln(‘R=’,R:3:1, ‘S=’,S:8:4); {Вывод}

    end.

    5.

    Отладка и получение результатов

    R= 4.0 S= 48.7654

    48 Правила программирования. Документирование программы

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

    0. САМЫЙ главный приоритет при разработке любой программы – это сохранение способности к развитию и повторному использованию. На практике только повторное использование кода может выявить ошибки и улучшить структуру (например, появление старых данных, но уже «нового» типа). Хорошая программа модифицируется перманентно.

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

    а) безопасной (прежний не портится) модификации УЖЕ существующего кода,

    б) возможность модификации и без исходного кода.

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

    С этой точки зрения главные требования к языку программирования (или стилю, которого следует придерживаться) –

    - хорошая читаемость;

    - замкнутость (явность кода);

    - быстрота компиляции проекта в целом, чтобы сразу увидеть результаты модификации.

    1.Оформление отдельных функций.

    - Пессимистическая точка зрения на входные переменные.

    - bool тип функций с изначальным результатом FALSE.

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

    - Желательность присваивания выходных переменных в самом конце, а в теле функции работа происходит с «внутренними копиями этих переменных», так чтобы вызывающая функция получила NIL в качестве результата, если в теле функции произошла ошибка.

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

    - При ручном управлении памятью -- постоянное использования предварительного заполнения NULL.

    2.Соглашения об именах переменных.и функций

    - Все глобальные переменные имеют начало “Gl”.

    - Следовать стандартным наименованиям функций: Free,Create,Init, Get, Set, Is и т.д.

    3.Методы фиксации ошибок.

    - Отладчик.

    - Организация потока сообщений об ошибках. Разные типы ошибок – идентификаторы опасных ошибок.

    - Использование trace файлов – чтобы грубо локализовать место краха.

    - Инструменты контроля утечек памяти (при ручном управлении памятью).

    - Assertions.

    - Способ согласования версий dll: хранение SizeOf(UsedRecord) как поля в записи передаваемой на вход dll.

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

    Когда программист-разработчик получает в той или иной форме задание на программирование, перед ним, перед руководителем проекта и перед всей проектной группой встают вопросы: что должно быть сделано, кроме собственно программы? что и как должно быть оформлено в виде документации? что передавать пользователям, а что — службе сопровождения? как управлять всем этим процессом? Кроме упомянутых вопросов есть и другие, например, что должно входить в само задание на программирование? Прошло много лет, программирование происходит в среде совершенно новых технологий, многие программисты, работая в стиле drag-and-drop, могут годами не видеть текст своих программ. Это не значит, что исчезла необходимость в их документировании. Более того, вопросы о наличии хоть какой-то системы, регламентирующей эту сторону создания программных средств, продолжают задавать постоянно. Спрашивают и о том, есть ли обязательные для применения стандарты (особенно остро стоит этот вопрос, когда разработка выполняется по заказу государственной организации или предприятия). Интересуются и тем, где можно купить имеющиеся стандарты.

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

  • Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]