首页 > 解决方案 > GnuCOBOL:尝试创建递归用户定义函数

问题描述

我正在尝试使用 GnuCOBOL 2.0.0 创建一个递归用户定义函数,但是当我尝试运行调用程序时,它会因“分段失败”错误而崩溃。

这是功能:

identification division.
function-id.   FATORIAL.
author.        Paulo Andre Dias.
date-written.  15/02/2017.
remarks.       Calcula o fatorial do numero N informado via argumento.     

environment division.
configuration section.

data division.
working-storage section.
77 ws-fatorial-n-menos-1    pic 9(006) value zeros.

linkage section.
01 lk-n                     pic 9(006).
01 lk-fatorial              pic 9(006). 

procedure division using lk-n returning lk-fatorial.
principal.

    if lk-n = zeros
        move 1 to lk-fatorial
    else
        move FATORIAL(lk-n - 1) to ws-fatorial-n-menos-1
        compute lk-fatorial = lk-n * ws-fatorial-n-menos-1
    end-if

    goback.

end function FATORIAL.

这是调用程序:

identification division.
program-id. gtc002.

environment division.
configuration section.
repository.
    function FATORIAL.

data division.
working-storage section.
77 ws-n pic 9(006) value zeros.

procedure division.
main.
    display "Entre com um numero inteiro positivo (ou zero para encerrar):"
    accept ws-n from console
    if ws-n = zeros
        stop run
    else
        display "O fatorial de " ws-n " e' " FATORIAL(ws-n)
    end-if
    go to main.

这就是发生的事情:

[aeisxpad ~/cbl]$ ../bin/gtc002
Entre com um numero inteiro positivo (ou zero para encerrar)::
5
Falha de segmentação
[aeisxpad ~/cbl]$ 

我错过了什么吗?有任何想法吗?

谢谢大家。

标签: recursionuser-defined-functionscobolgnucobol

解决方案


用户定义函数和 GnuCOBOL 错误的解决方法。

用户定义的 FUNCTION 调用在 BINARY 和 DISPLAY 使用方面未正确编组。值作为使用 DISPLAY 与 pic 9 一起传递。尝试更改ws-n为 USAGE BINARY。这将在调用中强制使用本机数字(然后需要lk-n在 FATORIAL 本身的链接部分匹配。

   identification division.
   program-id. gtc002.

   environment division.
   configuration section.
   repository.
       function FATORIAL.

   data division.
   working-storage section.
  *> 77 ws-n pic 9(006) value zeros.
   77 ws-n usage binary-long.

   procedure division.
   main.
       display "Entre com um numero inteiro positivo" &
               " (ou zero para encerrar):"
       accept ws-n from console
       if ws-n = zeros
           stop run
       else
           display "O fatorial de " ws-n " e' " FATORIAL(ws-n)
       end-if
       go to main.

   identification division.
   function-id.   FATORIAL.
   author.        Paulo Andre Dias.
   date-written.  15/02/2017.
   remarks. Calcula o fatorial do numero N informado via argumento.     
   
   environment division.
   configuration section.

   data division.
   working-storage section.
   77 ws-fatorial-n-menos-1    pic 9(006) value zeros.

   linkage section.
  *> 01 lk-n                     pic 9(006).
   01 lk-n                     usage binary-long.
   01 lk-fatorial              pic 9(006).

   procedure division using lk-n returning lk-fatorial.
   principal.

       if lk-n = zeros
           move 1 to lk-fatorial
       else
           move FATORIAL(lk-n - 1) to ws-fatorial-n-menos-1
           compute lk-fatorial = lk-n * ws-fatorial-n-menos-1
       end-if

       goback.

   end function FATORIAL.

在这里奉献,

prompt$ cobc -g -xj gtc002.cob FACTORIAL.cob
Entre com um numero inteiro positivo (ou zero para encerrar):
3
O fatorial de +0000000003 e' 000006
Entre com um numero inteiro positivo (ou zero para encerrar):
5
O fatorial de +0000000005 e' 000120
Entre com um numero inteiro positivo (ou zero para encerrar):
7
O fatorial de +0000000007 e' 005040
Entre com um numero inteiro positivo (ou zero para encerrar):
0

抱歉稍微重新格式化,上面的版本应该像 COBOL 编译的 FIXED 或 FREE 格式一样工作

原始文件将 ASCII“00005”传递给函数,尝试在不正确地编组为 USAGE BINARY 时进行大量递归(这是 GnuCOBOL 中的一个错误)。正如@Simon Sobisch 所指出的,这将在某一天得到解决,但目前一个合理的解决方法是使用数字的实际 USAGE BINARY 参数而不是 PIC 9 COBOL 字段来编码用户定义的函数。

该解决方法将适用于递归或非递归函数。

在源代码中使用文字,FUNCTION NUMVAL(123)用于 123。在 GnuCOBOL cobc 中,源文本文字默认为“123”PIC 9(使用显示)形式,并且在当前版本中调用用户定义函数时需要强制使用 USAGE BINARY 数字。


推荐阅读