是否有必要在任何其他代码之前声明数组维度?例如,我编写了以下简化示例代码:
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)
我试图做的一点是,我想创建一个数组c是k-by- k**2大小,并且k仅由代码中的其他计算确定; k一开始就不知道.
但是,上面的代码在编译时给出了以下错误消息:
mytest.f90:13.31:
REAL, DIMENSION(k, k**2) :: c
1
Error: Unexpected …Run Code Online (Sandbox Code Playgroud) 我经常看到人们使用该OPEN语句而不明确指定STATUS. 在 Fortran 90 和 2008 标准中,这样说STATUS:
如果指定 UNKNOWN,则状态取决于处理器。如果省略此说明符,则默认值为 UNKNOWN。
我将此解释为,如果STATUS省略,任何事情都可能发生,具体取决于您使用的机器。
然而,从进行一些测试来看,默认行为(当STATUS省略时)似乎是REPLACE. 但我找不到 gfortran 编译器手册(来自https://gcc.gnu.org/onlinedocs/)中记录的这种行为。
问题:这REPLACE确实是 gfortran 和 ifort 等流行编译器的默认行为吗?如果是这样,这实际上有记录吗(但我只是碰巧没有找到它)?
这可以正确编译:
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 中有一个字符串,我在循环中扩展:
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) 我正在使用几种派生类型.出于调试目的,我想通过使用一个很好的方式在屏幕上打印它们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) 我在Fortran的常数数字精度方面遇到了麻烦.
我是否需要将每一个都0.1写成0.1d0双精度?我知道编译器有一个标志,例如-fdefault-real-8在gfortran中解决了这种问题.它是一种便携可靠的方式吗?我怎么能检查标志选项是否真的适用于我的代码?
我使用F2py在我的Python代码中调用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) 请考虑以下代码
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) 我使用分配时的自动分配来计算两个数组的差异,边界从 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 具有相同的界限?
让所有例程都在模块内部。
如果我将数组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排列方式非常不同。
如果相反,例程被编写
subroutine sub(bb)
real*8, intent(in) :: bb(:,:)
...
end subroutine
Run Code Online (Sandbox Code Playgroud)
然后bb将具有与相同的形状和存储顺序aa。
问:如果忘记了例程中存在显式大小的声明,则第一种行为是非常危险的。当显形数组更改形状/对齐方式时,我可以使编译器发出警告吗?