1. ЭЛЕМЕНТЫ ЯЗЫКА PASCAL АЛФАВИТ Алфавит языка Турбо Паскаль включает буквы, цифры, шестнадцатеричные цифры, специальные символы, пробелы и зарезервированные слова. Буквы – это буквы латинского алфавита от a z и от А до Z, а так же знак подчеркивания. В Турбо Паскале нет различия между прописными и строчными буквами алфавита, если только они не входят в символьные и строковые выражения. Цифры – арабские цифры от 0 до 9. Каждая шестнадцатеричная цифра имеет значение от 0 до 15. Первые 10 значений обозначаются арабскими цифрами 0..9, остальные шесть – латинскими буквами A..F, или a..f. Специальные символы – это символы +-*/=,.:;<>[](){}^@$# а также пары символов <> <= >= := (* *) (. .) В Турбо Паскале имеются следующие зарезервированные слова: and, end, begin, const, do, if, else, for, goto, while и т.д. 1.2 Идентификаторы Идентификаторы – это имена констант, переменных, типов, процедур, функций и т.д. В качестве идентификатора можно использовать любые последовательности символов, которые удовлетворяют следующим ограничениям: Идентификатор может состоять из букв латинского алфавита, цифр, знака подчеркивания; Идентификатор не может начинаться с цифры; Идентификатор не может совпадать ни с одним из зарезервированных слов; Длина идентификатора может быть произвольной, но значащими считаются первые 63 символа. В Турбо Паскале игнорируется различие в высоте букв (заглавные или строчные), если только это не связано с текстовыми константами. Поэтому, например, идентификаторы Text, text и TEXT с точки зрения компилятора идентичны. 1.3 ТИПЫ ДАННЫХ Описать идентификатор – это значит указать тип связанного с ним объекта (константы, переменной). Т.е. данные (константы, переменные, значения функций) характеризуются своими типами. Тип определяет: - допустимые значения, которые может иметь объект; - допустимые операции, которые применимы к объекту; - формат внутреннего представления объекта в памяти компьютера. Основные типы данных: INTEGER – целочисленные данные, во внутреннем представлении занимают 2 байта; диапазон возможных значений от -32768 до +32767. REAL – вещественные данные, занимают 6 байт; диапазон возможных значений от 2.9Е-39 до +1.7Е+38. CHAR – символ, занимает 1 байт. STRING – строка символов, занимает MAX+1 байт, где MAX – максимальное число символов в строке. BOOLEAN – логический тип, занимает 1 байт и имеет два значения: FALSE (ложь) и TRUE (истина). 1.4. КОНСТАНТЫ. ПЕРЕМЕННЫЕ Константа – это объект программы, который не может изменять своего значения. Тип константы определяется способом записи ее значения: Const C1=17; целая константа C2=3.14; C3=’A’; C4=”Text”; C5=False; вещественная символьная строковая логическая Переменная именует объект программы, который может изменять свое значение в ходе выполнения программы. При описании переменной за идентификатором ставится двоеточие и имя типа. В начале раздела описания переменных должно стоять зарезервированное слово Var. Var Sigma : real; A, B : integer; C, D : char; Text : string; Flag : Boolean; 1.5 СТРУКТУРА PASCAL-ПРОГРАММЫ Структура программы на языке Паскаль имеет следующий вид: Program Имя_Программы; {Раздел описаний} Begin {раздел операторов} End. Программа на Паскале начинается словом Program и содержит объявление имени программы. Слово Program зарезервировано, т.е. не может использоваться ни в каких иных целях, кроме как для объявления имени программы. Строка Program Имя_Программы; заканчивается особым разделителем – точкой с запятой. Этот разделитель отмечает конец оператора или описания. Слова Program, Begin и End выделяют две части программы – раздел описаний и раздел операторов. Раздел описаний не связан с какими-либо конкретными действиями. Он сообщает компилятору некоторые сведения о самой программе и использующихся в нем объектах. В разделе описаний должны содержаться все описания всех идентификаторов, используемых в разделе исполняемых операторов. В разделе описаний объявляются идентификаторы типов, объектов, констант, переменных, а так же метки, процедуры и функции. Описанию типов и объектов должно предшествовать зарезервированное слово Type, описанию констант – Const, переменных – Var, меток – Lable. Слово Begin сигнализирует компилятору о начале раздела операторов. Завершает программу слово End с точкой. Program Input-Output; {Программа вводит два целых числа и выводит частное от деления первого на второе} Var N1, N2 : integer; X : real; Begin Write(‘N1=’); ReadLn(N1); Write(‘N2=’); ReadLn(N2); X:=N1/N2; WriteLn(‘N1/N2=’, X); End. Для вывода данных в Паскале предусмотрены операторы (специальные стандартные процедуры) Write() и WriteLn(). По сути эти операторы являются операторами обращения в встроенным процедурам вывода данных. Процедура – это некоторая последовательность операторов, к которой можно обратиться по имени. Всякий раз, когда мы называем в операторе имя процедуры, инициируется последовательность запрограммированных в ней действий. Имя процедуры вывода не является зарезервированным словом, и следовательно, пользователь может написать свою собственную процедуру с именем Write() или WriteLn(). При обращении к данным процедурам допускается использование произвольного числа параметров. Параметры передаются процедуре в виде списка в круглых скобках за именем процедуры. Write выводит информацию на экран и оставляет курсор в конце выведенной строки текста. WriteLn – после вывода информации осуществляет перевод строки и устанавливает курсор в начало следующей строки. Для ввода данных в Паскале предусмотрены операторы (специальные стандартные процедуры) Read() и ReadLn(). По данным операторам вызывается встроенные процедуры ввода данных и программа останавливается в ожидании ввода. Для вычисления отношения введенных чисел используется оператор присваивания :=. В левой части указывается имя переменной, правая часть представляет собой выражение. Комментарий – это произвольная последовательность символов, обрамленная фигурными скобками или парой символов (* - начало комментария и *) – конец комментария предназначенная для комментирования. 1.6 ПРЕОБРАЗОВАНИЕ ТИПОВ В Паскале преобразование типов следует использовать явно. Исключение сделано только в отношении констант и переменных целого типа, которые разрешается использовать в выражениях вещественного типа. Var X : integer; Y : real; То оператор Y:=X+2; будет синтаксически правильным. В то же время оператор X:=2.0 будет неверным, т.к. преобразование вещественного типа в целый запрещено. Для преобразования данных в языке предусмотрены встроенные функции, которые получают в качестве параметра значение одного типа а возвращают результат в виде значения другого типа. Как и процедура, функция вызывается своим именем и может содержать произвольное число операторов. Отличие функции от процедуры является то обстоятельство, что функция имеет собственное значение и, следовательно, может использоваться наравне с переменными в выражениях соответствующего типа. Для преобразования вещественного типа в целый имеются две встроенные функции – Round, которая округляет вещественное до ближайшего целого и Trunc, усекает вещественное путем отбрасывания дробной части. Для преобразования символьного типа в целое число предназначена функция Ord, обратное преобразование осуществляет функция Chr. Program Code; {Программа читает символ с клавиатуры и выводит на экран этот символ и соответствующий ему внутренний код} Var Ch : char; Begin Write(‘Введите символ’); ReadLn(Ch); WriteLn(ch, ‘=’, ord(ch)); End. 1.7 ВЫРАЖЕНИЯ. ОПЕРАЦИИ Из основных элементов из которых конструируется исполняемая часть программы (константы, переменные, обращения к функциям) с помощью знаков операций и скобок составляются выражения, которые фактически представляют собой правила получения новых значений. Операции: 1. Арифметические операции над переменными целого и вещественного типа + сложение - вычитание * умножение / деление вещественное div деление целочисленное (отбрасывание дробной части результата) Для целого типа существует операция mod – получение остатка от целочисленного деления (5 mod 2)=1. В Паскале отсутствует операция возведения в степень, однако это можно реализовать с помощью функции sqr, возвращающей квадрат от значения параметра. При работе с целыми существуют две процедуры: - Dec(x [,n]) – уменьшает содержимое переменной x на значение выражения n (если n не задано, то на 1). - Inc(x [,n]) – увеличивает значение x на значение выражения n (если n не задано, то на 1). 2. Над символами и строками символов определена единственная операция – сцепление двух строк (+). Остальные действия реализуются с помощью процедур и функций. 3. Над данными целого, вещественного, символьного и строкового типа определены следующие операции отношения = <> (не равно) < > <= >= В операциях сравнения должны участвовать однотипные операнды. Исключение составляют целый и вещественный типы, которые могут сравниваться друг с другом. Результат применения операции отношения к любым операндам имеет логический тип. Сравнение строк осуществляется следующим образом. Символы строк сравниваются попарно друг с другом так, что первый символ первой строки сравнивается с первым символом второй строки, второй символ первой строки со вторым символом второй строки и т.д. Символы сравниваются путем сравнения их кодов во внутреннем представлении. Отношение первой несовпадающей друг с другом пары символов и принимается за отношение двух строк. При сравнении данных логического типа учитывается, что false есть нулевой байт, а true – байт с единицей в младшем разряде. Функция ord преобразует к целому не только символы, но и логические величины: ord(true)=1. Операция отношения in применима к двум операндам. Левым операндом должно быть выражения целого, логического, символьного (перечисляемого, типа-диапазона) типа, правым – множество, состоящее из элементов того же типа, или идентификатор множественного типа. Операция даст результат истина, если левый операнд принадлежит множеству. 4. Логические операции not – логическое НЕ and – логическое И or – логическое ИЛИ xor – исключающее ИЛИ Применимы к операндам целого и логического типа. Если операнды целого типа – результат целое число, биты которого (двоичные разряды) формируются из битов операндов по определенным правилам. Если операнды логические данные – результат логического типа. К логическим операциям так же относят и две сдвиговые операции над целыми числами i shl j – сдвиг содержимого i на j разрядов влево; освободившиеся младшие разряды заполняются нулями. i shr j – сдвиг содержимого i на j разрядов вправо; освободившиеся старшие разряды заполняются нулями. 5. Операция @ применяется к операнду любого типа и возвращает результат типа Pointer, в котором содержится адрес операнда. При вычислении выражений приоритет вычислений определяется расставленными скобками, а при их отсутствии в порядке убывания приоритета. Приоритет 1 2 3 4 Операция not, @ *, /, div, mod, and, shl, shr +, -, or, xor =, <>, >, >=, <, <=, in 2. ОПЕРАТОРЫ 2.1. СОСТАВНОЙ И ПУСТОЙ ОПЕРАТОРЫ Составной оператор – это последовательность произвольных операторов программы, заключенная в операторные скобки – begin и end. Begin …… begin ….. end; ….. end; Пустой оператор не содержит никаких действий, просто в программу добавляется лишняя точка с запятой. 2.2. УСЛОВНЫЙ ОПЕРАТОР Условный оператор позволяет проверить некоторое условие и в зависимости от результатов проверки выполнить то или иное действие (это средство ветвления вычислительного процесса). Структура: If <условие> Then <оператор1> Else <оператор2> Вначале вычисляется условное выражение <условие>. Если результат есть истина, то выполняется оператор1, а оператор2 пропускается, если результат есть ложь, то оператор1 пропускается, а выполняется оператор2. Program Max; {Программа выводит максимальное из двух чисел} Var x, y, max : integer; begin Write(‘Vvod x’); Read(x); Write(‘Vvod max’); Read(max); if x>max then y:=x else y:=max; WriteLn(y); End. Часть Else условного оператора может быть опущена. Тогда при значении истина условного выражения выполняется оператор1, в противном случае этот оператор пропускается. 2.3. ОПЕРАТОРЫ ПОВТОРЕНИЙ 1. Счетный оператор цикла For: For <параметр цикла>:=<начальное значение> To <конечное значение> Do <оператор> Параметр цикла – переменная целого типа (точнее любого порядкового – целого, логического, символьного, перечисления, типа-диапазона). Вначале осуществляется присваивание начального значения параметру цикла. После этого циклически повторяется: Проверка условия параметр цикла <= конечное значение; если условие не выполнено, оператор For завершает работу. Если условие выполнено, выполняется оператор. Наращивание переменной параметр цикла на единицу. Program Sum; {Программа вводит целое положительное число N и подсчитывает сумму всех целых чисел от 1 до N} var i,n,s : integer; begin Write(‘N=’); ReadLn(n); s:=0; for i:=1 to n do s:=s+I; WriteLn(‘Сумма=’,s); End. Вторая форма оператора: For <параметр цикла>:=<начальное значение> DownTo <конечное значение> Do <оператор> Означает, что шаг наращивания параметра цикла равен (-1), а управляющее условие приобретает вид параметр цикла=конечное значение. 2. Оператор цикла While с предпроверкой условия: While <условие> Do <оператор> Условие – выражение логического типа. Если выражение условие имеет значение истина, то выполняется оператор, после чего вычисление выражения условие и его проверка повторяются. Если условие имеет значение ложь, оператор While прекращает свою работу. 3. Оператор цикла Reapit Until с постпроверкой условия: Reapit <оператор> Until <условие> Условие – выражение логического типа. Оператор выполняется хотя бы один раз, после чего вычисляется выражение условие. Если его значение есть ложь, оператор повторяется, в противном случае оператор Reapit Until завершает свою работу. 4. Для гибкого управления циклическими операторами в Паскале существуют две процедуры Break – реализует немедленный выход из цикла, управление передается оператору, стоящему сразу за концом циклического оператора. Continue – обеспечивает досрочное завершение очередного прохода цикла, эквивалент передачи управления в самый конец циклического оператора. 2.4. ОПЕРАТОР ВЫБОРА Оператор выбора позволяет выбрать одно из нескольких возможных продолжений программы. Параметр, по которому осуществляется выбор, служит ключ выбора – любого порядкового типа. Структура: Case <ключ выбора> Of <список выбора> [Else <операторы>] End Список выбора – это одна или более конструкций вида: <константа выбора> : <оператор>; Константа выбора – константа того же типа, что и выражение ключ выбора. Вначале вычисляется значение выражения <ключ выбора>, а затем в последовательности операторов <список выбора> отыскивается такой, которому предшествует константа, равная вычисленному значению. Найденный оператор выполняется, после чего оператор выбора завершает работу. Если в списке выбора не будет найдена константа, соответствующая вычисленному значению ключа выбора, управление передается оператору, стоящему за Else (часть Else может опускаться – тогда при отсутствии в списке выбора нужной константы ничего не произойдет и оператор выбора завершит работу). Program Calc; {Программа вводит два числа и один из знаков + - * / и выводит на экран результат арифметического действия} var operation : char; x, y, z : real; stop : boolean; {признак ошибочной операции и останова} begin stop:=false; repeat Write(‘x,y=’); ReadLn(x,y); Write(‘Операция’); ReadLn(operation); Case operation of ‘+’ : z:=x+y; ‘-’ : z:=x-y; ‘*’ : z:=x*y; ‘/’ : z:=x/y; else stop:=true; end; if not stop then WriteLn(‘Результат=’,z); Until stop End. 2.5 МЕТКИ И ОПЕРАТОРЫ ПЕРЕХОДА Оператор перехода Goto <метка> Метка – это произвольный идентификатор, позволяющий именовать некоторый оператор программы и таким образом ссылаться на него. Метка располагается непосредственно перед помеченным оператором и отделяется от него двоеточием. Перед тем как появиться в программе, метка должна быть описана. Описание меток состоит из зарезервированного слова Lable, за которым следует список меток Lable Lb1, Lb2; Begin … goto lb1; … lb1: lb2: … goto lb2; Действие оператора Goto состоит в передаче управления соответствующему меченому оператору. 4. МАССИВЫ В Турбо Паскале могут использоваться объекты, содержащие множество однотипных элементов. Это массивы – формальное объединение нескольких однотипных объектов (чисел, символов, строк и т.п.), рассматриваемое как единое целое. При описании массива необходимо указать общее число входящих в массив элементов и тип этих элементов. Var a : array [1..10] of real; b : array [0..40] of char; c : array [-2..2] of boolean; При описании массива используются зарезервированные слова Array Of. За словом Array в квадратных скобках указывается тип-диапазон, с помощью которого компилятор определяет общее число элементов массива. Тип-диапазон задается левой и правой границами изменения индекса массива, так что массив a состоит из 10 элементов, b – из 41, c – из 5. За словом Of указывается тип элементов, образующих массив. Доступ к каждому элементу массива в программе осуществляется с помощью индекса – целого числа (точнее выражения порядкового типа), служащим своеобразным именем элемента в массиве (если левая граница типа-диапазона равна 1, индекс элемента совпадает с его порядковым номером). При упоминании в программе любого элемента массива сразу за именем массива должен следовать индекс элемента в квадратных скобках. Var a : array [1..10] of real; b : array [0..40] of char; c : array [-2..2] of boolean; k : integer; begin b[17] :=’F’; c[-2]:=a[1]>a[2]; for k:=1 to 10 do a[k]:=0; … end. Индекс не должен выходить за пределы, определенные типом-диапазоном (нельзя использовать a[0], c[40]). Program Mas; {Программа создает массив из N случайных чисел, распределенных в диапазоне от 0 до MAX_VALUE-1, подсчитывает среднее арифметическое этих чисел, минимальное и максимальное из них} const N=1000; MAX_VALUE=100+1; Var m : array [1..N] of integer; i : integer; {индекс массива} max, min : integer; s : real; begin {наполняем массив случайными числами} for i:=1 to N do m[i]:=random(MAX_VALUE); {задаем начальное значение переменных} s:=0; max:=m[1]; min:=m[1]; {цикл вычисления суммы всех случайных чисел и поиска минимального и максимального} for i:=1 to N do begin s:=s+m[i]; if m[i]<min then min:=m[i] else if m[i]>max then max:=m[i] end; WriteLn(‘Min=’,min,’Max=’,max,’Sred=’,s/N) End. Функция random(Max) используется для создания массива и возвращает случайное целое число, равномерно распределенное от 0 до Max-1 (Max – параметр обращения). Количество элементов в списке индексных типов (размерность массива) не ограничено, однако суммарная длина внутреннего представления массива не может быть больше 65520 байт. В памяти компьютера элементы массива следуют друг за другом так, что при переходе от младших адресов к старшим наиболее быстро меняется самый правый индекс массива. Var A:array [1..2,1..2] of integer; Begin A[1,1]:=1; A[2,1]:=2; A[1,2]:=3; A[2,2]:=4; End. В памяти друг за другом будут расположены байты со значениями 1,3,2,4. Строка – это одномерный массив символов. К любому символу в строке можно обратиться как к элементу одномерного массива. Var St:string; Begin If st[5]=’A’ then End. Самый первый байт в строке имеет индекс 0 и содержит текущую длину строки. Первый значащий символ строки занимает второй байт и имеет индекс 1. 5. ПРОЦЕДУРЫ И ФУНКЦИИ Процедуры и функции представляют собой инструмент Турбо Паскаля, позволяющий писать хорошо структурированные программы (расчленненые на относительно самостоятельные фрагменты). В структурированных программах обычно легко прослеживается основной алгоритм, они проще в отладке и менее чувствительны к ошибкам программирования. Все эти свойства являются следствием особенности процедур (функций), каждая из которых представляет собой во многом самостоятельный фрагмент программы, связанный с основной программой лишь с помощью нескольких параметров. Самостоятельность процедур (функций) позволяет локализовать в них все детали программной реализации того или иного алгоритмического действия и поэтому изменение этих деталей обычно не приводит к изменениям основной программы. Процедурой называется особым образом оформленный фрагмент программы, имеющей собственное имя. Упоминание этого имени в тексте программы приводит к активизации процедуры и называется ее вызовом. Сразу после активизации процедуры начинают выполняться входящие в нее операторы, после выполнения последнего из них управление возвращается обратно в основную программу и выполняются операторы непосредственно стоящие за оператором вызова процедуры. Для обмена информацией между основной программой и процедурой используется один или насколько параметров вызова (параметры вызова могут и не использоваться). Если они есть, то они перечисляются в круглых скобках за именем процедуры и вместе с ним образуют оператор вызова процедуры. Функция отличается от процедуры тем, что результат ее работы возвращается в виде значения этой функции, и, следовательно, вызов функции может использоваться наряду с другими операторами в выражениях. С примерами процедур и функций мы уже встречались – это стандартные процедуры ввода-вывода данных, математические функции и др. Стандартными они называются потому, что созданы одновременно с системой Турбо Паскаля и являются ее неотьемлемой частью. Нестандартные процедуры и функции необходимо писать, чтобы компилятор мог установить связь между оператором вызова и теми действиями, которые предусмотрены в процедуре (функции). Описание процедуры (функции) помещается в разделе описаний. Program CharConvert; {Программа вводит текстовую строку, преобразует все входящие в нее буквы в прописные и выводит результат} Procedure UpString(s1:string; var s2:string); {Процедура преобразует буквы входной строки s1 в прописные буквы латинского алфавита и помещает результат преобразования в выходную строку s2. Предполагается, что последовательность букв образуют непрерывный массив. В соответствии с таблицей кодировки символов коды символов латинских строчных букв от а до z образуют непрерывный массив монотонно нарастающих чисел от 97 до 122, а коды соответствующих им прописных букв – непрерывный массив чисел от 65 до90. Преобразование строчных букв в прописные состоит в уменьшении кода буквы на 32} Var i:integer; c:char; {Рабочая переменная преобразования} begin s2:=’’; {вначале выходная строка пустая} {Цикл посимвольного анализа исходной строки} for i:=1 to Length(s1) do begin {Берем из входной строки очередной символ} c:=s1[i]; {Проверяем символ на принадлежность к массиву} if (c>=’a’) and (c<=’z’) then c:=chr(ord(‘A’)+ord(c)-ord(‘a’)); s2:=s2+c; end end; Var Sinp, Sout:String; {Исходная и преобразованная строки} Begin Write(‘Введите строку’); ReadLn(Sinp); UpString(Sinp, Sout); {Преобразуем введенную строку к прописным б} WriteLn(‘Результат’, Sout) End. Описание процедуры начинается словом Procedure за которым следует имя процедуры и список формальных параметров. Список параметров заключается в круглые скобки и содержит перечень параметров с указанием их типа. Перед параметром s2, с помощью которого в вызывающую программу возвращается результат преобразования, стоит зарезервированное слово Var. Именно таким способом компилятору указываются те параметры, в которых процедура возвращает вызвавшей ее программе результат своей работы. Procedure, имя и список параметров образуют заголовок процедуры. За заголовком следует тело процедуры, содержащее раздел описаний и раздел операторов. Второй способ реализации данной программы – оформим алгоритм преобразования в виде функции. Program CharConvert1; Function UpString(s1:string):string; Var i:integer; c:char; s2:string {Результат преобразования} begin s2:=’’; for i:=1 to Length(s1) do begin c:=UpCase(s1[i]); s2:=s2+c; end; UpString:=s2 {Присваиваем значение функции UpString } end; Var Sinp:String; Begin Write(‘Введите строку’); ReadLn(Sinp); WriteLn(‘Результат’, UpString(Sinp)) End. Функции UpString используется в качестве параметра обращения к другой процедуре (WriteLn). В теле любой функции необходимо осуществлять присваивание ей вычисленного значения (UpString:=s2). В левой части оператора присваивания в этом случае указывается имя функции. С помощью стандартной функции UpCase преобразуется каждый очередной символ латинского алфавита. 6. ЗАПИСИ Запись – это структура данных, состоящая из фиксированного числа компонентов, называемых полями записи. В отличие от массива, компоненты (поля) записи могут быть различного типа. Чтобы можно было ссылаться на тот или иной компонент записи, поля именуются. Структура: <имя типа> = Record <список полей> End Список полей – последовательность разделов записи, между которыми ставится точка с запятой. Каждый раздел записи состоит из одного или нескольких идентификаторов полей, отделяемых друг от друга запятыми. За идентификатором ставится двоеточие и описание типа поля. Type BirthDay = Record day, month : byte; year: integer End; Var a, b: BirthDay; Тип BirthDay есть запись с полями day, month, year. Переменные a, b содержат записи типа BirthDay. Значения переменных типа записи можно присвоить другим переменным того же типа: a:=b; К компонентам записи можно получить доступ, если использовать составное имя, т.е. указать имя переменной, затем точку и имя поля a.day:=27; b.year:=1990; Вложенные поля Type BirthDay = Record day, month : byte; year: integer End; Var c:Record name:string; bd:BirthDay end; begin … if c.bd.year=1990 then … end. Чтобы упростить доступ к полям записи, используется оператор присоединения With With <переменная> Do <оператор> With c.bd do month:=9; Это эквивалентно With c do with bd do month:=9; или With c,bd do month:=9; или c.bd.month:=9; 7. ФАЙЛЫ Под файлом понимается либо именованная область внешней памяти компьютера (дискета, жесткий диск, CD), либо логическое устройство – потенциальный источник или приемник информации. Любой файл имеет 3 характерные особенности. 1. У него есть имя, что дает возможность программе работать одновременно с несколькими файлами. Он содержит компоненты одного типа. Типом компонентов может быть любой тип Турбо Паскаля, кроме файлов. 3. Дли файла не оговаривается при его объявлении и ограничивается только емкостью устройств внешней памяти. Файловый тип или переменную файлового типа можно задавать одним из трех способов: 2. <имя> = File Of <тип>; <имя> = Text; <имя> = File; Type Text80=File of string [80]; Var F1: file of char; F2:text; F3:file; F4:text80; {типизированный} В зависимости от способа объявления можно выделить 3 вида файлов: Типизированные файлы (задаются File of) Текстовые файлы (определяются типом Text) Нетипизированные файлы (определяются типом File) Файлы, а также логические устройства становятся доступны программе после выполнения процедуры открытия файла (лог.устройства). Это процедура заключается в связывании ранее объявленной файловой переменной с именем существующего или вновь создаваемого файла, а также в указании направления обмена информацией: чтение из файла или запись в него. Assing (<файловая переменная>, <имя файла или лог. устройства>); Имя файла – выражение строкового типа, содержит до 8 разрешенных символов – прописные и строчные латинские буквы, цифры и символы ! @ # $ % ^ & () ~ - _`. За именем может следовать расширение – последовательность до 3 разрешенных символов. Расширение отделяется от имени точкой. Перед именем может указываться путь к файлу: имя диска, имя текущего каталога, имена каталогов вышестоящего уровня. Var finp:text; fout:file of string; consr name=’c:\dir\subdir\out.text’; begin assign(finp,’123.dat’); assign(fout,name); end. Инициировать файл означает указать для этого файла направление передачи данных. В Турбо Паскале можно открыть файл для чтения, для записи информации, а также для чтения и записи одновременно. Для чтения файл инициируется с помощью стандартной процедуры Reset(<файловая переменная>); При выполнении этой процедуры дисковый файл подготавливается к чтению информации. В результате специальная переменная – указатель, связанная с этим файлом, будет указывать на начало файла, т.е. на компонент с порядковым номером 0. Var f:file of char; begin assign(f, ‘file.dat’); {$I-} {Отключаем контроль ошибок ввода-вывода} reset(f) {$I+} {Включаем контроль ошибок ввода-вывода} if IOResult<>0 then … {Файл не существует} else … {Файл существует} end. С помощью директивы компилятора {$I-} отключается автоматический контроль ошибок вводавывода. Если этого не сделать, то отсутствие файла приведет к аварийному завершению работы. Если делается попытка инициировать чтение из несуществующего файла, возникает ошибка, которая может быть сообщена программе ненулевым значением встроенной функции IOResult. Разрешается обращаться к типизированным файлам, открытым процедурой Reset (для чтения) с помощью процедуры Write (для записи). Для текстовых файлов, открытых процедурой Reset, нельзя использовать процедуру Write или WriteLn. Стандартная процедура Rewrite (<файловая переменная>) инициирует запись информации в файл. Данной процедурой нельзя инициировать запись информации в ранее существующий файл – старый файл уничтожается и никаких сообщений об этом в программу не передается. Новый файл подготавливается к приему информации и его указатель принимает значение 0. Процедура Append (<файловая переменная>) Инициирует запись в ранее существующий текстовый файл для его расширения. При этом указатель файла устанавливается в его конец. Ее нельзя применять для типизированных и нетипизированных файлов. Если текстовый файл ранее уже был открыт с помощью Reset или Rewrite, использование Append приведет к закрытию этого файла и открытию его вновь, но уже для добавления записей. Процедуры и функции для работы с любого вида файлами: Close(<файловая переменная>) – закрывает файл. Rename(<файловая переменная>, <новое имя>) – переименовывает файл. Erase(<файловая переменная>) – уничтожает файл. EOF(<файловая переменная>) – функция тестирующая конец файла. Возвращает истина, если файловый указатель стоит в конце файла. При записи это означает, что очередной компонент будет добавлен в конец файла, при чтении – что файл исчерпан. ТЕКСТОВЫЕ ФАЙЛЫ Текстовые файлы связываются с файловыми переменными, принадлежащими стандартному типу Text. Предназначены для хранения текстовой информации (исходные тексты программ). Компоненты (записи) текстового файла могут иметь переменную длину. Текстовый файл – совокупность строк переменной длины. Доступ к каждой строке возможен лишь последовательно, начиная с первой. В конце каждой строки ставится специальный признак EOLN (конец строки), а в конце всего файла EOF(конец файла). Для доступа к записям применяются процедуры Read, ReadLn, Write, WriteLn. Ввод массива данных. Const N=100; Var f:text; m:array [1..N] of real; i:integer; begin assign(f,’prog.dat’); reset(f); i:=1; while not EOF(f) and (i<=N) do begin reaf(f,m[i]); inc(i) enf; close(f); … end. ТИПИЗИРОВАННЫЕ ФАЙЛЫ Длина компонента типизированного файла строго постоянна, что дает возможность организовать прямой доступ к каждому из них (доступ к компоненту по его порядковому номеру). Перед первым обращением к процедуре ввода-вывода указатель файла стоит в его начале и указывает на первый компонент с номером 0. После каждого чтения или записи указатель сдвигается к следующему компоненту файла. Процедуры: Read, Write. Seek(<файловая переменная>, <номер компонента>) – смещает указатель файла к требуемому компоненту. НЕТИПИЗИРОВАННЫЕ ФАЙЛЫ Нетипизированные файлы объявляются как файловые переменные типа File и отличаются тем, что для них не указан тип компонентов. Отсутствие типа делает эти файлы, с одной стороны, совместимыми с любыми другими файлами, а с другой – позволяет организовать высокоскоростной обмен между диском и памятью. При инициации нетипизированного файла процедурами Reset или Rewrite можно указать длину записи нетипизированного файла в байтах (максимальная длина - 65535). Var F:file; Begin Assign(F,’file.dat’); Reset(F,512); End. При работе с нетипизированными файлами могут применяться все процедуры и функции, доступные типизированным файлам, за исключением Read и Write, которые заменяются соответственно высокоскоростными процедурами BlockRead и BlockWrite. BlockRead(<файловая переменная>, <буфер>, <D>[,<NN>]) BlockWrite(<файловая переменная>, <буфер>, <D>[,<NN>]) Буфер – имя переменной, которая будет участвовать в обмене данными с дисками. D – количество записей, которые должны быть прочитаны или записаны за одно обращение к диску. 8. МОДУЛИ Модуль это автономно компилируемая единица программы, включающая в себя различные компоненты раздела описаний (типы, константы, переменные, процедуры и функции), и, возможно, некоторые исполняемые операторы инициирующей части. В модулях явным образом выделяется некоторая «видимая» интерфейсная часть, в которой сконцентрированы описания глобальных типов, констант, переменных, заголовки глобальных процедур и функций. Тела процедур и функций располагается в исполняемой части модуля, которая может быть скрыта от пользователя. Структура: Unit <имя модуля>; Interfase <интерфейсная часть> Implementation <исполняемая часть> Begin <инициирующая часть> End. Имя модуля служит для его связи с другими модулями и основной программой. Эта связь устанавливается с помощью ключевого слова Uses <список модулей> с которыми устанавливается связь Если Uses используется, то оно должно открывать раздел описаний основной программы. Uses CTR, Craph, Clobal; В интерфейсной части модуля содержится объявление всех глобальных объектов модуля (типов, констант и т.д.), которые должны стать доступными основной программе или другим модулям. При объявлении глобальных подпрограмм в интерфейсной части указывается только их заголовок. Unit Cmplx; Interface Type Complex=record re,im:real; end; Procedure Add(x,y:complex; var z:complex); Чтобы основной программе стал доступен тип Complex и процедура из модуля Cmplx, следует написать Uses Cmplx; Исполняемая часть содержит описания подпрограмм, объявленных в интерфейсной части. В ней могут объявляться локальные для модуля объекты – вспомогательные типы, константы, переменные и др., если они используются в инициирующей части. Описанию подпрограммы, объявленной в интерфейсной части модуля, в исполняемой части должен предшествовать заголовок, в котором можно опускать список формальных переменных (тип результата для функции), т.к. они описаны в интерфейсной части. Unit Cmplx; Interface Type Complex=record re,im:real; end; Procedure Add(x,y:complex; var z:complex); Implementation Procedure Add; Begin z.re:=x.re+y.re; z.im:=x.im+y.im; End; End. В инициирующей части размещаются исполняемые операторы, содержащие некоторый фрагмент программы. Эти операторы исполняются до передачи управления основной программе и обычно используются для подготовки ее работы. После объявления Uses программе станут доступны все объекты объявленные в интерфейсной части модуля Cmplx. Uses Cmplx; Var a,b,c:complex; begin a.re:=1; b.re:=1; a.im:=1; b.re:=1; Add(a,b,c); WriteLn(‘Сложение’, c.re,c.im); End.