Сложные типы данных в языке Pascal

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

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

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

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

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

Оглавление

Введение

Глава 1. Сложные типы данных в языке Pascal

1. Записи

1.1 Записи с вариантами

1.2 Оператор присоединения

1.3 Строки и средства их обработки

2. Файлы. Управление файлами

2.1 Основные задачи обработки файлов

2.2 Сортировка файлов

2.3 Задача корректировки файла

Глава 2. Сравнительный анализ обработки структур типа «файл» и «запись» в языках программирования высокого уровня Си++ и Паскаль

2.1 Сравнительный анализ обработки структур типа «файл»

2.1.1 Обработка структур типа «файл» в Паскале

2.1.2 Обработка структур типа «файл» в Си++

Файловый ввод-вывод с использованием потоков

2.2 Сравнительный анализ обработки структур типа «запись»

2.2.1 Обработка структур типа «запись» в Паскале

2.2.2 Обработка структур типа «запись» в Си++

2.3 Выводы сравнительного анализа

Заключение

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

Введение

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

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

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

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

Файл - динамическая структура данных, размер которой может меняться в процессе выполнения над ним каких-либо действий (он может быть равен нулю, что соответствует пустому файлу). Вообще-то, понятие файла используют и как абстракцию данных, хранящихся в памяти, что позволяет единообразно определить их общие характеристики и операции над ними. Однако свойства физического файла почти полностью совпадают со свойствами АТД файла, из-за чего абстракция в данном случае теряет весь смысл. Файл - структура, состоящая из последовательности компонент одного типа. Свойства последовательности определяет последовательный доступ к элементам, т.е. в каждый момент времени может быть доступен только один элемент файла. Основная операция над файлами - конкатенация (или слияние) файлов - позволяет создавать файлы неограниченной длины. Существует несколько видов файлов в Паскале. Текстовые файлы трактуются как последовательности строк переменной длины. В конце каждой строки ставится специальный признак конца строки EOLN. Типизированные файлы - последовательности компонент определенного типа. Длина любого элемента типизированного файла строго постоянна, что дает возможность организовать прямой доступ к каждому компоненту. В некоторых СП Паскаля это действие реализуется процедурой SEEK. Также, в отличие от текстовых файлов, здесь не работают процедуры READLN и WRITELN, поскольку нет нужды в переводе строки. Нетипизированные файлы объявляются предложением FILE и отличаются тем, что для них не указан тип компонент. Такой подход делает нетипизированные файловые переменные совместимыми с файлами любых типов, а также позволяет организовать высокоскоростной обмен данными между оперативной и внешней памятью. При инициации таких файлов процедурами RESET или REWRITE нужно указывать их длину в байтах, причем для достижения максимальной скорости обмена лучше, если эта длина кратна размеру физического сектора на внешней памяти.

Глава 1. Сложные типы данных в языке Pascal

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

Стандартные типы Типы, определяемые программистом

Integer; Перечисляемый тип;

Real; Скалярный тип.

Char;

Boolean.

С понятием простого типа связаны:

имя типа;

множество допустимых значений типа;

набор операций, определенных на типе;

набор отношений, определенных на типе;

набор функций, определенных или принимающих значения на типе;

Из данных простых типов можно конструировать данные сложных типов. Единственным (пока) примером сложных типов являются регулярные типы (значения - массивы). С понятием сложного типа связаны:

имя типа;

способ объединения данных в данное сложного типа;

способ доступа к данным, образующим сложное данное типа;

Type Vector = array [1..N] of Integer;

Var X: Vector;

Так, определение задает N целых чисел, объединенных в единое целое - массив c именем X. Доступ к компоненте массива осуществляется по его имени X и значению индексного выражения: X[i].

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

Это - комбинированный тип (записи), файловый тип (файлы), множественный тип (множества) и ссылочный тип (ссылки).

1. Записи

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

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

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

<комбинированный тип>::= Record < список описаний полей > End

<список полей>::= <фиксир. часть> | <фиксир. часть>;<вариант. часть> | <вариант. часть>

<фиксированная часть>::= <секция записи> {,<секция записи>}

< секция записи >::= <имя поля>{,<имя поля>}:< тип > <пусто>

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

Комбинированный

тип

Фиксированная секция

часть записи

Рис.1. Синтаксические диаграммы записей с вариантами

Примеры.

Пример 1

Type Complex = Record

Re, Im: Real

end;

Var z1, z2: Complex;

Пример 2

Type Name = array [1..15] of Char;

Student = Record

F1, F2, F3: Name;

Day: 1...31;

Month: 1...12;

Year: integer;

StudDoc: integer

end;

Var Group: array [1..25] of student;

S: Student;

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

1) z1.Re: = 2; z1.Im: = 3;

M := sqrt(sqr(z1.Re) + sqr(z1.Im));

2) S.F1:= Group[i].F1;

S.Year:= Group [i + 1].Year;

writeln(Group[i].StudDoc);

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

Пример 3

Type Name = array[1..20] of Char;

FullName = Record

Name1, Name2, Name3: Name

End;

Date = Record

Day : 1..31;

Month : 1..12;

Year : integer

end;

Student = Record

StudName: FullName;

BirthDay: Date;

StudDoc: integer

end;

Var StudGroup: Array [1..30] of Stugent;

A, B: Student;

Например, доступ к полю day переменной A возможен по имени A.BirthDay.Day, а к первой букве поля Name2 имени студента с номером 13 переменной StudGroup - по имени StudGroup[13]. StudName.Name2[1]

1.1. Записи с вариантами

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

Фиксированная часть

