Tabel COBOL dapat diakses melalui dua mekanisme, yaitu subskrip yang ditulis setiap kali elemen dirujuk dan register indeks yang dideklarasikan dengan klausa INDEXED BY. Topik ini membahas subskrip literal, variabel, dan relatif, pengisian serta penggeseran register indeks dengan verb SET, perbedaan kinerja keduanya, dan risiko akses di luar batas tabel. Dua program utuh memperagakan seluruh mekanisme tersebut pada tabel yang sama.
Subskrip literal, variabel, dan relatif#
Subskrip menyatakan posisi elemen yang diinginkan dan mengikuti tiga bentuk.
Bentuk literal seperti NILAI-HARI(3) menunjuk satu elemen yang tetap, bentuk
variabel seperti NILAI-HARI(I) menunjuk elemen yang bergantung isi I, dan
bentuk relatif seperti NILAI-HARI(POSISI + 1) menggeser posisi dari sebuah
nilai. Pada setiap akses, compiler menghitung letak byte elemen dari subskrip
tersebut, sehingga bentuk yang dipilih tidak mengubah isi tabel melainkan hanya
cara menunjuknya. Nilai yang sah berada pada rentang 1 sampai jumlah pengulangan
klausanya.
IDENTIFICATION DIVISION.
PROGRAM-ID. SUBSKRIP-UJI.
*--------------------------------------------------------------
* Subskrip literal, variabel, dan relatif pada tabel.
*--------------------------------------------------------------
DATA DIVISION.
WORKING-STORAGE SECTION.
01 NILAI-HARIAN.
05 NILAI-HARI PIC 9(3) OCCURS 5 TIMES.
01 I PIC 9(2).
01 POSISI PIC 9(2).
PROCEDURE DIVISION.
UTAMA.
MOVE 80 TO NILAI-HARI(1)
MOVE 75 TO NILAI-HARI(2)
MOVE 90 TO NILAI-HARI(3)
MOVE 85 TO NILAI-HARI(4)
MOVE 70 TO NILAI-HARI(5)
PERFORM TAMPIL-SATU
VARYING I FROM 1 BY 1 UNTIL I > 5
MOVE 2 TO POSISI
DISPLAY "Subskrip variabel : " NILAI-HARI(POSISI)
DISPLAY "Subskrip relatif : " NILAI-HARI(POSISI + 1)
STOP RUN.
TAMPIL-SATU.
DISPLAY "Literal " I " : " NILAI-HARI(I).Literal 01 : 080
Literal 02 : 075
Literal 03 : 090
Literal 04 : 085
Literal 05 : 070
Subskrip variabel : 075
Subskrip relatif : 090Lima baris pertama berasal dari subskrip variabel NILAI-HARI(I) yang
dikendalikan PERFORM VARYING, persis seperti pola penelusuran tabel pada umumnya.
Dua baris terakhir memperlihatkan perbedaan bentuk yang tersisa, yaitu
NILAI-HARI(POSISI) yang bernilai 075 karena POSISI berisi 2 dan
NILAI-HARI(POSISI + 1) yang bernilai 090 karena posisinya digeser satu. Bentuk
relatif berguna saat logika mengambil elemen berikutnya atau sebelumnya dari
posisi yang sedang dipegang.
Reproduksi keluaran di atas dengan perintah berikut, lalu jalankan ./subskrip.
# kompilasi program subskrip literal dan variabel
cobc -x subskrip.cblINDEXED BY dan verb SET#
Klausa INDEXED BY pada entri ber-OCCURS mendeklarasikan register indeks
(index), yaitu item khusus yang menyimpan jarak byte elemen dari awal tabel dan
bukan nomor elemennya. Karena isinya berupa jarak, register indeks hanya boleh
diatur melalui verb SET. SET IDX-STOK TO 1 mengisi register tersebut dengan
sebuah nilai, SET IDX-STOK UP BY 1 menaikkan nilainya, dan
SET IDX-STOK DOWN BY 1 menurunkannya.
Register indeks dipakai sebagai subskrip dalam bentuk JUMLAH-STOK(IDX-STOK) dan
boleh diuji dalam kondisi seperti UNTIL IDX-STOK > 5. Untuk membaca posisi yang
sedang ditunjuk ke dalam variabel biasa, gunakan bentuk SET POSISI TO IDX-STOK.
IDENTIFICATION DIVISION.
PROGRAM-ID. INDEKS-SET.
*--------------------------------------------------------------
* Register indeks INDEXED BY: diisi dan digeser lewat verb SET.
*--------------------------------------------------------------
DATA DIVISION.
WORKING-STORAGE SECTION.
01 STOK-GUDANG.
05 JUMLAH-STOK PIC 9(4) OCCURS 5 TIMES
INDEXED BY IDX-STOK.
01 I PIC 9(2).
01 POSISI PIC 9(2).
PROCEDURE DIVISION.
UTAMA.
PERFORM ISI-SATU
VARYING I FROM 1 BY 1 UNTIL I > 5
SET IDX-STOK TO 1
PERFORM TAMPIL-INDEKS
UNTIL IDX-STOK > 5
SET IDX-STOK TO 4
SET POSISI TO IDX-STOK
DISPLAY "Indeks berhenti di posisi " POSISI
DISPLAY "Elemen pada posisi itu : " JUMLAH-STOK(IDX-STOK)
SET IDX-STOK DOWN BY 2
SET POSISI TO IDX-STOK
DISPLAY "Setelah diturunkan dua : " JUMLAH-STOK(IDX-STOK)
STOP RUN.
ISI-SATU.
COMPUTE JUMLAH-STOK(I) = I * 100.
TAMPIL-INDEKS.
SET POSISI TO IDX-STOK
DISPLAY "Indeks " POSISI " : " JUMLAH-STOK(IDX-STOK)
SET IDX-STOK UP BY 1.Indeks 01 : 0100
Indeks 02 : 0200
Indeks 03 : 0300
Indeks 04 : 0400
Indeks 05 : 0500
Indeks berhenti di posisi 04
Elemen pada posisi itu : 0400
Setelah diturunkan dua : 0200Perulangan PERFORM TAMPIL-INDEKS UNTIL IDX-STOK > 5 menelusuri tabel tanpa
variabel penghitung tambahan, karena peningkatan posisi dikerjakan oleh
SET IDX-STOK UP BY 1 di akhir paragraf TAMPIL-INDEKS. Syarat perulangan diuji
sebelum setiap iterasi, sehingga setelah iterasi kelima indeks bernilai 6 dan
perulangan berhenti. Dua baris terakhir menunjukkan SET IDX-STOK DOWN BY 2
yang mundur dua posisi dari 4 menuju 2, dan elemen yang dibaca mengikuti
posisi barunya.
Reproduksi keluaran di atas dengan perintah berikut, lalu jalankan
./indeks-set.
# kompilasi program register indeks dengan SET
cobc -x indeks-set.cblKinerja dan pemeriksaan batas#
Perbedaan kedua mekanisme terletak pada kapan jarak byte dihitung. Subskrip dihitung ulang pada setiap akses, sedangkan register indeks menyimpan jarak tersebut sehingga aksesnya tidak perlu perhitungan baru. Pada tabel kecil perbedaannya dapat diabaikan, tetapi pada tabel besar yang ditelusuri berulang kali penggunaan indeks mengurangi perhitungan pada setiap iterasi. Karena itu, tabel yang menjadi sasaran SEARCH dideklarasikan dengan INDEXED BY, seperti dibahas pada pencarian tabel.
Akses di luar batas tabel merupakan risiko yang terpisah dari pilihan mekanisme.
GnuCOBOL menolak subskrip literal yang keluar batas sejak waktu kompilasi,
sedangkan subskrip variabel yang bernilai di luar rentang tidak diperiksa sama
sekali pada kompilasi bawaan dan menyebabkan perilaku tak terdefinisi, misalnya
membaca atau merusak byte milik data lain. Bendera cobc -debug memasang
pemeriksaan batas saat program berjalan dan menghentikannya dengan pesan seperti
error: subscript of 'X' out of bounds: 7 disertai catatan batas maksimum
subskripnya. Pasang bendera tersebut pada masa pengembangan untuk menangkap
akses di luar batas lebih dini.
Kesalahan umum#
- Mengatur register indeks dengan verb selain SET. Standar COBOL hanya
mengizinkan pengubahan indeks melalui SET, dan sebagian compiler menolak bentuk
lain dengan pesan error. Gunakan
SET ... TO,SET ... UP BY, danSET ... DOWN BYuntuk seluruh pengaturannya. - Mengakses tabel melalui indeks yang belum pernah diisi. Nilai awal register
indeks yang baru dideklarasikan tidak terdefinisi, sehingga rujukan pertama
menunjuk posisi sembarangan. Isi indeks dengan
SET IDX TO 1sebelum pemakaian pertamanya. - Menganggap indeks menyimpan nomor elemen. Register indeks menyimpan jarak
byte, sehingga nilainya tidak boleh dihitung seperti variabel biasa dan tidak
boleh diisi dengan aritmetika ADD atau COMPUTE. Salin posisinya ke variabel
numerik dengan
SET POSISI TO IDXapabila nomor posisi diperlukan.
Ringkasan#
- Subskrip berbentuk literal, variabel, atau relatif dihitung ulang pada setiap akses, sedangkan register indeks dari INDEXED BY menyimpan jarak byte sehingga aksesnya lebih ringan pada tabel besar.
- Register indeks hanya diatur melalui verb SET dalam bentuk TO, UP BY, dan DOWN
BY, serta dibaca ke variabel numerik melalui
SET POSISI TO IDX. - Subskrip literal di luar batas ditolak saat kompilasi, sedangkan subskrip
variabel yang keluar batas menyebabkan perilaku tak terdefinisi dan hanya
terdeteksi bila program dikompilasi dengan
cobc -debug.
Referensi#
- GnuCOBOL Manual — Free Software Foundation — Memuat aturan subskrip, klausa INDEXED BY, dan verb SET pada pembahasan table handling.
- IBM Enterprise COBOL for z/OS documentation — IBM — Halaman SUBSCRIPT dan INDEXED BY clause menjelaskan perbedaan subskrip dan register indeks beserta aturan penggunaannya.