Partilhar: WhatsApp
aulify · Sebenta
UC · Unidade de Competência · UC02840

Sebenta · COBOL (UC02840)

Linguagem business para bancos, seguros, mainframes
25h · 2.25 pontos crédito Curso: T. Desenv. Software ↗ Referencial oficial SNQ
Índice

Introdução

COBOL (COmmon Business-Oriented Language) é uma das linguagens mais antigas em uso activo. Criada em 1959 sob liderança de Grace Hopper, foi desenhada para aplicações de negócio: processamento de transacções, contabilidade, gestão de stocks, cálculo de salários. Sessenta e cinco anos depois, continua a correr em mainframes IBM processando triliões de dólares todos os dias.

Aprender COBOL hoje não é nostalgia — é estratégia de carreira. As estimativas dizem que 80% das transacções de cartões de crédito passam por COBOL, e a maioria dos sistemas core de bancos, seguradoras e governos continua a depender desta linguagem. Os programadores que aprenderam COBOL nos anos 70/80 estão a reformar-se em massa. Os bancos pagam fortunas a quem souber manter os seus sistemas legacy.

Esta sebenta cobre COBOL básico até saberes ler, modificar e escrever programas business simples.

1. COBOL em contexto

História breve

Onde corre

Setor por setor

Carreira COBOL hoje

2. Setup

GnuCOBOL

Compilador open source. Permite aprender COBOL sem mainframe.

Ubuntu/Debian:

sudo apt install gnucobol

Fedora:

sudo dnf install gnucobol

Mac:

brew install gnucobol

Windows: instalador no site gnucobol.sourceforge.io.

Verifica:

cobc --version

IDE

Compilar e correr

cobc -x hello.cob -o hello    # -x = executable
./hello

# Subprogram (módulo)
cobc -m subprog.cob            # -m = module (.so)

# Free format (sem formato em colunas)
cobc -free -x moderno.cob -o moderno

3. Estrutura de um programa

Hello world

       IDENTIFICATION DIVISION.
       PROGRAM-ID. HELLO-WORLD.

       PROCEDURE DIVISION.
           DISPLAY "Olá mundo!".
           STOP RUN.

Formato em colunas (fixed)

COBOL clássico exige indentação rigorosa:

Col 1-6:   Numeração (opcional, ignorada)
Col 7:     Indicador
              espaço = código normal
              * = comentário
              / = page break
              - = continuação
Col 8-11:  Area A (DIVISION, SECTION, paragraph)
Col 12-72: Area B (statements, declarações)
Col 73+:   Identificação (ignorada)

Exemplo:

123456 78901234567890...72
       IDENTIFICATION DIVISION.
       PROGRAM-ID. EXEMPLO.
       PROCEDURE DIVISION.
           DISPLAY "Olá".

Formato livre (moderno)

Com flag -free (GnuCOBOL) ou em COBOL 2002+:

IDENTIFICATION DIVISION.
PROGRAM-ID. EXEMPLO.
PROCEDURE DIVISION.
    DISPLAY "Olá".
    STOP RUN.

Recomendado em código novo. Para esta UC vamos usar o formato clássico (mais comum em legacy).

As 4 DIVISIONS

       IDENTIFICATION DIVISION.   * obrigatória, metadados
       PROGRAM-ID. NOME-PROG.
       AUTHOR. JOÃO SILVA.
       DATE-WRITTEN. 2026-05-25.

       ENVIRONMENT DIVISION.      * opcional, hardware/files
       CONFIGURATION SECTION.
       SOURCE-COMPUTER. PC.
       OBJECT-COMPUTER. PC.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           * definições de ficheiros aqui

       DATA DIVISION.             * opcional, variáveis
       FILE SECTION.
           * estruturas dos ficheiros
       WORKING-STORAGE SECTION.
           * variáveis do programa
       LINKAGE SECTION.
           * parâmetros (subprograms)

       PROCEDURE DIVISION.        * obrigatória, lógica
           DISPLAY "Olá".
           STOP RUN.

4. Tipos de dados — PICTURE

A PICTURE (ou PIC) define tipo e tamanho de uma variável.

Caracteres especiais

Char Significado
9 dígito numérico
X qualquer carácter (alfanumérico)
A letra alfabética
V ponto decimal implícito
S sinal (+/-)
Z dígito com supressão de zero
$, ,, ., -, +, / edição (para output formatado)