Фамилия Имя Отчество

{автора}

Название

{книги}

Издательство

{его атрибуты}

Шифр

{библиотеки}

Состояние

(выдана, в фонде, в архиве)

Вариантная часть

Значение признака

выдана

в фонде

в архиве

Поля Вариантной части

Фамилия И.О

N% {чит.билета}

Дата {выдачи}

адрес {хранения}

имя {архива}

адрес {хранения}

дата {архивации)

Синтаксис вариантной части:

<вариантная часть >::= case <поле признака> <имя типа> of < вариант >{;<вариант>}

<вариант>::=<список меток варианта>:(<список полей>) _ <пусто>

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

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

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

Вариантная

часть

поле

признака вариант

Рис. 2. Соответствующие синтаксические диаграммы

Описание типа записи в рассмотренном примере может иметь вид:

Пример 4

Book = record

Author: FullName; {фиксированная часть} BookName: String; BookCode: Code;

Station: (Readed, inFile, inArchive);

case Station of {поле признака}

Readed: Reader: FullName; {вариантная часть}

ReadCode: Integer;

ReadDate: Date;

inFile: FilAdress : Adress;

inArc: ArcName : Srting;

ArcAdress: Adress

end

end;

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

Type BookStation = (Readed, inFile, inArc);

Book = record

Author: FullName;

BookName: String;

BookCode: Code;

case Station : BookStation of

Readed: Reader: FullName;

ReadCode: Integer;

ReadDate: Date;

inFile: FilAdress: Adress;

inArc: ArcName : String;

ArcAdress: Adress

end

end;

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

EmptyVariant :() {EmptyVariant - метка пустого варианта}

1.2 Оператор присоединения

Если A - переменная типа Student из примера 1, ee значение можно изменить группой операторов:

A.F1: = 'Иванов '; A.F2: = 'Илья '; A.F3: = 'Иннокентьевич ';

A.Day:= 14; A.Month:= 9; A.Year:= 1976;

A.StudDoc: = 123;

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

With <переменная-запись> {<переменная-запись>} do <оператор>

Пример 5

with A do begin

F1: = 'Иванов `; F2: = 'Илья '; F3: = 'Иннокентьевич ';

Day: = 14; Month: = 9; Year: = 1976;

StudDoc: = 123;

end { оператора with }

Более того, в группе операторов обработки переменной StudGroup[i] (пример 3) запись может быть сформирована следующим образом:

With StudGroup [3], StudName do begin

Name1:= 'Иннокентьева'; Name2:= 'Инна '; Name3:= 'Ивановна ';

BirthDay.Day:= 14; BirthDay.Month:= 9; BirthDay.Year:= 1976;

StudDoc: = 123

end;

Таким образом, оператор вида

With r1,...,rn do S

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

With r1 do with r2 ... with rn do S.

Замечание: В операторе With R do S выражение R не должно содержать переменных, изменяемых в операторе S. Например, оператор With S[j] do j: = j + 1 недопустим!

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

Запись имеет вид:

Полное имя (Фамилия Имя Отчество)

День рождения (День, Месяц, Год)

Адрес (Индекс, Страна, Город, Улица, N дома, N кварт)

Program Adress;

Const n = 100;

Type

{описания типов Name, FullName, Date из примера 3 }

Mail = Record Index: LongInt; {длинное (4 байта) целое число}

Country, Sity, Street: Name;

House, Flat: Integer

end;

Person = Record

Who: FullName;

When: Date;

Where: Mail

end;

Var

Today: Date;

Department: array [1..N] of Person;

i: Integer;

Function theSame(var X : Date, var Y : Person): Boolean;

Begin

With Y, When do

theSame := (X.Day = Day) and (X.Month = Month)

End;

{Procedure ReadDepartment - ввод массива записей}

Procedure ReadDate(var Z : Date);

Begin

With Z do Read(Day, Month)

End;

Procedure WriteMail(var X : Person);

Begin

With X, Who do Writeln(Name1, ' ', Name2, ' ', Name3);

With X, Where do begin

Writeln(Street, ' ',House, ' ', Flat);

Writeln(Index, ' ', Sity, ' ', Country);

end

End;

Begin

ReadDepartment; { ввод массива записей }

ReadDate(Today);

For i := 1 to N do

if theSame(Today, Department[i])

then WriteMail(Department[i])

End;

1.3 Строки и средства их обработки

Значением строкового типа данных являются строки. Стандарт языка предусматривает использование строк только как констант, используемых в операторах вывода Write, Writeln. В расширении языка Turbo-Pascal строковый тип данных определен гораздо полнее.

Рис. 3. Определение строкового типа

Здесь целое принадлежит диапазону 1..255 и означает максимальное количество символов в строке этого типа. Если описание типа String используется без указания максимального количества символов, это (по умолчанию) означает, что под этот тип резервируется 255 символов.

Например:

Type Name = String[20]; { строки из 20-ти символов }

Post = String; { строки из 255-ти символов }

Процедуры и функции типа String.

Над строками определена операция конкатенации "+", результат которой - строка, в которой операнды соединены в порядке их следования в выражении. Например:

'Turbo' + 'Pascal' = 'TurboPascal'; 'Turbo_' + 'Pascal ' + 'System' = 'Turbo_Pascal System';

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

Пример сложения строк

X := 'Пример'; У := 'сложения'; Z := 'строк';

Writeln(X + Y + Z); Writeln(Y + ' ' + Z + ' ' + X)

Тип String допускает и пустую строку - строку, не содержащую символов: EmptyStr := '' {подряд идущие кавычки}. Она играет роль нуля (нейтрального элемента) операции конкатенации: EmptyStr + X = X + EmptyStr = X

