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

FIXME

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

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

структура программы
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.                  // Конец всему (в этой программе)!
Примеры программ нелепых, но синтаксически грамотных

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

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

Данная программа действительно работает (стирает с экрана следы работы предыдущих программ), но не содержит ни одного описания. Её реальный аналог есть, например, в операционной системе ДОС.

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

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

3
Program Prog;       // К бессмысленному предложению Program - бесполезное, но правильное имя
// Всё есть и никто ничего не делает.
 
Uses CRT, Graph;    // Собираемся работать и с текстом, и с графикой, но так и не собирёмся
 
Const               // Раздел констант 
  n = 5;            // В данном случае n - не переменная, а другое обозначение 5.
  m : integer = 6;  // Один из ужасов Паскаля. Это - статическая переменная! 
                    // Без понимания, что к чему, лучше не использовать,
                    // но это - настоящая переменная
 
Var                 // Раздел переменных
  i:integer;        // Запасная переменная - нам не потребуется
 
Label               // Раздел меток. 
  BeeginProgram,    // У меток описывать нечего, но они должны 
  EndProgram;       // быть перечислены.
 
Type
  S100 =  string[100]; 
 
Procedure Proc(x:integer);
// Данная процедура принимает параметр x
// после чего всегда печатает:  
// "Опять - 25. Не мешайте работать!"
 
Const
  S2 = '. Не мешайте работать!';
Var  
  S1 : S100;
 
Begin:
  x  := n;           // Для данной процедуры значения параметров не важны 
  S1 := 'Опять - ';
  writeln(S1, x, S2 );
End;
 
Begin                
BeginProgram:        // Метка ничего не делает, но место указывает
  ;                  // Отсюда собираемся работать
  goto EndProgram;   // Хватит УЖЕ работать, пошли домой
  Proc(n);           // Здесь мы к счастью никогда не побываем,
  goto BeginProgram; // иначе - никогда не выберемся 
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.