Exemplos

       01 WS-NOME       PIC X(30).      * 30 chars
       01 WS-INICIAL    PIC A.          * 1 letra
       01 WS-IDADE      PIC 9(3).       * 3 dígitos (0-999)
       01 WS-SALARIO    PIC 9(7)V99.    * 7 inteiros + 2 decimais
       01 WS-TEMPERATURA PIC S9(3)V99.  * com sinal
       01 WS-TELEFONE   PIC 9(9).
       01 WS-NIF        PIC 9(9).

       * Edição (formato visual)
       01 WS-PRECO-EDIT PIC ZZ,ZZ9.99.  * 12345.67  "12,345.67"
       01 WS-DATA-EDIT  PIC 9999/99/99. * "20260525"  "2026/05/25"

VALUE — inicialização

       01 WS-CONTADOR PIC 9(5) VALUE 0.
       01 WS-EOF      PIC X    VALUE "N".
       01 WS-NOME     PIC X(30) VALUE "Anónimo".
       01 WS-FLAG     PIC X    VALUE SPACE.   * literais especiais
       01 WS-ZEROS    PIC 9(5) VALUE ZEROS.
       01 WS-HIGH     PIC X    VALUE HIGH-VALUES.  * todos os bits a 1
       01 WS-LOW      PIC X    VALUE LOW-VALUES.   * todos a 0

Literais especiais: SPACE/SPACES, ZERO/ZEROS, HIGH-VALUES, LOW-VALUES, QUOTE/QUOTES.

Grupos (records)

Permite agrupar campos:

       01 WS-CLIENTE.
          05 WS-ID            PIC 9(6).
          05 WS-NOME          PIC X(30).
          05 WS-MORADA.
             10 WS-RUA        PIC X(40).
             10 WS-CIDADE     PIC X(20).
             10 WS-CP         PIC 9(4)-9(3).
          05 WS-IDADE         PIC 9(3).
          05 WS-SALARIO       PIC 9(7)V99.

Níveis: - 01 = record principal. - 02-49 = subgrupos / campos. - 66, 77, 88 = especiais.

Acesso por campo individual ou pelo grupo:

MOVE "Ana"  TO WS-NOME.
MOVE 25     TO WS-IDADE.
DISPLAY WS-CLIENTE.       * imprime tudo concatenado

Tabelas (arrays)

       01 WS-NOTAS.
          05 WS-NOTA OCCURS 5 TIMES PIC 9(3).

       PROCEDURE DIVISION.
           MOVE 18 TO WS-NOTA(1).
           MOVE 14 TO WS-NOTA(2).
           MOVE 12 TO WS-NOTA(3).

           PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 5
               DISPLAY WS-NOTA(WS-I)
           END-PERFORM.

Tabelas multi-dimensionais com OCCURS aninhado:

       01 WS-MATRIZ.
          05 WS-LINHA OCCURS 3 TIMES.
             10 WS-CEL OCCURS 4 TIMES PIC 9(3).

       * Acesso: WS-CEL(2, 3)

5. Operações básicas

MOVE — atribuição

       MOVE "Ana" TO WS-NOME.
       MOVE 25 TO WS-IDADE.
       MOVE WS-A TO WS-B.
       MOVE WS-CLIENTE TO WS-CLIENTE-BACKUP.   * grupo inteiro

       * MOVE com truncagem
       MOVE "Hello World" TO WS-CURTO.   * WS-CURTO PIC X(5)  "Hello"

Aritmética básica

       01 WS-A PIC 9(5) VALUE 100.
       01 WS-B PIC 9(5) VALUE 30.
       01 WS-RES PIC 9(5).

       * ADD
       ADD WS-A TO WS-B.                    * B = A + B (130)
       ADD WS-A TO WS-B GIVING WS-RES.      * RES = A + B
       ADD 1 TO WS-CONTADOR.

       * SUBTRACT
       SUBTRACT WS-B FROM WS-A.             * A = A - B
       SUBTRACT WS-B FROM WS-A GIVING WS-RES.

       * MULTIPLY
       MULTIPLY WS-A BY WS-B.               * B = A * B
       MULTIPLY WS-A BY WS-B GIVING WS-RES.

       * DIVIDE
       DIVIDE WS-A BY WS-B GIVING WS-RES.
       DIVIDE WS-A BY WS-B GIVING WS-RES REMAINDER WS-REM.

COMPUTE — expressões

       COMPUTE WS-RES = WS-A + WS-B - 5.
       COMPUTE WS-MEDIA = (WS-N1 + WS-N2 + WS-N3) / 3.
       COMPUTE WS-IVA = WS-PRECO * 0.23.
       COMPUTE WS-TOTAL = WS-PRECO + WS-IVA.

COMPUTE é mais legível para fórmulas. Suporta +, -, *, /, ** (exponenciação).