Над строками определены также отношения (операции логического типа)

" = ", " <> ", " < ", " > ", " <= ", " >= ".

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

а) порядок на строках согласован с порядком, заданным на символьном типе (Char);

б) сравнение двух строк осуществляется посимвольно, начиная с первых символов;

в) если строка A есть начало строки B, то A < В;

г) пустая строка - наименьший элемент типа.

Например:

а) 'с' < 'k', так как Ord(`c') < Ord(`k');

б) 'abс' < 'abk', так как первые два символа строк совпадают, а сравнение третьих дает Ord(`c') < Ord(`k');

в) 'abс' < 'abkd', так как первые два символа строк совпадают, а сравнение третьих дает Ord(`c') < Ord(k);

г) 'ab' < 'abсd', так как строка 'ab'- начало строки 'abсd'.

На строковом типе данных определены:

Функции:

a) Length(X: String): Byte; - длина строки X; { Length(EmptyStr) = 0 }

б) Pos(Y:String; X:String):Byte; - позиция первого символа первого слева вхождения подстроки Y в строку X. Если X не содержит Y, Pos(Y, X) = 0.

в) Copy(X:String; Index, Count: Integer):String - подстрока строки X, начинающаяся с позиции Index и содержащая Count символов.

г) Concat(X1, X2, .., Xk: String): String; - конкатенация строк Х1, X2, .., Xk. Другая форма записи суммы X1+X2+ .. +Xk.

Процедуры:

д) Delete(var X: String; Index, Count: Integer); Из строки X удаляется Сount символов, начиная с позиции Index. Результат помещается в переменную X.

e) Insert(Y:string; var X: String; Index: Integer); В строку X вставляется строка Y, причем вставка осуществляется начиная с позиции Index.

Стандартные процедуры ввода-вывода Паскаля расширены для ввода-вывода строк. Отметим, однако, что для ввода нескольких строковых данных следует пользоваться оператором Readln. Оператор Read в этих случаях может вести себя непредсказуемо.

Пример 2. Дан массив A[1..n] of string[20]. Составить программу замены всех первых вхождений подстроки L в A[i] на подстроку R. Строки L и R вводятся с клавиатуры в виде равенства L = R. Результат замен отобразить в массив, элементы которого - равенства вида A[i]=результат замены L на R в A[i].

Program RewriteArray;

Const n = 100; Single = 20; Double = 41;

Type

Sitem = string[Single]; Ditem = string[Double];

SWordArray = array[1..n] of Sitem; DWordArray = array[1..n] of Ditem;

Var

A: SWordArray; B: DWordArray;

L, R: Sitem; X : Sitem;

i, Index : Integer;

Procedure InpWord(var U, V : Sitem);

Var X : Ditem;

j : Integer;

Begin

Writeln('________ Ввод равенства L = R __________');

Read(X); j := Pos('=', X);

U := Copy(X, 1, j - 1);

V := Copy(X, j + 1, Length(X))

End;

Procedure InpArray;

begin

Writeln('====== Ввод массива слов ======');

For i:=1 to n do Readln(A[i])

end;

Procedure OutArray;

begin

Writeln('====== Вывод массива слов ====');

For i:=1 to n do Writeln(B[i])

end;

Begin

InpArray; {ввод массива слов с клавиатуры}

InpWord(L, R); {ввод и анализ равенства L = R}

For i := 1 to n do begin

X := A[i]; Index := Pos(L, X);

If Index <> 0

then begin

Delete(X, Index, Length(L));

Insert(R, X, Index)

end;

B[i] := A[i] + '=' + X

end;

OutArray; {вывод массива слов на печать }

End.

2. Файлы. Управление файлами

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

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

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

В результате выполнения программы происходит преобразование одного текстового файла (называемого Input) в другой текстовый файл (называемый Output). Оба эти файла являются стандартными и служат для ввода/вывода данных.

Над файлами можно выполнять два явных вида действий:

1.Просмотр (чтение) файла.

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

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

Имена нестандартных файлов, используемых в программе, необходимо описывать в разделе переменных.

Рис. 4. Описание файлового типа

Файл, компоненты которого являются символами, называется текстовым и имеет стандартный тип Text:

Type Text = File of Char;

Примеры: Type

ExtClass = File of Person;CardList = File of Integer;

Var

F : Text;

Data : File of real;

List1, List2 : CardList;

Class10A, Class10B : ExtClass;

Для работы с нестандартными файлами имя файла должно быть отождествлено с реально существующим объектом - внешним устройством. Именно, если нам необходимо обработать данные из файла, находящегося на магнитном диске и имеющего (внешнее) имя D:\ExtName.dat, мы должны сообщить системе, что работая с файлом IntName (читая из него данные или записывая в него данные), мы работаем с файлом ExtName.dat, находящимся на диске D:.

Для отождествления внутреннего имени файла со внешним именем используется процедура Assign (< внутреннее имя >, < 'внешнее имя'>).

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

Процедура Rewrite(<имя файла>) - открывает файл для записи. Если файл ранее существовал, все данные, хранившиеся в нем, уничтожаются. Файл готов для записи первой компоненты.

Процедура Reset(<имя файла>) - открывает файл для чтения. Файл готов для чтения из него первой компоненты.

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

Для обмена данными с файлами используют процедуры Read и Writе.

Процедура Read(<имя файла>, <список ввода>) читает данные из файла (по умолчанию имя файла - Input). Список ввода - это список переменных.

Процедура Write(<имя файла>, <список вывода>) записывает данные в файл (по умолчанию имя файла - Output). Список вывода - это список выражений.

Если F - файл типа Text, то в списке ввода/вывода допустимы переменные/выражения типа Integer, Real, Char, String[N]. В других случаях типы всех компонент списка должны совпадать с типом компоненты файла.

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

Eof(F) (end of file) - стандартная функция - признак конца файла. Если файла F исчерпан, то Eof(F) = True, в противном случае Eof(F) = False.

Eoln(F) (End of line) - стандартная функция - признак конца строки текстового файла. Если строка текстового файла F исчерпана, то Eoln(F) = True, в противном случае Eoln(F) = False. Функция Eoln определена только для файлов типа Text. Обычно в программах используют либо текстовые файлы, либо файлы, компонентами которых являются структурированные данные (например, записи).

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

Пример 3. Программа формирования файла как выборки из компонент другого файла.

Пусть F - файл записей вида (поле ключа, поле данных). Требуется сформировать файл G, содержащий те компоненты F, ключи которых удовлетворяют условию: значение ключа - целое число из интервала ]Max, Min [.

Program FileForm;

Type Component = Record

Key: Integer; { поле ключа }

Data: String[20] { поле данных}

End;

OurFile = File of Component;

Var F, G : OurFile;

Max, Min : Integer;

X: Component;

Function Correct(var U: Component): Boolean;

begin

Correct := (U.Key < Max) and (U.Key > Min)

end;

Begin

Read(Max, Min);

Assign(F, 'D:InpFile.dat'); {определено значение F }

Assign(G, 'D:OutFile.dat'); {определено значение G }

Reset(F); {файл F открыт для чтения}

Rewrite(G); {файл G открыт для записи}

While not(Eof(F)) do begin {цикл чтения F - записи G}

Read(F, X);

If Correct(X) then Write(G, X)

end;

Close(G) {файл G закрыт}

End;

2.1 Основные задачи обработки файлов

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

Задача 1. Добавление элемента к файлу. Дан файл F и элемент X типа Component. Расширить F, включив в него компоненту X с сохранением упорядоченности.

Вот, наверное, единственно возможное решение:

Переписывать покомпонентно F в новый файл G до тех пор, пока F^.Key < X.Key ;

Записать X в G;

Переписать "хвост" файла F в G;

Переименовать G в F.

Задача 2. Удаление элемента из файла. Дан файл F и число K - значение ключа удаляемых элементов. Сократить F, удалив из него все компоненты с ключом K.

Решение аналогично решению задачи 1:

Переписывать покомпонентно F в новый файл G до тех пор, пока F^.Key < X.Key ;

Пока F^.Key = K читать F;

Переписать "хвост" файла F в G;

Переименовать G в F.

Отметим, что:

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

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

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

Задача 3. Слияние файлов. Даны файлы F и G. Требуется сформировать файл H, содержащий все компоненты как F, так и G.

Алгоритм состоит в последовательном и поочередном просмотре файлов F и G и записи очередной компоненты в H. Очередность определяется сравнением значений ключей компонент F и G. Оформим алгоритм в виде процедуры:

Procedure FileMerge(var F, G, H: OurFile);

Var X, Y : Component;

Flag : Boolean;

Procedure Step(var U:OurFile; var A, B:Component);

begin

Write(H, A);

If Eof(U)

then begin Write(H, B); Flag := False end

else Read(U, A)

end;

Procedure AppendTail(var U: Ourfile);

Var A: Component;

Begin

While not(Eof(U)) do begin

Read(U, A); Write(H, A)

end

end;

Begin

Reset(F); Reset(G); Rewrite(H);

Flag := True;

Read(F, X); Read(G, Y);

While Flag do

If X.Key < Y.Key

then Step(F, X, Y)

else Step(G, Y, X);

AppendTail(F);

AppendTail(G);

Close(H)

End;

Задача 4. Пересечение файлов. Даны файлы F и G. Требуется сформировать файл H, содержащий все компоненты, входящие как в F, так и в G.

Задача 5. Вычитание файлов. Даны файлы F и G. Требуется сформировать файл H, содержащий все компоненты входящие в F, но не входящие в G.

Решение этих задач аналогично решению задачи слияния файлов.

2.2 Сортировка файлов

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

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

Так, например, алгоритм сортировки простыми обменами требует N прогонов сортируемого файла (N - количество компонент файла). Алгоритм быстрой сортировки вообще не имеет смысла рассматривать, поскольку при его реализации необходимо было бы читать файл от конца к началу!

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

Алгоритм сортировки слиянием.

Пусть сортируемая последовательность F = { f1, ..., fN } представлена в виде двух уже отсортированных половин - F1 и F2. Тогда для сортировки F достаточно слить (т.е. применить аналог алгоритма слияния FileMerge) последовательности F1 и F2 в выходную последовательность G. Поскольку упорядоченные половинки F1 и F2 можно получить с помощью тех же действий, мы можем описать алгоритм сортировки слияниями рекурсивно. При этом, очевидно, необходимо использовать оптимальное количество промежуточных файлов. Поскольку слияния нужно начинать с однокомпонентных файлов, точная реализация описанного алгоритма потребует 2N дополнительных файлов, что, конечно, неприемлимо. Поэтому мы должны использовать один файл для хранения нескольких сливаемых подпоследовательностей. Уточним эту идею:

Пусть сортируемый файл F содержит k-элементные упорядоченные подпоследовательности A1, A2, ..., A2l, k = 2l.

1.Разделение F заключается в переписи подпоследовательностей Aj с четными номерами в файл F1, а с нечетными номерами - в файл F2.

Пусть файл F1 содержит k-элементные упорядоченные подпоследовательности B1, B3, ..., B2l-1, а F2 - k-элементные упорядоченные подпоследовательности B2, B4, ..., B2l.

2.Слияние F1 и F2 заключается в слияниях пар <Bi, Bi+1> в подпоследовательности A(i+1) div 2 в файл F. После обработки F будет содержать l 2k-элементных подпоследовательностей Aj.

Если N - степень 2-x (N = 2m), то после m-кратного повторения разделения-слияния, начиная с A1={f1}, ..., AN={fN}, файл F будет содержать отсортированную последовательность. В общем случае, когда N 2m, управление слияниями-разделениями немного усложняется:

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

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

Program MergeSort;

Type Component = Record

Key: Integer; { поле ключа }

Data: String[20] { поле данных}

End;

OurFile = File of Component;

Var F, F1, F2 : OurFile;

k, L, t, SizeF: Integer;

{Procedure FileOut(var F :OurFile);}

{Procedure FileInp(var F: Ourfile);}

Procedure CopyBlock(Var U, V: OurFile; k: Integer);

Var i: Integer;

X: Component;

Begin

For i := 1 to k do begin

Read(U, X); Write(V, X)

end

End;

{ разделение блоками по k компонент F ==> F1, F2 }

Procedure Partition(k: Integer);

Var i: Integer;

Begin

Reset(F); Rewrite(F1); Rewrite(F2);

For i:= 1 to L do

If Odd(i)

then CopyBlock(F, F1, k)

else CopyBlock(F, F2, k);

If Odd(L)

then CopyBlock(F, F2, t)

else CopyBlock(F, F1, t);

Close(F1); Close(F2)

End;

{ слияние блоками по k компонент F1, F2 ==> F }

Procedure Merge(k: Integer);

Var i: Integer;

Procedure MergeBlock(t: Integer);

Var count1, count2: Integer;

X1, X2: Component;

Flag: Boolean;

Procedure AppendTail(var U: Ourfile; var p: Integer; s: Integer);

Var A: Component;

Begin

While p <= s do begin

Read(U, A); Write(F, A); p := p + 1

end;

End { AppendTail };

Procedure Step(var U: OurFile; Var A, B: Component; var p, q: Integer; s: Integer);

begin

Write(F, A); p := p + 1;

If p <= s

then Read(U, A)

else begin Write(F, B); q := q + 1; Flag := False end

end { Step };

Begin { MergeBlock }

count1 := 1; count2 := 1; Flag := True;

Read(F1, X1); Read(F2, X2);

While Flag do

If X1.Key < X2.Key

then Step(F1, X1, X2, count1, count2, k)

else Step(F2, X2, X1, count2, count1, t);

AppendTail(F1, count1, k); AppendTail(F2, count2, t);

end { MergeBlock };

Begin { Merge }

Rewrite(F); Reset(F1); Reset(F2);

For i := 1 to (L div 2) do MergeBlock(k);

If t<> 0

then if Odd(L)

then MergeBlock(t)

else CopyBlock(F1, F, t)

else if Odd(L)

then CopyBlock(F1, F, k)

End { Merge };

Procedure FirstPartition;

Var X : Component;

Begin

Reset(F); Rewrite(F1); Rewrite(F2);

SizeF := 0;

While not(Eof(F)) do begin

Read(F, X); SizeF := Succ(SizeF);

If Odd(SizeF)

then Write(F1, X)

else Write(F2, X)

end;

Close(F1); Close(F2)

End { FirstPartition };

Begin {Определение внешних имен файлов F, F1, F2}

FileInp(F);

FirstPartition; {первое разделение с подсчетом SizeF}

L := SizeF; t := 0;

Merge(1); {первое слияние 1-блоков}

k := 2;

While k < SizeF do begin

L := SizeF div k; {количество полных k-блоков в F}

t := SizeF mod k; { размер неполного k-блока }

Partition(k);

Merge(k);

k := 2*k

end;

FileOut(F);

End.

Оценим сложность алгоритма в терминах С(n), M(n), L(n), где L(n) - число прогонов файла F и n = SizeF.

1.Оценка L(n).

L(n)= число разделений + число слияний. Каждое разделение - вызов процедуры Partition, а слияние - вызов Merge. Поэтому L(n) - удвоенное число повторений тела цикла While. Отсюда, поскольку переменная k, управляющая циклом, каждый раз увеличивается вдвое, на L-том шаге k = 2L, и, следовательно, L - наибольшее число такое, что 2L < n, т.е. L = [log2 n].

L(n) = 2[log2n]

2.Оценка С(n).

Сравнения копонент по ключу производятся при слиянии. После каждого сравнения выполняется процедура Step, которая записывает одну компоненту в F. Поэтому при каждом слиянии количество сравнений не превосходит n. Отсюда C(n) L(n)*n/2, т.е.

С(n) n [log2 n]

3.Оценка M(n).

Процедуры Partition и Merge пересылают компоненты файлов. Независимо от значений ключей вызов каждой из них либо читает F, либо записывает F. Поэтому M(n) = nL(n), т.е.

M(n) = 2n[log2 n]

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

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

а. Заметим, что процедура Partition носит вспомагательный характер. Не анализируя ключей, она просто формирует файлы F1 и F2 для слияния. Поэтому ее можно исключить, если процедуру Merge заставить формировать не F, а сразу F1 и F2. При этом, конечно, количество файлов в программе увеличится. Именно:

1.F разделим на (F1, F2).

2.Определим вспомогательные файлы G1, G2

3.Основной цикл алгоритма:

Слияние (F1, F2) ===> (G1, G2);

Слияние (G1, G2) ===> (F1, F2);

(Нечетные пары блоков сливаем на 1-ый файл, четные - на 2-ой).

Временная сложность алгоритма улучшается почти вдвое.

б. Заметим, что на начальной стадии работы алгоритма размеры блоков малы. Их можно сортировать в оперативной памяти, используя представление в виде массива и быстрые алгоритмы сортироки массивов. Таким образом, следует изменить процедуру FirstPartition, определив ее как процедуру внутренней сортировки k0-блоков при некотором (максимально возможном) значении k0. Цикл While основной программы теперь можно начинать с k = k0.

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

2.3 Задача корректировки файла

Задача корректировки файла является одной из основных задач обработки файлов. Рассмотрим ее формулировку:

Исходные данные задачи - корректируемый файл F, файл корректировок G. Результат - откорректированный файл H. Будем считать, что файл F имеет тип OurFile. Тогда файл H имеет тот же тип. Файл корректировок G состоит из записей с вариантами:

Type

CorСomponent = record

Key: Integer;

job: (Include, Change, Exclude); {включить, изменить, исключить}

Case job of

Include, Change: Data: String[20]; Exclude: ()

end

End;

CorFile = File of CorComponent;

Var G : CorFile;

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

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

Решение задачи обычно содержит два этапа:

а) Сортировка файла корректировок G по ключу;

б) Обобщенное слияние файлов F, G в H.

На практике файл G может быть небольшим. В этом случае применяют внутреннюю сортировку.Обобщенный алгоритм слияния производит все три варианта обработки файла F за один прогон.

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

Глава 2. Сравнительный анализ обработки структур типа «файл» и «запись» в языках программирования высокого уровня Си++ и Паскаль

Язык высокого уровня - тип языка компьютерного программирования. Языки высокого уровня предназначены для выражения потребностей программиста, а не возможностей компьютера. Они используют абстрактные данные и контролируют структуры, символические обозначения и переменные. Существует много языков высокого уровня, в том числе Бейсик (BASIC), Кобол (COBOL), Паскаль (Pascal), Фортран (FORTRAN), Алгол (Algol) и Си (C). Чтобы можно было использовать программы, написанные на языках высокого уровня, их нужно перевести в машинные коды. Рассмотрим в противопоставлении обработку структур типа «файл» и «запись» в языках высокого уровня Си и Паскаль.

2.1 Сравнительный анализ обработки структур типа «файл»

2.1.1 Обработка структур типа «файл» в Паскале

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

долговременного хранения данных;

доступа различных программ к одним и тем же данным;

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

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

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

Работа с файлами выполняется следующими процедурами:

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

Reset - открывает существующий файл для чтения.

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

Close - закрывает открытый файл.

Для определения конца файла используется стандартная встроенная функция EOF (файловая переменная), которая принимает значение True, если достигнут конец файла, и значение False в противном случае.

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

Текстовые файлы - файлы на диске, состоящие из символов ASCII. Для разделения строк используются символы «конец строки». Текстовые файлы являются файлами с последовательным доступом. В любой момент времени доступна только одна запись файла. Другие записи становятся доступными лишь в результате последовательного продвижения по файлу. Текстовые файлы внутренне разделены на строки, длины которых различны. Для разделения строк используется специальный маркер конца строки. Объявляются текстовые файлы переменной типа text. Обрабатывать их можно только последовательно и с помощью процедур и функций:

Readln (f, st) - чтение строки st из файла f и переход на начало следующей;

Writeln (f, st) - запись строки st в файл f и маркера конца строки;

Append (f) - процедура, открывающая файл f для добавления строк в конец файла;

Eoln (st)- логическая функция, результат выполнения которой равен TRUE, если достигнут маркер конца строки st.

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

Program File_text;

var

f1 : text;

st : string;

n: byte;

begin

assign (f1, 'file1.txt'); {связать с файлом file1.txt файловую переменную f1 }

rewrite (f1); { создать новый файл с именем file1.txt }

writeln ( f1, 'Очень полезно изучать'); { записать предложения в файл}

writeln ( f1, ' всем студентам ');

writeln (f1, ' язык Pascal ');

close (f1); { закрыть файл для записи }

reset (f1); { открыть файл для чтения }

while not eof (f1) do { пока не конец файла f1}

begin

readln (f1, st); {читаем строку из файла f1 }

writeln(st); { выводим на экран }

n:= length (st); {определяем длину строки }

writeln (' длина =',n);

end;

close (f1); { закрыть файл для чтения}

end .

Типизированные файлы.

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

Процедуры и функции обработки файлов:

1) Write и Read- записывают, и читают информацию из указанного файла и перемещают указатель файла к следующей записи.

2) Seek (файловая переменная, номер записи); процедура перемещения указателя на запись файла с заданным номером.

3) Truncate (файловая переменная); процедура, усекающая файл по текущей позиции указателя файла, т.е. все записи, находящиеся после указателя файла, удаляются.

4) Функция Filesize (файловая переменная); имеет тип Integer и определяет размер файла, т.е. число записей.

5) Функция Filepos (файловая переменная); имеет тип Integer и возвращает текущую позицию указателя файла.

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

Readln (a);

Seek (f, filesize (f));

Write (f, a);

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

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

Пример: Cоздать файл из списка 10 студентов с их оценками (номер, Ф.И.О. и три оценки). Вывести его содержимое на экран, изменить фамилию студента с номером, введенным с клавиатуры, заново прочитать файл.

Program file;

Type

wed = record {Тип wed включает 3 поля: n, fio, bal}

n : byte ; fio : string[15] ;

bal : array [1..3] of byte; {Поле bal - массив из 3 оценок }

end;

Var

spisok : wed ; {Запись spicok типа wed}

sp : file of wed; {Файл записей типа wed}

procedure vvod; { процедура создания файла}

var i,j:byte;

begin { оператор assing находится в основной прграмме }

rewrite ( sp); {открытие файла для записи}

with spisok do For i:=1 to 10 do

begin n:=i;

writeln (' Введите фамилию - ', i ); readln (fio);

writeln (' Введите 3 оценки ', fio ); For j:= 1 to 3 do readln ( bal [j] );

write (sp , spisok); { запись в файл информации о студенте}

end;

close (sp); { закрытие файла для записи }

end;

procedure print; { процедура чтения и печати всего файла }

var j : byte;

begin

reset ( sp); {открытие файла для чтения}

writeln (`Список студентов: `);

while not eof (sp) do

with spisok do

begin

Read (sp, spisok); {чтение данных из файла}

write (n,' ',fio); {вывод записи на экран}

For j:= 1 to 3 do write (' ', bal [j] );

writeln ;

end;

readln;

close (sp) ;

end;

procedure work;

var num: integer;

begin reset ( sp); {открытие файла для чтения}

writeln ('номер= ');

readln (num);

seek (sp, num-1); {поиск записи с указанным номером (нумерация записей с 0)}

read (sp,spisok);{чтение и перемещение указателя к след. записи}

write ('fio=');

writeln (spisok.fio);

seek (sp,filepos(sp)-1); {возвращение к изменяемой записи }

writeln (` Введите новую фамилию' );

readln (spisok.fio);

write (sp, spisok); {запись в файл измененной записи}

close (sp);

end;

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

assign (sp,'Vedom.DAT'); {связать файловую перем-ю sp с файлом Vedom.dat}

vvod; print; {процедуры создания и чтения файла}

work; print; {корректировка и чтение измененного файла}

readln

end.

2.1.2 Обработка структур типа «файл» в Си++

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

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

Текстовый поток -- это последовательность символов. При передаче символов из потока на экран, часть из них не выводится (например, символ возврата каретки, перевода строки).

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

Организация работы с файлами средствами C++

Файловый ввод-вывод с использованием потоков

Библиотека потокового ввода-вывода

fstream

Связь файла с потоком вывода

ofstream имя логического файла;

Связь файла с потоком ввода

ifstream имя логического файла;

Открытие файла

имя логического файла.open(имя физического файла);

Закрытие файла

имя логического файла.close();

Пример 4. Заполнить файл значениями функции y = x * cos x.

/* Заполнить файл значениями функции y = x * cos x. */

/* Dev-C++ */

#include <cstdlib>

#include <iostream>

#include <fstream>

#include <cmath>

using namespace std;

double fun(double x);

int main()

{double a, b, h, x; char s[20];

cout << "Enter the beginning and end of the segment, step-tabulation: ";

cin >> a >> b >> h;

cout << "File name? "; cin >> s;

ofstream f;

f.open(s);

for (x=a; x<=b; x+=h)

{f.width(10); f << x;

f.width(15); f << fun(x) << endl; }

f.close();

system("PAUSE");

return EXIT_SUCCESS;

}

double fun(double x)

{ return x*cos(x); }

Пример 5. Файл содержит несколько строк, в каждой из которых записано единственное выражение вида a#b (без ошибок), где a, b - целочисленные величины, # - операция +, -, /, *. Вывести каждое из выражений и их значения.

/* Dev-C++ */

#include <cstdlib>

#include <iostream>

#include <fstream>

using namespace std;

int main()

{

long a, b; char s[256], c; int i;

cout << "File name? "; cin >> s;

ifstream f; f.open(s);

while (!f.eof())

{ f.getline(s, 256);

i=0; a=0;

while (s[i]>='0'&&s[i]<='9')

{

a=a*10+s[i]-'0';

i++;

}

c=s[i++]; b=0;

while (s[i]>='0'&&s[i]<='9')

{

b=b*10+s[i]-'0';

i++;

}

switch (c){

case '+': a+=b; break;

case '-': a-=b; break;

case '/': a/=b; break;

case '*': a*=b; break;}

cout << s << " = " << a << endl; }

f.close();

system("PAUSE");

return EXIT_SUCCESS;

}

Пример 6. В заданном файле целых чисел посчитать количество компонент, кратных 3.

/* В заданном файле целых чисел посчитать количество компонент, кратных 3. */

/* Dev-C++ */

#include <cstdlib>

#include <iostream>

#include <fstream>

using namespace std;

int main()

{int r,ch;

ifstream f;

f.open("CH_Z.TXT");

ch=0;

for (;f.peek()!=EOF;)

{f>>r;

cout << r << " ";

if (r%3==0) ch++ ;

}

f.close();

cout << endl << "Answer: " << ch;

system("PAUSE");

return EXIT_SUCCESS;

}

2.2 Сравнительный анализ обработки структур типа «запись»

2.2.1 Обработка структур типа «запись» в Паскале

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

type t = record

id11, id12, …: type1;

id21, id22, …: type2;

……………….

end;

здесь id - идентификаторы полей; type - типы полей; t - имя типа.

Пример. Данные комплексного вида можно описать переменной типа record.

type complex = record

re, im: real

end;

var c: complex;

здесь complex - имя типа, а c - имя переменной. Переменная c состоит из двух полей: re и im, имеющих один и тот же тип (real). Эти поля переменной c обозначаются как c.re и c.im.

Пример. Даты каких-либо событий можно описать следующим образом:

type date = record

month: 1..12;

day: 1..31;

year: integer

end;

var d: date;

В этом примере описан тип date и переменная d, принадлежащая этому типу.

Переменная d описана как запись, состоящая из трех полей: month, day и year. Каждое поле содержит соответственно данные: целое число в пределах от 1 до 12 (номер месяца), целое число от 1 до 31 (число), целое число (год).

Поле day переменной d записывается как d.day.

Например, чтобы заслать в d дату 12.01.2003, надо выполнить следующие операторы:

d.month := 1;

d.day := 12;

d.year := 2003;

Пример. Вычислить сумму s двух комплексных чисел x = 2 + 7i и y = 6 + 3i (т.е. x, y, s: complex;).

x.re := 2.0; x.im := 7.0;

y.re := 6.0; y.im := 3.0;

s.re := x.re + y.re;

s.im := x.im + y.im;

Запись может быть компонентой других структур. Например, введем тип family (семья: отец, мать, 1-й ребенок, 2-й ребенок):

type family = (father, mother, child1, child2);

var birthday: array[family] of date;

где date - описанная выше запись.

Переменная birthday есть массив, состоящий из записей - дат рождения членов семьи: отца, матери, 1-го ребенка, 2-го ребенка. Каждая дата рождения имеет тип date, который может быть описан в программе.

Для занесения даты рождения, например, mother, достаточно выполнить операторы:

birthday[mother].month := 5;

birthday[mother].day := 1;

birthday[mother].year := 1965;

2.2.2 Обработка структур типа «запись» в Си++

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

Рис. 5. Иллюстрация «записи».

Запись В состоит из трех полей, имеющих последовательно типы «текст», «целое число», «вещественное число»: 1-е поле - название детали, 2-е - условный номер по каталогу, 3-е - длина. При работе с одной единственной записью (что бывает нечасто), имя поля можно использовать как обычную переменную, т.е. можно изменять значение поля с помощью операции присваивания или любых других операций, доступных над величинами данного типа. Если же данная запись - лишь часть набора данных, то имя поля состоит из двух частей и называется составным именем поля (на рис. 1.33 составные имена В. name, В. number, В. length).

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

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

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

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

1) объединение множеств (операция сложения '+');

