Что выполняет данная строка программы var d s real присваивает переменным тип var
Главное меню
Соглашение
Регистрация
Английский язык
Астрономия
Белорусский язык
Информатика
Итальянский язык
Краеведение
Литература
Математика
Немецкий язык
Обществознание
Окружающий мир
Русский язык
Технология
Физкультура
Для учителей
Дошкольникам
VIP — доступ
Автор: Озерков А.В. | ID: 7501 | Дата: 10.2.2016
Помещать страницу в закладки могут только зарегистрированные пользователи
Зарегистрироваться
Получение сертификата
о прохождении теста
Что выполняет данная строка программы var d s real присваивает переменным тип var
Строка программы var d s real имеет значение в контексте языка программирования. Эта строка задает переменные d и s с типом данных real.
В языках программирования, var обозначает ключевое слово, которое используется для объявления переменных. Ключевое слово var позволяет компилятору или интерпретатору языка программирования определить тип данных переменной автоматически, на основе присвоенного значения.
Тип данных real в данном случае обозначает числовой тип данных, который представляет действительные числа (числа с плавающей точкой). Этот тип данных может быть использован для хранения значений вещественных чисел, таких как 3.14 или -1.5.
Присвоение переменным типа var позволяет упростить и ускорить процесс написания кода, так как не требуется указывать тип данных явно. Однако, использование переменных типа var может усложнить чтение и понимание кода, особенно если переменные имеют разные типы данных.
Учебная программа C++, например, позволяет использовать переменные типа var, но рекомендуется использовать явное указание типов для улучшения читабельности кода и уменьшения возможных ошибок.
Значение строки программы var d s real
Строка программы var d s real задает объявление переменных d и s c типом данных real .
В языке программирования, ключевое слово var используется для объявления переменных. Объявление переменных указывает на то, что мы хотим создать переменную с определенным именем и типом данных.
В данном случае, переменные d и s имеют тип данных real . Тип данных real обычно используется для хранения чисел с плавающей точкой. Он может представлять дробные числа.
Значение переменных d и s будет зависеть от дальнейшего кода программы и от присваивания им конкретных значений.
Например, после объявления переменных можно присвоить им значения:
d = 3.14;s = 2.5;
Таким образом, после присваивания, переменная d будет содержать значение 3.14, а переменная s будет содержать значение 2.5.
Использование ключевого слова var перед объявлением переменных позволяет явно указать тип данных переменных. Это делает код более понятным и помогает предотвратить ошибки в программе.
Разъяснение значения строки «var d s real» в программировании
Строка «var d s real» является частью программного кода и имеет определенное значение и значение переменных в этой строке.
Здесь присутствуют ключевые слова «var» и «real», которые указывают на то, что в данный момент происходит объявление и инициализация одной или нескольких переменных.
Переменные, объявленные в этой строке, имеют идентификаторы «d» и «s». Имя «d» и «s» представляет собой идентификаторы переменных, которые позволяют обращаться к ним в программе.
Тип данных «real» указывает, что переменная будет хранить вещественные числа, то есть числа с плавающей точкой.
Таким образом, строка «var d s real» означает объявление двух переменных (d и s) типа real, которые будут использоваться для хранения вещественных чисел.
Применение строки «var d s real» для объявления переменных
Ключевое слово «var»
Ключевое слово «var» в программировании используется для объявления переменных. Оно указывает компилятору, что в данной программе будет использоваться переменная с определенным именем. В строке «var d s real» каждое слово после «var» представляет собой имя переменной.
Переменная «d» типа «real»
Переменная «d» объявлена как тип «real». Тип «real» относится к числовым данным с плавающей точкой. Это означает, что переменная «d» может хранить вещественные числа (числа с десятичной частью).
Переменная «s» без указания типа
Переменная «s» объявлена без явного указания типа. В некоторых языках программирования это может быть допустимо, однако, лучшей практикой является явное указание типа переменной для повышения читаемости кода и улучшения безопасности программы.
Пример использования:
Пример | Описание |
---|---|
d = 3.14; | Присваивание переменной «d» значения 3.14. |
s = «Hello World»; | Присваивание переменной «s» значения «Hello World». |
Преимущества и недостатки использования строки «var d s real»
- Преимущества:
- Краткость объявления нескольких переменных.
- Возможность объявления разных типов переменных.
- Отсутствие явного указания типа переменной «s».
- Ограниченность в выборе доступных типов данных.
Специфика использования типа «var» для переменных
Тип «var» в языке программирования относится к динамической типизации. При использовании типа «var», переменной необходимо присвоить значение при объявлении, и этому значению будет присвоен соответствующий тип данных.
Код Результат var a = 5; a -> тип int var b = «Hello!»; b -> тип string var c = true; c -> тип bool Однако, следует учитывать, что при использовании типа «var» недостаточно явно указать тип данных, что может привести к некорректным результатам или ошибкам в программе.
Тип «var» также может быть использован для объявления переменных без присваивания им значений:
Код Результат var x; x -> тип неопределенный (ошибка при использовании) В этом случае, переменной необходимо будет присвоить значение перед использованием, иначе программа выдаст ошибку.
Использование типа «var» может быть полезным при работе с переменными, значения которых могут меняться в процессе выполнения программы или в зависимости от ввода пользователя.
Однако, не рекомендуется использовать тип «var» для объявления переменных, если их тип данных известен заранее. Это может ухудшить читаемость кода и затруднить его поддержку и отладку.
Определение значений переменных типа «var» с помощью строки «var d s real»
В языке программирования, таком как Pascal, для определения переменных используется ключевое слово «var». Оно позволяет создать переменные различных типов данных и определить их значения. Одним из способов определения значений переменных типа «var» является использование строки «var d s real».
Когда мы указываем в программе такую строку, мы создаем три переменные с именами «d», «s» и «real». Обратите внимание, что ключевое слово «var» обозначает, что мы объявляем новые переменные, а «real» является типом данных переменной «s».
Переменные с типом «var» могут хранить значения различных типов данных, таких как целые числа, вещественные числа, логические значения и строки. В данном случае, переменная «s» будет иметь тип данных «real», что означает, что она может хранить вещественные числа.
Значение переменных можно задать сразу при их создании или позже, путем присваивания им новых значений. Например:
- var d: integer = 10;
- var s: real;
- s := 3.14;
В примере выше, переменной «d» сразу же присваивается значение 10. Переменная «s» остается без значения, и мы можем присвоить ей значение 3.14 позднее.
Использование переменных типа «var» с помощью строки «var d s real» является удобным способом для определения и задания значений переменных в начале программы. Это позволяет программисту легко отслеживать, какие переменные используются в программе и какие типы данных они имеют.
Однако, следует помнить, что использование переменных типа «var» может быть ограничено определенными правилами языка программирования. Например, в Pascal переменная типа «var» должна быть определена перед использованием.
Особенности присвоения переменным типа «var» значения с использованием строки «var d s real»
При объявлении переменной с использованием ключевого слова «var» тип переменной определяется автоматически на основе присвоенного значения.
Ключевое слово «var» позволяет создавать переменные с любым типом данных и автоматически менять их тип во время выполнения программы. Это отличает переменные типа «var» от переменных типизированных, где тип должен быть определен заранее.
Рассмотрим строку программы: var d s real. В данной строке объявляются три переменных типа «var» — «d», «s» и «real». Присвоение типа переменным осуществляется при помощи ключевого слова «var», после которого следует имя переменной.
Конкретные типы переменных «d», «s» и «real» могут быть определены либо явно в другой части программы, либо определены автоматически в зависимости от присвоенных значений.
Например, если переменная «d» присваивается целочисленное значение, она будет иметь тип int. Если переменная «s» присваивается значение строки, то ее тип будет string. А если переменной «real» присваивается значение с плавающей запятой, то ее тип будет float или double.
Для более точного определения типа переменной и избежания ошибок во время выполнения программы, рекомендуется использовать переменные с явным определением типа, а не переменные типа «var».
В общем случае, использование переменных типа «var» позволяет гибко управлять типами данных в программе и упростить ее написание, но может привести к непредсказуемым ошибкам, связанным с автоматическим определением типов.
Преимущества использования строки «var d s real» для инициализации переменных
Строка «var d s real» является сокращенной формой инициализации переменных в языке программирования Pascal. Она позволяет объявить и присвоить значения переменным одновременно, что упрощает и ускоряет процесс написания кода.
Преимущества использования строки «var d s real»:
- Экономия времени и усилий: строка «var d s real» позволяет инициализировать переменные без необходимости отдельно объявлять каждую переменную и задавать ей значение. Это значительно сокращает объем кода и упрощает процесс написания программы.
- Удобство и читаемость кода: использование одной строки для объявления и инициализации переменных делает код более лаконичным и понятным, особенно при объявлении нескольких переменных.
- Гибкость и масштабируемость: использование строки «var d s real» позволяет объявлять и инициализировать переменные различных типов данных, таких как целые числа, строки и числа с плавающей запятой.
- Улучшение производительности: благодаря сокращенной форме инициализации переменных, время, затрачиваемое на написание кода, сокращается, что в свою очередь может повлиять на общую производительность программы.
Важно отметить, что использование строки «var d s real» возможно только в некоторых языках программирования, таких как Pascal, и может быть недоступно или иметь другой синтаксис в других языках.
Рекомендации по использованию строки «var d s real» в программировании
Строка программы «var d s real» встречается в некоторых языках программирования и имеет определенное значение и применение. В данной статье мы рассмотрим основные рекомендации по использованию данной строки в программировании.
1. Понимание типов данных
Перед использованием строки «var d s real» в программе нужно хорошо понять, какие типы данных она представляет. В данном случае, «var» означает переменную, «d» — дробное число (real), «s» — строку. Таким образом, строка «var d s real» объявляет переменные, которые могут содержать значения дробных чисел и строк.
2. Правильное использование переменных
При использовании переменных типа «var d s real» необходимо правильно идентифицировать и использовать каждую переменную в соответствии с ее типом данных. Например, переменная «d» должна использоваться для хранения и работы с дробными числами, а переменная «s» — для работы со строками.
3. Обработка и присвоение значений
При обработке и присвоении значений переменным типа «var d s real» необходимо учитывать их особенности. Например, при работе с дробными числами в переменной «d» нужно уделить внимание точности вычислений и округлению. А при работе с строками в переменной «s» нужно учитывать возможность конкатенации и обработки текстовых данных.
4. Четкое именование переменных
Для повышения читабельности и понимания кода, содержащего переменные типа «var d s real», рекомендуется их четкое именование. Названия переменных должны отражать их назначение и тип данных. Например, переменную для хранения дробного числа можно назвать «decimalNumber», а переменную для хранения строки — «textString».
5. Документирование кода
Для лучшего понимания и поддержки кода, содержащего переменные типа «var d s real», рекомендуется правильно документировать код. Пояснения и комментарии должны быть понятными и содержательными, особенно если код будет использоваться другими разработчиками.
В заключение, использование строки «var d s real» в программировании требует понимания типов данных, правильного использования переменных, обработки и присвоения значений, четкого именования переменных и документирования кода. Соблюдение данных рекомендаций поможет создать более понятный, читаемый и поддерживаемый код.
Вопрос-ответ
Что такое строка программы var d s real?
Строка программы var d s real объявляет две переменные с именами d и s типа real. Данная строка является объявлением переменных и задает их тип. Таким образом, переменные d и s будут могли хранить значения дробного типа.
Какие значения могут принимать переменные типа var?
Переменные типа var могут принимать значения различных типов. В зависимости от программы и требуемых операций, переменные могут хранить значения целого типа (integer), дробного типа (real), символьного типа (char), строкового типа (string), логического типа (boolean) и других.
Какие операции можно выполнять с переменными типа var?
С переменными типа var можно выполнять различные операции в зависимости от их типов. Например, с целыми числами можно выполнять арифметические операции (сложение, вычитание, умножение, деление), а с символами — операции сравнения на равенство или неравенство.
Можно ли объявить переменные типа var без указания их типа?
Нет, нельзя объявить переменные типа var без указания их типа. В языке программирования необходимо явно указывать тип переменных при их объявлении, чтобы компилятор мог корректно работать с ними.
Можно ли присвоить переменным типа var значения других типов?
Да, можно присвоить переменным типа var значения других типов. Если тип присваиваемого значения совпадает с объявленным типом переменной, то присвоение будет успешным. В противном случае, может произойти ошибка во время компиляции или выполнения программы.
2 . Введение в Турбо Паскаль.
Язык Паскаль был разработан Никласом Виртом первоначально для целей обучения программированию.
Во-первых, по своей идеологии Паскаль наиболее близок к современной методике и технологии программирования. В частности, он достаточно полно отражает идеи структурного программирования, что довольно хорошо видно даже из основных управляющих структур языка. Во-вторых, Паскаль хорошо приспособлен для применения технологии разработки программ сверху-вниз (пошаговой детализации). В-третьих, Паскаль содержит большое разнообразие различных структур данных, что обеспечивает простоту алгоритмов, а следовательно снижение трудоемкости при разработке программ.
Основные отличия алгоритмических языков от машинных языков:
— алгоритмический язык обладает гораздо большими выразительными возможностями, т.е. его алфавит значительно шире алфавита машинного языка, что существенно повышает наглядность текста программы;
— набор операций, допустимых для использования, не зависит от набора машинных операций, а выбирается из соображений удобства формулирования алгоритмов решения задач определенного класса;
-формат предложений достаточно гибок и удобен для использования, что позволяет с помощью одного предложения задать достаточно содержательный этап обработки данных;
— требуемые операции задаются в удобном для человека виде, например, с помощью общепринятых математических обозначений;
— для задания операндов операций, используемым в алгоритме данным присваиваются уникальные имена, выбираемые программистом, и ссылка на операнды производится в основном по именам;
— в языке может быть предусмотрен значительно более широкий набор типов данных по сравнению с набором машинных типов данных.Из вышеперечисленного следует, что алгоритмический язык в значительной мере является машинно-независимым.
Для описания синтаксиса алгоритмического языка используется специальный метаязык, позволяющий в компактной форме отразить все особенности конкретных конструкций алгоритмического языка. Мы воспользуемся для этих целей металингвистическими формулами Бэкуса-Наура (язык БНФ).
При описании синтаксиса языка используются некоторые его понятия: определив простейшие из них, с их помощью можно уже достаточно просто определить более сложные понятия и т.д., пока не будет определено наиболее сложное понятие — программа. С точки зрения синтаксиса каждое определяемое понятие (но не основной символ) есть метапеременная языка БНФ, значением которой может быть любая конструкция (т.е. последовательность основных символов) из некоторого фиксированного для этого понятия набора конструкций.
Для каждого понятия языка должна существовать единственная метаформула, в левой части которой указывается определяемое понятие, т.е. метапеременная языка БНФ, а правая часть формулы тем или иным способом задает все множество значений этой метапеременной, т.е. все допустимые конструкции, которые объединяются в это понятие. Все метапеременные заключаются в специальные угловые скобки < и >, которые не принадлежат алфавиту определяемого языка, т.е. являются метасимволами, например, , и т.д. Основные же символы языка указываются непосредственно. Левая и правая части метаформулы разделяются специальным знаком : : =, смысл которого можно интерпретировать как «по определению есть». Обычно в качестве значений метапеременной может приниматься любая из нескольких допустимых конструкций. Все допустимые конструкции указываются в правой части формулы и разделяются метасимволом «|», смысл которого можно передать словом «или» («либо»). Кроме перечисления всех возможных значений метапеременной в правой части метаформулы может быть указано правило построения значений.
2 .2. Основные понятия языка Турбо-Паскаль .
Язык Турбо-Паскаль допускает использование прописных и строчных букв латинского алфавита, знака подчеркивания, арабских цифр и ограничителей.
> :: = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Ограничителями являются знаки операций, скобки, зарезервированные слова и разделители.
Простые операторы:
простым оператором является такой оператор, который не содержит в себе других операторов.
Оператор присваивания
оператор присваивания заменяет текущее значение переменной новым значением, которое определяется выражением, или определяет выражение, значение которого должно возвращаться функцией.
выражение должно быть совместимо по присваиванию с типом переменной или типом значения, возвращаемого функцией в качестве результата
приведем некоторые примеры операторов присваивания:
done := (i >= 1) and (i < 100);
huel := [blue, succ(c)];
Присваивания объектного типа
правила совместимости по присваиванию объектных типов позволяют присваивать экземпляру объекта экземпляр любого из его дочерних типов. такое присваивание представляет собой проекцию потомка на пространство его предка. присваивание экземпляру объектного типа не инициализирует экземпляр. например, в предыдущем примере присваивание f := z означает, что вызов конструктора для f можно опустить.
Операторы процедуры
оператор процедуры определяет активизацию процедуры, обозначенную с помощью идентификатора процедуры. если соответствующее описание процедуры содержит список формальных параметров, то оператор процедуры должен содержать в себе соответствующий ему список фактических параметров (параметры, список которых приводится в определении, являются формальными параметрами, а в операторе вызова процедуры они являются фактическими параметрами). при вызове происходит передача фактических параметров формальным параметрам.
приведем некоторые примеры операторов процедур:
Операторы перехода
оператор перехода goto вызывает передачу управления оператору, которому предшествует метка, указанная в данном операторе перехода. синтаксическая схема оператора перехода имеет следующий вид:
при использовании оператора перехода должны соблюдаться следующие правила:
1. метка, которая указывается в операторе перехода, должна находиться в том же блоке или модуле, что и сам оператор перехода. другими словами, не допускаются переходы из процедуры или функции или внутрь нее.
2. переход извне внутрь структурного оператора (то есть переход на более глубокий уровень вложенности) может вызвать непредсказуемые эффекты, хотя компилятор не выдает сообщения об ошибке. например, вы не должны переходить в тело цикла for.
примечание: хорошая практика программирования требует минимального использования переходов.
Структурные операторы
структурные операторы строятся из других операторов, порядок выполнения которых должен быть последовательным (составные операторы и операторы над записями), определяемым условной передачей управления (условные операторы) или повторяющимся (операторы цикла).
Составные операторы
составные операторы задают порядок выполнения операторов, являющихся их элементами. они должны выполняться в том порядке, в котором они записаны. составные операторы обрабатываются, как один оператор, что имеет решающее значение там, где синтаксис паскаля допускает использование только одного оператора. операторы заключаются в ограничители begin и end, и отделяются друг от друга точкой с запятой.
приведем пример составного оператора:
Условные операторы
условные операторы позволяют выбрать для выполнения один из составных операторов (или не выбрать ни одного).
Оператор условия (if)
синтаксис оператора if можно представить следующим образом:
в выражении должен получаться результат, имеющий стандартный булевский тип. если результатом выражения является истинное значение (true), то выполняется оператор, следующий за ключевым словом then.
если результатом выражения является значение false и присутствует ключевое слово else, то выполнятся оператор, следующий за ключевым словом else. если ключевое слово else отсутствует, то никакой оператор не выполняется.
синтаксическая неоднозначность, возникающая в конструкции:
if e1 then e2 else e3 разрешается путем следующей интерпретации этой конструкции:
if e1 then
if e2 then
примечание: в предшествующем операторе else двоеточие не указывается.
в общем случае ключевое слово else связывается с ближайшим ключевым словом if, которое еще не связано с ключевым словом else.
оператор варианта (case)
оператор варианта (casе) состоит из выражения (переключателя) и списка операторов, каждому из которых предшествует одна или более констант (они называются константами выбора) или ключевое слово else. переключатель (селектор) должен иметь порядковый тип (размером в байт или слово). таким образом, строковый тип и длинный целый тип являются недопустимыми типами переключателя. все константы выбора должны быть уникальными и иметь порядковый тип, совместимый с типом переключателя.
оператор варианта case приводит к выполнению оператора, которому предшествует константа выбора, равная значению переключателя или диапазону выбора, в котором находится значение переключателя. если такой константы выбора или такого диапазона выбора не существует и присутствует ветвь else, то выполнятся оператор, следующий за ключевым словом else. если же ветвь else отсутствует, то никакой оператор не выполняется.
приведем некоторые примеры оператора варианта:
case operator of
Оператор цикла
оператор цикла задает повторное выполнение определенных операторов.
если число повторений заранее известно, то подходящей конструкций является оператор for. в противном случае следует использовать операторы while или repeat.
для управления повторением операторов можно использовать стандартные процедуры break и continue. break завершает оператор цикла, а continue продолжает со следующей итерации этого оператора. подробности вы можете найти в главе 1 «справочного руководства программиста».
Оператор цикла с постусловием (repeat)
в операторе цикла с постусловием (начинающимся со слова repeat) выражение, которое управляет повторным выполнением последовательности операторов содержится внутри оператора repeat.
результат выражения должен быть булевского типа. операторы, заключенные между ключевыми словами repeat и until, выполняются последовательно до тех пор, пока результат выражения не примет значение true. последовательность операторов выполнится по крайней мере один раз, поскольку вычисление выражения производится после каждого выполнения последовательности операторов.
приведем примеры оператора цикла с постусловием:
write(‘введите значение (0..9):’);
until (i >= 0) and (i
Операторы цикла с предусловием (while)
оператор цикла с предусловием (начинающийся с ключевого слова while) содержит в себе выражение, которое управляет повторным выполнением оператора (который может быть составным оператором).
выражение, с помощью которого осуществляется управление повторением оператора, должно иметь булевский тип. вычисление его производится до того, как внутренний оператор будет выполнен. внутренний оператор выполнятся повторно до тех пор, пока выражение принимает значение тruе. если выражение с самого начала принимает значение false, то оператор, содержащийся внутри оператора цикла с предусловием, не выполняется.
примерами операторов цикла с предусловием могут служить следующие операторы:
while i > 0 do
if odd(i) then z := z * x;
i := i div 2;
Операторы цикла с параметром (for)
операторы цикла с параметром (которые начинаются со слова for) вызывает повторяющееся выполнение оператора (который может быть составным оператором) пока управляющей переменной присваивается возрастающая последовательность значений.
в качестве управляющей переменной должен использоваться идентификатор переменой (без какого-либо квалификатора), который обозначает переменную, объявленную локальной в блоке, в котором содержится оператор for. управляющая переменная должна иметь перечислимый тип. начальное и конечное значения должны иметь тип, совместимый по присваиванию с перечислимым типом.
примечание: о локальности и области действия рассказы вается в главе 8.
когда начинает выполняться оператор for, начальное и конечное значения определяются один раз, и эти значения сохраняются на протяжении всего выполнения оператора for.
оператор, который содержится в теле оператора for, выполняется один раз для каждого значения в диапазоне между начальным и конечным значением. управляющая переменная всегда инициализируется начальным значением. когда работает оператор for, значение управляющей переменной (счетчика циклов) увеличивается при каждом повторении на единицу. если начальное значение превышает конечное значение, то содержащийся в теле оператора for оператор не выполнятся. когда в операторе цикла используется ключевое слово downto, значение управляющей переменной уменьшается при каждом повторении на единицу. если начальное значение в таком операторе меньше, чем конечное значение, то содержащийся в теле оператора цикла оператор не выполнятся.
если оператор, содержащийся в теле оператора for, изменяет значение управляющей переменной, то это является ошибкой. после выполнения оператора for значение управляющей переменной становится неопределенным, если только выполнение оператора for не было прервано с помощью оператора перехода.
если принять во внимание эти ограничения, то оператор for v := expr1 to expr2 do body; эквивалентен оператору:
while v <> temp2 do
и оператор цикла: for v := expr1 downto exp2 do body; эквивалентен операторам:
if temp1 >= temp2 then
while v <> temp2 o
где temp1 и temp2 — вспомогательные переменные, тип которых совпадает с основным типом переменной v и которые не встречаются в другом месте программы.
приведем примеры оператора цикла с параметром:
for i := 2 to 63 do
if data[i] > max then max := data[i]
for i := 1 to 10 do
for j := 1 to 10 do
for k := 1 to 10 do
x := x + mat1[i,k]*mat2[k,j];
Оператор with
в операциях над записями оператор with удобно использовать для краткого обращения к полям записи. в операторе with к полям одной или более конкретных переменных типа запись можно обращаться, используя только идентификаторы полей. оперaтор with имеет следующий синтаксис:
возьмем следующее описание:
day : integer:
month : integer;
year : integer:
с учетом данного описания приведем пример оператора with:
with orderdate do
if month = 12 then
year := year + 1
end else
month := month + 1;
это эквивалентно следующему:
if orderdate.month = 12 then
orderdate.month := 1;
orderdate.year := tdate.year + 1
date.month := tdate.month + 1;
в операторе with сначала производится проверка каждой ссылки на переменную, а именно: можно ли ее интерпретировать, как поле записи. если это так, то она всегда интерпретируется именно таким образом, даже если имеется доступ к переменной с тем же именем.
допустим описаны следующие переменные:
x,y: integer;
в этом случае и к x, и к y можно обращаться, как к переменной или как к полю записи. в операторе:
with x do
x между ключевыми словами with и dо относится к переменной типа указатель, а в составном операторе x и y ссылаются на x.x и y.y.
with v1,v2. vn do s;
with v1 do
with v2 do
with vn do
в обоих случаях, если vn является полем и v1, и v2, то она интерпретируется как v2.vn, а не как v1.vn.
если выборка переменной типа запись связана с индексированием массива или разыменованием указателя, то эти действия производятся до того, как будет выполняться составной оператор.
№22 типы данных. классификация
типы данных в языке паскаль делятся следующим образом:
базовые типы данных – типы, определяемые в языке программирования
конструируемы типы данных – типы данных, которые создаются программистом
в этом уроке мы рассмотрим только базовые типы данных кроме указателей.
Порядковые типы данных
с первого взгляда очень трудно представить, как эти типы данных могут быть связаны между собой, однако связь есть, и я попробую ее объяснить. начну уже со знакомых целых типов данных
Целые типы данных
тип данных longint следует использовать для огромных расчетов и не следует использовать в обычных программах. позже я расскажу о действиях и функциях (процедурах), применяемым к порядковым типам данных, но скажу, что особенными для этих типов данных являются операции div и mod.операция div – это операция целочисленного деления, то есть результатом будет целая часть от деления целого числа на целое. операция mod – это операция остатка отделения, т.е она вернет делимое минус делитель умноженное на целую часть.
Символьные типы данных
символьный тип данных это тип char. очевидно, что переменная типа char можно присвоить значение в виде символьной константы, например c:=’a’.но символьный тип данных может иметь значения, задающиеся кодам в таблице ascii-кодов, то есть, то, что приведено в первом примере может быть c:=#65. 65 – ascii код символа а. теперь понятно, почему символьный тип данных – это порядковый тип данных, потому что мы можем любой символ заменить числом в диапазоне 0..255, а все числа идут по определенному порядку.
Логический тип данных
логический тип данных имеет всего два значения и кодируется одни битом его значения true и false, 1 и 0 соответственно истина и ложь.
рассмотрю перечисленные операции. конъюнкция – логическое и или еще ее называют логическим умножением, таблица истинности приведена ниже.
дизъюнкция — логическое или, иначе ее называют логическим сложением. в языке программирования паскаль обозначается or.таблица истинности приведена ниже.
еще есть операция инверсии, в которой все делается в обратную сторону: 0 меняется на 1, 1 меняется на 0.
приоритет логических операций. сначала выполняется операция инверсии, замет конъюнкции, и в последнюю очередь дизъюнкции.
Функции и процедуры, применяемые к порядковым типам данных
после того, как мы убедились, что все вышеназванные типы данных не зря объединены в одну группу, можно будет посмотреть общие для всех этих типов данных функции и процедуры.
сначала рассмотрим функции:
ord(x) — возвращает порядковый номер значения переменной x (относительно того типа, к которому принадлежит переменная х).
pred(x) — возвращает значение, предшествующее х (к первому элементу типа неприменима).
succ(x) — возвращает значение, следующее за х (к последнему элементу типа неприменима).
inc(x) – оператор инкремента, возвращает значение x:=x+1
inc(x,k) — возвращает значение x:=x+k.
dec(x) – оператор декремента, возвращает значение x:=x-1.
dec(x,k) — возвращает значение x:=x-k.
мы рассмотрели порядковые типы данных, но еще не полностью, в части «преобразования типов данных» мы увидим еще функции, применяемые к порядковым типам данных. ну а теперь рассмотрим вещественные типы данных.
Вещественные типы данных
как и с целочисленными типами данных, вещественные тип данных это не только тип real.вещественные типы данных приведены в таблице ниже.
количество байт
диапазон (абсолютной величины)
1.5*10 -45 ..3.4*10 38
2.9*10 -39 ..1.7*10 38
5.0*10 -324 ..1.7*10 308
3.4*10- 4932 ..1.1*10 4932
из этой таблици видно, что тип real – самый оптимальный для использования, так как имеет достаточно большой диапазон значений, но при этом занимает не так много памяти, а тип extended надо использовать лишь для астрономических расчетов и не использовать в обычных программах. к этим типам данных применяются все арифметические операции кроме операций div и mod, еще применяются операции преобразования типов данных.
мы рассмотрели базовые типы данных сполна, осталось только рассмотреть преобразования типов данных, чтобы порядковые не были отдельно от вещественных и были единым целом, базовыми типами данных.
№23 простые типы данных в turbo pascal. примеры
к простым типам относятся порядковые и вещественные типы.
порядковые типы отличаются тем, что каждый из них имеет конечное число возможных значений. эти значения можно определённым образом упорядочить (отсюда – название типов) и, следовательно, с каждым из них можно сопоставить некоторое целое число – порядковый номер значения.
вещественные типы тоже имеют конечное число значений, которое определяется форматом внутреннего представления вещественного числа. однако количество возможных значений вещественных типов настолько велико, что сопоставить с каждым из них целое число (его номер) не представляется возможным.
вещественные типы
2,9×10 -39 — 1,7×10 38
1,5×10 -45 — 3,4×10 38
5×10 -324 — 1,7×10 308
3,4×10 -4932 — 1,1×10 4932
логический тип
символьный тип
все символы кода ascii
№24 структурированные типы данных в turbo pascal. примеры
структурированные типы
любой из структурированных типов (а в турбо паскале их четыре: массивы, запиcи, множества и файлы) характеризуется множественностью образующих этот тип элементов, т.е. переменная или константа структурированного типа всегда имеет неcколько компонентов. каждый компонент, в свою очередь, может принадлежать cтруктурированному типу, что позволяет говорить о возможной вложенности типов. в турбо паскале допускается произвольная глубина вложенности типов, однако суммарная длина любого из них во внутреннем представлении не должна превышать -5520 байт.
4.2.1. Массивы
массивы в турбо паскале во многом схожи с аналогичными типами данных в других языках программирования. отличительная особенность массивов заключается в том, что все их компоненты суть данные одного типа (возможно, структурированного). эти компоненты можно легко упорядочить и обеспечить доступ к любому из них простым указанием его порядкового номера.
4.2.2. Записи
запись — это структура данных, состоящая из фиксированного числа компонентов, называемых полями записи. в отличие от массива, компоненты (поля) записи могут быть различного типа. чтобы можно было ссылаться на тот или иной компонент записи, поля именуются.
структура объявления типа записи такова:
здесь — правильный идентификатор;
record, end — зарезервированные слова (запись,конец); — список полей; представляет собой последовательность разделов записи, между которыми ставится точка с запятой.
каждый раздел записи состоит из одного или нескольких идентификаторов полей, отделяемых друг от друга запятыми. за идентификатором (идентификаторами) ставится двоеточие и описание типа поля (полей), например:
имена полей должны быть уникальными в пределах той записи, где они объявлены, однако, если записи содержат поля-записи, т.е. вложены одна в другую, имена могут повторяться на разных уровнях вложенности.
4.2.3. Множества
множества — это наборы однотипных логически связанных друг с другом объектов. характер связей между объектами лишь подразумевается программистом и никак не контролируется турбо паскалем. количество элементов, входящих в множество, может меняться в пределах от 0 до 256 (множество, не содержащее элементов, называется пустым). именно непостоянством количества своих элементов множества отличаются от массивов и записей.
два множества считаются эквивалентными тогда и только тогда, когда все их элементы одинаковы, причем порядок следования элементов в множестве безразличен. если все элементы одного множества входят также и в другое, говорят о включении первого множества во второе. пустое множество включается в любое другое.
пример определения и задания множеств:
digitchar= set of ‘0’..’9′;
digit = set of 0. .9;
в этом примере множества s1 и s2 эквивалентны, а множество s3 включено в s2 , но не эквивалентно ему.
над множествами определены следующие операции:
= проверка эквивалентности; возвращает true, если оба множества эквивалентны;
<> проверка неэквивалентности; возвращает true, если оба множества неэквивалентны;
>= проверка вхождения; возвращает true, если второе множество включено в первое;
in проверка принадлежности; в этой бинарной операции первый элемент — выражение, а второй — множество одного и того же типа; возвращает true , если выражение имеет значение, принадлежащее множеству:
3 in s6 возвращает true;
2*2 in s1 возвращает false.
дополнительно к этим операциям можно использовать две процедуры. include — включает новый элемент во множество. exclude — исключает элемент из множества.
4.3. Строки
тип string (строка) в турбо паскале широко используется для обработки текстов. он во многом похож на одномерный массив символов array[o..n] of char, однако, в отличие от последнего, количество символов в строке-переменной может меняться от 0 до n, где n — максимальное количество символов в строке. значение n определяется объявлением типа string [n] и может быть любой константой порядкового типа, но не больше 255 . турбо паскаль разрешает не указывать n, в этом случае длина строки принимается максимально возможной, а именно n=255 .
строка в турбо паскале трактуется как цепочка символов. к любому символу в строке можно обратиться точно так же, как к элементу одномерного массива array [0..n] of char.
все остальные действия над строками и символами реализуются с помощью описываемых ниже стандартных процедур и функций.
concat(s1 [,s2, . , sn]) — функция типа string; возвращает строку, представляющую собой сцепление строк-параметров si, s2, . sn.
copy(st, index, count) — функция типа string; копирует из строки st count символов, начиная с символа с номером index.
delete (st, index, count) — процедура; удаляет соunt символов из строки st, начиная с символа с номером index.
insert (subst, st, index) — процедура; вставляет подстроку subst в строку st, начиная с символа с номером index.
length (st) — функция типа integer; возвращает длину строки st.
pos (subst, st) — функция типа integer; отыскивает в строке stпервое вхождение подстроки subst и возвращает номер позиции, с которой она начинается; если подстрока не найдена, возвращается ноль.
str(x [; width [: decimals] ], st) — процедура; преобразует число x любого вещественного или целого типов в строку символов st так, как это делает процедура writeln перед выводом; параметры width и decimals, если они присутствуют, задают формат преобразования: width определяет общую ширину поля, выделенного под соответствующее символьное представление вещественного или целого числа x, a decimals — количество символов в дробной части (этот параметр имеет смысл только в том случае, когда х- вещественное число).
val(st, x, code) — процедура; преобразует строку символов st во внутреннее представление целой или вещественной переменной x, которое определяется типом этой переменной; параметр code содержит ноль, если преобразование прошло успешно, и тогда в x помещается результат преобразований, в противном случае он содержит номер позиции в строке st, где обнаружен ошибочный символ, и в этом случае содержимое х не меняется;
upcase (сн) — функция типа char; возвращает для символьного выражения сн, которое должно представлять собой строчную латинскую букву, соответствующую заглавную букву; если значением сн является любой другой символ (в том числе строчная буква русского алфавита), функция возвращает его без преобразования.
№25 тип – массив. примеры
конечная именованная последовательность однотипных величин называется массивом. чтобы описать массив, надо определить, какого типа его элементы и каким образом они пронумерованы.
type имя_типа = array [тип индекса] of тип_элемента
type mas = array [1..10] of real
color = array [byte] of mas
active = array [menu] of boolean
в первом операторе описан тип массива из вещественных элементов, которые нумеруются от 1 до 10. во втором операторе элементами массива являются массивы типа mas, а нумеруются они в пределах, допустимых для типа byte, т.е. от 0 до 255. в третьем в качестве индекса использовано имя из раздела «перечисляемый тип данных», а сами элементы могут принимать значения true или false.
тип элементов массива модет быть любым, кроме файлового, тип индексов — интервальным, перечисляемым или byte. чаще всего для описания индекса используется интервальный тип данных.
размещение массива в памяти происходит до выполнения программы, поэтому при описании индекса можно применять только константы или константные выражения. использовать для этого переменные нельзя!
обычно при описании массива верхняя граница его индекса задается в виде именованной константы:
type intmas = array [1..n] of integer;
c массивами в целом можно выполнять только одну операцию: присваивание. все остальные действия выполняются с отдельными элементами массива.
при обращении к элементу массива автоматический контроль выхода индекса за границу массива не производится.
инициализация массивов. можно присвоить значения элементам массива до начала выполнения программы. это делается так же, как и для простых переменных, — в разделе описания констант:
const a: intmas = (0,5, -7,100,15,1);
количесвто констант должно точно соответствовать числу элементов масива. массивы, описанные в разделе var главной программы, обнуляются автоматически.
№26 тип – запись. примеры
в программах часто возникает необходимость логического объединения данных. однотипные данные организуются в массивы, а для объединения разнотипных данных предназначен типе «запись». он вводится с помощью ключесвого слова record. элементы записи называются полями.
type имя_типа = record
описание 1-го поля записи;
описания 2-го типа записи;
описание n-го поля записи»
поля записи могут быть любого типа, кроме файлового.
type goods = record
name=: string [20];
price=: real;
number=: integer;
переменные типа “запись» описываются обычным образом. можно задавать описание типа при описании переменной, создавать массивы из записей, записи из массивов и т.д.
есть 2 способа доступа к полю записи: либо с помощью конструкции имя_записиюимя_поля, либо с использованием оператора присоединения with:
with g1 do begin
price:=200; number:=10
оператор with удобнее использовать, если требуется обращаться к нескольким полям одной и той же записи.
пример. сведения о товарах на складе хранятся в текстовом файле. для каждого товара отводится одна строка, в первых 20 позициях которой записано наименование товара, а затем через произвольное количесвто пробелов его цена и количество единиц. программа по запросу выдает сведения о товаре или сообщение о том, что товар не найден
program store;
const max_n = 100;
str20 = string[20];
goods = record
number=:integer;
var stock: array[1..max_n] of goods;
i,j,len: integer;
found: boolean;
assign(f,’stock.txt’); reset(f);
while not eof(f) do begin
with stock[i] do readln(f,name,price,number);
if i>max_n then begin
writeln (‘переполнение массива’); exit end;
while true do begin
writeln (‘введите наименование:’); readln(name);
len:= length(name);
if len = 0 then break;
for j:= len + 1 to 20 do name:= name + ‘ эж
for j:=1 to i-1 do begin
if name <> stock[j].name then continue;
with stock[j] do writeln (name:22, price:7:2, number:5);
if not found then writeln(‘товар не найден’);
инициализация записей выполняется в разделе констант, при этом для каждого поля задается его имя, после которого через двоеточие указывается значение
const g: goods = (name:’boots’; price:200; number:10);
записи с вариантной частью применяются для экономии памяти. например, в телефонной книге для каждого абонента хранится его фамилия и телефонный номер, при этом для служебных контактов указывается должность, а для личных – дата рождения и код на входной двери в дом. изменяющаяся чатсь памяти называется вариантной. все варианты располагаются в памяти на одном и том же меcnt в конце записи:
type contact = record
name:string[40];
tel:string[15];
case i:integer of
0: (post:string[20]);
1: (date:string[10]; code:word);
вариантная часть может быть только одна, ее длина равна длине наибольшего из вариантов. в данном примере адрес начала поля post совпадает с началом поля date. записи с вариантной частью
записи с вариантной частью применяются только тогда, когда известно, что любая конкретная запись может содержать набор полей только из одного варианта. какой именно вариант используется можно определить по значению поля i, о формировании значения которого должен позаботиться сам программист.
поле варианта должно быть порядкового типа. часто его делают перечисляемым. например, пусть требуется хранить в памяти характеристики геометрических фигур — прямоугольника, треугольника и круга. для каждой из них задается местоположение (это будет общая часть записи), а также длины сторон для прямоугольника, координаты 2-х вершин для треугольника и радиус для круга:
figure = (rect, triangle, circle);
shape = record;
case kind: figure of
rect: (height, width,:real);
triangle: (x2,y2,x3,y3:real);
circle: (radius:real);
можно не хранить в записи поле варианта, в этом случае его имя не указывается:
type shape = record
case integer of
0: (height, width,:real);
1: (x2,y2,x3,y3:real);
2: (radius:real);
доступ к вариантным полям остается на совести программиста, т.е. ничто не мешает записать в вариантную часть одни поля, а обратиться к ним через другие.
№27 тип – множество. примеры
множественный тип данных в языке паскаль соответствует математическому представлению о множествах: это ограниченная совокупность различных элементов. множество создается на сонове элементов базового типа – это может быть перечисляемый тип, интервальный или byte. в множестве не может быть более 256 элементов, а их порядковые номера должны лежать в пределах от 0 до 255.
множество описывается с помощью служебных слов set of.
type имя_типа = set of базовый_тип
примеры описания:
type caps = set of ‘a’..’z’;
colors = set of (red, green, blue);
numbers = set of byte;
принадлежность переменных к множественному типу может быть определена прямо в разделе описания переменных
var oct: set of 0..7;
Константы множественного типа записываются в виде заключенной в квадратные скобки последовательности элементов или интервалов базового типа, разделенных запятыми.
Константа вида [ ] означает пустое множество.
Тип «множество» задает набор всех возможных подмножеств его элементов, включая пустое. Если базовый тип, на котором строится множесвто, имеет k элементов, то число подмножеств, входящих в это множество, равно 2 k .
Переменная типа «множество» содержит одно конкретное подмножесвто значений множества. Пусть имеется переменная b интервального типа:
var b: 1..3;
Эта переменная может принимать три различных значения 1,2 или 3. Переменная m типа «множество».
var m: set of 1..3
может принимать 8 различных значений
[ ] [1] [2] [3] [1,2] [1,3] [2,3] [1,2,3]
Порядок перечисления элементов базового типа в константах не имеет значения
Операции над множествами
Величины множественного типа не могут быть элементами списка ввода-вывода. Допустимые операции над множествами
Операции над множествами в соновном соответствуют операциям, определенным в теории множеств. Объединение множеств А и В – это множество, состоящее из всех элементов, принадлежащих А и В. Пересечение множеств А и В – множество, состяощее из элементов, принадлежащих одновременно А и В. Дополнение множеств А и В – множество, состоящее из элементов множества А, не принадлежащих В.
Тождественность множеств А и В означает, что эти множества совпадают, нетождественность – не совпадают. Множество А содержится в множестве В, если все элементы А принадлежат В. Множество А содержит множество В, если все элементы В принадлежат А.
В операциях могут участвовать переменные и константы совместимых множественных типов. Исключение составляет операция in: ее первый операнд должен принадлежать базовому типу элементов множества, записанного вторым операндом.
Пример. Пусть задано множество, основанное на значениях прописных латинских букв:
type Caps = set of ‘A’ .. ‘Z’;
var a,b,c: Caps;
if a=b then writeln (‘тождественны’);
if a<>b then writeln (‘не тождественны’);
if ‘N’ in b then writeln (‘ в b есть N’);
С помощью констант-множеств часто проверяют, входит ли символ в заданный диапазон.
Является ли введенной символ цифрой:
if c in [‘0’..’9’] then…
В гонках участвуют 30 машин со стартовыми номерами от 101 до 130. Проводится 5 заездов по 6 машин. Программа формирует состав заездов случайным образом.
program race;
var cast, lap: set of 100..130;
for i:=1 to 5 do begin
write (i, ‘-й заезд’);
for j:= 1 to 6 do begin
n:= random (30) +101;
until not 9n in lap) and not (n in cast);
cast:= cast+lap;
№28 Тип — строка. примеры
Строки используются для хранения последовательностей символов. В Паскале существуют 3 типа строк:
- стандартные (string)
- определяемые программистом на основе string
- строки в динамической памяти
Строка типа string может содержать до 255 символов. Под каждый символ отводится по 1 байту, в котором хранится код символа. Еще один байт отводится под фактическую длину строки. Т.о., в памяти под одну переменную типа string всегда отводится 256 байт.
Для коротких строк использовать стандартную строку неэффективно, поэтому в язык введена возможность самостоятельно задавать максимальную длину строки
Str4 = string[4];
Здесь описан собственный тип данных с именем str4. Переменная этого типа занимает в памяти 5 байт.
Длина строки должна быть константой или константным выражением, потому что инструкции по выделению памяти формируются компилятором до начала выполнения программы.
Примеры описания:
Const n=15
Var s: string
S1: str4
S2: string [n]
Инициализация строк, как и переменных других типов, выполняется в разделе описания констант
const s3: string[15] = ‘shooshpanchik’;
Внутреннее представление строки s3:
S3:string [15]
Строки можно присваивать друг другу. Если максимальная длина результирующей строки меньше длины исходной, лишние символы справа отбрасываются:
s2:= ‘shooshpanchik’;
Строки можно склеивать (сцеплять) между собой с помощью операции конкатенации, котороая обозначается знаком +
s1:= ‘ком’;
s2:= s1+’пот’;
Строки можно сравнивать друг с другом с помощью оперций отношения. При сравнении строки рассматриваются посимвольно слева направо, при этом сравниваются коды соответствующих пар символов. Строки равны, если они имеют одинаковую длину и посимвольно эквивалентны. В строках разной длины существующий символ всегда больше соответствующего ему отсутствующего символа
Имя строки может использоваться в процедурах ввода-вывода:
readln (s1,s2);
при вводе в строку считывается из входного потока количесвто символов, равное длине строки или меньшее, если символ перевода строки (который вводится нажатием клавиши Enter) встретится раньше. При выводе под строку отводится количесвто позиций, равное ее фактической длине.
К отдельному символу строки можно обращаться как к элементу массива символов, например s1[4]. Символ строки совместим с типом char, их можно использовать в выражениях одновременно:
s1[4]:= ‘X’; writeln (s2[3]+s2[5]+’r’);
При работе со строками, как правило, возникает необходимость выполнять определенный набор действий со строкой и ее фрагментами, например копирование, вставку, удаление или поиск. Для эффективной реализации этих действий в Паскале предусмотрены стандартные процедуры и функции.
Функция Concat(s1,s2..sn) возвращает строку, являющуюся слиянием строк s1,s2..sn. Ее действие аналогично операции конкатенации.
Функция Copy(s,start,len) возвращает подстроку длиной len, начинающуюся с позиции start строки s. Параметры len и start должны быть целого типа.
Процедура Delete(s,start,len) удаляет из строки s, начиная с позиции start, подстроку длиной len.
Процедура Insert(subs,s,start) вставляет в строку s подстроку subs, начиная с позиции start/
Функция Length(s) возвращает фактическую длину строки s, результат имеет тип byte.
Функция Pos(subs,s) ищет вхождение подстроки subs в строку s и возвращает номер первого символа sums в s или 0, если subs не содержится в s.
Процедура Str(x,s) преобразует числовое значение x в строку s, при этом для x может быть задан формат, как в процедурах вывода write и writeln.
Процедура Val)s,x,errcode) преобразует строку s в значение числовой переменной x, при этом строка s должна содержать символьное представление числа. В случае успешного преобразования переменная errcode равна 0. Если же обнаружена ошибка, то errcode будет содержать номер позиции первого ошибочного символа, а значение x не определено.
Программа, которая читает текст из файла и выводит его на экран, заменяя заданную с клавиатуры последовательность символов на многоточие
program censor;
var s,str: string[10];
assign(f,’primer.txt’); reset(f);
writeln(‘какую последовательность заменять?’); readln(s);
while not eof(f) do begin
while i<>0 do begin
if i<>0 then begin
delete(str,i,dl);
№29 Тип – файл. Примеры
Файловые типы данных введены в язык для работы с внешними устройствами – файлами на диске, портами, принтерами и т.д. Передача данных с внешнего устройства в оперативную память називается чтением, или вводом, обратный процесс – записью, или выводом.
Файловые типы языка Паскаль бывают стандартные и определяемые программистом. Стандартными являются текстовый файл (text) и бестиповой файл (file).
Описание их в программе:
Программист может определить файл, состоящий из элементов определенного типа. Такой файл называется компонентным или типизированным:
var fc: file of
Компоненты могут быть любого типа, кроме файлового. Любой файл, в отличие от массива и записи, может содержать неограниченное количество элементов.
Текстовые файлы предназначены для хранения информации в виде строк символов. При выводе в текстовый файл данные преобразуются из внутренней формы представления в символьную, понятную человеку, при вводе выполняетс обратное преобразование.
Бестиповые и компонентные файлы хранят данные в том же виде, в котором они представлены в оперативной памяти, т.е. при обмене с файлом происходит побитовое копирвоание информации.
Доступ к файлам может быть последовательным, когда очередной элемент можно прочитать (записать) только после аналогичной операции с предыдущим элементов и прямым, при котором выполняется чтение )запись) произвольного элемента по заданному адресу. Текстовые файлы позволяют выполнять только последовательный доступ, в бестиповых и компонентных можно использовать оба метода.
Прямой доступ возможе блягодаря тому, что данные в этих файлах условно разделены на блоки одинакового размера и перед операцией обмена выполняется установка текущей позиции файла на заданный блок. Прямой доступ в сочетании с отсутствием преобразований обеспечивает высокую скорость получения нужной информации.
Для понимания сути работы с файлами полезно разделить их по признаку наличия или отсутствиия преобразования информации при выполнении чения-записи и по способу доступа
Чтобы не путать файлы в программе и файлы на диске, переменные файлового типа называют логическими файлами, а реальные устройства и файлы на диске – физическими файлами. Их имена задаются с помощью строк символов:
‘Primer.pas’ – имя файла в текущем каталоге
‘D:\pascal\input.txt’ – полное имя файла
‘CON’ ‘NUL’ ‘COM1’ ‘PRN’ – имена устройств
Для организации ввода-вывода в программе необходимо выполнить следующие действия:
1. Объявить файловую переменную
2. Связать ее с физическим файлом
3. Открыть файл для чтения и/или записи
4. Выполнить операции ввода-вывода
Все стандартные процедуры и функции Паскаля, обеспечивающие ввод-вывод данных, работают только с логическими файлами, т.е. с файловыми переменными. Перед выполнением операций файловая переменная связывается с физическим файлом, после чего он в тексте программы не упоминается.
Ввод-вывод выполняется не непосредственно между внешним устройством и переменными программы, а через так называемый буфер – специальную область оперативной памяти. Буфер выделяется для каждого открытого файла. При записи в файл вся информация сначала направляется в буфер и там накапливается до тех пор, пока весь буфер не заполнится. Только после этого или после специальной команды сброса происходит передача данных на внешнее устройство. При чтении из файла данные вначале считываются в буфер, причем данных считывается не столько, сколько запрашивается, а сколько поместится в буфер.
Механизм буферизации позволяет более быстро и эффективно обмениваться информацией с внешними устройствами.
В Паскале есть подпрограммы, применяемые для файлов любог типа, а также подпрограммы для работы с определенными типами файлов
Подпрограммы для работы со всеми типами файлов
assign(var f;filename:string);
Связывает логический файл f с физическим файлом, имя которого задано в строке filename. Если путь к файлу не задан, предполагается, что он находится в текущем каталоге.
close(var f)
Закрывает открытый логический файл. Вызов процедуры close необходим при завершении работы с файлом, который был октрыт для записи, поскольку при ее выполнении происходит выгрузка содержимого буфера. При отсутствии процедуры close последнее содержимое буфера вывода может быть утеряно. Для входных файлов закрывать файл не обязательно.
erase(var f)
Уничтожает физический файл, который был связан с файловой переменной f. Файл к моменту вызова этой процедуры должен быть закрыт.
rename(var f;newname:string)
Переименовывает физический файл на диске, связанный с логическим файлом f. Переименование возможно после закрытия файла.
reset(var f)
Открывает логический файл f для последубщего чтения данных, т.е. открывает входной файл. После успешного выполнения процедуры reset файл готов к чтению из него первого элемента.
rewrite(var f)
Открывает логический файл f для записи данных (открывает выходнйо файл). После успешного выполнения этой процедуры файл готов к записи в него первого элемента. Если физический файл, с которым связана переменная f, чуществовал ранее, он очищается, т.е вся информация из него теряется. Если файл не существовал, он создается
eof(var f):Boolean
Возвращает значение true, если при чтении достигнут конец файла. Это означает, что прочитан последний элемент в файле или что файл после открытия оказался пуст.
I0result: integer
Возвращает целое число, соответствующее коду последней ошибки ввода-вывода. При номральной завершении операции функция вернет значение 0. Значение функции I0result необходимо присваивать какой-либо переменной, т.к. при каждом вызове функция обновляет свое значение. Функция I0result работает только при выключенном режиме проверки ошибок ввода-вывода, т.е. с ключом компиляции .
Текстовые файлы
Тексовый файл представляет собой последовательность строк символов переменной длины. Каждая строка заканчивается символами перевода строки и возврата каретки (их коды 13 и 10). Эти символы вставляются в физический файл при нажатии клавиши Enter. При чтении файла эти символы не вводятся в переменные в программе, а воспринимаются как разделитель.
Текстовый файл можно открыть не только для чтения или записи с помощью процедур reset и rewrite, но и для добавления информации в конец:
append(var f)
Для чтения из текстового файла применяются процедуры:
read (f, список)
readln (f, [список])
Они отличаются от известных процедур ввода с клавиатуры только наличием первого параметра – имени логического файла.
Для ввода с клавиатуры определено стандартное имя файла INPUT, а для вывода на экран – OUTPUT. Эти файлы отличаются от обычных тем, что их нельзя открывать и закрывать, поскольку это делается автоматически и их имена можно не указывать при обращении к процедурам ввода и вывода.
Процедуры записи в текстовый файл:
write(f, список)
writeln(f, [список])
При записи в текстовый файл происходит преобразование из внутренней формы представления выводимых величин в символьные строки.
Чтение и запись выполняются последовательно, т.е. считать или записать очередной символ можно только после аналогичной операции с предыдущим.
flush(var f:text)
Процедура принудительно записывает данные из буфера в файл независимо от степени заполнения буфера. Прмиеняется к открытым выходным файлам.
settextbuf(var f:text; var buf; bufsize:word)
Процедура служит для увеличения или уменьшения буфера ввода-вывода текстового файла f. Размер буфера для текстовых файлов по умолчанию равен 128 байт. Увеличение буфера сокращает количество обращений к диску. Рекомендуется изменять размер буфера до открытия файла. Буфер файла начнется с первого байта переменной buf. Размер буфера задается в необязательном параметре budsize. Если параметр отсутствует, размер буфера определяется длиной переменной buf.
seekEof (var f:text):Boolean
Функция возвращает значение true, если до конца файла остались только строки, заполненные пробелами.
seekEoln (var f:text):boolean
Функция возвращает значение true, если до конца строки остались только пробелы.
Бестиповые файлы
Бестиповые файлы предназанчены для хранения участков оперативной памяти на внешних носителях. После описания файловой переменной
var имя: file;
ее требуется связать с физическим файлом с помощью процедуры assign. Чтение и запись производятся через буфер порциями равными размеру буфера. Размер буфера, отличающийся от стандартного (128байт), можно задать с помощью второго параметра процедур reset и rewrite при открытии файла.
reset(var f:file; bufsize:word)
Размер буфера должен находиться в пределах от 1 байта до 64 Кбайт.
Собственно чтение и запись выполняются с помощью процедур blockread и blockwrite
blockread(var f:file; var x:count; var num: word)
Процедура blockread считывает в переменную x количесвто блоков count. Длина блока равна размеру буфера. Значение count должно быть больше или равно 1, за одно обращение нельзя ввести больше 64Кбайт. Поскольку при вводе никаких преобразований данных не выполняется, имеет значение только адрес начала области памяти и ее длина, поэтому тип переменной x не указывается.
Необязательный параметр num возвращает количество прочитанных блоков. В случае успешного завершения операции чтения оно равно запрошенному, в случае аварийной ситуации параметр num будет содержать число успешно прочитанных блоков. Следовательно, с помощью параметра num можно контролировать правильность выполнения операции чтения.
Процедура blockwrite записывает в файл количесвто блоков, равно count, начиная с адреса, заданного переменной x. Длина блока равна длине буфера. Необязательный параметр num возвращает число успешно записанных боков (неудача может произойти, например, из-за переполнения или сбоя диска).
Для бестиповых файлов применяется как последовательный, так и прямой доступ.
Программа выполняет ввод вещественных чисел из текстового файла и запись их в бестиповой файл блоками по 4 числа
program create_bfile;
var buf: array[1..4] of real;
name_in, name_out: string;
writeln (‘введите имя входного файла’); readln (name_in);
assign(f_in,name_in);
if I0result <>0 then begin
writeln (‘файл ‘,name_in, ‘не найден’); exit end;
writeln (‘введите имя выходного файла ‘); readln(name_out);
assign(f_out, name_out);
rewrite (f_out, sizeof(real)*4);
while not eof(f_in) do begin
read(f_in,buf[i]);
if i=4 then begin
blockwrite (f_out,buf,1); i:=1; end;
if i<>o then begin
for k:=i+1 to 4 do buf[k]:=0;
blockwrite (f_out, buf,1);
close (f_in); close (f_out);
Компонентные файлы
Компонентные файлы применяются для хранения однотипных элементов в их внутренней форме представления. Тип компонент задается после ключевых слов file of.
var имя: file of тип_компонент;
Компоненты могут быть любого типа, кроме файлового. В операциях ввода-вывода могут участвовать только величины того же типа, что и компоненты файла:
type mas=array[1..100] of real;
f: file of mas;
assign(f,’some_file.dat’); rewrite(f);
Компонентой этого файла является массив целиком. В аткой файл нельзя записать отдельный элемент массива или простую переменную вещественного типа. За одну операцию записывается или считывается столько компонент, сколько перечислено в процедурах write ли read.
Из текстового файла прочитать пары вещественных чисел, считая первое вещественной, а второе – мнимой составляющей комплексного числа, и записать их в файл комплексных чисел
program tip_file;
complex=record
var x:complex;
f2:file of complex;
assign(f1,’tipfile.dat’); reset(f1);
assign(f2,’tipfile.res’); rewrite(f2);
while not eof(f1) do begin
read(f1,x.d,x.m); write(f2,x);
close(f10; close(f2);
Прямой доступ
При последовательном доступе чтение или запись очередного элемента файла возможны только после аналогичной операции с предыдущим элементом. Например, чтобы получить n-й элемент файла, требуется считать n-1 элементов. Бестиповые и компонентные файлы состоят из блоков одинакового размера. В бестиповом файле размер блока равен длине буфера, а в компонентном – длине компоненты. Это позволяет применить к таким файлам прямой доступ, при котором операции выполняются с заданным блоком. Прямой доступ применяется только для физических файлов, расположенных на дисках.
С помощью стандартной процедуры seek производится установка текущей позиции в файле на начало заданного блока, и следующая операция чтения-записи выполняется, начиная с этой позиции. Первый блок файла имеет номер 0.
Стандартные подпрограммы, используемые для реализации прямого доступа
filepos(var f):longint
Функция возвращет текущую позицию в файле f. Для только что открытого файла текущей позицией будет 0. После чтения или записи первого блока текущая позиция станет равно 1. После прочтения последней записи функция возвратит количесвто блоков в файле.
filesize (var f):longint
Функция возвращает количество блоков в открытом файле а
seek(var f; n:longint)
процедура выполняет установку текущей позиции в файле (позиционирование). В параметре n задается нмоер блока, к которому будет выполняться обращение. Блоки нумеруются с 0. Например, чтобы работать с четвертым блоком, необходимо задать значение n равное 3. Процедура seek работает с открытыми файлами.
truncate(var f)
процедура устанавливает в текущей позиции признак конца файла и удаляет все последующие блоки.
Программа, которая выводит на экран заданную по номеру запись из файла, сформирвоанного в программе create_bfile:
program ger_bfile;
var buf:array[1..4] of real;
filename:string;
writeln(‘введите имя входного файла: ‘); readln(filename);
assign(f,filename);
reset(f,sizeof(real)*4);
if i0result <>0 then begin
writeln(‘файл ‘, filename, ‘не найден’); exit end;
while true do begin
write(‘введите номер записи или -1 для окончания’);
writeln(‘такой записи в файле нет’); exit end;
blockread(f,buf,1);
for i:=1 to 4 do write(buf[i]:6:1);
Таким же образом можно изменять заданную запись в файле. Файл при этом может быть открыт как для чтения, так и для записи. Попытка чтения-записи несуществующего блока приводит к ошибке времени выполнения.
Стандартный модуль Dos содержит полпрограммы, с помощью которых можно обращаться к некоторым функциям операционной системы, например получать и устанавливать время создания и атрибуты файла, выполнять поиск в заданных каталогах по имени файла, получать объем свободного дискового пространства и т.д. Воспользоваться этими подпрограммами можно, подключив к своей программе модуль Dos в разделе uses.
№30 Процедуры передачи управления. Примеры
В Паскале есть несколько стандартных процедур, изменяющих последовательность выполнения операторов:
- break — завершает выполнение цикла, внутри которого записана;
- continue — выполняет переход к следующей итерации цикла;
- exit — выходит из программы или подпрограммы, внутри которой записана;
- halt — немедленно завершает выполнение программы.
const MaxIter = 500;
var x, eps : double;
done : boolean;
writeln(‘Введите аргумент и точность:’);
readln(x, eps);
while abs(c) > eps do begin
c := c * sqr(x) /(2 * n + 1)/(2 * n + 2);
if n > MaxIter then begin
writeln(‘Ряд расходится!’);
done := false; break
if done then
writeln(‘Для аргумента ‘, x, ‘ значение функции: ‘, y, #13#10,
‘вычислено с точностью’, eps, ‘ за ‘, n, ‘ итераций’);
Оператор Go to
Этот оператор имеет простой синтаксис: в точке программы, из которой требуется организовать переход, после слова goto через пробел записывается имя метки, например, goto 1 или goto error. При программировании на Паскале необходимость в применении оператора перехода возникает в очень ограниченном количестве ситуаций, в большинстве же случаев используются операторы циклов вместе с процедурами передачи управления.
Использование оператора безусловного перехода оправдано, как правило, в двух случаях:
- принудительный выход вниз по тексту программы из нескольких вложенных циклов или переключателей;
- переход из нескольких мест программы в одно (например, если перед выходом из программы необходимо всегда выполнять какие-либо действия).
Во всех остальных случаях следует привести алгоритм к структурному виду, то есть преобразовать его так, чтобы он мог быть записан с помощью базовых конструкций.
№31 Совместимость типов
Операнды в выражениях должны быть совместимых типов. Совместимость типов величин, участвующих в каждой операции, достигается при выполнении по крайней мере одного из следующих условий:
- оба типа одинаковые
- оба типа вещественные
- оба типа целочисленные
- один тип является поддиапазоном другого
- оба типа являются отрезками одного и того же основного типа
- оба типа являются множественными типами с совместимыми базовыми типами
- один тип является строковым типом, другой – строковым или типом pchar
- один тип – pointer, другой – любой тип указателя
- один тип – pchar, другой – символьный массив с нулевой базоу вида array[0..X] of char (только при разрешении расширенного синтаксиса директивой
- оба типа являются указателями идетичных типов (только при разрешении расширенного синтаксиса директивой )/
- оба типа являются процедурными с идентичными типами результатов, одинаковым числом параметров и соответствием между параметрами
№32 Совместимость по присваиванию
Этот вид совместимости требуется при присваивании значений, например в операторе присваивания или при передаче значений в подпрограмму
Значение типа Т1 является совместимым по присваиванию с типом Т2 (т.е. допустим оператор Т1:=Т2), если выполняется одно из следующих условий:
- Т1 и Т2 – тождественные типы (кроме файловых или типов, содержащих элементы файлового типа).
- Т1 и Т2 – совместимые порядковые типы, при этом значения типа Т2 попадают в диапазон возможных значений Т1.
- Т1 и Т2 – вещественные типы, при этом значения типа Т2 попадают в диапазон возможных значений Т1.
- Т1 – вещественный тип, а Т2 – целочисленный
- Т1 и Т2 – строковые типы
- Т1 – строковый тип, а Т2 – символьный (char)
- Т1 и Т2 – совместимые множественные типы, при этом все значения типа Т2 попадают в диапазон возможных значений Т1
- Т1 и Т2 – совместимые типы указателей
- Т1 – тип char, а Т2 – строковая константа (только при разрешении расширенного синтаксиса директивой
- Т1 – тип char, а Т2 – символьный массив с нулевой базой array[0..n] of char (только при разрешении расширенного синтаксиса директивой
- Т1 и Т2 – совместимые процедурные типы
- Т1 представляет собой процедурный тип, а Т2 – процедура или функция с идентичным типом результата и соответствующими параметрами
На этапе компиляции и выполнения выдается сообщение об ошибке, если совместимость по присваиванию необходима, а ни одно из условий предыдущего списка не выполнено.
№33 Подпрограммы. Процедуры и функции. Примеры записи на Turbo Pascal
Подпрограмма – это фрагмент кода, к которому можно обратиться по имени. Она описывается один раз, а вызываться может столько раз, сколько необходимо. Одна и та же подпрограмма может обрабатывать различные данные, переданные ей в качестве аргументов.
В Паскале имеется два вида подпрограмм: процедуры и функции. Они имеют незначительные отличия в синтаксисе и правилах вызова. Процедуры и функции определяются в соответствующих разделах описания, до начала блока исполняемых операторов.
Само по себе описание не приводит к выполнению подпрограммы. Для того, чтобы подпрограмма выполнилась, ее надо вызвать. Вызов записывается в том месте программы, где требуется получить результаты работы подпрограммы. Подпрограмма вызывается по имени, за которым следует список аргументов в круглых скобках. Если аргументов нет, скобки не нужны. Список аргументов при вызове как бы накладывается на список параметров, поэтому они должны попарно соответствовать друг другу. Правила соответствия подробно рассматриваются в следубщих разделах. Процедура вызывается с помощью отдельного орператора, а функция – в правой части оператора присваивания:
Внутри подпрограмм можно описывать другие подпрограммы. Они доступны только из той подпрограммы, в которой они описаны. Рассмотрим правила описания подпрограмм.
Процедуры
Структура процедуры аналогична структуре основной программы:
procedure имя [(список параметров)];
Найти разность средних арифметических значений двух вещественных массивов из 10 элементов.
Как видно из условия, для двух массивов требуется найти одну и ту же величину — среднее арифметическое. Следовательно, логичным будет оформить его нахождение в виде подпрограммы, которая сможет работать с разными массивами.
program dif_average;
const n = 10;
type mas = array[1 .. n] of real;
var a, b : mas;
dif, av_a, av_b : real;
procedure average(x : mas; var av : real);
var i : integer;
for i := 1 to n do av := av + x[i];
for i := 1 to n do read(a[i]);
for i := 1 to n do read(b[i]);
average(a, av_a);
average(b, av_b);
dif := av_a — av_b;
writeln(‘Разность значений ‘, dif:6:2)
Описание процедуры average расположено в строках с по . В строках, помеченных цифрами и , эта процедура вызывается сначала для обработки массива а, затем — массива b. Эти массивы передаются а качестве аргументов. Результат вычисления среднего арифметического возвращается в главную программу через второй параметр процедуры.
Функции
Описание функции отличается от описания процедуры незначительно:
function имя [(список параметров)] : тип;
разделы описаний
раздел операторов
имя := выражение;
Функция вычисляет одно значение, которое передается через ее имя. Следовательно, в заголовке должен быть описан тип этого значения, а в теле функции — оператор, присваивающий вычисленное значение ее имени. Этот оператор не обязательно должен находиться в конце функции. Более того, таких операторов может быть несколько – это определяется алгоритмом, реализованным в функции
Найти разность средних арифметических значений двух вещественных массивов из 10 элементов.
program dif_average1;
type mas = array[1 .. n] of real;
function average(x : mas) : real;
var i : integer;
for i := 1 to n do av := av + x[i];
average := av / n;
for i := 1 to n do read(a[i]);
for i := 1 to n do read(b[i]);
dif := average(a) — average(b);
writeln(‘Разность значений ‘, dif:6:2)
Оператор, помеченный комментарием , представляет собой заголовок функции. Тип функции определен как вещественный, потому что такой тип имеет среднее арифметическое элементов вещественного массива. Оператор присваивает вычисленное значение имени функции. В операторе функция вызывается дважды: сначала для одного массива, затем для другого.
№34 Глобальные и локальные переменные
В IBM PC-совместимых компьютерах память условно разделена на так называемые сегменты. Адрес каждого байта составляется из номера сегмента и смещения относительно его начала.
Длина адресов сегмента и смещения — 16 бит, поэтому размер сегмента не может превышать 2 16 байт (64K). При вычислении адреса байта в оперативной памяти адрес сегмента сдвигается на 4 двоичных разряда влево, и к нему прибавляется смещение. Таким образом, длина адреса составляет 20 бит, и с помощью него можно адресовать память объемом 2 20 байт (1 мегабайт).
Компилятор Паскаля формирует сегмент кода, в котором хранится программа в виде машинных команд, сегмент данных, в котором выделяется память под глобальные переменные программы, и сегмент стека, предназначенный для размещения локальных переменных во время выполнения программы.
Адреса сегментов хранятся во время выполнения программы в сегментных регистрах: CS – адрес сегмента кода, DS – адрес сегмента данных, SS – адрес сегмента стека.
Глобальными называются переменные, описанные в главной программе. Переменные, которые не были инициализированы явным образом, перед началом выполнения программы обнуляются. Время жизни глобальных переменных — с начала программы и до ее завершения. Глобальные переменные доступны в любом месте программы или подпрограммы, кроме тех подпрограмм, в которых описаны локальные переменные с такими же именами.
Внутри подпрограмм описываются локальные переменные. Они располагаются в сегменте стека, причем распределение памяти происходит в момент вызова подпрограммы, а ее освобождение — по завершении подпрограммы. Значения локальных переменных между двумя вызовами одной и той же подпрограммы не сохраняются и эти переменные предварительно не обнуляются. Локальные переменные могут использоваться только в подпрограмме, в которой они описаны, и всех вложенных в нее.
В подавляющем большинстве случаев для обмена данными между вызывающей и вызываемой подпрограммами предпочтительнее использовать механизм параметров. Если все данные передаются подпрограммам через списки параметров, для локализации места ошибки достаточно просмотреть заголовки подпрограмм, а затем — тексты только тех из них, в которые передается интересующая нас переменная.
ВНИМАНИЕ Подпрограмму надо писать таким образом, чтобы вся необходимая для ее использования информация содержалась в ее заголовке.
№35 Структура исполняемой программы в ОП
Программа реализует алгоритм решения задачи. В ней программист записывает последовательность действий, выполняемых над определенными данными с помощью определенных операций для реализации заданной цели. Основными характеристиками программы являются: точность полученного результата, время выполнения и объем требуемой памяти. О соответствии этих показателей решаемой задаче и возможностям компьютера должен позаботиться сам программист. В большинстве случаев определяющим требованием является точность. Ограничения по объему памяти и времени выполнения носят менее жесткий характер.
Программа на языке Pascal состоит из строк. Набор текста программы осуществляется с помощью встроенного редактора текстов системы программирования Turbo Pascal или любого другого редактора. В первом случае программа может после выхода из редактора (при нажатии клавиши F10) в главное меню компилироваться и выполняться; во втором случае программу следует записать в файл и затем вызвать для компиляции и выполнения в интегрированной среде программирования Turbo Pascal.
Набирая текст программы, программист может произвольно располагать строки на экране. Строка может начинаться с любой колонки, т. е. величина отступа от левой границы экрана для каждой строки устанавливается самим программистом с целью получить наиболее удобный для чтения текст программы. Количество операторов в строке произвольно, но если в строке записывается один оператор, то такая программа легче читается.
Существуют различные схемы написания программ на языке Pascal, все они отличаются количеством отступов слева в каждой строке и различным использованием прописных букв.
Можно рассмотреть следующую схему:
– зарезервированные слова program, procedure, function пишутся строчными буквами;
– имена констант, переменных, процедур, функций начинаются с прописных букв;
– операторы записываются только строчными буквами;
– логически подчиненные структуры записываются на одну строку ниже и на одну или две позиции правее по отношению к более старшим.
Такая схема записи создает условия для лучшего понимания программы и значительно более быстрого обнаружения в ее тексте ошибок. Следует учитывать, что максимальный размер программы на Pascal ограничен. Компилятор позволяет обрабатывать программы и библиотечные модули, в которых объем данных и генерируемый машинный код не превышают 64 Кбайт каждый. Если программа требует большего количества памяти, следует использовать библиотечные модули (.TPU-файлы) или оверлейные структуры.
Оверлеи – части исполняемой программы, которые используют одну и ту же область оперативной памяти. В каждый момент времени в памяти может находиться только один оверлей, в зависимости от выполняемой функции. В процессе выполнения программы эти части могут замещать друг друга в памяти.
Синтаксически программа состоит из необязательного заголовка и блока.
Блок может содержать в себе другие блоки. Блок состоит из двух частей: описательной и исполнительной. Первая часть может отсутствовать, без второй блок не имеет смысла. Блок, который не входит ни в какой другой блок, называется глобальным. Если глобальный блок содержит другие блоки, то они называются локальными. Глобальный блок — это основная программа, он должен присутствовать в любом случае. Локальные блоки — это процедуры и функции, их присутствие необязательно. Объекты программы (типы, переменные, константы и т. д.) тоже называются глобальными и локальными. Областью действия объектов является блок, в котором они описаны, и все вложенные в него блоки.
Блочная структура обеспечивает структуризацию программ на уровне исходных текстов. В идеальном случае программа на языке Pascal состоит из процедур и функций, которые вызываются для выполнения из раздела операторов основной программы.
Исходя из этого можно записать структуру программы следующим образом:
Обязательной частью является лишь тело программы, которое начинается словом begin, а заканчивается словом end с точкой. Операторы в Паскале разделяются точкой запятой. Заголовок программы является хотя и необязательным, но желательным элементом и состоит из зарезервированного слова program и идентификатора — имени программы, за котором следует точка с запятой. Порядок объявлений и описаний не регламентируется.
ПРИМЕР : Простейшая программа.
program prim_1;
write(‘Привет! Вот мы и начали.’) (* эта строка текста появится на экране *)
№36 Виды параметров подпрограмм
Список параметров, то есть величин, передаваемых в подпрограмму и обратно, содержится в ее заголовке. Для каждого параметра обычно задается его имя, тип и способ передачи. Либо тип, либо способ передачи могут не указываться.
Важно запомнить, что в заголовке подпрограммы нельзя вводить описание нового типа, там должны использоваться либо имена стандартных типов, либо имена типов, описанных программистом ранее в разделе type.
В Паскале четыре вида параметров:
- значения;
- переменные;
- константы;
- нетипизированные параметры.
Кроме того, по другим критериям можно выделить особые виды параметров:
- открытые массивы и строки;
- процедурные и функциональные параметры;
- объекты.
Параметры-значения
Параметр-значение описывается в заголовке подпрограммы следующим образом:
Например, передача в процедуру Р величины целого типа записывается так:
procedure P(x : integer);
Имя параметра может быть произвольным. Параметр х можно представить себе как локальную переменную, которая получает свое значение из главной программы при вызове подпрограммы. В подпрограмму передается копия значения аргумента.
Механизм передачи следующий: из ячейки памяти, в которой хранится переменная, передаваемая в подпрограмму, берется ее значение и копируется в область сегмента стека, называемую областью параметров. Подпрограмма работает с этой копией, следовательно, доступа к ячейке, где хранится сама переменная, не имеет. По завершении работы подпрограммы стек освобождается. Такой способ называется передачей по значению.
При вызове подпрограммы на месте параметра, передаваемого по значению, может находиться выражение. Тип выражения должен быть совместим по присваиванию с типом параметра.
Например, если в вызывающей программе описаны переменные
var x : integer;
то следующие вызовы подпрограммы Р, заголовок которой описан выше, будут синтаксически правильными:
P(x); P(c); P(y); P(200); P(x div 4 + 1);
Недостатками передачи по значению являются затраты времени на копирование параметра, затраты памяти в стеке и опасность его переполнения, когда речь идет о параметрах, занимающих много места — например, массивах большого размера. Поэтому более правильно использовать для передачи в подпрограмму исходных данных параметры-константы, о которых речь пойдет чуть дальше.
Параметры-переменные
Признаком параметра-переменной является ключевое слово var перед описанием параметра:
var имя : тип;
Например, передача в процедуру Р параметра-переменной целого типа записывается так:
procedure P(var x : integer);
При вызове подпрограммы в область параметров копируется не значение переменной, а ее адрес, и подпрограмма через него имеет доступ к ячейке, в которой хранится переменная. Этот способ передачи параметров называется передачей по адресу. Подпрограмма работает непосредственно с переменной из вызывающей программы и, следовательно, может ее изменить.
ВНИМАНИЕ При вызове подпрограммы на месте параметра-переменной может находиться только ссылка на переменную точно того же типа.
Проиллюстрируем передачу параметров-значений и параметров-переменных на примере.
ar a, b, c, d, e : word;
procedure X(a, b, c : word; var d : word);
var e : word;
c := a + b; d := c; e := c;
writeln (‘Подпрограмма:’);
writeln (‘c = ‘, c, ‘ d = ‘, d, ‘ e = ‘, e);
writeln (‘Главная программа:’);
writeln (‘c = ‘, c, ‘ d = ‘, d, ‘ e = ‘, e);
Результаты работы этой программы приведены ниже:
c = 8 d = 8 e = 8
c = 0 d = 8 e = 0
Значение переменной с в главной программе не изменилось, поскольку переменная передавалась по значению, а значение переменной е не изменилось потому, что в подпрограмме была описана локальная переменная с тем же именем.
Параметры-константы
Параметр-константу можно узнать по ключевому слову const перед описанием параметра:
const имя : тип;
Это ключевое слово говорит о том, что в пределах подпрограммы данный параметр изменить невозможно. При вызове подпрограммы на месте параметра может быть записано выражение, тип которого совместим по присваиванию с типом параметра. Фактически параметры-константы передаются по адресу, но доступ к ним обеспечивается только для чтения.
Например, передача в процедуру Р параметра-константы целого типа записывается так:
procedure P(const x : integer);
Подведем итоги. Если данные передаются в подпрограмму по значению, их можно изменять, но эти изменения затронут только копию в области параметров и не отразятся на значении переменной в вызывающей программе. Если данные передаются как параметры-константы, изменять их в подпрограмме нельзя. Следовательно, эти два способа передачи должны использоваться для передачи в подпрограмму исходных данных.
Параметры составных типов (массивы, записи, строки) предпочтительнее передавать как константы, потому что при этом не расходуется время на копирование и место в стеке.
Результаты работы процедуры следует передавать через параметры-переменные, результат функции — через ее имя.
Нетипизированные параметры
Как можно догадаться из названия, при описании нетипизированных параметров не указывается тип. Передаются они всегда по адресу — либо как константы, либо как переменные, например:
procedure P(const a, b; var y);
Есть одно важное ограничение: передать-то их можно, а вот делать с ними в подпрограмме что-либо до тех пор, пока они не приведены к какому-то определенному типу, все равно нельзя!
Функция сравнения на равенство двух величин произвольного размера и типа.
Function EQ(const x, y; size : word) : boolean;
type mas_byte = array[0 .. MaxInt] of byte;
var n : integer;
EQ := n = size;
В эту функцию фактически передаются только адреса начала расположения в памяти двух переменных, поэтому необходим еще один параметр: длина сравниваемых величин в байтах (параметр size). Единственный способ выяснить, равны ли две величины, размер которых заранее не известен — их побайтное сравнение, поэтому оба параметра приводятся к типу mas_byte, объявленному в функции. При описании массива используется стандартная константа MaxInt, в которой хранится максимальное значение для величин типа integer, то есть 32767.
С помощью функции EQ можно сравнить две любые величины. Пусть, например, в программе описаны переменные:
var a, b : array [1 .. 10] of byte; x: real; c: string;
Следующие обращения к функции EQ будут корректны:
EQ(a, b, sizeof(a))
массива «b», соответственно >
Открытые массивы и строки
Открытый массив может быть только одномерным и состоять из элементов любого типа, кроме файлового. На место открытого массива можно передавать одномерный массив любой размерности, состоящий из элементов такого же типа. Передавать открытый массив можно как значение, переменную или константу, например:
procedure P(a : array of real);
Элементы массива нумеруются с нуля. Номер максимального элемента в массиве можно определить с помощью функции High.
Функция, определяющая максимальный элемент любого целочисленного массива.
function max_el(const mas : array of integer) : integer;
var i, max : integer;
for i := 0 to High(mas) do
if mas[i] > max then max := mas[i];
max_el := max;
Для передачи в подпрограмму по адресу строк любой длины используется либо специальный тип OpenString, называемый открытой строкой, либо тип string при включенном режиме (по умолчанию этот режим выключен).
Пример передачи строк в подпрограмму:
type s20 = string[20];
var s1 : string[40];
s2 : string[10];
procedure P(const x : s20; y : string; var z : openstring);
. P(s2, s1, s1); .
№37 Примеры передачи двух основных видом параметров подпрограмм. Их отличие
№38 Рекурсивные подпрограммы. Пример функции n!
Рекурсивной называется подпрограмма, в которой содержится обращение к самой себе. Такая рекурсия называется прямой. Есть также косвенная рекурсия, когда две или более подпрограмм вызывают друг друга.
При обращении подпрограммы к самой себе происходит то же самое, что и при обращении к любой другой функции или процедуре: в стек записывается адрес возврата, резервируется место под локальные переменные, происходит передача параметров, после чего управление передается первому исполняемому оператору подпрограммы.
Для завершения вычислений каждая рекурсивная подпрограмма должна содержать хотя бы одну ветвь алгоритма, заканчивающуюся возвратом в вызывающую программу.
Простой пример рекурсивной функции — вычисление факториала. Чтобы получить значение факториала числа n, требуется умножить на n факториал числа (n — 1). Известно также, что 0! = 1 и 1! = 1.
function fact(n : byte) : longint;
if (n = 0) or (n = 1) then fact := 1
else fact := n * fact(n — 1);
Рассмотрим, что происходит при вызове этой функции при n = 3. В стеке отводится место под параметр n, ему присваивается значение 3 и начинается выполнение функции. Условие в операторе if ложно, поэтому управление передается на ветвь else. Для вычисления выражения n * fact(n — 1) требуется повторно вызвать функцию fact. Для этого в стеке отводится новое место под параметр n, ему присваивается значение 2, и выполнение функции начинается сначала. В третий раз функция вызывается со значением параметра, равным 1, и вот тут-то становится истинным выражение (n = 0) or (n = 1), поэтому происходит возврат из подпрограммы в точку вызова, то есть на выражение n * fact(n — 1) для n = 2. Результат выражения присваивается имени функции и передается в точку ее вызова, то есть в то же выражение, только теперь происходит обращение к параметру n, равному 3.
Достоинством рекурсии является компактная запись, а недостатками — расход времени и памяти на повторные вызовы функции и передачу ей параметров, а, главное, опасность переполнения стека.
№39 Модули. Описание модулей. Использование модулей
Модуль — это подключаемая к программе библиотека ресурсов. Он может содержать описания типов, констант, переменных и подпрограмм. В модуль обычно объединяют связанные между собой ресурсы: например, в составе оболочки есть модуль Graph для работы с экраном в графическом режиме.
Модули применяются либо как библиотеки, которые могут использоваться различными программами, либо для разбиения сложной программы на составные части.
Использование модулей позволяет преодолеть ограничение в один сегмент на объем кода исполняемой программы, поскольку код каждого подключаемого к программе модуля содержится в отдельном сегменте.
Модули можно разделить на стандартные, которые входят в состав системы программирования, и пользовательские, то есть создаваемые программистом. Чтобы подключить модуль к программе, его требуется предварительно скомпилировать. Результат компиляции каждого модуля хранится на диске в отдельном файле с расширением .tpu.
Описание модулей
Исходный текст каждого модуля хранится в отдельном файле с расширением .pas. Общая структура модуля:
элементов модуля
(видимых извне) >
(внутренних) элементов
ВНИМАНИЕ Имя файла, в котором хранится модуль, должно совпадать с именем, заданным после ключевого слова unit.
Модуль может использовать другие модули, для этого их надо перечислить в операторе uses, который может находиться только непосредственно после ключевых слов interface или implementation.
В интерфейсной секции модуля определяют константы, типы данных, переменные, а также заголовки процедур и функций.
В секции реализации описываются подпрограммы, заголовки которых приведены в интерфейсной части. Заголовок подпрограммы должен быть или идентичным указанному в секции интерфейса, или состоять только из ключевого слова procedure или function и имени подпрограммы. Для функции также указывается ее тип.
Кроме того, в этой секции можно определять константы, типы данных, переменные и внутренние подпрограммы.
Секция инициализации предназначена для присваивания начальных значений переменным, которые используются в модуле. Операторы, расположенные в секции инициализации модуля, выполняются перед операторами основной программы.
Для сохранения скомпилированного модуля на диске требуется установить значение пункта Destination меню Compile в значение Disk. Компилятор создаст файл с расширением .tpu.
Пример описания модуля. Оформим в виде модуля подпрограмму вычисления среднего арифметического значения элементов массива.
unit Average;
const n = 10;
type mas = array[1 .. n] of real;
procedure average(x : mas; var av : real);
implementation
procedure average(x : mas; var av : real);
var i : integer;
for i := 1 to n do av := av + x[i];
Использование модулей
Для использования в программе величин, описанных в интерфейсной части модуля, имя модуля указывается в разделе uses. Можно записать несколько имен модулей через запятую, например:
program example;
uses Average, Graph, Crt;
Поиск модулей выполняется сначала в библиотеке исполняющей системы, затем в текущем каталоге, а после этого — в каталогах, заданных в диалоговом окне Options/Directories.
Если в программе описана величина с тем же именем, что и в модуле, для обращения к величине из модуля требуется перед ее именем указать через точку имя модуля.
№40 Стандартные модули Turbo Pascal
В Паскале имеется ряд стандартных модулей, в которых описано большое количество встроенных констант, типов, переменных и подпрограмм. Каждый модуль содержит связанные между собой ресурсы.
Модуль System
Модуль содержит базовые средства языка, которые поддерживают ввод-вывод, работу со строками, операции с плавающей точкой и динамическое распределение памяти. Этот модуль автоматически используется во всех программах, и его не требуется указывать в операторе uses. Он содержит все стандартные и встроенные процедуры, функции, константы и переменные Паскаля.
Модуль Crt
Модуль предназначен для организации эффективной работы с экраном, клавиатурой и встроенным динамиком. При подключении модуля Crt выводимая информация посылается в базовую систему ввода-вывода (ВIОS) или непосредственно в видеопамять.
В текстовом режиме экран представляется как совокупность строк и столбцов. Каждый символ располагается на так называемом знакоместе на пересечении строки и столбца. Символы хранятся в специальной части оперативной памяти, называемой видеопамятью. Ее содержимое отображается на экране.
Под каждый символ отводится два байта: один байт занимает ASCII-код символа, другой байт хранит атрибуты символа: его цвет, цвет фона и признак мерцания (рис. 1). Можно получить восемь различных цветов фона и 16 цветов символов.
Модуль Crt позволяет:
- выполнять вывод в заданное место экрана заданным цветом символа и фона;
- открывать на экране окна прямоугольной формы и выполнять вывод в пределах этих окон;
- очищать экран, окно, строку и ее часть;
- обрабатывать ввод с клавиатуры;
- управлять встроенным динамиком.
Работа с экраном
Текущие цвета символа и фона задаются с помощью процедур TextColor и TextBackGround и действуют на следующие за ними процедуры вывода. Вывод выполняется в текущую позицию курсора. Для ее изменения служит процедура GotoXY.
Окно определяется с помощью процедуры Window. Оно задается координатами левого верхнего и правого нижнего угла.
Очистка текущего окна выполняется с помощью процедуры ClrScr, которая заполняет его пробелами с текущим цветом фона и устанавливает курсор в левый верхний угол.
Программа «угадай число».
program luck;
const max = 10;
i, k, n : integer;