小编fra*_*lus的帖子

在Fortran 90中,是否必须事先声明数组维度?

是否有必要在任何其他代码之前声明数组维度?例如,我编写了以下简化示例代码:

PROGRAM mytest
  IMPLICIT NONE
  INTEGER :: i, j, k, mysum

  ! Let array c be a k-by-k**2 array
  ! Determine k within the program by some means...for example,
  mysum=0
  DO i=1, 3
    mysum=mysum+1
  END DO
  k=mysum

  REAL, DIMENSION(k, k**2) :: c

  WRITE(*,*) "k=", k
  WRITE(*,*) "k**2=", k**2
  WRITE(*,*)
  DO i=1,size(c,1)
    WRITE(*,"(100(3X,F3.1))") (c(i,j), j=1,size(c,2))
  END DO
END PROGRAM mytest
Run Code Online (Sandbox Code Playgroud)

我试图做的一点是,我想创建一个数组ck-by- k**2大小,并且k仅由代码中的其他计算确定; k一开始就不知道.

但是,上面的代码在编译时给出了以下错误消息:

mytest.f90:13.31:

  REAL, DIMENSION(k, k**2) :: c
                               1
Error: Unexpected …
Run Code Online (Sandbox Code Playgroud)

arrays fortran dimensions

5
推荐指数
1
解决办法
5828
查看次数

打开时默认状态为“未知”

我经常看到人们使用该OPEN语句而不明确指定STATUS. 在 Fortran 90 和 2008 标准中,这样说STATUS

如果指定 UNKNOWN,则状态取决于处理器。如果省略此说明符,则默认值为 UNKNOWN。

我将此解释为,如果STATUS省略,任何事情都可能发生,具体取决于您使用的机器。