2) пересечение множеств (операция умножения '*');

...

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

  • Сравнительный анализ языков программирования высокого уровня Си и Паскаль. Реализация алгоритма обработки данных. Тестирование и отладка программы или пакета программ. Структура программы на языке Турбо Паскаль. Указатели и векторные типы данных.

    курсовая работа [233,5 K], добавлен 14.12.2012

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

    учебное пособие [1,5 M], добавлен 10.12.2010

  • Изучение основных конструкций и способов написания программ на языке Паскаль. Обзор принципов работы и интерфейса написанной программы. Обработка и модификация двумерных массивов. Файловые структуры данных. Текстовые файлы. Элементы машинной графики.

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

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

    курсовая работа [336,2 K], добавлен 27.06.2015

  • Изучение организации диалоговой программы и закрепления основных элементов программирования на языке Паскаль и Си (Delphi, C++ Builder). Описание представления информации в программах на языках высокого уровня. Сравнительная характеристика Delphi и C++.

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

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

    реферат [11,5 K], добавлен 19.01.2009

  • Сущность понятия "тип данных". Объектно-ориентированный стиль программирования. Простые типы данных в языке Паскаль: порядковые, вещественные, дата-время. Булевский (логический) тип. Синтаксис определения ограниченного типа. Регулярные типы (массивы).

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

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

    лабораторная работа [11,4 K], добавлен 13.05.2011

  • Методы численного интегрирования. Характеристика основных составляющих структурного программирования. Решение задания на языке высокого уровня Паскаль. Построение графического решения задачи в пакете Matlab. Решение задания на языке высокого уровня C.

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

  • Файл - именованная область памяти на магнитном носителе. Программирование доступа к файлу в языке Turbo Pascal. Описание файловой переменной. Виды файлов в зависимости от способа описания: текстовые, двоичные или типизированные и нетипизированные.

    реферат [14,8 K], добавлен 19.01.2009

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

    курсовая работа [75,0 K], добавлен 21.03.2013

  • Основные принципы концепции типа данных в языках программирования. Разновидности структур данных. Дискретные и непрерывные скалярные типы. Файл, последовательность, множество. Линейный список. Сложность алгоритмов. Построение рекурсивных подпрограмм.

    презентация [2,5 M], добавлен 14.10.2013

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

    учебное пособие [211,1 K], добавлен 30.03.2008

  • Приобретение теоретических и практических навыков программирования на языке Паскаль. Математическая формулировка задачи и выбор метода обработки информации. Разработка алгоритма и его описание. Описание программы. Форма представления исходных данных.

    курсовая работа [224,3 K], добавлен 11.02.2016

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

    учебное пособие [1,3 M], добавлен 02.12.2011

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

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

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

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

  • Создание программного продукта на языке Pascal в визуальной среде программирования Borland Developer Studio в консольном приложении. Разработка типизированного файла для записи данных и их вывод на экран, добавление данных в конец файла, поиск информации.

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

  • Разработка программы обработки типизированных файлов с кодом на языке Object Pascal, с использованием компонентов Delphi для ввода и вывода данных. Разработка экранных форм и алгоритма программы. Описание программных модулей и инструкция оператору.

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

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

    реферат [49,0 K], добавлен 12.11.2009

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