إذا رأيت هذا ، فهو (شبه مؤكد) خطأ في برمجة COBOL. يرتكب معظم مبرمجي COBOL هذا الخطأ الغبي ، وأنا لست استثناءً.
سبب المشكلة هو الطريقة التي نهيئ بها السجل عادةً. لنأخذ برنامجًا صغيرًا مثل هذا:
identification division.
program-id.
mistake.
data division.
working-storage section.
* *** Input record, typically maintained on disk/tape somewhere.
01 dr-datarec.
03 dr-name pic x(20).
03 dr-amount pic s9(7)v99, comp-3.
* *** print record, sent to a line printer.
01 dt-detail.
03 dt-name pic x(20).
03 filler pic x.
03 dt-amount pic z,zzz,zz9.99.
procedure division.
move spaces to dr-datarec.
move "test" to dr-name.
move 100 to dr-amount.
move spaces to dt-detail.
move dr-name to dt-name.
move dr-amount to dt-amount.
display dt-detail.
stop run.
في هذا البرنامج ، سجل الإدخال
dr-datarec. عادةً ما يأتي من مكان ما على القرص ، ولكن يتم إنشاؤه يدويًا لهذا الاختبار البسيط.
بمجرد استلام سجل الإدخال ، يتم إجراء الحساب ، ثم يتم إخراج السجل باستخدام
dt-detail.
المشكلة هي كيف يتم إنشاء السجل
dr-datarec. لاحظ كيف يتم نقل المساحات لتهيئتها. كانت هذه هي الطريقة النموذجية لتهيئة السجل.
وبالتالي ، هناك فراغات في جميع مجالات الموافقة المسبقة عن علم X. لكن! يتم أيضًا تهيئة جميع حقول COMP-3 ، ولكن ليس إلى الصفر. يجب أن يتأكد المبرمج من إنشاء القيم الصالحة لجميع حقول COMP-3. برنامج الاختبار يفعل ذلك بشكل صحيح:
move spaces to dr-datarec.
move "test" to dr-name.
move 100 to dr-amount.
من
dr-amountالواضح أن هناك 100 في هذا المجال. بعد البدء اتضح:
./mistake
test 100.00
ماذا لو حدث خطأ في الترميز ولم تتم
dr-amountتهيئة السجل بشكل صحيح؟
لا تزال هناك مساحات ASCII هناك. هذه قيمة سداسية عشرية 20 أو ثنائي 0010 0000.
يخزن COMP-3 الأرقام على هيئة أربعة بتات ، لذلك يتم عرض مسافة واحدة على شكل 20. إذا كان لديك 9 أرقام مثل dr-amount ، فهذا يتطلب 10 ذاكرة للقضم للأرقام وواحد للتوقيع) أو 5 بايت. سينتج عن
نقل المسافات في
dr-datarec5 مسافات أو يتم تخزين القيمة السداسية العشرية 2020202020 في هذا الحقل. إذا حاولت استخدام متغير غير مهيأ ، فسيتم تفسيره على أنه 2020 202.02.
إذا علقت على التهيئة
dr-amount، فيمكنك فرض هذا الخطأ:
move spaces to dr-datarec.
move "test" to dr-name.
* move 100 to dr-amount.
الآن عند بدء البرنامج:
./mistake
test 2,020,202.02
لتصحيح هذه المشكلة ، قدم COBOL 85 فعل INITIALIZE. بدلاً من نقل المسافات إلى سجل ، يمكنك تهيئته ، وسوف ينقل المسافات إلى الحقول الأبجدية الرقمية والأصفار إلى الحقول الرقمية:
* move spaces to dr-datarec.
initialize dt-detail.
move "test" to dr-name.
* move 100 to dr-amount.
نتيجة التنفيذ:
./mistake
test 0.00
لذا في المرة القادمة التي ترى فيها أرملة فقيرة حصلت على فاتورة خدمات بقيمة 2.020202.02 دولار ، ستعرف بالضبط ما حدث!