COBOL递归帕斯卡三角项计算器结果异常问题求助
问题分析与解决方案
你的递归帕斯卡三角计算器返回错误结果,核心原因是参数传递方式的问题,而非COBOL递归机制本身的缺陷。
问题根源
你在PASCAL子程序中使用了BY VALUE传递参数,但部分COBOL编译器(尤其是旧版本)可能不支持该特性,会默认按BY REFERENCE传递参数。这会导致递归调用中修改X的值时,直接影响上层调用的X变量:
- 当计算
C(4,2)时,第一次递归调用PASCAL(3,2),如果是按引用传递,该实例中修改X为2会直接改变上层的X值; - 后续计算第二个项时,
X已经变成2而非预期的3,导致调用PASCAL(2,1)返回2而非3,最终总和为3+2=5。
此外,使用RETURN-CODE返回计算结果并非COBOL的最佳实践(它主要用于状态码返回),主程序与子程序的参数类型不匹配(十进制vs二进制)也可能引发潜在的转换问题。
修复方案
1. 使用局部变量隔离递归参数
在递归子程序中声明局部变量,将传入的参数值复制到局部变量中操作,避免引用传递导致的参数污染:
IDENTIFICATION DIVISION. PROGRAM-ID. PASCAL RECURSIVE. DATA DIVISION. FILE SECTION. WORKING-STORAGE SECTION. 01 LOCAL-X USAGE IS BINARY-LONG. 01 LOCAL-Y USAGE IS BINARY-LONG. 01 ADDENDO1 USAGE IS BINARY-LONG. 01 ADDENDO2 USAGE IS BINARY-LONG. LINKAGE SECTION. 01 PARAM-X USAGE IS BINARY-LONG. 01 PARAM-Y USAGE IS BINARY-LONG. PROCEDURE DIVISION USING PARAM-X PARAM-Y. MOVE PARAM-X TO LOCAL-X. MOVE PARAM-Y TO LOCAL-Y. IF LOCAL-X < 0 OR LOCAL-Y < 0 OR LOCAL-Y > LOCAL-X THEN MOVE 0 TO RETURN-CODE GOBACK END-IF. IF LOCAL-Y = LOCAL-X OR LOCAL-Y = 0 THEN MOVE 1 TO RETURN-CODE GOBACK END-IF. COMPUTE LOCAL-X = LOCAL-X - 1. CALL "PASCAL" USING LOCAL-X LOCAL-Y RETURNING ADDENDO1. COMPUTE LOCAL-Y = LOCAL-Y - 1. CALL "PASCAL" USING LOCAL-X LOCAL-Y RETURNING ADDENDO2. COMPUTE RETURN-CODE = ADDENDO1 + ADDENDO2. GOBACK. END PROGRAM PASCAL.
2. 统一参数类型
主程序中使用与子程序一致的二进制类型,避免类型转换错误:
IDENTIFICATION DIVISION. PROGRAM-ID. pascaltrianglepost. DATA DIVISION. WORKING-STORAGE SECTION. 01 N USAGE IS BINARY-LONG. 01 K USAGE IS BINARY-LONG. 01 CASELLA USAGE IS BINARY-LONG. PROCEDURE DIVISION. MAIN-PROGRAM. ACCEPT N. ACCEPT K. CALL "PASCAL" USING N K RETURNING CASELLA. DISPLAY CASELLA. STOP RUN. END PROGRAM pascaltrianglepost.
3. 可选:替换RETURN-CODE为显式返回变量(推荐)
如果你想避免使用RETURN-CODE,可以在子程序的LINKAGE SECTION中添加一个返回变量:
LINKAGE SECTION. 01 PARAM-X USAGE IS BINARY-LONG. 01 PARAM-Y USAGE IS BINARY-LONG. 01 RESULT USAGE IS BINARY-LONG. PROCEDURE DIVISION USING PARAM-X PARAM-Y RESULT. ... COMPUTE RESULT = ADDENDO1 + ADDENDO2. GOBACK.
主程序调用时改为:
CALL "PASCAL" USING N K CASELLA.
验证
修改后输入N=4、K=2,程序会正确返回6,符合预期。
内容的提问来源于stack exchange,提问作者Francesco Raso Stoia
相关产品推荐
相关产品推荐

