Основные понятия

Структура программы

Общая структура программы на языке Паскаль задана жёстко и выглядит так:

Program <правильное имя>; // Предложение, содержащее **заголовок программы**. // Данное предложение может отсутствовать, поскольку в // используемой нами системе Free Pascal // и большинстве (во всех?) современных версий Паскаля // никакой роли не играет. // Оно оставлено для совместимости с другими версиями // языка, которые его требуют. // Например: Program ChoiseSort3v; // Предложения заканчивается точкой с запятой Uses <список подключаемых библиотек>; // **Раздел импорта**, // который всегда состоит из одного предложения! // Данное предложение может отсутствовать, если вы не // используете никаких дополнительных библиотек. // Например: Uses CRT, OGLgraph; // Список разделяется запятыми, // предложения заканчивается точкой с запятой <Раздел описаний> // Раздел глобальных описаний может состоять из нескольких // подразделов, порядок следования которых - свободный, // но все они должны быть здесь - перед кодом. // // Этот раздел содержит описание всего, что // не задано изначально, // не импортируется из библиотек, // не является локальным объектом внутри процедуры. // А именно - именованные константы, пользовательские типы, // переменные и наконец - имена меток. // // В принципе, этот раздел тоже может отсутствовать. Begin // Обязательные операторные скобки Begin-end <Раздел кода> // Операторы, составляющие "главную процедуру" // Чисто теоретически, их тоже может не быть! // Тогда программа честно ничего не делает. // Но "скобки" должны быть. End. // Программа кончается точкой

Текст в угловых скобках (символы < и >) требует замены «по смыслу». Не путайте с операциями < и >!

Ещё раз обратите внимание на жёсткий порядок следования частей программы на этом уровне детализации её структуры. Все части идут именно в этом порядке и не повторяются. Но некоторые могут отсутствовать совсем.

Раздел описаний

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

const // Начался раздел констант n = 10; // Описание (именованной) константы var // Начался раздел глобальных переменных, // значит - закончился раздел констант i, j : integer; // 1-е описание переменных r, q : real; // 2-е описание переменных k, m : integer; // 3-е описание переменных - снова integer. Имеем право. Begin // Обязательный раздел кода ... End. // Конец всему (в этой программе)!

Объекты программы могут быть связаны описанием.

const n = 10; // Константа n определяет длину массива type Arr10 = array[1 .. n] of integer; // Используя n, описываем целый тип массивов var A,B : Arr10; // Используем описание типа Arr10 для описания переменных A, B

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

Учтите, что библиотечные объекты, т.е. объекты системные или описанные в библиотеках, подключённых с помощью uses, описывать не надо и на них можно ссылаться из любого места. Но, как мы узнаем позже, их имена можно «перекрыть»!

Ниже приведён неправильный код, где ничего не описывается заблаговременно.

var A,B : Arr10; // А что это? type Arr10 = array[1 .. n] of integer; // И сколько же это будет? const n = 10;

В раздел описаний может входить несколько «однотипных» подразделов описаний.

var i, j : integer; // Описали часть переменных const n = 10; // Спохватились и описали константу n var A,B : array[1 .. n] of integer; // "Дописали" ещё часть переменных

Полный пример

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

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

Метки описываются там, где это удобно.

... // Здесь могли бы быть заголовок и раздел импорта const // Начался 1-й раздел констант Pi = 4.0; // Описание (именованной) константы // Внимание - мы перекрыли системное определение Пи! var // Начался 1-й раздел глобальных переменных, // значит - закончился раздел констант i, j : integer; // 1-е описание переменных r, q : real; // 2-е описание переменных k, m : integer; // 3-е описание переменных - снова integer. Имеем право. const // Начался 2-й раздел констант n = 10; // Описание (именованной) константы type // Начался раздел типов A10 = array[1..n] of integer; // Это тип, определённый пользователем. // Обратите внимание - мы использовали // ранее описанную константу var // Начался раздел переменных, закончился раздел типов A,B : A10; // 4-е описание переменных пользовательского типа A10 ... // Что-то ещё, возможно - ничего // Где-то здесь кончается раздел переменных label // Раздел меток нужен редко 1, endOfAll; // список объявленных меток // Теперь это "законные" метки ... // Что-то ещё, возможно - ничего Begin // Обязательный раздел кода ... End. // Конец всему (в этой программе)!