然而,从进行一些测试来看,默认行为(当STATUS省略时)似乎是REPLACE. 但我找不到 gfortran 编译器手册(来自https://gcc.gnu.org/onlinedocs/)中记录的这种行为。

问题:这REPLACE确实是 gfortran 和 ifort 等流行编译器的默认行为吗?如果是这样,这实际上有记录吗(但我只是碰巧没有找到它)?

fortran gfortran intel-fortran

5
推荐指数
1
解决办法
2903
查看次数

如何使用可分配组件设置名为常量的派生类型的值?

这可以正确编译:

type t1
    integer :: a, b(2), c
end type t1
type(t1), parameter :: t1a = t1(1, [2, 3], 4)
Run Code Online (Sandbox Code Playgroud)

我想写这样的东西,除了它不能编译:

type t2
    integer :: a
    integer, allocatable :: b(:)
    integer :: c
end type t2
type(t2), parameter :: t2a = t2(1, [2, 3], 4) ! compile error
type(t2), parameter :: t2b = t2(1, [2, 3, 4], 5) ! compile error
Run Code Online (Sandbox Code Playgroud)

gfortran 错误消息

Error: Invalid initialization expression for ALLOCATABLE component 'b' in structure constructor
Run Code Online (Sandbox Code Playgroud)

没有给我任何关于正确语法的线索。

我没有收到任何关于尝试声明具有可分配类型的参数变量的抱怨,所以我认为必须有某种方法来初始化它!

fortran gfortran fortran2003

5
推荐指数
1
解决办法
2381
查看次数

编写很长的字符串时,Fortran 中的自动换行符

我在 fortran 中有一个字符串,我在循环中扩展:

character(:), allocatable :: string
...
do i = 1, n
  string = string // "some stuff depending on i"
end do
Run Code Online (Sandbox Code Playgroud)

只要字符串小于 80 个字符,就可以正常工作。当达到 80 个字符时,字符串中会包含一个换行符。

有谁知道为什么会发生这种情况以及是否有机会避免这种情况?

我有以下完整示例:

program string

  implicit none

  character(:), allocatable :: long_string
  character(:), allocatable :: line

  integer      :: i
  character(8) :: idx

  line = " This is line number: "

  long_string = "First line" // NEW_LINE('A')

  do i = 1, 3
    write(idx, "(I8)") i
    long_string = long_string // line // adjustl(trim(idx)) // NEW_LINE('A') …
Run Code Online (Sandbox Code Playgroud)

fortran

5
推荐指数
2
解决办法
3507
查看次数

`generic :: write(formatted)`groutran中的子程序被其他派生类型调用

我正在使用几种派生类型.出于调试目的,我想通过使用一个很好的方式在屏幕上打印它们generic :: write(formatted).

这是一个显示我的意思的示例程序:

program main
  use :: test_mod
  implicit none

  type(test1) :: t1
  type(test2) :: t2

  t1 = test1(name="t1")
  t2 = test2(name="t2", t1)
  print *, 'Test1:', t1
  print *, 'Test2:', t2
end program
Run Code Online (Sandbox Code Playgroud)

这是模块:

module test_mod
  implicit none
  private
  public :: test1, test2

  type :: test1
    character(2) :: name
  contains
    procedure, private :: test1_writef
    generic :: write(formatted) => test1_writef
  end type test1

  type :: test2
    character(2) :: name
    type(test1) :: t1
  contains
    procedure, private :: test2_writef
    generic …
Run Code Online (Sandbox Code Playgroud)

generics fortran gfortran

5
推荐指数
1
解决办法
145
查看次数

Fortran精确默认带/ out编译器标志

我在Fortran的常数数字精度方面遇到了麻烦.

我是否需要将每一个都0.1写成0.1d0双精度?我知道编译器有一个标志,例如-fdefault-real-8在gfortran中解决了这种问题.它是一种便携可靠的方式吗?我怎么能检查标志选项是否真的适用于我的代码?

我使用F2py在我的Python代码中调用Fortran代码,即使我给出了一个未指定的标志,它也不会报告错误,这就是让我担心的问题.

fortran

5
推荐指数
2
解决办法
498
查看次数

接口C函数与Fortran中的结构

我想将C函数与Fortran中的相应结构相链接

struct ovf_file {
    bool found;
    bool is_ovf;
    int n_segments;
    struct ovf_file_handle *_file_handle;
};
DLLEXPORT struct ovf_file * ovf_open(const char *filename);
Run Code Online (Sandbox Code Playgroud)

这是我尝试这样做的:

module ovf
    use, intrinsic :: iso_c_binding
    implicit none

    type, bind(c) :: ovf_file
      logical(c_bool)   :: found
      logical(c_bool)   :: is_ovf
      integer(c_int)    :: n_segments
      type(c_ptr)       :: file_handle
    end type ovf_file
end module ovf

program main
    use ovf
    use, intrinsic :: iso_c_binding
    implicit none
    type(ovf_file)               :: file_handle

    interface
      function ovf_open(filename) bind ( C, name = "ovf_open" ) result(handle)
        character(len=1, kind=c_char), intent(in) :: …
Run Code Online (Sandbox Code Playgroud)

c fortran fortran-iso-c-binding

5
推荐指数
1
解决办法
234
查看次数

在声明类型中分配参数声明类型时,ifort发生严重错误

请考虑以下代码

  module t_test
     implicit none

     type ttt(tsize)
        integer, len :: tsize
        real x(tsize)
     end type ttt



  type :: t_rndom_diameter(t_rsize,t_csize)
      integer, len :: t_rsize,t_csize
      real :: x(t_rsize,t_csize)
     type(ttt(tsize=:)), allocatable :: test_type
  end type t_rndom_diameter




  end module t_test


  program p_test
  USE t_test
  implicit none

  type(t_rndom_diameter(t_rsize=3,t_csize=3)) :: gdad

  allocate(gdad% ttt(tsize=10) ::  gdad % test_type)


  end program
Run Code Online (Sandbox Code Playgroud)

它给了我一个灾难性的错误,而没有提到错误是什么:

catastrophic error: **Internal compiler error: segmentation violation signal raised** Please
report this error along with the circumstances in which it occurred in a Software Problem
Report. …
Run Code Online (Sandbox Code Playgroud)

fortran intel-fortran

5
推荐指数
0
解决办法
98
查看次数

保留内在分配中的分配界限

我使用分配时的自动分配来计算两个数组的差异,边界从 0 开始:

program main
   implicit none
   integer, allocatable :: a(:), b(:), c(:)

   allocate(a(0:10))
   allocate(b(0:10))

   a = 1
   b = 2

   write (*,*) lbound(a)
   write (*,*) lbound(b)

   c = b - a

   write (*,*) lbound(c)
end program main
Run Code Online (Sandbox Code Playgroud)

gfortran 和 ifort 都给出输出:

       0
       0
       1
Run Code Online (Sandbox Code Playgroud)

为什么 c 与 a 和 b 的界限不同?是否有一种简短(没有显式分配)的方法来确保 c 具有相同的界限?

arrays fortran

5
推荐指数
1
解决办法
169
查看次数

警告明确形状的数组重塑

让所有例程都在模块内部。

  1. 如果我将数组real*8 aa(5,3)传递给例程

    subroutine sub(bb)
    real*8, intent(in) :: bb(2,5)
    ...
    end subroutine
    
    Run Code Online (Sandbox Code Playgroud)

    用下面的语句call sub(aa),这将编译没有警告,前2 aa将填补bb阵列。数组aa和元素的bb排列方式非常不同。

  2. 如果相反,例程被编写

    subroutine sub(bb)
    real*8, intent(in) :: bb(:,:)
    ...
    end subroutine
    
    Run Code Online (Sandbox Code Playgroud)

    然后bb将具有与相同的形状和存储顺序aa

问:如果忘记了例程中存在显式大小的声明,则第一种行为是非常危险的。当显形数组更改形状/对齐方式时,我可以使编译器发出警告吗?

arrays fortran gfortran

5
推荐指数
0
解决办法
65
查看次数