DATA DIVISION и WORKING-STORAGE SECTION

Разбираемся, где COBOL-программа хранит свои переменные и почему это место — не просто «где-то наверху файла».

DATA DIVISION — раздел COBOL-программы, где заранее объявляются все данные, с которыми она будет работать.

Зачем нужен отдельный раздел для данных

В Python вы можете написать x = 5 в любом месте программы, и переменная x появится прямо там же, где её создали. В COBOL так не работает. Здесь программа строго поделена на четыре раздела — IDENTIFICATION DIVISION (кто автор и как называется программа), ENVIRONMENT DIVISION (на каком оборудовании и с какими файлами работаем), DATA DIVISION (какие данные вообще существуют) и PROCEDURE DIVISION (что с этими данными делать). Это разделение — не прихоть, а требование языка: сначала вы полностью описываете «склад» переменных, и только потом пишете код, который эти переменные использует.

Такая жёсткость может показаться неудобной после Python или JavaScript, где переменная создаётся «по требованию». Но у неё есть практический смысл. COBOL появился в 1959 году для программ, которые считали зарплаты и вели бухгалтерию банков — там цена ошибки в объявлении переменной высока. Когда все данные видны в одном месте DATA DIVISION, легко посмотреть на «план склада» и понять, с чем вообще работает программа, не читая тысячи строк логики.

WORKING-STORAGE SECTION — рабочий стол программы

Внутри DATA DIVISION есть несколько секций, но чаще всего вы будете использовать WORKING-STORAGE SECTION. Это место для «рабочих» переменных — тех, что программа создаёт сама для промежуточных вычислений, счётчиков, флагов и текстовых сообщений. Представьте письменный стол бухгалтера: калькулятор, черновик, стикеры с пометками — всё то, что нужно для работы, но не является самим архивом документов (архив — это уже отдельные секции для файлов).

Вот как выглядит минимальная программа с объявлением переменных:

IDENTIFICATION DIVISION.
PROGRAM-ID. PRIVET.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 IMYA PIC X(20) VALUE "Мир".
01 SCHETCHIK PIC 9(3) VALUE 0.

PROCEDURE DIVISION.
    DISPLAY "Привет, " IMYA.
    STOP RUN.

Вывод:

Привет, Мир

Разбираем построчно

IDENTIFICATION DIVISION и PROGRAM-ID — это «паспорт» программы, обязательная формальность в начале любого COBOL-файла. Дальше начинается DATA DIVISION, а в нём — WORKING-STORAGE SECTION, куда мы помещаем две переменные. Строка 01 IMYA PIC X(20) VALUE "Мир". объявляет переменную IMYA: число 01 — это уровень записи (о нём подробно поговорим в третьем уроке раздела), PIC X(20) означает «текстовое поле длиной ровно 20 символов», а VALUE "Мир" задаёт начальное значение. Вторая строка объявляет SCHETCHIK — числовое поле из трёх цифр с начальным значением 0. Заметьте: точка в конце каждой строки — не украшение, а обязательный знак окончания предложения COBOL, как точка в обычном тексте.

Дальше, в PROCEDURE DIVISION, мы уже используем объявленные переменные — командой DISPLAY печатаем текст на экран, а STOP RUN завершает программу. Обратите внимание: переменную IMYA нельзя было бы использовать в PROCEDURE DIVISION, если бы она не была заранее объявлена в DATA DIVISION — компилятор просто откажется собирать программу.

Чем это принципиально отличается от Python и Java

В Python переменная не имеет фиксированного типа и размера — x = 5, а через секунду x = "привет", и никто не возражает. В Java тип объявляется один раз (int x = 5;), но размер числа определяется самим типом (int, long) и невидим программисту напрямую. В COBOL же вы объявляете не просто тип, а точный физический размер данных в байтах — PIC X(20) это буквально 20 байт текста, ни больше ни меньше. Если попытаться записать в IMYA строку длиннее 20 символов, лишнее просто обрежется. Это прямое наследие эпохи, когда память мейнфрейма была дорогим и жёстко ограниченным ресурсом, и программист обязан был заранее спланировать каждый байт.

Мини-пример: карточка товара

Представим, что нужно хранить название товара и его цену — простейший пример из мира магазина, но именно такие задачи и решал COBOL десятилетиями в бухгалтерских системах.

DATA DIVISION.
WORKING-STORAGE SECTION.
01 TOVAR PIC X(15) VALUE "Tetrad".
01 CENA PIC 9(4) VALUE 55.

PROCEDURE DIVISION.
    DISPLAY "Tovar: " TOVAR " Cena: " CENA.
    STOP RUN.

Вывод:

Tovar: Tetrad          Cena: 0055

Обратите внимание на вывод: после слова «Tetrad» идут пробелы — это «хвост» текстового поля длиной 15 символов, а число 55 напечаталось как «0055», потому что поле PIC 9(4) всегда занимает ровно 4 цифры, и незанятые позиции заполняются нулями слева. Это не баг — это и есть суть данных фиксированной длины, к которой мы вернёмся подробнее в следующем уроке.

Частые ошибки новичков

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

Вторая ошибка — попытка использовать переменную в PROCEDURE DIVISION, не объявив её заранее в DATA DIVISION. В Python интерпретатор просто создаст новую переменную «на лету»; COBOL-компилятор в этом случае выдаст ошибку компиляции и откажется собирать программу — это защита от опечаток, но с непривычки раздражает.

Третья — путать секции. Начинающие иногда пытаются писать переменные прямо в DATA DIVISION, забыв указать WORKING-STORAGE SECTION. Раздел DATA DIVISION — это «этаж», а секция WORKING-STORAGE — «комната» внутри него, и переменные объявляются именно внутри комнаты, а не на лестничной клетке.

Итоги

  • COBOL-программа строго делится на четыре раздела, и все переменные объявляются заранее, в разделе DATA DIVISION.
  • WORKING-STORAGE SECTION — секция для «рабочих» переменных, которые программа использует для вычислений.
  • В отличие от Python или Java, COBOL требует указывать точный физический размер данных в байтах — это отражено в клаузе PIC, о которой пойдёт речь дальше.
  • Каждое объявление и оператор заканчивается точкой — пропущенная точка одна из самых частых ошибок новичков.
Проверьте себя
1. В каком разделе COBOL-программы нужно заранее объявить переменную, прежде чем использовать её в PROCEDURE DIVISION?
AВ IDENTIFICATION DIVISION
BВ DATA DIVISION
CПеременную можно объявить прямо в PROCEDURE DIVISION при первом использовании
DВ ENVIRONMENT DIVISION
2. Чем объявление переменной в COBOL принципиально отличается от привычного x = 5 в Python?
AНичем, синтаксис просто выглядит иначе
BCOBOL требует указывать точный размер данных в байтах заранее, а не определять его по значению во время выполнения
CВ COBOL вообще нет переменных, только константы
DCOBOL позволяет менять тип переменной на лету, как Python