Переполнение ячеек памяти
После выполнения программы
VAR i:Byte;
BEGIN i:=250; WriteLn(i); i:=i+10; WriteLn(i) END.
мы увидим на экране числа 250 и 4. А почему не 250 и 260? Потому что тип Byte представляет только числа от 0 до 255. Если в процессе выполнения программы значение переменной вышло за диапазон своего типа, Паскаль не замечает ошибки, а в соответствующей ячейкеоказывается ерунда. Это касается всех типов. Впрочем, ценой некоторой потери скорости Паскаль можно легко настроить на проверку выхода за диапазон (см. приложение).
Дерево типов
Паскаль предоставляет солидные возможности для конструирования новых типов. Так, если мы пишем VAR a : array[1..10] of array [2..5] of set of Byte, то имеем в виду, что переменная a является массивом array[1..10], который сконструирован из массивов array [2..5], каждый из которых сконструирован из элементов, являющихся множествами set, каждое из которых сконструировано из элементов типа Byte.
Схема, приводимая ниже, демонстрирует, какие типы из каких можно конструировать. Например, файлы можно конструировать из строк, а записи из массивов. А вот множества из вещественных чисел конструировать нельзя.
Синтаксисические диаграммы Паскаля
В этой книге я излагал Паскаль в основном на примерах, не стараясь очень уж строго давать правила записи операторов и других конструкций Паскаля. Тем не менее, когда Паскаль указывает вам на ошибку, вы, чтобы исправить ее, должны эти правила знать абсолютно точно.
Есть два самых распространенных способа записи синтаксиса. С одним из них я вас познакомил в 5.2, другой использует так называемые синтаксические диаграммы. Здесь я буду использовать второй метод плюс еще третий - обычный словесный (когда понятность будет достаточным возмещением за нестрогость).
Синтаксическую диаграмму рассмотрим на примере. Все мы знаем, что имя - это цепочка букв, цифр и знаков подчеркивания, не начинающаяся с цифры. Это обычное словесное определение. А вот это же определение в виде синтаксической диаграммы:
Пользоваться синтаксической диаграммой нужно так. Заходите в диаграмму по стрелке. Оказавшись внутри «домика», записывайте на лист бумаги в строчку то, что там указано. Предположим, в нашем случае вы зашли в «букву». Значит, записывайте любую букву, например, N. Затем продолжайте путешествие строго по стрелкам. Оказавшись на развилке, поворачивайте в любую сторону, разрешенную стрелками. Снова оказавшись в «домике», приписывайте справа в строчку то, что там указано. Пусть, например, следующий ваш домик «цифра». Вы должны приписать справа к букве любую цифру, например, 8. Получится N8. И так далее. Когда надоест, добирайтесь до выходной стрелки. Вы гарантированно получите правильное имя.
Сейчас я приведу синтаксические диаграммы всех изученных нами элементов Паскаля. Кое-какие элементы мы не проходили, кое-какие проходили упрощенно – соответствующие диаграммы тоже или будут отсутствовать, или будут нарисованы упрощенно, все такие случаи я буду оговаривать.
Также во избежание затемнения смысла подробностями диаграммы будут не везде до конца конкретны. Например, в диаграмме имени я писал “буква”, а надо было – “латинская буква”.
| | | | | | | | | | | | | | | | | | | | | | | Опережающее описание процедуры или функции см. в 10.6
| | | | | | | | | | | | | | | | |
| | Имя переменной, имя константы и все прочие имена, упомянутые в синтаксических диаграммах, образуются согласно синтаксической диаграмме Имя.
| |
Глава 15. Другие возможности Паскаля
На этом со строгостями покончили. Нам осталось рассмотреть несколько дополнительных возможностей Паскаля.
Работа с файлами данных
Мы пока знакомы с выводом данных только на экран, а со вводом - только с клавиатуры. Сейчас мы познакомимся с выводом данных в файли со вводом из файла. Если вы еще не знакомы с понятием файла или каталога, прочтите приложение. Для определенности мы будем считать, что файл расположен на магнитном диске, хотя файл - достаточно общее понятие, которое может применяться к различным устройствам ввода, вывода и хранения информации.
В Паскале существует три типа файлов. Мы познакомимся с самым распространенным из них - текстовым файлом. Вам совершенно не обязательно знать, как физически устроен носитель, на который файл будет записываться. При работе с текстовым файлом удобно представлять, что носитель - не диск, состоящий из дорожек, а подобен листу бумаги или экрану монитора, файл же - это строки информации на этом листе или экране. Данные в текстовых файлах могут быть целыми или вещественными числами, символами, строками.
Задача: Записать слово ‘Азия’ и число 1998 на магнитный диск c: в текстовый файл с именем fedos, располагающийся в каталоге PASCAL.
Начнем с того, что придумаем файлу fedos псевдоним, которым мы будем пользоваться в программе. Пусть это будет fepas. Затем нам нужно объяснить Паскалю, что fepas - это текстовый файл, для чего мы начнем программу со строчки
Var fepas :Text;
Раздел операторов начинаем с того, что объясняем Паскалю, какое настоящее имя соответствует псевдониму fepas:
Assign(fepas, 'c:\PASCAL\fedos');
Затем переместим магнитную головку в начало файла для записи информации в файл (откроем файл для записи):
Rewrite(fepas);
Теперь запишем в файл нужную информацию:
WriteLn(fepas, ‘Азия’);
WriteLn(fepas, 1998);
Поскольку мы не собираемся ничего больше писать в файл, то закрываем его для записи:
Close(fepas);
Вот программа целиком:
VAR fepas :Text;
Begin
Assign(fepas, 'c:\PASCAL\fedos');
Rewrite(fepas);
WriteLn(fepas, ‘Азия’);
WriteLn(fepas, 1998);
Close(fepas);
END.
После выполнения программы вы обнаружите в файле fedos две строки:
Азия
Если бы вы вместо WriteLn использовали Write, то строка была бы одна:
Азия1998
Если к моменту выполнения программы файл fedos не существовал, то процедура Rewrite создаст пустой файл с таким именем в указанном каталоге. Если существовал, то стирает его содержимое.
Если вы не хотите стирать содержимое файла, а просто хотите дописать что-нибудь в его конец, то процедура Rewrite вам не подойдет. Вам вместо нее нужно будет употребить процедуру Append. Вот ее вызов - Append(fepas).
Если вы знаете, какой каталог во время выполнения программы является текущим, и хотите, чтобы файл fedos был создан в текущем каталоге, вы можете записать просто
Assign(fepas, 'fedos')
Информация в наш файл может записываться только по порядку, последовательно. Мы не можем записать что-то сперва в начало файла, потом в конец, потом в середину. То же самое относится и к считыванию, о котором сейчас пойдет речь.
А теперь решим обратную задачу: В некоем файле fedos записаны строки. Вывести первую и третью из них на экран монитора.
VAR fepas :Text;
a,b,c :String; {Три переменные в оперативной памяти, в которые будут
записаны первые три строки из файла}
Begin
Assign(fepas, 'c:\PASCAL\fedos');
Reset(fepas); {Переместим магнитную головку в начало файла для считывания
информации из файла (откроем файл для считывания) }
ReadLn(fepas, a); {Читаем первую строку из файла}
ReadLn (fepas, b); {Читаем вторую строку из файла}
ReadLn (fepas, c); {Читаем третью строку из файла}
Close(fepas);
WriteLn(a); {Печатаем первую строку из файла}
WriteLn(c); {Печатаем третью строку из файла}
END.
Как видите, для того, чтобы добраться до третьей строки, нам пришлось прочитать вторую.
Если третья строка числовая, то можно было бы описать переменную c, как числовую, а не строковую.
А теперь напишем программу, которая в цикле записывает в файл 10 строк, а затем для проверки их считывает.
VAR f :Text;
a,b :String;
i :Byte;
Begin
Assign(f,'c:\PASCAL\textik.txt'); {Обозначим файл textik.txt из каталога PASCAL именем f}
Rewrite(f); {Переместим магнитную головку в начало файла для
записи информации в файл (откроем файл)}
WriteLn('Введите с клавиатуры 10 произвольных строк');
for i:=1 to 10 do begin
ReadLn(a); {Ввести с клавиатуры в оперативную память произвольную строку текста}
WriteLn(f,a) {Записать эту строку из оперативной памяти в файл}
end;
Close(f); {Закрываем файл для записи}
WriteLn('А теперь посмотрим, что мы записали в файл:');
Reset(f); {Переместим магнитную головку в начало файла для
считывания информации из файла (откроем файл)}
for i:=1 to 10 do begin
ReadLn(f,b); {Переслать из файла в оперативную память строку текста}
WriteLn(b) {Послать эту строку из оперативн.памяти на монитор}
end;
Close(f); {Закрываем файл для чтения}
End.
Если вы хотите прочесть текстовый файл, но не знаете, сколько там строк, то вам нужно какое-то средство, чтобы компьютер определил, когда заканчивается файл. Это средство - функция EOF(сокращение от end of file – «конец файла»). Вот фрагмент, решающий дело:
while NOT EOF(fepas) do ... ReadLn(fepas, ....)
пока нет конца файла fepas делай …
Задание 126: “База данных ваших школьных оценок”. Вы завели файл, в который записываете свои школьные оценки. Каждый раз, получив оценку, вы дописываете в файл оценку и предмет, по которому оценка получена. Создайте 4 программы:
1) Для дозаписи в конец файла очередной оценки и предмета.
2) Для вывода на экран всего файла.
3) Для вывода на экран всех отметок по заданному предмету. (Для определенности договоримся, что больше 1000 оценок в год вы не получите.)
4) Для определения, сколько было по заданному предмету таких-то оценок (скажем, троек).
Оформите каждую из четырех программ, как процедуру, и создайте единую программу - “Систему управления базой данных”, которая начинает работу с вопроса: “Чем будем заниматься - дозаписывать, выводить весь файл ...?” и в зависимости от ответа запускает одну из четырех процедур.
Задание 127: Вы можете помочь адмиралу из 12.13 и организовать чтение из файла всей нужной информации о подлодках.
Задание 128: Многие компьютерные игры позволяют “сохраняться”, то есть в любой момент игры при нажатии определенной клавиши записывать в файл все данные об этом моменте, чтобы в следующий раз, когда вы сядете играть, начинать не сначала, а с того момента, в который вы записались. В игре “Торпедная атака” организуйте при нажатии на клавишу S сохранение, то есть запись в файл имени игрока, уровня игры, количества выстрелов и количества попаданий. А при запуске игра должна спрашивать, будем ли возобновлять сохраненную игру или начинать новую.
Не нашли, что искали? Воспользуйтесь поиском по сайту:
©2015 - 2024 stydopedia.ru Все материалы защищены законодательством РФ.
|