ACCEPT e DISPLAY

       DISPLAY "Nome: ".
       ACCEPT WS-NOME.

       DISPLAY "Idade: ".
       ACCEPT WS-IDADE.

       DISPLAY "Olá " WS-NOME ", " WS-IDADE " anos".

       * Múltiplas linhas com separadores
       DISPLAY "Nome: " WS-NOME
               "Idade: " WS-IDADE
               "Salário: " WS-SALARIO.

6. Estruturas de controlo

IF / ELSE

       IF WS-IDADE >= 18
           DISPLAY "Adulto"
       ELSE
           DISPLAY "Menor"
       END-IF.

       * Condições compostas
       IF WS-NOTA >= 10 AND WS-PRESENCAS >= 60
           DISPLAY "Aprovado"
       ELSE
           DISPLAY "Reprovado"
       END-IF.

       * Se / senão se aninhado
       IF WS-NOTA >= 18
           DISPLAY "Excelente"
       ELSE
           IF WS-NOTA >= 14
               DISPLAY "Bom"
           ELSE
               IF WS-NOTA >= 10
                   DISPLAY "Suficiente"
               ELSE
                   DISPLAY "Reprovado"
               END-IF
           END-IF
       END-IF.

Comparações: =, >, <, >=, <=, NOT =. Lógicas: AND, OR, NOT.

EVALUATE (switch)

       EVALUATE WS-DIA
           WHEN 1 THRU 5
               DISPLAY "Dia útil"
           WHEN 6
               DISPLAY "Sábado"
           WHEN 7
               DISPLAY "Domingo"
           WHEN OTHER
               DISPLAY "Inválido"
       END-EVALUATE.

       * Múltiplos critérios
       EVALUATE WS-ESTADO ALSO WS-IDADE
           WHEN "A" ALSO 0 THRU 17
               DISPLAY "Activo, menor"
           WHEN "A" ALSO 18 THRU 64
               DISPLAY "Activo, adulto"
           WHEN OTHER
               DISPLAY "Outro"
       END-EVALUATE.

PERFORM — chamar paragraph

       PROCEDURE DIVISION.
       MAIN.
           PERFORM INICIALIZAR.
           PERFORM PROCESSAR.
           PERFORM FINALIZAR.
           STOP RUN.

       INICIALIZAR.
           DISPLAY "Início".
           MOVE 0 TO WS-CONTADOR.

       PROCESSAR.
           DISPLAY "A processar...".

       FINALIZAR.
           DISPLAY "Fim".

PERFORM N TIMES

       PERFORM 10 TIMES
           DISPLAY "Olá"
       END-PERFORM.

PERFORM UNTIL

       MOVE 1 TO WS-I.
       PERFORM UNTIL WS-I > 10
           DISPLAY WS-I
           ADD 1 TO WS-I
       END-PERFORM.

PERFORM VARYING (for loop)

       PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 10
           DISPLAY WS-I
       END-PERFORM.

       * Decremento
       PERFORM VARYING WS-I FROM 10 BY -1 UNTIL WS-I < 1
           DISPLAY WS-I
       END-PERFORM.

       * Aninhado
       PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 3
           PERFORM VARYING WS-J FROM 1 BY 1 UNTIL WS-J > 3
               DISPLAY WS-I "," WS-J
           END-PERFORM
       END-PERFORM.

7. Ficheiros sequenciais

Setup do ficheiro

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT CLIENTES-FILE 
               ASSIGN TO "clientes.dat"
               ORGANIZATION IS LINE SEQUENTIAL.

       DATA DIVISION.
       FILE SECTION.
       FD CLIENTES-FILE.
       01 CLIENTE-REC.
          05 CLI-NOME    PIC X(30).
          05 CLI-IDADE   PIC 9(3).
          05 CLI-SALARIO PIC 9(7)V99.

LINE SEQUENTIAL = ficheiro de texto (uma linha por record). SEQUENTIAL = ficheiro binário (records de tamanho fixo).

Ler ficheiro

       WORKING-STORAGE SECTION.
       01 WS-EOF PIC X VALUE "N".

       PROCEDURE DIVISION.
           OPEN INPUT CLIENTES-FILE.

           PERFORM UNTIL WS-EOF = "Y"
               READ CLIENTES-FILE
                   AT END 
                       MOVE "Y" TO WS-EOF
                   NOT AT END
                       DISPLAY CLI-NOME ", " CLI-IDADE
               END-READ
           END-PERFORM.

           CLOSE CLIENTES-FILE.
           STOP RUN.

