对于我的新项目,我必须使用数组而不是临时文件来存储来自用户的信息.为此,我还需要创建派生类型.
但是,我还没有理解数组是什么,派生类型是什么,如何使用它们,它们可以做什么,以及其他一些基本想法.任何人都可以给我一些关于数组和派生类型的信息吗?
我为他们编写了代码,但我不知道它是否写得正确.如果有人能为我检查这个,我将不胜感激.
这是我的数组和派生类型:
! derived type
TYPE Bank
INTEGER :: acNumber, acChecks
REAL :: acBlance, acRate
CHARACTER :: acType*1, acLName*15, acFName*15
END TYPE
! array
INTEGER, PARAMETER :: MaxRow, MaxColum = 7
INTEGER, DIMENSION(MaxRow:MaxColum) :: AccountData
Run Code Online (Sandbox Code Playgroud) 这个Fortran代码的含义是什么:
IF (J1-3) 20, 20, 21
21 J1 = J1 - 3
20 IF (J2-3) 22, 22, 23
23 J2 = J2 - 3
22 CONTINUE
Run Code Online (Sandbox Code Playgroud)
我在旧项目中看到过,我不知道带有数字(标签)的IF是什么意思.
我正在开发一个需要在FORTRAN中实现很少数值方法的项目.为此,我需要编写一些递归函数.这是我的代码.
!
! File: main.F95
!
RECURSIVE FUNCTION integrate(n) RESULT(rv)
IMPLICIT NONE
DOUBLE PRECISION :: rv
INTEGER, INTENT(IN) :: n
DOUBLE PRECISION, PARAMETER :: minusone = -1.0
IF (n == 1) THEN
rv = 10 !exp(minusone)
RETURN
ELSE
rv = 1 - (n * integrate(n - 1))
RETURN
END IF
END FUNCTION integrate
RECURSIVE FUNCTION factorial(n) RESULT(res)
INTEGER res, n
IF (n .EQ. 0) THEN
res = 1
ELSE
res = n * factorial(n - 1)
END IF
END
PROGRAM …Run Code Online (Sandbox Code Playgroud) Fortran有,stop并且error stop都过早地退出程序并且可以返回错误代码.
这两者之间有什么区别,什么时候应该使用?(另外,这里有实现/编译器问题吗?)
我从英特尔的文档中了解到stop终止程序,但error stop似乎做了一些.那个页面很有用,但并不能完全回答我的问题,因为1)它对我来说有点太技术了,2)我知道Fortran标准在实现中为"艺术表达"留下了空间,所以我不这样做相信该页面能够完美地反映标准.
我注意到这个问题与Fortran中"stop"和"exit"之间的区别有什么关系?- 事实上,我的问题是受到这个问题答案的启发.而这个问题问的区别stop和exit,我专门在看的基本事实的差异stop和error stop.回想起来,我的问题在这个问题上是一个有用的补充,但由于事实并非如此,这是一个单独的问题.
我想在Chapel中尝试类和多态,所以我试着让以下示例代码工作:
module SomeAnimals {
class Animal {
}
class Bird: Animal {
}
class Fish: Animal {
}
proc Bird.fly() {
writeln("Flying ...!");
}
proc Fish.swim() {
writeln("Swimming ...!");
}
} // module SomeAnimals
proc main() {
use SomeAnimals;
var anim: Animal;
anim = new Fish();
select (anim.type) {
when Fish do anim.swim();
}
delete anim;
anim = new Bird();
select (anim.type) {
when Bird do anim.fly();
}
delete anim;
} // proc main
Run Code Online (Sandbox Code Playgroud)
这个编译,但运行它,它只是退出而不产生任何打印输出.显然,由于某些原因,对select语句中包含的anim.swim()和anim.fly()方法的调用不会被执行.在不使用这些select语句来检查多态变量"anim"的实际类型的情况下,代码当然不会编译.
上面的例子实际上是一个使用Fortran的"选择类型"语句的Fortran 2008代码的相当直译.Chapel是否提供了类似的陈述,或者为了在Chapel工作,这个例子是否必须以完全不同的方式编码?我在Chapel文档中找不到任何相关内容.
我想知道 Fortran 中是否有类似构造函数的派生类型机制,这样,无论何时创建类型的实例,都会自动调用构造函数。我读这个问题,但对我来说并不满意。
完整性的示意图示例:
module mod
integer :: n=5
type array
real, dimension(:), allocatable :: val
contains
procedure :: array()
end type
subroutine array(this)
allocate(this%val(n))
end subroutine
end module
Run Code Online (Sandbox Code Playgroud)
现在,当我创建一个实例时,type(array) :: instance我想要构造函数array(instance)自动调用,而无需call array(instance)在手动添加的代码中添加任何额外内容。
我在这个站点上找到了一些有希望的信息,但在其他地方找不到:它指定了一个类似构造函数的机制,并声明了类型绑定过程initial,pass :: classname_ctor0。这是什么标准?ifort在版本 16 中不会编译发布在那里的示例,而且我没有可用的标准。
调试器可执行文件/usr/local/bin/gdb未签名。因此,在 macOS Catalina 10.15.6 中的 vscode 中调试可能无法正常工作。
我提供 launch.json 文件以供参考。
{
"version": "0.2.0",
"configurations": [
{
"name": "(lldb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceRoot}/build/ghermite.mod",
"miDebuggerPath": "/usr/local/bin/gdb",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceRoot}",
"externalConsole": false,
"preLaunchTask": "build"
}
]
}
Run Code Online (Sandbox Code Playgroud) 我在 Fortran 例程中有 3 个可分配的一维数组,VX(:)、VY(:)、VZ(:),它们都具有相同的大小。
我需要将它们聚合在一个名为 VARXYZ 的二维数组中,并将其发送到修改“矩阵”的例程。下面的代码可以工作,但会强制将内存大小加倍。
SUBROUTINE TEST(VX,VY,VZ)
REAL(8), INTENT(INOUT), DIMENSION(:) :: VX,VY,VZ ! They've been allocated with size N in the main
REAL(8), ALLOCATABLE, DIMENSION(:,:) :: VARXYZ ! The 'matrix'
ALLOCATE(VARXYZ(3,N))
VARXYZ(1,:)=VX(:)
VARXYZ(2,:)=VY(:)
VARXYZ(3,:)=VZ(:)
CALL CHANGE_MATRIX(VARXYZ)
VX(:)=VARXYZ(1,:)
VY(:)=VARXYZ(2,:)
VZ(:)=VARXYZ(3,:)
...
Run Code Online (Sandbox Code Playgroud)
为了避免“双重分配”,我的第一个错误反应是在一维数组和矩阵的 3 个“列”之间使用 EQUIVALENCE,但显然这是不允许的。
经过一番阅读后,我看到有人推荐使用指针和 TRANSFER 内部函数,但我不知道如何在这里使用它们。
您能否举例说明如何模仿我需要的这种等效机制?
我正在使用几种派生类型.出于调试目的,我想通过使用一个很好的方式在屏幕上打印它们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代码,即使我给出了一个未指定的标志,它也不会报告错误,这就是让我担心的问题.