SyntaxEdit
COBOL ma składnię podobną do angielskiej, która jest używana do opisania prawie wszystkiego w programie. Na przykład warunek można wyrazić jako x JEST WIĘKSZA NIŻ y
lub bardziej zwięźle jako x WIĘKSZA y
lub x > y
. Bardziej złożone warunki można „skrócić”, usuwając powtarzające się warunki i zmienne. Na przykład a > b AND a > c OR a = d
można skrócić do a > b AND c OR = d
. Aby obsługiwać składnię podobną do angielskiej, COBOL ma ponad 300 słów kluczowych. Niektóre słowa kluczowe to proste alternatywne lub w liczbie mnogiej pisownia tego samego słowa, co zapewnia bardziej angielskie stwierdzenia i klauzule; np. IN
i OF
słowa kluczowe mogą być używane zamiennie, podobnie jak IS
i ARE
i VALUE
i WARTOŚCI
.
Każdy program w języku COBOL składa się z czterech podstawowych elementów leksykalnych: słów, literałów, ciągów znaków obrazkowych (patrz § RYSUNEK klauzula) i separatory. Słowa obejmują słowa zastrzeżone i identyfikatory zdefiniowane przez użytkownika. Mają maksymalnie 31 znaków i mogą zawierać litery, cyfry, łączniki i podkreślenia. Literały obejmują cyfry (np. 12
) i ciągi (np. „Witaj!”
). Separatory zawierają znak spacji oraz przecinki i średniki, po których następuje spacja.
Program w języku COBOL jest podzielony na cztery części: podział na identyfikację, podział środowiska, podział danych i podział na procedury. Podział identyfikacji określa nazwę i typ elementu źródłowego i jest miejscem, w którym określone są klasy i interfejsy. Podział środowiska określa wszelkie funkcje programu, które zależą od systemu, w którym jest uruchomiony, takie jak pliki i zestawy znaków. Podział danych służy do deklarowania zmiennych i parametrów. Podział procedury zawiera instrukcje programu. Każdy podział jest podzielony na sekcje, które składają się z akapitów.
MetalanguageEdit
Składnia języka COBOL jest zwykle opisywana za pomocą unikalny metajęzyk wykorzystujący szelki, nawiasy, kreski i podkreślenia. Metajęzyk został opracowany zgodnie z oryginalnymi specyfikacjami COBOL. Chociaż forma Backus – Naur istniała w tamtym czasie, komitet o nim nie słyszał.
Element | Wygląd | Funkcja |
---|---|---|
Wszystkie wielkie litery | EXAMPLE | Zarezerwowane słowo |
Podkreślenie | EXAMPLE | Zarezerwowanym słowem jest obowiązkowe |
Nawiasy klamrowe | {} | Można wybrać tylko jedną opcję |
Nawiasy | Można wybrać zero lub jedną opcję | |
Wielokropek | … | Poprzedni element może się powtórzyć |
Bars | {| |} | Można wybrać jedną lub więcej opcji. Dowolną opcję można wybrać tylko raz. |
Można wybrać zero lub więcej opcji. Dowolna opcja może być wybrana tylko wybrany raz. |
Na przykład consi der następujący opis instrukcji ADD
:
Ten opis dopuszcza następujące warianty:
ADD 1 TO xADD 1, a, b TO x ROUNDED, y, z ROUNDEDADD a, b TO c ON SIZE ERROR DISPLAY "Error"END-ADDADD a TO b NOT SIZE ERROR DISPLAY "No error" ON SIZE ERROR DISPLAY "Error"
Format koduEdit
COBOL może być zapisany w dwóch formatach: stałym (domyślnym) lub darmowym. W stałym formacie kod musi być wyrównany, aby zmieścił się w określonych obszarach (brak możliwości używania kart perforowanych).Do wydania COBOL 2002 były to:
Name | Column (s) | Użycie |
---|---|---|
Obszar numeru sekwencji | 1–6 | Pierwotnie używany do karty / numery linii (ułatwiające mechaniczne sortowanie kart perforowanych w celu zapewnienia zamierzonej sekwencji kodu programu po ręcznej edycji / obsłudze), ten obszar jest ignorowany przez kompilator |
Obszar wskaźnika | 7 | W tym miejscu dozwolone są następujące znaki:
|
Obszar A | 8–11 | Zawiera: DIVISION , SECTION i nagłówki procedur; Numery poziomów 01 i 77 oraz deskryptory plików / raportów |
Obszar B | 12–72 | Każdy inny kod niedozwolony w obszarze A |
Obszar nazwy programu | 73– | Historycznie do kolumny 80 dla kart perforowanych służy do identyfikacji programu lub kolejność, do której należy karta |
W COBOL 2002 obszary A i B były scalone w celu utworzenia obszaru tekstu programu, który teraz kończy się na kolumnie zdefiniowanej przez implementatora.
COBOL 2002 również wprowadził kod o dowolnym formacie. Kod w dowolnym formacie można umieścić w dowolnej kolumnie pliku, tak jak w nowszych językach programowania. Komentarze są określane za pomocą *>
, które można umieścić w dowolnym miejscu i można ich również używać w kodzie źródłowym o stałym formacie. Brakuje linii kontynuacji, a dyrektywa >>PAGE
zastępuje wskaźnik /
.
Identification DivisionEdit
Dział identyfikacji identyfikuje następującą jednostkę kodu i zawiera definicję klasy lub interfejsu.
Programowanie obiektoweEdit
Klasy i interfejsy są w języku COBOL od 2002 roku. Klasy mają obiekty fabryczne zawierające metody i zmienne klas oraz obiekty instancji zawierające metody i zmienne instancji. Dziedziczenie i interfejsy zapewniają polimorfizm. Obsługa programowania ogólnego jest zapewniana przez sparametryzowane klasy, których wystąpienia można utworzyć w celu użycia dowolnej klasy lub interfejsu. Obiekty są przechowywane jako odniesienia, które mogą być ograniczone do określonego typu. Istnieją dwa sposoby wywołania metody: instrukcja INVOKE
, która działa podobnie do CALL
lub poprzez wywołanie metody wbudowanej, co jest analogiczne do używania funkcji.
*> These are equivalent.INVOKE my-class "foo" RETURNING varMOVE my-class::"foo" TO var *> Inline method invocation
COBOL nie zapewnia sposobu na ukrycie metod. Dane klasy można jednak ukryć, deklarując je bez klauzuli PROPERTY
, co powoduje, że użytkownik nie ma do nich dostępu. Przeciążanie metod zostało dodane w języku COBOL 2014.
Podział środowiskaEdit
Podział środowiska zawiera sekcję konfiguracyjną i sekcję wejścia-wyjścia. Sekcja konfiguracji służy do określania zmiennych funkcji, takich jak znaki walutowe, ustawienia regionalne i zestawy znaków. Sekcja wejścia-wyjścia zawiera informacje związane z plikami.
FilesEdit
COBOL obsługuje trzy formaty plików lub organizacje: sekwencyjny, indeksowany i względny. W plikach sekwencyjnych rekordy są ciągłe i muszą być przechodzone sekwencyjnie, podobnie jak w przypadku listy połączonej. Pliki indeksowane mają jeden lub więcej indeksów, które umożliwiają losowy dostęp do rekordów i które można na nich sortować. Każdy rekord musi mieć unikalny klucz, ale inne, alternatywne klucze rekordów nie muszą być unikalne. Implementacje plików indeksowanych różnią się w zależności od dostawców, chociaż typowe implementacje, takie jak C-ISAM i VSAM, są oparte na ISAM firmy IBM. Pliki względne, podobnie jak pliki indeksowane, mają unikalny klucz rekordu, ale nie mają kluczy alternatywnych. kluczem rekordu względnego jest jego pozycja porządkowa; na przykład dziesiąty rekord ma klucz 10. Oznacza to, że utworzenie rekordu z kluczem 5 może wymagać utworzenia (pustych) rekordów poprzedzających. Pliki względne pozwalają również na dostęp sekwencyjny i losowy.
Popularnym niestandardowym rozszerzeniem jest porządkowanie wierszy, używane do przetwarzania plików tekstowych. Rekordy w pliku są zakończone znakiem nowej linii i mogą mieć różną długość.
Podział danychEdytuj
Podział danych jest podzielony na sześć sekcji, które deklarują różne pozycje: sekcja pliku, dla akta plików; sekcja pamięci roboczej dla zmiennych statycznych; sekcja przechowywania lokalnego dla zmiennych automatycznych; sekcja powiązania dla parametrów i wartości zwracanej; sekcja raportu i sekcja ekranu dla interfejsów użytkownika opartych na tekście.
Zagregowane dataEdit
Pozycje danych w języku COBOL są deklarowane hierarchicznie przy użyciu numerów poziomów, które wskazują, czy dana pozycja jest częścią innej. Przedmiot o wyższym numerze poziomu jest podrzędny wobec przedmiotu o niższym. Elementy danych najwyższego poziomu o numerze 1 nazywane są rekordami. Pozycje, które mają podrzędne dane zagregowane, nazywane są pozycjami grupowymi; te, które nie są, nazywane są elementami elementarnymi. Numery poziomów używane do opisu standardowych elementów danych mieszczą się w zakresie od 1 do 49.
W powyższym przykładzie element podstawowy num
i element grupy data
są podrzędne w stosunku do rekordu some-record
, natomiast elementy podstawowe rok
, miesiąc
i -day
są częścią elementu grupy the-date
.
Elementy podrzędne można rozróżnić za pomocą IN (lub OF
). Na przykład rozważ powyższy przykładowy kod wraz z następującym przykładem:
01 sale-date. 05 the-year PIC 9(4). 05 the-month PIC 99. 05 the-day PIC 99.
Nazwy rok
, miesiąc
i dzień
są same w sobie niejednoznaczne, ponieważ więcej niż jeden element danych jest zdefiniowany z tymi nazwami. Aby określić konkretną pozycję danych, na przykład jedną z pozycji zawartych w grupie sale-date
, programista użyje rok IN data-sprzedaży
(lub odpowiednik rok daty-sprzedaży
). (Składnia ta jest podobna do „notacji z kropkami” obsługiwanej przez większość współczesnych języków).
Inne poziomy danychEdytuj
Numer poziomu 66 jest używany do zadeklarowania ponownego zgrupowania wcześniej zdefiniowane pozycje, niezależnie od ich struktury. Ten poziom danych, do którego odnosi się również powiązana klauzula RENAMES
, jest rzadko używany i około 1988 roku był zwykle znajdowany w starych programach. Jego zdolność do ignorowania danych o strukturze hierarchicznej i logicznej oznaczała, że jego użycie nie było zalecane, a wiele instalacji zabraniało jego używania.
Numer poziomu 77 wskazuje, że element jest samodzielny iw takich sytuacjach jest równoważny z numer poziomu 01. Na przykład poniższy kod deklaruje dwie 77-poziomowe pozycje danych, nazwa-właściwości
i sales-region
, które są pozycjami danych niebędącymi grupami, które są niezależne (nie podporządkowane) żadnym innym elementom danych:
77 property-name PIC X(80). 77 sales-region PIC 9(5).
88-poziomowy numer deklaruje nazwę warunku (tak zwany 88-poziomowy), który jest prawdziwy, gdy jego nadrzędny element danych zawiera jedną z wartości określonych w jego VALUE
. Na przykład poniższy kod definiuje dwie pozycje nazwy warunku na 88 poziomach, które są prawdziwe lub fałszywe w zależności od bieżącej wartości danych znakowych elementu danych wage-type
. Gdy pozycja danych zawiera wartość "H"
, nazwa-warunku stawka-godzinowa
jest prawdziwe, podczas gdy gdy zawiera wartość "S"
lub "Y"
, nazwa-warunku wage-is-yearly
ma wartość true. Jeśli element danych zawiera jakąś inną wartość, obie nazwy warunków mają wartość false.
01 wage-type PIC X. 88 wage-is-hourly VALUE "H". 88 wage-is-yearly VALUE "S", "Y".
Data typesEdit
Standard COBOL udostępnia następujące typy danych:
Typ danych | Przykładowa deklaracja | Uwagi |
---|---|---|
Alphabetic | PIC A (30) |
Może zawierać tylko litery lub spacje |
Alfanumeryczne | PIC X (30) |
Może zawierać dowolne znaki |
Boolean | BIT UŻYCIA PIC 1 |
Dane przechowywane w postaci zer i jedynek, jako liczba binarna |
Indeks | INDEKS UŻYTKOWANIA |
Używany do odwoływania się do elementów tabeli |
National | PIC N (30) |
Podobny do alfanumerycznego, ale wykorzystujący znak rozszerzony zestaw, np. UTF-8 |
Numeryczne | PIC 9 (5) V9 (5) |
Może zawierać tylko cyfry |
Obiekt | WYKORZYSTANIE OBIEKTU ODNOŚNIK |
Może odwoływać się do obiektu lub NULL |
Pointer | WSKAŹNIK UŻYCIA |
Bezpieczeństwo typów jest zmienne w języku COBOL.Dane liczbowe są konwertowane dyskretnie między różnymi reprezentacjami i rozmiarami, a dane alfanumeryczne można umieścić w dowolnym elemencie danych, który można przechowywać jako ciąg, w tym dane liczbowe i dane grupowe. Natomiast odniesienia do obiektów i wskaźniki mogą być przypisywane tylko z elementów tego samego typu, a ich wartości mogą być ograniczone do określonego typu.
PICTURE klauzulaEdit
A PICTURE
(lub PIC
) jest ciągiem znaków, z których każdy reprezentuje część elementu danych i co może zawierać. Niektóre znaki graficzne określają typ elementu oraz liczbę znaków lub cyfr zajmowanych w pamięci. Na przykład 9
oznacza cyfrę dziesiętną, a S
oznacza, że element jest podpisany. Inne znaki graficzne (nazywane znakami wstawiania i edycji) określają sposób formatowania elementu. Na przykład seria znaków +
definiuje pozycje znaków, a także sposób umieszczania początkowego znaku znaku w końcowych danych znakowych; znak nienumeryczny znajdujący się najbardziej na prawo będzie zawierał znak elementu, podczas gdy inne pozycje znaków odpowiadające +
na lewo od tej pozycji będą zawierać spację. Powtarzane znaki można określić bardziej zwięźle, podając liczbę w nawiasach po znaku graficznym; na przykład 9 (7)
jest równoważne z 9999999
. Specyfikacja obrazu zawiera tylko cyfrę ( 9
) i znak ( Znaki S
) określają czysto numeryczne elementy danych, podczas gdy specyfikacje obrazu zawierają alfabetyczne ( A
) lub alfanumeryczne ( X
) definiują alfanumeryczne elementy danych. Obecność innych znaków formatujących definiuje edytowane numeryczne lub edytowane alfanumeryczne elementy danych.
USAGE klauzulaEdit
USAGE deklaruje format dane są przechowywane w. W zależności od typu danych można je uzupełnić lub użyć zamiast klauzuli PICTURE
. Chociaż może być używany do deklarowania wskaźników i odniesień do obiektów, jest głównie nastawiony na określanie typów liczbowych. Te formaty liczbowe to:
- Binarne, gdzie minimalny rozmiar jest określony przez klauzulę
PICTURE
lub przezUSAGE
, na przykładBINARY-LONG
. -
USAGE COMPUTATIONAL
, gdzie dane mogą być przechowywane w dowolnym formacie, jaki zapewnia implementacja; często odpowiednikUSAGE BINARY
-
USAGE DISPLAY
, format domyślny , gdzie dane są przechowywane jako ciąg znaków - zmiennoprzecinkowy, w formacie zależnym od implementacji lub zgodnie z IEEE 754.
-
USAGE NATIONAL
, gdzie dane są przechowywane jako ciąg przy użyciu rozszerzonego zestawu znaków -
USAGE PACKED-DECIMAL
, gdzie dane jest przechowywany w najmniejszym możliwym formacie dziesiętnym (zwykle spakowanym dziesiętnym kodem binarnym)
Report writerEdit
Narzędzie do tworzenia raportów jest deklaratywnym narzędziem do tworzenia raportów. Programista musi tylko określić układ raportu i dane wymagane do jego utworzenia, zwalniając go z konieczności pisania kodu obsługującego takie rzeczy, jak podziały stron, formatowanie danych oraz nagłówki i stopki.
Raporty są powiązane z raportem pliki, które są plikami, do których można zapisywać tylko za pomocą instrukcji autora raportu.
FD report-out REPORT sales-report.
Każdy raport jest zdefiniowany w sekcji raportu podziału danych. Raport jest podzielony na grupy raportów, które definiują nagłówki, stopki i szczegóły raportu. Raporty omijają hierarchiczne podziały kontroli. Przerwy kontroli występują, gdy zmienna kluczowa zmienia jej wartość; na przykład podczas tworzenia raportu opisującego zamówienia klientów, a Przerwa w kontroli może wystąpić, gdy program dotrze do zamówień innego klienta. Oto przykładowy opis raportu dla raportu, który zawiera informacje o sprzedaży sprzedawcy i który ostrzega o wszelkich nieprawidłowych rekordach:
Powyższy opis raportu opisuje następujący układ:
Cztery instrukcje sterują narzędziem do tworzenia raportów: INITIATE
, który przygotowuje program piszący raport do drukowania; GENERATE
, który drukuje grupę raportów; SUPPRESS
, który pomija drukowanie grupy raportów; i TERMINATE
, co kończy przetwarzanie raportu.W powyższym przykładzie raportu sprzedaży podział procedur może wyglądać następująco:
OPEN INPUT sales, OUTPUT report-out INITIATE sales-report PERFORM UNTIL 1 <> 1 READ sales AT END EXIT PERFORM END-READ VALIDATE sales-record IF valid-record GENERATE sales-on-day ELSE GENERATE invalid-sales END-IF END-PERFORM TERMINATE sales-report CLOSE sales, report-out .
Korzystanie z narzędzia Report Writer było różne wydatnie; niektóre organizacje stosowały go w szerokim zakresie, a inne wcale. Ponadto implementacje narzędzia Report Writer różniły się jakością, przy czym te na niższym końcu czasami zużywały nadmierną ilość pamięci w czasie wykonywania.
Podział procedurEdit
ProceduresEdit
Sekcje i akapity w podziale procedur (zwane łącznie procedurami) mogą być używane jako etykiety i jako proste podprogramy. W przeciwieństwie do innych podziałów, akapity nie muszą znajdować się w sekcjach. Wykonywanie przechodzi przez procedury programu aż do jego zakończenia. Aby użyć procedur jako podprogramów, PERFORM
czasownik jest używany.
Instrukcja PERFORM
przypomina nieco wywołanie procedury we współczesnym języku w tym sensie, że wykonanie wraca do kodu po instrukcji PERFORM
na końcu wywoływanego kodu; jednak nie zapewnia żadnego mechanizmu przekazywania parametrów ani zwracania wartości wynikowej. Jeśli podprogram jest wywoływany za pomocą prostej instrukcji, takiej jak PERFORM podprocedura
, to sterowanie wraca na koniec wywoływanej procedury. Jednak PERFORM
jest nietypowe, ponieważ może być używane do wywoływania zakresu obejmującego sekwencję kilku sąsiednich procedur. Odbywa się to za pomocą konstrukcji PERFORM sub-1 THRU sub-n
:
PROCEDURE so-and-so. PERFORM ALPHA PERFORM ALPHA THRU GAMMA STOP RUN.ALPHA. DISPLAY "A".BETA. DISPLAY "B".GAMMA. DISPLAY "C".
Wynik tego programu będzie wyglądał następująco: „AABC”.
PERFORM
różni się również od konwencjonalnych wywołań procedur w że nie ma, przynajmniej tradycyjnie, pojęcia stosu wywołań. W konsekwencji możliwe są wywołania zagnieżdżone (sekwencja kodu PERFORM
„ed może wykonać PERFORM
), ale wymagają dodatkowej uwagi, jeśli części tego samego kodu są wykonywane przez oba wywołania.Problem pojawia się, gdy kod w wywołaniu wewnętrznym osiągnie punkt wyjścia wywołania zewnętrznego. Bardziej formalnie, jeśli kontrola przechodzi przez punkt wyjścia wywołania PERFORM
, które zostało wywołane wcześniej, ale jeszcze się nie zakończyło. Norma COBOL 2002 oficjalnie stanowi, że zachowanie jest niezdefiniowane.
Powodem jest to, że język COBOL, a nie „adres zwrotny”, działa z tak zwanym adresem kontynuacji. Kiedy przepływ sterowania osiąga koniec dowolnej procedury, adres kontynuacji jest wyszukiwany, a sterowanie jest przesyłane na ten adres. program jest uruchomiony, adres kontynuacji dla każdej procedury jest inicjalizowany na adres początkowy pro następną wskazówką w tekście programu jest to, że jeśli nie wystąpią żadne instrukcje PERFORM
, sterowanie przepływa przez program od góry do dołu. Ale kiedy wykonywana jest instrukcja PERFORM
, modyfikuje adres kontynuacji wywoływanej procedury (lub ostatnią procedurę z wywoływanego zakresu, jeśli PERFORM THRU
), dzięki czemu kontrola wróci na koniec do strony wywołania. Oryginalna wartość jest zapisywana i później odtwarzana, ale jest tylko jedna pozycja pamięci. Jeśli dwa zagnieżdżone wywołania działają na nakładającym się kodzie, mogą na kilka sposobów zakłócać wzajemne zarządzanie adresem kontynuacji.
Poniższy przykład (zaczerpnięty z Veermana & Verhoeven 2006) ilustruje problem:
Można by się spodziewać, że wynikiem działania tego programu będzie „1 2 3 4 3”: Po wyświetleniu „2” drugie PERFORM
powoduje wyświetlenie „3” i „4”, a następnie pierwsze wywołanie jest kontynuowane z „3”. W tradycyjnych implementacjach języka COBOL tak nie jest. Zamiast tego pierwsze PERFORM
ustawia adres kontynuacji na końcu LABEL3
, tak aby przeskoczył z powrotem do wywołanie witryny wewnątrz LABEL1
. Druga instrukcja PERFORM
ustawia zwrot na końcu LABEL4
, ale nie zmienia adresu kontynuacji LABEL3
, przeskakuje z powrotem do zewnętrznego PERFORM
, a program przestanie drukować tylko „1 2 3”. Z drugiej strony, w niektórych implementacjach języka COBOL, takich jak kompilator TinyCOBOL o otwartym kodzie źródłowym, dwie instrukcje PERFORM
nie kolidują ze sobą, a wynikiem jest rzeczywiście „1 2 3 4 3 „.Dlatego zachowanie w takich przypadkach jest nie tylko (być może) zaskakujące, ale także nie jest przenośne.
Szczególną konsekwencją tego ograniczenia jest to, że WYDAJNOŚĆ
nie może służyć do pisania kodu rekurencyjnego. Kolejny prosty przykład ilustrujący to (nieco uproszczony z Veermana & Verhoeven 2006):
MOVE 1 TO A PERFORM LABEL STOP RUN.LABEL. DISPLAY A IF A < 3 ADD 1 TO A PERFORM LABEL END-IF DISPLAY "END".
Można by się spodziewać, że na wyjściu pojawi się „1 2 3 END END END” i faktycznie to właśnie wyprodukują niektóre kompilatory języka COBOL. Jednak niektóre kompilatory, takie jak IBM COBOL, utworzą kod, który wypisuje „1 2 3 END END END END…” i tak dalej, wypisując „END” w nieskończonej pętli. Ponieważ miejsce na przechowywanie adresów kontynuacji kopii zapasowych jest ograniczone, kopie zapasowe są nadpisywane w trakcie wywołań rekurencyjnych, a wszystko, co można przywrócić, to powrót do DISPLAY "END"
.
InstrukcjeEdit
COBOL 2014 zawiera 47 instrukcji (zwanych także czasownikami), które można podzielić na następujące szerokie kategorie: przepływ sterowania, I / O, manipulacja danymi i autor raportu. Oświadczenia autora raportu są omówione w sekcji edytora raportów.
Control flowEdit
Instrukcje warunkowe w języku COBOL to IF
i EVALUATE
. EVALUATE
to instrukcja podobna do przełącznika z dodatkową możliwością oceny wielu wartości i warunki. Można to wykorzystać do implementacji tabel decyzyjnych. Na przykład do sterowania tokarką CNC można użyć:
EVALUATE TRUE ALSO desired-speed ALSO current-speed WHEN lid-closed ALSO min-speed THRU max-speed ALSO LESS THAN desired-speed PERFORM speed-up-machine WHEN lid-closed ALSO min-speed THRU max-speed ALSO GREATER THAN desired-speed PERFORM slow-down-machine WHEN lid-open ALSO ANY ALSO NOT ZERO PERFORM emergency-stop WHEN OTHER CONTINUEEND-EVALUATE
Instrukcja PERFORM
służy do definiowania pętli, które są wykonywane do momentu spełnienia warunku (a nie do spełnienia warunku, co jest częstsze w innych językach). jest również używany do wywoływania procedur lub zakresów procedur (zobacz sekcję dotyczącą procedur, aby uzyskać więcej informacji). CALL
i INVOKE
wywołanie odpowiednio podprogramów i metod. Nazwa podprogramu / metody jest zawarta w str które mogą być literałem lub elementem danych. Parametry mogą być przekazywane przez referencję, zawartość (gdzie kopia jest przekazywana przez referencję) lub według wartości (ale tylko jeśli dostępny jest prototyp). CANCEL
zwalnia podprogramy z pamięci. GO TO
powoduje, że program przechodzi do określonej procedury.
GOBACK
jest instrukcją powrotu, a instrukcja STOP
zatrzymuje program. Instrukcja EXIT
ma sześć różnych formatów: może być używana jako instrukcja powrotu, instrukcja przerwania, instrukcja kontynuacji, znacznik końca lub do opuszczenia procedury.
Wyjątki są zgłaszane przez instrukcję RAISE
i przechwytywane przez procedurę obsługi lub deklaratywną zdefiniowaną w DECLARATIVES
część podziału procedury. Deklaraty to sekcje zaczynające się od instrukcji USE
, które określają błędy do obsłużenia. Wyjątkami mogą być nazwy lub obiekty. RESUME
jest używane w deklaracji, aby przejść do instrukcji po tej, która wywołała wyjątek, lub do procedury poza DEKLARACJE
. W przeciwieństwie do innych języków, nieprzechwycone wyjątki mogą nie zakończyć programu, a program może działać bez zmian.
I / OEdit
We / wy pliku jest obsługiwane przez samoopisujące się OTWÓRZ
, ZAMKNIJ
, CZYTAJ
, i WRITE
wraz z następnymi trzema: REWRITE
, które aktualizują rekord; START
, który wybiera kolejne rekordy do dostępu, znajdując rekord z określonym kluczem; i UNLOCK
, co zwalnia blokadę ostatniego dostępnego rekordu.
Interakcja użytkownika odbywa się za pomocą ACCEPT
i DISPLAY
.
Manipulacja danymiEdit
Następujące czasowniki manipulują danymi:
-
INITIALIZE
, który ustawia elementy danych na ich wartości domyślne. -
MOVE
, który przypisuje wartości elementom danych; MOVE CORRESPONDING przypisuje odpowiednie pola o podobnych nazwach. -
SET
, który ma 15 formatów: może modyfikować indeksy, przypisywać odniesienia do obiektów i zmieniać tabelę pojemności, między innymi funkcji. -
ADD
,SUBTRACT
,MULTIPLY
,DIVIDE
iCOMPUTE
, które obsługują arytmetyczne (zCOMPUTE
przypisującym wynik formuły do zmiennej). -
ALLOCATE
iFREE
, które obsługują pamięć dynamiczną. -
VALIDATE
, który sprawdza i dystrybuuje dane zgodnie z opisem elementu w podziale danych. -
STRING
iUNSTRING
, które odpowiednio łączą i dzielą ciągi. -
INSPECT
, co odpowiada lub zastępuje wystąpienia określonych podciągów w ciągu. -
SEARCH
, który przeszukuje tabelę pod kątem pierwszego wpisu spełniające warunek.
Pliki i tabele są sortowane przy użyciu SORT
i MERGE
czasownik łączy i sortuje pliki. Czasownik RELEASE
zapewnia rekordy do sortowania i RETURN
pobiera posortowane rekordy w kolejności.
Zakończenie zakresuEdit
Niektóre instrukcje, takie jak IF
i READ
, mogą same zawierać instrukcje. Takie instrukcje mogą zostać zakończone na dwa sposoby: przez kropkę (niejawne zakończenie), która kończy wszystkie zawarte w niej niezakończone instrukcje, lub przez terminator zakresu, który kończy najbliższą pasującą instrukcję otwartą.
Zagnieżdżone instrukcje zakończone są znakiem okres są częstym źródłem błędów. Na przykład przeanalizuj następujący kod:
IF x DISPLAY y. DISPLAY z.
Tutaj celem jest wyświetlenie y
i z
, jeśli warunek x
jest prawdziwy. Jednak z
będzie wyświetlane niezależnie od wartości x
, ponieważ instrukcja IF
jest zakończona błędną kropką po DISPLAY y
.
Kolejny błąd jest wynikiem wiszącego problemu else, gdy dwa IF
mogą być powiązane z ELSE
.
IF x IF y DISPLAY aELSE DISPLAY b.
W powyższym fragmencie ELSE
wiąże się z instrukcją IF y
zamiast IF x
, powodując błąd. Przed wprowadzeniem jawnych terminatorów zakresu, zapobieżenie temu wymagałoby umieszczenia ELSE NEXT SENTENCE
po wewnętrznym IF
.
Self-modifying codeEdit
Oryginalna (1959) specyfikacja COBOL obsługiwała niesławną ALTER X TO PROCEED TO Y
, dla której wiele kompilatorów wygenerowało samomodyfikujący się kod. X
i Y
to etykiety procedur, a pojedyncza PRZEJDŹ DO
instrukcja w procedurze X
wykonana po takiej instrukcji ALTER
oznacza Zamiast tego PRZEJDŹ DO Y
. Wiele kompilatorów nadal to obsługuje, ale zostało uznane za przestarzałe w standardzie COBOL 1985 i usunięte w 2002 roku.
Instrukcja ALTER
została źle oceniona ponieważ podważa to „lokalność kontekstu” i sprawia, że ogólna logika programu jest trudna do zrozumienia. Jak napisał autor podręcznika Daniel D. McCracken w 1976 r., „ktoś, kto nigdy wcześniej nie widział programu, musi jak najszybciej go poznać , czasami pod krytyczną presją czasu, ponieważ program zawiódł … sam widok instrukcji GO TO w akapicie, sygnalizujący istnienie nieznanej liczby instrukcji ALTER w nieznanych miejscach w całym programie, budzi strach w serce najodważniejszego programisty. ”
Witaj, worldEdit
Program„ Hello, world ”w języku COBOL:
IDENTIFICATION DIVISION. PROGRAM-ID. hello-world. PROCEDURE DIVISION. DISPLAY "Hello, world!" .
Kiedy – teraz już sławny – przykład programu „Hello, World!” w języku programowania C został po raz pierwszy opublikowany w 1978 roku, podobny maj Przykładowy program nframe COBOL zostałby przesłany przez JCL, najprawdopodobniej przy użyciu czytnika kart perforowanych i 80 kart perforowanych. Poniższa lista, z pustym PODZIAŁEM DANYCH, została przetestowana przy użyciu systemu GNU / Linux i emulatora System / 370 Hercules z systemem MVS 3.8J. Dokument JCL, napisany w lipcu 2015 r., Pochodzi z samouczków i próbek Herkulesa udostępnianych przez Jaya Moseleya. Zgodnie z programowaniem w języku COBOL z tamtej epoki, HELLO, WORLD jest wyświetlane wielkimi literami.
Po przesłaniu JCL wyświetliła się konsola MVS:
19.52.48 JOB 3 $HASP100 COBUCLG ON READER1 COBOL BASE TEST 19.52.48 JOB 3 IEF677I WARNING MESSAGE(S) FOR JOB COBUCLG ISSUED 19.52.48 JOB 3 $HASP373 COBUCLG STARTED - INIT 1 - CLASS A - SYS BSP1 19.52.48 JOB 3 IEC130I SYSPUNCH DD STATEMENT MISSING 19.52.48 JOB 3 IEC130I SYSLIB DD STATEMENT MISSING 19.52.48 JOB 3 IEC130I SYSPUNCH DD STATEMENT MISSING 19.52.48 JOB 3 IEFACTRT - Stepname Procstep Program Retcode 19.52.48 JOB 3 COBUCLG BASETEST COB IKFCBL00 RC= 0000 19.52.48 JOB 3 COBUCLG BASETEST LKED IEWL RC= 0000 19.52.48 JOB 3 +HELLO, WORLD 19.52.48 JOB 3 COBUCLG BASETEST GO PGM=*.DD RC= 0000 19.52.48 JOB 3 $HASP395 COBUCLG ENDED
Linia 10 powyższej listy konsoli jest podświetlony dla efektu, podświetlenie nie jest częścią rzeczywistego wyjścia konsoli.
Powiązana lista kompilatora wygenerowała na czterech stronach szczegółów technicznych i informacji o przebiegu zadania, dla pojedynczej linii wyjścia z 14 linii COBOL.