Escrever ficheiro

       OPEN OUTPUT CLIENTES-FILE.

       MOVE "Ana Silva"   TO CLI-NOME.
       MOVE 25            TO CLI-IDADE.
       MOVE 1500.00       TO CLI-SALARIO.
       WRITE CLIENTE-REC.

       MOVE "Bruno Costa" TO CLI-NOME.
       MOVE 32            TO CLI-IDADE.
       MOVE 2200.00       TO CLI-SALARIO.
       WRITE CLIENTE-REC.

       CLOSE CLIENTES-FILE.

Modos de abertura

Ficheiros indexados (KSDS)

Para acesso por chave (como dicionário):

       SELECT CLIENTES-FILE 
           ASSIGN TO "clientes.idx"
           ORGANIZATION IS INDEXED
           ACCESS MODE IS DYNAMIC
           RECORD KEY IS CLI-ID.

       * READ direct por chave:
       MOVE 12345 TO CLI-ID.
       READ CLIENTES-FILE
           INVALID KEY
               DISPLAY "Não encontrado"
           NOT INVALID KEY
               DISPLAY CLI-NOME
       END-READ.

8. Subprograms

Subprogram

SOMA.cob:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. SOMA.

       DATA DIVISION.
       LINKAGE SECTION.
       01 LK-A    PIC 9(5).
       01 LK-B    PIC 9(5).
       01 LK-RES  PIC 9(6).

       PROCEDURE DIVISION USING LK-A LK-B LK-RES.
           COMPUTE LK-RES = LK-A + LK-B.
           GOBACK.

Programa principal

MAIN.cob:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. MAIN-PROG.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 WS-X    PIC 9(5) VALUE 100.
       01 WS-Y    PIC 9(5) VALUE 250.
       01 WS-RES  PIC 9(6).

       PROCEDURE DIVISION.
           CALL "SOMA" USING WS-X WS-Y WS-RES.
           DISPLAY "Resultado: " WS-RES.
           STOP RUN.

Compilar e correr:

cobc -m soma.cob       # módulo (.so / .dll)
cobc -x main.cob -o main
./main

BY REFERENCE vs BY VALUE vs BY CONTENT

       CALL "SOMA" USING BY REFERENCE WS-X    * default  modificável
                         BY VALUE     WS-Y    * só leitura
                         BY CONTENT   WS-Z    * cópia, modificável dentro

9. Boas práticas

Convenções

Estilo

       * ─────────────────────────────────────────────
       * Paragraph: PROCESSAR-VENDA
       * Função:    Calcula totais e aplica IVA
       * Inputs:    WS-VENDA-BRUTO
       * Outputs:   WS-VENDA-LIQUIDO
       * ─────────────────────────────────────────────
       PROCESSAR-VENDA.
           COMPUTE WS-IVA = WS-VENDA-BRUTO * 0.23.
           COMPUTE WS-VENDA-LIQUIDO = WS-VENDA-BRUTO + WS-IVA.

Anti-patterns

10. Mainframe na prática

Stack típica IBM

JCL exemplo

//MYJOB    JOB (ACCT),'PROCESS DAILY',MSGCLASS=X
//STEP1    EXEC PGM=COBPROG
//STEPLIB  DD DSN=MY.LOADLIB,DISP=SHR
//INFILE   DD DSN=MY.INPUT.DATA,DISP=SHR
//OUTFILE  DD DSN=MY.OUTPUT.DATA,DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(10,5)),DCB=(RECFM=FB,LRECL=80)
//SYSOUT   DD SYSOUT=*

COBOL + DB2 (embedded SQL)

       EXEC SQL
           SELECT NOME, SALARIO
           INTO :WS-NOME, :WS-SALARIO
           FROM EMPREGADOS
           WHERE ID = :WS-ID
       END-EXEC.

: prefixa variáveis COBOL no SQL. Pré-processador converte para CALL adequado.

COBOL + CICS

       EXEC CICS
           RECEIVE MAP("MAPA1")
           MAPSET("MAPSET1")
       END-EXEC.

       EXEC CICS
           SEND MAP("MAPA2")
           MAPSET("MAPSET1")
           END
       END-EXEC.

11. Modernização

COBOL não está estagnado:

A maioria do código continua COBOL clássico. Aprender o velho é mais útil que o novo, para mercado de trabalho.

12. Próximos passos

Glossário

Recursos

COBOL não é "sexy" mas é dinheiro. Aprender COBOL aos 20 anos significa salário acima da média até à reforma. As empresas que dependem disto não conseguem encontrar pessoas. Se a parte técnica não te assusta (sintaxe arcaica, formatação rígida, falta de features modernas), é uma carreira sólida.