Учебное пособие по курсу Программирование на языке высокого уровня для вузов по специальности 230105 Программное обеспечение вычислительной техники и автоматизированных систем
Скачать 0.64 Mb.
|
. Пропускает все пробелы и знаки табуляции до маркера конца строки EOLN или до первого значащего символа и возвращает TRUE, если маркер обнаружен. Формат обращения: SEEKEOLN (<ф.п.>) Если параметр <ф.п.> опущен, функция проверяет стандартный файл INPUT. ЛОГИЧЕСКАЯ ФУНКЦИЯ SEEKEOF. Пропускает все пробелы, знаки табуляции и маркеры конца строки EOLN до маркера конца файла или до первого значащего символа и возвращает TRUE, если маркер обнаружен. Формат обращения: SEEKEOF (<ф.п.>) Если параметр <ф.п.> опущен, функция проверяет стандартный файл INPUT. В следующем примере, иллюстрирующем работу с текстовым файлом, подсчитывается общее количество символов в файле и результат делится на 40000 - таким способом можне оценить об'ем рукописи в так называемых учетно-издательских листах: var f: text; s: string; const Sum: iongint = 0; { здесь будет количество символов } BEGIN Write('Имя файла'); { запросить } Readln(s); { и ввести имя файла } assign(f,s); PDF created with pdfFactory Pro trial version www.pdffactory.com 44 Reset(f); { открыть файл } while not EOF(f) do { подсчитать } begin { количество } Readln(f,s); { символов } inc(Sum, Length(s)) { в тексте } end; { этой программы } Close(f); { закрыть файл } Writeln('Обьем = ',Sum/40000:6:2,' уч.изд.л.') END. PDF created with pdfFactory Pro trial version www.pdffactory.com 45 ЛЕКЦИЯ 19. ТИПИЗИРОВАННЫЕ ФАЙЛЫ . Длина любого компонента типизированного файла строго постоянна, что дает возможность организовать прямой доступ к каждому из них (т.е. доступ к компоненту по его порядковому номеру ). Перед первым обращением к процедурам ввода-вывода указатель файла стоит в его начале и указывает на первый компонент с номером 0. После каждого чтения или записи указатель сдвигается к следующему компоненту файла. Переменные в списках ввода-вывода должны иметь тот же тип, что и компоненты файла. Если этих переменных в списке несколько, указатель будет смещаться после каждой операции обмена данными между переменными и дисковым файлом. ПРОЦЕДУРА READ. Обеспечивает чтение очередных компонентов типизированного файла. Формат обращения: READ (<ф.п.>,<сп.ввода>) Здесь <сп.ввода> - список ввода, содержащий одну или более переменных такого же типа, что и компоненты файла. Файловая переменная <ф.п.> должна быть об'явлена предложением FILE OF ... и связана с именем файла процедурой ASSIGN. Файл необходимо открыть процедурой RESET. Если файл исчерпан, обращение к READ вызовет ошибку ввода-вывода. ПРОЦЕДУРА WRITE. Используется для записи данных в типизированный файл. Формат обращения: WRITE (<ф.п.>,<сп.вывода>) Здесь <сп.вывода> - список вывода, содержащий одно или более выражений того же типа, что и компоненты файла. ПРОЦЕДУРА SEEK. Смещает указатель файла к требуемому компоненту. Формат обращения: SEEK(<ф.п.>,< N компонента >) Здесь < N компонента > - выражение типа LONGINT, указывающее номер компонента файла. Первый компонент файла имеет номер 0. Процедуру нельзя применять к текстовым файлам. PDF created with pdfFactory Pro trial version www.pdffactory.com 46 ФУНКЦИЯ FILESIZE. Возвращает значение типа LONGINT, которое содержит число компонентов файла. Формат обращения: FILESIZE(<ф.п.>) Функцию нельзя использовать для текстовых файлов. Чтобы переместить указаталь в конец файла, можно написать: seek (FileVar, FileSize(FileVar)); где FileVar - файловая переменная. ФУНКЦИЯ FILEPOS. Возвращает значение типа LONGINT, содержащее порядковый номер компонента файла, который будет обрабатываться следующей операцией ввода-вывода. Формат обращения: FILEPOS (<ф.п.>) Функцию нельзя использовать для текстовых файлов. Первый компонент файла имеет порядковый номер 0. PDF created with pdfFactory Pro trial version www.pdffactory.com 47 ЛЕКЦИЯ 20. НЕТИПИЗИРОВАННЫЕ ФАЙЛЫ . Нетипизированные файлы об'являются как файловые переменные типа FILE и отличаются тем, что для них не указан тип компонентов. Отсутствие типа делает эти файлы, с одной стороны, совместимыми с любыми другими файлами, а с другой - позволяет организовать высокоскоростной обмен данными между диском и памятью. При инициации нетипизированного файла процедурами RESET или REWRITE можно указать длину записи нетипизированного файла в байтах. Например так: var f : file; assign (f, 'myfile.dat '); reset (f, 512); Длина записи нетипизированного файла указывается вторым паметром при обращении к процедурам RESET или REWRITE, в качества которого может использоваться выражение типа WORD. Если длина записи не указана, она принимается равной 128 байтам. Турбо-Паскаль не накладывает каких-либо ограничений на длину записи нетипизированного файла, за исключением требования положительности и ограничения максимальной длины 65535 байтам (емкость целого типа WORD). Однако для обеспечения максимальной скорости обмена данными следует задавать длину, которая была бы кратна длине физического сектора дискового носителя информации (512 байт). Более того, фактически пространство на диске выделяется любому файлу порциями - кластерами, которые в зависимости от типа диска могут занимать 2 и более смежных секторов. Как правило, кластер может быть прочитан или записан за один оборот диска, поэтому наивысшую скорость обмена данными можно получить, если указать длину записи, равную длине кластера. При работе с нетипизированными файлами могут применяться все процедуры и функции, доступные типизированным файлам, за исключением READ и WRITE, которые заменяются соответственно высокоскоростными процедурами BLOCKREAD и BLOCKWRITE. Для вызова этих процедур используются следующие предложения: BLOCKREAD(<ф.п.>,<буф>, BLOCKWRITE(<ф.п.>,<буф>, Здесь <буф> - буфер: имя переменной, которая будет участвовать в обмене данными с дисками; PDF created with pdfFactory Pro trial version www.pdffactory.com 48 За одно обращение к процедурам может быть передано до N*RECS байт, где RECS - длина записи нетипизированного файла. Передача идет, начиная с первого байта переменной <буф>. Программист должен позаботиться о том, чтобы длина внутреннего представления переменной <буф> была достаточной для размещения всех N*RECS байт при чтении информации с диска. Если при чтении указана переменная <буф> недостаточной длины или если в процессе записи на диск не окажется нужного свободного пространства, возникнет ошибка ввода-вывода, которую можно заблокировать, указав необязательный параметр (переменная типа WORD). После завершения процедуры указатель смещается на PDF created with pdfFactory Pro trial version www.pdffactory.com 49 Семинар . Работа с файлами . ЗАДАЧА . Program fzap(input,output); Uses crt; Type zap=record fio:packed array[1..10] of char; godr:integer; end; fpk=file of zap; Var fizap:fpk; a,b:zap; i,j:integer; Begin clrscr; assign(fizap,'res.dat'); rewrite(fizap,'abc.dat) rewrite(fizap); readln; for j:=1 to 3 do begin write('=>'); for i:=1 to 10 do read(b.fio[i]); readln(b.godr); write(fizap,b); end; close(fizap); reset(fizap); for j:=1 to 3 do begin read(fizap,a); writeln(j:2,'-ая запись ',a.fio ,a.godr:5); end; End. Эта программа формирует файл и сохраняет его на внешнемносителе, что обеспечивается заданием внешнего имени abc.dat при открытии файла на запись. Ввод исходной информации осуществляется до тех пор, пока не введется 10 звездочек (признак конца ввода). Это сделано для того, чтобы пользователю не надо было предварительно подсчитывать количество вводимых записей. ЗАДАЧА Program stud(output); PDF created with pdfFactory Pro trial version www.pdffactory.com 50 Uses crt; Type zap=record fio:array[1..10] of char; godr:integer; end; fpk=file of zap; Var fizap,rb:fpk; a:zap; i:integer; Begin clrscr; assign(fizap,'abc.dat'); reset(fizap); assign(rb,'l.dat'); rewrite(rb); repeat read(fizap,a); if a.godr>=1945 then write(rb,a); until eof(fizap); close(rb); close(fizap); reset(rb); rewrite(fizap); repeat read(rb,a); writeln(a.fio,a.godr:5); write(fizap,a); until eof(rb); close(fizap) End. В этой программе из внешнего файла с именем abc.dat удаляются все записи ,соответствующие людям, родившимся до 1970 года.Для этого используется рабочий файл с внешним именем l.dat , в который сначала переписываются из внешнего файла все оставляемые записи, затем внешний файл открывается на запись, рабочий файл - на чтение и все содержимое рабочего файла переписывается во внешний файл. При этом для контроля работы программы оставляемые записи выдаются на терминал. Пример : PROGRAM S1(INPUT); TYPE СИМСТР=FILE OF CHAR; VAR СПИСОК:СИМСТР;C:CHAR;I,N:INTEGER; PDF created with pdfFactory Pro trial version www.pdffactory.com 51 BEGIN REWRITE (СПИСОК,'IMY.TXT'); WRITE ('вводи длину строки =>'); READLN(N);WRITELN('вводи фамилии =>'); FOR I:=1 TO N DO BEGIN WHILE NOT EOLN DO BEGIN READ(C); WRITE(список С) END; (* переход к новой строке *) READLN; WRITELN( список ) END; CLOSE( список ) end. В этой программе требуется построить файл,представляющий собой список группы.Удобно сделать так,чтобы в каждой строке файла записывалась одна фамилия. При вводе каждая фамилия начинается с новой строки. Программа S1 записывает во внешний файл с именем imy.txt фамилии, вводимые с терминала, а программа S2 считывает из каждой строки внешнего файла фамилию и выводит ее на терминал с новой строки. PROGRAM S2(INPUT); TYPE семестр=FILE OF CHAR; VAR список,семестр; C:CHAR;I:INTEGER; BEGIN RESET(список,'IMY','TXT'); WHILE NOT EOF(список) DO BEGIN WHILE NOT EOLN(список) DO BEGIN READ(список,C); WRITE(C); END READLN(список); WRITELN; END END. Стандартные файлы INPUT и OUTPUT являются текстовыми и в программе их описывать не надо, т.к.они описаны как текстовые файлы: TYPE TEXT=FILE OF CHAR VAR INPUT,OUTPUT:TEXT При обращении к стандартным процедурам READ,READLN,WRITE,WRITELN в качестве стандартного аргумента можно указывать имя любого текстового файла. Если имя файла не указано, то происходит обращение к стандартному файлу. PDF created with pdfFactory Pro trial version www.pdffactory.com 52 ЗАДАЧА Написать программу, которая читает фамилии и пять оценок и записывает суммарный балл в текстовый файл. Program result(input,output); Uses crt; Const imf='res.dat'; Var fio:string; summa:0..100; ball:0..20; schet:1..5; simvol:char; fres:text; Begin clrscr; assign(fres,imf); rewrite(fres); repeat writeln('Введите ФИО'); readln; read(fio); writeln(fres,fio); summa:=0; for schet:=1 to 5 do begin write('Результат='); readln(ball); summa:=summa+ball; end; writeln(fres,summa); writeln('Есть ли еще студенты (y/n)'); read(simvol) until simvol='n'; writeln('*** Программа завершена ***'); close(fres); End. ЗАДАЧА Написать программу, которая изображает данные,хранящиеся в текстовом файле предыдущей программы. Program izres; PDF created with pdfFactory Pro trial version www.pdffactory.com 53 Const imf='res.dat'; Var fio:string; summa:0..100; simvol:char; fres:text; Begin assign(fres,imf); reset(fres); write('Для изображения очередной записи нажмите клавишу tab'); while not eof(fres) do begin read(simvol); readln(fres, fio, summa); writeln(fio,'сумма=',summa:3); end; writeln('*** Достигнут конец файла ***'); End. ЗАДАЧА Написать программу, которая считывает записи и заносит их в файл, а затем печатает их по порядку (телефонный справочник) . Program tel; Uses crt; Type dan=record fio:string; adres:string; nomer:string; end; Var spisok:file of dan; simvol:char;a:dan; Procedure chten(var tekzap:dan); Begin with tekzap do begin writeln('Введите ФИО'); readln(fio); writeln('Введите адрес'); readln(adres); writeln('Введите номер телефона'); readln(nomer); end; End; PDF created with pdfFactory Pro trial version www.pdffactory.com 54 Procedure izobr(tekzap:dan); Begin with tekzap do begin writeln(fio); writeln(adres); writeln('телефон',nomer); end; End; Begin clrscr; assign(spisok,'acd.dat'); rewrite(spisok); repeat chten(a); write(spisok,a); write('Есть ли еще записи(y/n)'); readln(simvol); until simvol='n'; close(spisok); reset(spisok); while not eof(spisok) do begin write('Для изображения следующей записи нажмите клавишу ENTER'); readln; read(spisok,a); izobr(a); { get(spisok) } end; writeln('*** Конец записей ***'); End. PDF created with pdfFactory Pro trial version www.pdffactory.com 55 ЛЕКЦИЯ 1, 2 для 2- го семестра 1 курса УКАЗАТЕЛИ И ДИНАМИЧЕСКАЯ ПАМЯТЬ Динамическая память . Все переменные, обьявленные в программе, размещаются в одной непрерывной области оперативной памяти, которая называется сегментом данных. Длина сегмента данных определяется архитектурой микропроцессора 8086 и составляет 65536 байт, что может вызвать известные затруднения при обработке больших массивов данных. С другой стороны, обьем памяти ПК (обычно не менее 640 Кбайт) достаточен для успешного решения задач с большой размерностью данных. Выходом из положения может служить использование так называемой динамической памяти. Динамическая память - это оперативная память ПК, предоставляемая программе при ее работе, за вычетом сегмента данных (64 Кбайт), стека (обычно 16 Кбайт) и собственно тела программы. По умолчанию этот размер определяется всей доступной памятью ПК и,как правило, составляет не менее 200...300 Кбайт. Динамическая память- это фактически единственная возможность обработки массивов данных большой размерности. Многие практические задачи трудно или невозможно решить без использования динамической памяти. Такая необходимость возникает, например ,при разработке систем автоматезированного проектирования (САПР): размерность математических моделей, используемых в САПР, может значительно отличаться в разных проектах; статическое (т.е. на этапе разработки САПР) распределение памяти в этом случае, как правило, невозможно. Наконец, динамическая память широко используется для временного запоминания данных при работе с графическими и звуковыми средствами ПК. Динамическое размещение данных означает использование динамической памяти непосредственно при работе программы. В отличие от этого статическое размещение осуществляется компилятором Турбо- Паскаля в процессе компиляции программы. При динамическом размещение заранее не известны ни тип, ни количество размещаемых данных, к ним нельзя обращаться по именам, как к статическим переменным. PDF created with pdfFactory Pro trial version www.pdffactory.com 56 Оперативная память 0 ОС 100-130Кб Паскаль+прога 64Кб 640 Динамическая память 1024Кб Адреса и указатели Оперативная память ПК представляет собой совокупность элементарных ячеек для хранения информации - байтов, каждый из которых имеет собственный номер. Эти номера называются адресами, они позволяют обращаться к любому байту памяти. Турбо Паскаль предоставляет в распоряжение программиста гибкое средство управления динамической памятью- так называемые указатели. Указатель- это переменная, которая в качестве своего значения содержит адрес байта памяти. В ПК адреса задаются совокупностью двух шестнадцатиразрядных слов, которые называются сегментом и смещением. Сегмент- это участок памяти, имеющий длину 65536 байт (64 Кбайт) и начинающийся с физического адреса, кратного 16 (т.е.0,16,32,48 и т.д.). Смещение указывает, сколько байт от начала сегмента необходимо пропустить, чтобы обратиться к нужному адресу. Адресное пространство ПК составляет 1 Мбайт (речь идет о так называемой основной памяти ПК; на компьютерах класса IBM PC/AT адресное пространство составляет 16 Мбайт; такие ПК могут иметь до 15 Мбайт дополнительной памяти, однако в Турбо Паскале нет средств, поддерживающих работу с дополнительной памятью). Для адресации в пределах 1 Мбайта нужно 20 двоичных разрядов, которые получаются из двух шестнадцатиразрядных слов (сегмента и смещения) следующим образом: содержимое сегмента смещается влево на 4 разряда, освободившиеся правые разряды заполняются нулями, результат складывается с содержимым смещения. Фрагмент памяти в 16 байт называется параграфом, поэтому можно сказать, что сегмент адресует память с точностью до параграфа, а смещение- с точностью до байта. Каждому сегменту соответствует PDF created with pdfFactory Pro trial version www.pdffactory.com 57 непрерывная и отдельно адресуемая область памяти. Сегменты могут следовать в памяти один за другим без промежутков или с некоторым интервалом, или, наконец, перекрывать друг друга. Таким образом, по своей внутренней структуре любой указатель представляет собой совокупность двух слов (данных типа WORD),трактуемых как сегмент и смещение. С помощью указателей можно размещать в динамической памяти любой из известных в Турбо Паскале типов данных. Лишь некоторые из них (BYTE,CHAR,SHORTINT,BOOLEAN) занимают во внутреннем представлении один байт, остальные - несколько смежных. Поэтому на самом деле указатель адресует лишь первый байт данных. Объявление указателей Как правило, в Турбо Паскале указатель связывается с некоторым типом данных. Такие будем называть типизированными. Для обьявления типизированного указателя используется значок ^, который помещается перед соответствующим типом, например: type PerconPointer = ^PerconRecord; PerconRecord = record Name : string; Job : string; Next : PerconPointer end; var p1 : ^integer; p2 : ^real; Обратите внимание: при обьявлении типа PERCONPOINYER мы сослались на тип PERCONRECORD, который предварительно в программе объявлен не был. Как уже отмечалось, в Турбо Паскале последовательно проводиться в жизнь принцип, в соответствии с которым перед использованием какого- либо идентификатора он должен быть описан. Исключение сделано только для указателей, которые могут ссылаться на еще не обьявленный тип данных. Это исключение сделано не случайно. Динамическая память дает возможность реализовать широко используемую в некоторых программах организацию данных в виде списков. Каждый элемент списка имеет в своем составе указатель на соседний элемент, что обеспечивает возможность просмотра и коррекции списка. Если бы в Турбо Паскале не было этого исключения, реализация списков была бы значительно затруднена. PDF created with pdfFactory Pro trial version www.pdffactory.com |