Примеры программ нелепых, но синтаксически грамотных

Данная программа содержит только раздел кода, но он - пуст, так что программа самым честным образом ничего не делает. Ибо и не должна.

Begin // Если убрать этот комментарий, то получится // минимальная правильная программа на Паскале End.

Данная программа работает (стирает с экрана следы работы предыдущих программ), но не содержит ни одного описания.

Uses CRT; // без CRT не будет работать clrscr ("clearscreen") Begin clrscr; // команда очищает экран от результатов предыдущих вводов/выводов End.

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

Program Prog; // К бессмысленному предложению Program - бесполезное, но правильное имя // Всё есть и никто ничего не делает. Uses CRT, Graph; // Собираемся работать и с текстом, и с графикой, но так и не собирёмся Const // Раздел констант n = 5; // В данном случае n - не переменная, а другое обозначение 5. m : integer = 6; // Один из ужасов Паскаля. Это - статическая переменная! Без понимания, что к чему, лучше не использовать. Var // Раздел переменных i:integer; // Запасная переменная - нам не потребуется Label // Раздел меток. У меток описывать нечего, но они должны быть перечислены. BeeginProgram, EndProgram; Procedure Proc(x:integer); Begin: writeln('Не мешайте работать!') End; Begin BeginProgram: goto EndProgram; // Хватит работать пошли домой Proc(n); EndProgram: ; End.

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

Ввод/вывод

var x, y, z: integer; a, b, c: real;
var x: integer; a: real; begin read(x); {Сохранит введенное с клавиатуры в переменную x} readln(a); {Сохранит введенное с клавиатуры в переменную a и добавит перевод строки} end.

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

Заметьте, что в строковую переменную можно занести и «Мама мыла раму», и «2.0».

var x: integer; a: real; begin x := 2; write(x); {Выведет на экран значение переменной x} write('x= ', x); writeln(x); {Выведет на экран значение переменной x и перейдет на следующую строку} writeln('x= ', x); a := 0.15; writeln(a); writeln(a * x); writeln(a * x:4:1); end.

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

begin write(0.3); write( 0.15 * 2.0 ); writeln( sin(3.14) ); end.

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

begin

writeln("Полученное значение ", 0.3); // Обратите внимание на пробелы
writeln( 100.0:5:2, '(км/ч)'); //
writeln( 200.0:5:2, '(км/ч)');
writeln( 300.0:5:2, '(км/ч)');
writeln( sin(3.14*1/2):8:4,
sin(3.14*1/4):8:4,
sin(3.14*1/8):8:4 );

end.

Распространённые ошибки

Недопустимо следующее :

const x=0.3; var y : integer; A : array[1..9] of integer; F : text; begin read (0.3); // чтение "в никуда" - нет переменной, которая примет введённое значение. read (x); // тоже самое, но константа указана по имени readln (0.15 * y); // тоже самое, но вместо константы - целое выражение readln (A); // составной тип данных можно заполнять только по-элементно readln (F); // "неудачное" чтение из файла F - и файл F не открыт, и не указана // переменная-приёмник. Считать же саму файловую переменную F - нельзя! end.
var A : array[1..9] of integer; F : text; begin writeln (x, 0.15 * y, 0.3); // Вывод - будет, но все выводимые значения сольются в нечто нечитаемое writeln (A); // составной тип данных можно выводить только по-элементно writeln (F); // "неудачнае" запись в файл F - и файл F не открыт, и не указано, // что выводить. Выводить таким образом у файл F - нельзя! end.