Правила оформления исходного кода в Паскаль (форматирование отступами) [Pascal]

В этом разделе мы поговорим о том как форматировать исходный код программы на языке Паскаль.

Смысл форматирования кода состоит в том, что увеличить его читаемость, то есть понятность для программиста.

Блоковые конструкции

В Паскаль можно выделить как минимум $6$ блоковых конструкций -- то есть таких, для окружения тела которых нужны операторные скобки, а именно:

Смысл блока состоит в том, что в него как бы можно вложить одно или более действий -- обычно, когда действий несколько используют операторные скобки (кроме конструкции repeat/until, где операторные скобки не нужны).

Один блок может вкладываться в другой бесконечное число раз по принципу матрёшки:
кложенные блоки в паскаль правила оормления форматирования

Главная идея форматирования

Главная идея состоит в том форматирования кода (то есть придания ему определённой фромы), чтобы каждое вложенное действие имело число отступов по уровню вложенности своего блока.

Единичный отступ предлагается брать любым, но достаточно заметным.

Мы возьмём в качестве единичного отступ в 2 пробела.
Тогда для тела программы все операторы будут сдвинуты на 2 пробела, например:

var a:integer;
begin   // нулевой отступ
  a := 2; // одинарные отступ
  a := 3 + 5;  // одинарные отступ
end;  

-- для операторных скобок и слова var обычно используют нулевой отступ -- то есть вообще не добавляют пробелов слева.

Любой блок

Содержимое любой блока внутри тела программы для своих операторов уже нуждается как минимум в 2 двух отступах, например оператор ветвления (неполная форма, одно действие в ветке):

var a:integer;
begin
  a := 2;           // одинарные отступ
  if (a > 2) then    // одинарные отступ
    a := 3 + 5;    // двойной отступ для блока ветки then
end;  

-- здесь присваивание и сам условный опертор лежат на одном уровне в теле программы и потому у них равные отступы, а вот операция

a := 3 + 5;

уже вложена в ветку $then$ и потому ей требуется $+1$ относительно отступов родительской операции (в данном случае для $if..then$ был один отступ, а потому для ветки $then$ требуется $1+1=2$ -- т.е. двойной отступ.)

Условный оператор IF

Если условный оператор IF находится в полной форме, то отступы могут выглядеть так (по одной операции в каждой ветке):

var a:integer;
begin
  a := 2;           // одинарные отступ
  if (a > 2) then    // одинарные отступ
    a := 3 + 5    // двойной отступ для блока ветки then
  else
    a := b + 5;  // двойной отступ оператора в ветке else
  b := 2; { -- независимый от if оператор,
  находится на том же уровне, что и сам if }
end; 

Если мы используем операторные скобки для того, чтобы отнести к блоку оператора более одного одно действия, то форматировать код можно так:

var a:integer;
begin
  a := 2;       // одинарные отступ
  if (a > 2) then    // начало блока then
    a := 3 + 5
  else begin  // конец then и начало блока ветки else
    a := b + 5;
    b := 2;
  end; // конец блока ветки else
end; 

-- в последнем примере в ветке else (ветка ложности оператора if) содержит два оператора, а потому они окружены операторными скобками.

Вложенные Условные операторы

Пример:

var a, b, c, d : integer;
begin
  writeln('vvedite a, b, c, d');
  readln(a, b, c, d);
  if (a > b) then
  begin
    if (a > c) then
      if (a > d) then
        writeln ('Выбираем a')
  end
  else
    if (b > c) then
    begin
      if (b > d) then
        writeln ('Выбираем b')
    end
    else
      if (c > d) then
        writeln ('Выбираем c')
      else
        writeln ('Выбираем d');

  readln();
end.

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

"Линейная запись" else if ("исключение" из правил)

Бывает что на практике последовательность вложенных else if записывают без дополнительных отступов, например:

if (a > b) then
  c := 1;
else if (a > 34) then
  c := 8;
else if (a > f) then
  c := 56; 

-- для удобства форматируем на одном уровне

По этому же принципу пример для вложенных условных операторов (см. выше) можно переписать так (такой стиль не рекомендуется для начинающих, хотя и допустим, просто не всегда удобен для понимания структуры):

var a, b, c, d : integer;
begin
  writeln('vvedite a, b, c, d');
  readln(a, b, c, d);
  if (a > b) then
  begin
    if (a > c) then
      if (a > d) then
        writeln ('Выбираем a')
  end
  else if (b > c) then
  begin
    if (b > d) then
      writeln ('Выбираем b')
  end
  else if (c > d) then
    writeln ('Выбираем c')
  else
    writeln ('Выбираем d');

  readln();
end.

Циклы

Также приведём пример оформления блока цикла с вложенным условием:

var i:integer;
begin
  for i:=1 to 15 do
  begin
    if (i > 5) then
    begin
      write(i, ' ');
      write('@');
    end else
      write('# ');
  end;
end; 

-- см. разбор этого варианта форматирования и его сравнение с классическим способом оформления отступов.

Ещё примеры

Смотрите Примеры исправлений неправильного форматирования с пояснениями
.

gani84's picture

Если условный оператор IF находится в полной форме, то отступы могут выглядеть так (по одной операции в каждой ветке):
var a:integer;
begin
a := 2; // одинарные отступ
if (a > 2) then // одинарные отступ
a := 3 + 5 // двойной отступ для блока ветки then
else
a := b + 5; // двойной отступ оператора в ветке else
b := 2; { -- независимый от if оператор,
находится на том же уровне, что и сам if }
end;

vedro-compota's picture

не хватает begin после else

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

var a:integer;
begin
    a := 2;           // одинарные отступ
    if (a > 2) then    // одинарные отступ
        a := 3 + 5    // двойной отступ для блока ветки then
    else
        a := b + 5;  // двойной отступ оператора в ветке else
    b := 2; { -- независимый от if оператор,
  находится на том же уровне, что и сам if }
end;

-- тут в комментарии написано, что b := 2; не относится вообще к веткам if, т.е. это строка выполнится вообще всегда, чтобы дополнительно показать это (человеку, паскалю всё равно) мы убираем отступ, так как этот оператор находится на одном уровне с самим if, а не в его ветках.
если же вы напишите:

var a:integer;
begin
    a := 2;           // одинарные отступ
    if (a > 2) then    // одинарные отступ
        a := 3 + 5    // двойной отступ для блока ветки then
    else begin
        a := b + 5;  
        b := 2;
    end; 
end;

-- то, как уже было сказано выше это будет другая логика (тоже правильная - всё зависит от того какую задачу вы программируете), но здесь уже b := 2; выполнится только если (a > 2), а не в любом случае, как это было в оригинальном варианте.

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

в следующем же примере рассматривается ситуация, о котороый вы спрашиваете:

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

_____________
матфак вгу и остальная классика =)