Fortran CHARACTER(LEN =*)仅适用于伪参数或PARAMETER

Lel*_*uch 4 recursion fortran character

我想打印以下输出

*****
****
***
**
*
Run Code Online (Sandbox Code Playgroud)

使用递归子程序.我的代码如下:

PROGRAM PS
IMPLICIT NONE

CALL print_star(5, '*')

CONTAINS
    RECURSIVE SUBROUTINE print_star(n, star)
    INTEGER :: n
    CHARACTER(LEN = *) :: star
    CHARACTER(LEN = *) :: new_star
    IF (n > 1) THEN
        new_star = star // '*'
        CALL print_star(n - 1, new_star)
    END IF
    print *, star
    END SUBROUTINE print_star
END PROGRAM PS
Run Code Online (Sandbox Code Playgroud)

然后它返回错误:

 CHARACTER(LEN = *) :: new_star
                           1
Error: Entity with assumed character length at (1) must be a dummy argument or a PARAMETER
Run Code Online (Sandbox Code Playgroud)

如果我只是避免定义new_star,只是CALL

 CALL print_star(n - 1, star // '*')
Run Code Online (Sandbox Code Playgroud)

然后该程序按预期工作.我想知道错误是什么以及如何解决它?

Ian*_*anH 14

CHARACTER(*)声明一个假定长度的字符对象.这意味着对象从其他东西获取其长度("假定它").

  • 对于伪参数的CHARACTER(*)声明,从实际参数的长度假定长度.

  • 在CHARACTER(*)常量(PARAMETER)的情况下,从给定常量的值假定长度.

从语言概念的角度来看,你的变量new_star在声明它的位置上没有任何东西可以假设它的长度.导致您看到的错误消息的语言规则反映了这一点.

但是你知道new_star程序中稍后需要给出逻辑的长度- 它需要比star伪参数的长度多一个.所以你可以恰当地声明它:

CHARACTER(LEN(star) + 1) :: new_star
Run Code Online (Sandbox Code Playgroud)

作为替代方案,Fortran 2003引入了延迟长度字符对象.这些是可分配对象或指针对象,其中长度在分配或关联对象时指定.它们使用长度说明符声明:.