Я написал это приложение на COBOL для выполнения простой факторизации, оно еще не завершено.
Когда я запускаю код, я получаю эту ошибку/вывод:
Programm zur Darstellung der Primfaktorzerlegung mit einer gegebenen Zahl
attempt to reference invalid memory address (signal)
Last statement of "primfaktorzerlegung" unknown
Last statement of "primzahl_check" unknown
Last statement of "main_methode" unknown
Started by ./jdoodle
Command terminated by signal 11
В качестве IDE я использую JDoodle и GNUCobol 3.2.0.
Код, который я написал, выполняет базовое деление с остатком, чтобы проверить, существует ли простое число. Если это простое число, на выходе будет простое число, если это не простое число, которое проверяется в подпрограмме, код выполнит простую факторизацию.
identification division.
program-id. main_methode.
data division.
working-storage section.
01 divident pic 9(5).
01 rest pic 9v9.
01 divisor pic 9(5).
01 ergebnis pic 9(5).
*> Kurze Erklärung:
*> Primfaktorzerlegung der Zahl 20.
*> 20 / 2 = 10
*> 10 / 2 = 5
*> 5 / 2 = 2.5
*> Also lautet die Primfaktorzerlegung: von 20 = 2 *> 2 *> 5
*> Bis zu der Zahl wo die Division einen Rest ergibt.
*> Eine Liste für alle Zahlen von 2 bis 100 mit den dazugehörigen Zerlegungen ausgeben
procedure division.
display 'Programm zur Darstellung der Primfaktorzerlegung mit einer gegebenen Zahl'.
display ' '.
call 'primzahl_check' using divident rest divisor ergebnis.
end program main_methode.
identification division.
program-id. primzahl_check.
data division.
linkage section.
01 divident pic 9(5).
01 rest pic 9v9.
01 divisor pic 9(5).
01 ergebnis pic 9(5).
01 zerlegt pic x(5).
01 priv_divident pic 9(5).
01 zahlenarray.
05 zahlen occurs 4 times indexed by z_idx.
10 z_zahl pic s9(5).
01 i pic 9(5).
01 quotient pic 9(5).
*> Überprüfen ob es bei der Zahl um eine Primzahl handelt
procedure division using divident rest divisor ergebnis.
perform until divident = 3
move 2 to divisor
move 1 to rest
perform until rest = 0 or divisor >= divident
divide divident by divisor giving ergebnis remainder rest
add 1 to divisor
end-perform
if divident = divisor then
display ' '
display divisor " ist eine Primzahl"
display ' '
else
call 'primfaktorzerlegung' using divisor zerlegt divident priv_divident zahlenarray i quotient
add 1 to divident
end-perform.
end program primzahl_check.
identification division.
program-id. primfaktorzerlegung.
data division.
linkage section.
01 divisor pic 9(5).
01 zerlegt pic x(5).
01 divident pic 9(5).
01 priv_divident pic 9(5).
01 zahlenarray.
05 zahlen occurs 4 times indexed by z_idx.
10 z_zahl pic s9(5).
01 i pic 9(5).
01 quotient pic 9(5).
01 rest pic 9v9.
procedure division using divisor zerlegt divident priv_divident zahlenarray i quotient.
*> Primfaktorzerlegung
move 2 to divisor.
move 'false' to zerlegt.
*> Ursprünglicher Divident speichern, in diesem Fall die 20
move divident to priv_divident
move 1 to z_idx
move 2 to i
move priv_divident to z_zahl(z_idx)
move 2 to divident.
perform until zerlegt = 'true'
divide divident by divisor giving quotient remainder rest
move quotient to divident
if rest = 0 then
move i to z_idx
move divisor to z_zahl(z_idx)
add 1 to i
else
move i to z_idx
move quotient to z_zahl(z_idx)
move 'true' to zerlegt
*> call 'zahlen_ausgeben' using z_zahl
end-perform.
end program primfaktorzerlegung.
Любая помощь будет оценена по достоинству.
Ищем документацию, меняем код, чтобы он работал.
Это из предыдущих вопросов, остальные ошибки были исправлены, но я столкнулся с этой и не знаю, как ее решить.
При использовании jdoodle вы, вероятно, захотите перейти к настройкам компилятора (возможно, перенесенным в настройки IDE) и настроить командную строку компиляции, включив --debug, чтобы включить проверки во время выполнения (получить приятную ошибку и стек вместо текущей программы SIGSEGV + onyl) и можно добавить -Wall top, чтобы получить полезные ошибки компиляции (и -Wextra если у вас есть странные результаты, которые вы не можете объяснить - это также покажет возможную END-IF проблему).





Переменные, определенные в разделе «Связывание», не выделяются автоматически, как переменные в разделах «Рабочее хранилище» и «Локальное хранилище». Либо вы должны явно выделить их с помощью оператора ALLOCATE, либо вы должны ссылаться на них в операторе CALL, который вызывает вашу программу.
Когда вы ВЫЗЫВАЕТЕ программу primfaktorzerlegung, вы не передаете переменную rest. Вы передаете переменные zahlenarray, i и quotient, но они сначала определяются в разделе связывания primzahl_check и не передаются при вызове из main_methode, поэтому с ними автоматически не связано хранилище.
Я предлагаю определить переменные zahlenarray, i и quotient в разделе «Рабочее хранилище» или «Локальное хранилище» программы primzahl_check и добавить rest к вызывающим параметрам при ВЫЗОВЕ программы primfaktorzerlegung.
У вас также есть операторы IF как в primzahl_check, так и в primfaktorzerlegung, у которых нет END-IF. Я не уверен, что GNU COBOL справится с этим, предполагая, что IF завершается точкой в конце END-PERFORM, или это другая проблема, но я решил указать на это.
cschneid ответ правильный.
Однако! Я знаю, что это не интуитивно понятно, но опытные программисты на COBOL избегают вызовов подпрограмм, если для этого нет действительно веской причины. Абсолютно нет проверки или проверки времени компиляции того, что передается через «использование» в раздел связывания.
В вашем случае вы можете просто «PERFORM SECTION», что имеет тот же эффект, что и вызов подпрограммы, за исключением того, что вы разделяете рабочее хранилище и нет необходимости постоянно передавать и дважды определять переменные.
Вы продолжаете публиковать две программы. О каком из них ваш вопрос?