Coding · Programming languages
COBOL tutorial for beginners
Short answer
COBOL (Common Business-Oriented Language) is a compiled language designed for business data processing: records, files, reports and exact decimal arithmetic. Programs are split into four divisions, data is described with PIC (picture) clauses, and the code reads like English sentences such as ADD AMOUNT TO TOTAL. It still runs core systems in banks, insurers and governments, mostly on IBM mainframes. You can learn it for free with the GnuCOBOL compiler: cobc -x hello.cob.
What COBOL is and who uses it
COBOL was designed in 1959 by the CODASYL committee, with strong influence from Grace Hopper's earlier FLOW-MATIC language. It is standardized by ISO; later standards added structured programming, object orientation and other features, and the most recent revision was published in 2023.
COBOL is used for batch processing and transaction systems: account processing, payroll, insurance claims, tax and benefit systems. Much of this code runs on IBM Z mainframes with IBM Enterprise COBOL, together with CICS for transactions and Db2 for data. Jobs maintaining and modernizing these systems remain common.
Install GnuCOBOL and run Hello, world
GnuCOBOL is a free compiler that translates COBOL to C and then to a native program. It is available as the gnucobol package on many Linux distributions and in Homebrew on macOS; Windows users can use WSL or a prebuilt package.
IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO.
PROCEDURE DIVISION.
DISPLAY "Hello, world!".
STOP RUN.cobc -x hello.cob
./hello
# Hello, world!The code uses the traditional fixed format: columns 1 to 6 are for sequence numbers, column 7 marks comments (*) or continuation lines, Area A (columns 8 to 11) holds division, section and paragraph names, and Area B (columns 12 to 72) holds statements. GnuCOBOL also accepts free-format source with cobc -x -free. The option -x builds an executable instead of a module.
The four divisions
| Division | Purpose |
|---|---|
| IDENTIFICATION DIVISION | Names the program (PROGRAM-ID) |
| ENVIRONMENT DIVISION | Connects the program to the outside world, for example which files it uses |
| DATA DIVISION | Declares all data: file records, working storage, parameters |
| PROCEDURE DIVISION | The executable statements, organized into paragraphs |
Every variable must be declared in the DATA DIVISION before use. The WORKING-STORAGE SECTION holds the program's variables, the FILE SECTION describes file records, and the LINKAGE SECTION describes parameters passed by a caller.
Data and PIC clauses
COBOL describes data by its exact layout. A level number shows the hierarchy (01 is a record, 05 a field inside it), and a PIC clause gives the format: X is any character, 9 is a digit, S a sign, and V an implied decimal point.
| Declaration | Meaning | Example value |
|---|---|---|
PIC X(10) | 10 characters, padded with spaces | "Ana " |
PIC 9(3) | Unsigned 3-digit number | 030 |
PIC S9(5)V99 | Signed, 5 digits before and 2 after the decimal point | -01234.50 |
PIC $ZZ,ZZ9.99 | Edited output: currency sign, leading zeros as spaces | $ 1,234.50 |
PIC S9(7)V99 COMP-3 | Packed decimal, common on mainframes | stored in 5 bytes |
88 IS-DONE VALUE "Y" | Condition name: a Boolean test on its parent field | IF IS-DONE |
IDENTIFICATION DIVISION.
PROGRAM-ID. DATA-DEMO.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-NAME PIC X(10) VALUE "Ana".
01 WS-AGE PIC 9(3) VALUE 30.
01 WS-PRICE PIC S9(5)V99 VALUE 1234.50.
01 WS-PRICE-OUT PIC $ZZ,ZZ9.99.
01 WS-CUSTOMER.
05 WS-FIRST PIC X(10).
05 WS-LAST PIC X(15).
PROCEDURE DIVISION.
MOVE WS-PRICE TO WS-PRICE-OUT
DISPLAY WS-NAME "is " WS-AGE
DISPLAY "Price: " WS-PRICE-OUT
STOP RUN.
*> Ana is 030
*> Price: $ 1,234.50Numbers are stored in decimal, so 0.10 + 0.20 is exactly 0.30, which is one reason COBOL suits money. WS-CUSTOMER is a group item: it can be moved as a whole or field by field.
Control flow: IF, EVALUATE and PERFORM
IDENTIFICATION DIVISION.
PROGRAM-ID. CONTROL-DEMO.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-I PIC 99.
01 WS-TOTAL PIC 9(4) VALUE 0.
01 WS-SCORE PIC 999 VALUE 85.
PROCEDURE DIVISION.
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 10
ADD WS-I TO WS-TOTAL
END-PERFORM
DISPLAY "Total: " WS-TOTAL
EVALUATE TRUE
WHEN WS-SCORE >= 90
DISPLAY "A"
WHEN WS-SCORE >= 80
DISPLAY "B"
WHEN OTHER
DISPLAY "C"
END-EVALUATE
IF WS-TOTAL > 50
DISPLAY "big"
ELSE
DISPLAY "small"
END-IF
STOP RUN.
*> Total: 0055
*> B
*> bigPERFORM VARYING is COBOL's counting loop and PERFORM UNTIL condition its while loop. EVALUATE is a switch statement. Scope terminators such as END-IF and END-PERFORM close each block; a period ends the whole sentence.
Paragraphs, arithmetic and tables
COBOL has no functions in the usual sense. You organize logic into named paragraphs and run them with PERFORM; larger units become separate programs called with CALL "PROG" USING .... Arithmetic uses verbs (ADD, SUBTRACT, MULTIPLY, DIVIDE) or COMPUTE with a formula. Arrays are called tables and are declared with OCCURS; their indexes start at 1.
IDENTIFICATION DIVISION.
PROGRAM-ID. PARA-DEMO.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-PRICES.
05 WS-PRICE PIC 9(3)V99 OCCURS 3 TIMES.
01 WS-I PIC 9.
01 WS-SUM PIC 9(4)V99 VALUE 0.
01 WS-SUM-OUT PIC Z,ZZ9.99.
PROCEDURE DIVISION.
MAIN-PARA.
MOVE 10.50 TO WS-PRICE(1)
MOVE 4.25 TO WS-PRICE(2)
MOVE 7.00 TO WS-PRICE(3)
PERFORM ADD-PRICE VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 3
COMPUTE WS-SUM = WS-SUM * 1.1
MOVE WS-SUM TO WS-SUM-OUT
DISPLAY "With 10% tax: " WS-SUM-OUT
STOP RUN.
ADD-PRICE.
ADD WS-PRICE(WS-I) TO WS-SUM.
*> With 10% tax: 23.92The sum is 21.75; multiplied by 1.1 it is 23.925, and COBOL truncates to the two declared decimals (23.92) unless you write COMPUTE ... ROUNDED.
Error handling
COBOL has no exceptions in everyday code. Instead, statements have conditional phrases: ON SIZE ERROR for arithmetic overflow or division by zero, AT END for the end of a file, INVALID KEY for indexed files, and a FILE STATUS field that receives a two-character code after every file operation ("00" means success).
DIVIDE WS-A BY WS-B GIVING WS-C
ON SIZE ERROR
DISPLAY "Division failed"
NOT ON SIZE ERROR
DISPLAY "Result: " WS-C
END-DIVIDEA small complete program: total of a sales file
Reading fixed-layout records from a file is typical COBOL work. This program reads sales.txt, where each line has a 10-character item name followed by a 7-digit amount with two implied decimals.
apples 0001250
pears 0000899
plums 0002000 IDENTIFICATION DIVISION.
PROGRAM-ID. SALES-TOTAL.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT SALES-FILE ASSIGN TO "sales.txt"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS WS-FS.
DATA DIVISION.
FILE SECTION.
FD SALES-FILE.
01 SALES-REC.
05 SR-ITEM PIC X(10).
05 SR-AMOUNT PIC 9(5)V99.
WORKING-STORAGE SECTION.
01 WS-FS PIC XX.
01 WS-EOF PIC X VALUE "N".
88 NO-MORE-RECORDS VALUE "Y".
01 WS-TOTAL PIC 9(7)V99 VALUE 0.
01 WS-TOTAL-OUT PIC Z,ZZZ,ZZ9.99.
PROCEDURE DIVISION.
OPEN INPUT SALES-FILE
IF WS-FS NOT = "00"
DISPLAY "Cannot open file, status " WS-FS
STOP RUN
END-IF
PERFORM UNTIL NO-MORE-RECORDS
READ SALES-FILE
AT END SET NO-MORE-RECORDS TO TRUE
NOT AT END ADD SR-AMOUNT TO WS-TOTAL
END-READ
END-PERFORM
CLOSE SALES-FILE
MOVE WS-TOTAL TO WS-TOTAL-OUT
DISPLAY "Total sales: " WS-TOTAL-OUT
STOP RUN.Running it prints Total sales: followed by 41.49 right-aligned in the 12-character edited field. LINE SEQUENTIAL means a text file with one record per line; it is supported by GnuCOBOL and other PC compilers, while mainframe programs usually read fixed-length datasets defined in JCL.
Where to go next
- The GnuCOBOL project pages and its Programmer's Guide for a full language reference.
- IBM's Enterprise COBOL for z/OS documentation for mainframe COBOL, CICS and Db2 usage.
- Practice reading and writing files, sorting with the
SORTverb, and producing formatted reports. - Learn the surrounding mainframe tools (JCL, TSO/ISPF) if you want to work on production systems.
FAQ
Is COBOL still used?
Yes. Many banks, insurers and government agencies still run COBOL programs for core batch and transaction processing, so there is ongoing demand for developers who can maintain and modernize them.
Is COBOL hard to learn?
The syntax is verbose but simple, and most beginners can write working programs quickly. The harder part is the mainframe environment around it: JCL, datasets, CICS and Db2.
Can I learn COBOL without a mainframe?
Yes. GnuCOBOL runs on Linux, macOS and Windows and supports standard COBOL, so you can learn the language on a normal computer before moving to a mainframe.
Why does COBOL use decimal numbers?
Business data such as money must be exact. COBOL stores numbers as decimal digits with a fixed number of decimal places, which avoids the rounding errors of binary floating point.