我对以下程序有些困惑
module test
implicit none
type TestType
integer :: i
end type
contains
subroutine foo(test)
type (TestType), intent(out) :: test
test%i = 5
end subroutine
subroutine bar(test)
type (TestType), intent(out) :: test
test%i = 6
end subroutine
end module
program hello
use test
type(TestType) :: t
call foo(t)
print *, t%i
call bar(t)
print *, t%i
end program hello
Run Code Online (Sandbox Code Playgroud)
及其衍生物。稍后再谈。正如我们所知,Fortran语言传递程序参数作为一个传递引用,这意味着实体出现在伪参数test两者foo与bar被许可的堆栈上相同的内存空间program hello。到现在为止还挺好。
假设我在program hello中定义type(TestType) :: t为一个指针,并分配它。
program hello
use …Run Code Online (Sandbox Code Playgroud) 以下代码,结合模块程序和外部程序:
module module_dummy
implicit none
contains
subroutine foo(a)
real, intent(inout) :: a(:)
call bar(a)
end subroutine foo
end module module_dummy
program main
use module_dummy
implicit none
integer, parameter :: nelems = 100000000
real, allocatable :: a(:)
allocate( a(nelems) )
a = 0.0
call foo(a)
print *, a(1:10)
deallocate(a)
end program main
subroutine bar(a)
implicit none
real, intent(inout) :: a(:)
a = 1.0
end subroutine bar
Run Code Online (Sandbox Code Playgroud)
似乎失败了:
segmentation fault0.000而不是块1.000在我迄今为止尝试过的任何平台上。该问题与 的隐式接口声明 …
假设我有矩阵A并且B都有大小 nxn 。现在我想把A的每一列当作一个列矩阵ColA(i)[i=1,n],把B矩阵的每一行当作一个行矩阵RowB(j)[j=1,n]。
现在我可以使用matmul函数来构造一个新矩阵,称为C其元素是通过将所有可能的 i 和 j 值乘以 ColA 和 RowB 来找到的吗?就像是
do i = 1, n
do j= 1, n
C(i,j) = matmul( ColA(i), RowB(j) )
end do
end do
Run Code Online (Sandbox Code Playgroud) 如果参数列表的长度不同,Fortran 95 标准是否允许两个子例程(或函数)具有相同的名称?例如,
subroutine a(i)
! code here
end subroutine a
subroutine a(j,k)
! code here
end subroutine a
Run Code Online (Sandbox Code Playgroud) 我想知道什么应该是使用指针变量作为循环计数的fortran程序的行为?比如使用gfortran,这个程序:
program foo
integer, pointer :: x
integer, target :: y
x => y
do x=0,10
y = 100
print*, "hello"
enddo
end program
Run Code Online (Sandbox Code Playgroud)
执行时变成无限循环.这应该发生吗?
我不想在我的程序中使用公共块.我的主程序调用一个调用函数的子程序.该函数需要子程序中的变量.
有什么方法可以将子程序中的信息集传递给函数?
program
...
call CONDAT(i,j)
end program
SUBROUTINE CONDAT(i,j)
common /contact/ iab11,iab22,xx2,yy2,zz2
common /ellip/ b1,c1,f1,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2
call function f(x)
RETURN
END
function f(x)
common /contact/ iab11,iab22,xx2,yy2,zz2
common /ellip/ b1,c1,f1,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2
end
Run Code Online (Sandbox Code Playgroud) 一个显而易见的方法是:
integer function log2_i(val) result(res)
implicit none
integer, intent(IN) :: val
if (val<0) then
print *, "ERROR in log2_i(): val cannot be negative."
else if (val==0) then
print *, "ERROR in log2_i(): todo: return the integer equivalent of (-inf)..."
else if (val==1) then
res = 0
else
res = FLOOR( LOG(val+0.0d0)/LOG(2.0d0) )
endif
end function log2_i
Run Code Online (Sandbox Code Playgroud)
使用Fortran的位移操作符有更好的方法吗?
这个问题几乎相同,但使用无符号整数.不幸的是,符号位将禁止使用相同的算法.
现在我正在处理在我之前从事该项目的人的 Fortran 代码。代码比较大,这里就不提供了。在这个代码的很多地方都有双精度值除以整数。IE:
double precision :: a,c
integer :: b
a = 1.0d0
b = 3
c = a/b
Run Code Online (Sandbox Code Playgroud)
这有时会导致比常规浮点数错误更严重的错误。我会为您复制粘贴其中一个这样的错误:3.00000032899483。对于他的目的来说,这是可以的,但对我来说,这个错误是可怕的。似乎fortran正在将实数除以整数,然后将数字放大到双精度,添加一些随机的东西。如果我会写,当然可以处理:
c = a/(real(b,8))
Run Code Online (Sandbox Code Playgroud)
所以,我可以做到,但是搜索他的所有代码需要很长时间。这就是为什么,我尝试以下一种方式重载 (/) 运算符:
MODULE divisionoverload
!-----------------------------------------------------
INTERFACE OPERATOR (/)
MODULE PROCEDURE real_divoverinteger
END INTERFACE OPERATOR ( / )
CONTAINS
!-----------------------------------------------------
DOUBLE PRECISION FUNCTION real_divoverinteger(a,b)
IMPLICIT NONE
DOUBLE PRECISION, INTENT (IN) :: a
INTEGER, INTENT(IN) :: b
real_divoverinteger = a/real(b,8)
END FUNCTION real_divoverinteger
END MODULE divisionoverload
Run Code Online (Sandbox Code Playgroud)
但是 gfortran4.8 给我的错误清楚地表明这与内在除法运算符冲突:
MODULE PROCEDURE real_divoverinteger
1
Error: Operator interface at (1) …Run Code Online (Sandbox Code Playgroud) 我想翻转我的矩阵。使得 T(1,1)=C(2,1)
我已经制作了这个程序,我发现了一个应该在线完成的代码,C=T(2:1:-1, :)但是当尝试获得应该是 3 的值 C(1,1) 时,我得到 1.3533635457363350E-306。你如何翻转矩阵使得向上变成向下?
program main
implicit none
integer iMax, jMax
double precision, dimension(:,:), allocatable :: T,C
double precision x, dx,f,L2old,L2norm
integer i, j,n
allocate(T(0:2, 0:2))
allocate(C(0:2, 0:2))
T(1,1)=1
T(1,2)=2
T(2,1)=3
T(2,2)=4
write(*,*) T(2,2)
C=T(2:1:-1, :)
Write(*,*) C(1,2)
end program main
Run Code Online (Sandbox Code Playgroud) 假设我有一个数组:
real, dimension(100000, 5) :: a
Run Code Online (Sandbox Code Playgroud)
该数组将由实数填充,a(0, :)直到a(n, :)wheren是小于 的数字100000。填充完所有值后,我们可以决定的值n(让我们假设它30000)。我想将数组重塑为:
real, dimension(30000, 5) :: a
Run Code Online (Sandbox Code Playgroud)
只是为了删除数组中未使用的元素。我不希望执行任何数组复制过程,因为数组很大,因此它会破坏程序效率。这里有解决办法吗?