以下代码返回分段错误,因为我尝试传递的可分配数组未被正确识别(大小返回1,应该是3).在这个页面(http://www.eng-tips.com/viewthread.cfm?qid=170599)中,一个类似的例子似乎表明它应该在F95中正常工作; 我的代码文件有.F90扩展名,但我尝试将其更改为F95,我正在使用gfortran进行编译.
我的猜测是问题应该是我将可分配数组传递给子程序的方式; 我究竟做错了什么?
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
PROGRAM test
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
IMPLICIT NONE
DOUBLE PRECISION,ALLOCATABLE :: Array(:,:)
INTEGER :: iii,jjj
ALLOCATE(Array(3,3))
DO iii=1,3
DO jjj=1,3
Array(iii,jjj)=iii+jjj
PRINT*,Array(iii,jjj)
ENDDO
ENDDO
CALL Subtest(Array)
END PROGRAM
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
SUBROUTINE Subtest(Array)
DOUBLE PRECISION,ALLOCATABLE,INTENT(IN) :: Array(:,:)
INTEGER :: iii,jjj
PRINT*,SIZE(Array,1),SIZE(Array,2)
DO iii=1,SIZE(Array,1)
DO jjj=1,SIZE(Array,2)
PRINT*,Array(iii,jjj)
ENDDO
ENDDO
END SUBROUTINE
!%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%!
Run Code Online (Sandbox Code Playgroud) 使用带use声明的模块或带声明的隔离文件有什么实际区别include?我的意思是,如果我有一个使用了很多在整个程序中的子程序:当或为什么我应该把它放在一个模块内部或者只是把它写在一个单独的文件,包括它在它需要程序的所有其他部分用过的?
另外,将所有子程序写入单独文件中的模块并include在模块内使用是不是一个好习惯?特别是如果在子程序的代码很长,这样才能保持代码组织得更好(这样子程序都装在国防部,但如果我有编辑一个我并不需要去虽然代码迷宫).
考虑
INTEGER,DIMENSION(3) :: NumberVector
Run Code Online (Sandbox Code Playgroud)
和
INTEGER :: NumberVector(3)
Run Code Online (Sandbox Code Playgroud)
这两个声明之间是否有任何差异,或者它们是否完全相同?(我的意思是在任何可能的上下文和变体中:例如,在这两个是相同的情况下,如果我声明一个隐式大小的数组作为子程序的输入参数之一怎么办?它仍然是无关紧要的我用了?)
我的部分makefile有以下代码:
target.o:
cd dir; $(MAKE)
Run Code Online (Sandbox Code Playgroud)
该文件target.o有目录内自己的makefile文件dir.在编译期间,我得到以下输出行:
make[1]: Entering directory `dir'
ifort -c target.f -o target.o
make[1]: Leaving directory `dir'
Run Code Online (Sandbox Code Playgroud)
我想沉默第一和第三输出线,但保持第二.在主makefile中将-s添加到make中会消除第一个和第三个,也会删除我要保留的那个.
(1)有办法做到这一点吗?
(2)为什么这样做可能不是一个好主意?
我对alloc_array和automatic_array以下摘录之间的区别感兴趣:
subroutine mysub(n)
integer, intent(in) :: n
integer :: automatic_array(n)
integer, allocatable :: alloc_array(:)
allocate(alloc_array(n))
...[code]...
Run Code Online (Sandbox Code Playgroud)
我对分配的基础知识非常熟悉(对高级技术的了解不多),知道分配使您可以在代码中间更改数组的大小(如本问题所指出),但是我对此很感兴趣在考虑不需要更改数组大小的情况下;它们可能会传递给其他子例程以进行操作,但是代码和任何子例程中的变量的唯一目的是保存维数组的数据n(并且可能会更改数据,但不会更改大小)。
(1)内存使用是否有差异?我不是底层程序的专家,但是我对它们的重要性以及它们如何影响高层编程的知识非常了解(我正在谈论的经验是:曾经尝试在fortran中运行大代码我遇到了一个我不明白的错误,sysadmin告诉我:“哦,是的,您可能正在饱和堆栈;请尝试在运行的脚本中添加此行”;任何使我深刻了解在实际编码时如何考虑这一点的东西并且不必在以后修补它们)。有人告诉我,这可能取决于许多其他因素,例如编译器或体系结构,但是我从这些响应中解释说,他们并不完全确定这是怎么回事。
(2)子例程会具有不同的接口需求吗?再说一次,不是专家,但是在那之前,由于我声明子例程变量的方式发生在我身上,最终我不得不将子例程放入模块中。我被理解为这可能会有所不同,具体取决于我是否使用可分配变量的特殊内容。我正在考虑这样一种情况,我对变量所做的所有事情都可以通过可分配的和自动的方式完成,而不是有意地使用特定于可分配的任何东西(除了使用前的分配以外)。
最后,如果这是有用的:我要问的原因是因为我们正在一个团队中发展,最近我们注意到不同的人以不同的方式使用这两个声明,因此我们需要确定这是否可以保留个人喜好或设置清晰标准(以及如何设置该标准)的好主意的原因。我不需要非常详细的答案,我正在尝试确定这是否是我应该进行研究的内容,以谨慎使用它以及应在研究的哪些方面进行。
尽管我很想知道“有趣的把戏”,而不是分配所能完成的,但与大小可变性的需求没有直接关系,但我将那些留给未来可能的后续问题,并将重点放在严格的功能上。差异(意思是:我明确告诉编译器处理我的代码的内容)。我提到的两个项目是我根据以前的经验可以想到的,但是我想念的任何其他重要的项目都请考虑。
我想确定这两个选项中哪一个最好:
subroutine sqtrace( Msize, Matrix, Value )
integer, intent(in) :: Msize
real*8, intent(in) :: Matrix(Msize, Msize)
real*8, intent(out) :: Value
[instructions...]
end subroutine sqtrace
Run Code Online (Sandbox Code Playgroud)
VS
subroutine sqtrace( Matrix, Value )
real*8, intent(in) :: Matrix(:,:)
real*8, intent(out) :: Value
if ( size(Matrix,1) /= size(Matrix,2) ) then
[error case instructions]
end if
[instructions...]
end subroutine sqtrace
Run Code Online (Sandbox Code Playgroud)
我知道当你使用警告进行编译时,如果调用sqtrace符合指示的大小,第一种情况应该在编译时自动检查.但是,我不知道编译器是否可以在给定参数可分配时执行这些检查(例如,如果此类分配依赖于在运行时确定的其他事项,则更多如此).第二个需要一个显式接口,并有更多的代码(检查),但似乎会捕获更多的错误.
使用每种情况的优点/缺点是什么?在哪种情况下,哪一种情况应该与另一种情况一起使用?
我有以下问题.我想在Fortran90中编写一个程序,我希望能够像这样调用:
./program.x < main.in > main.out
Run Code Online (Sandbox Code Playgroud)
除了"main.out"(我可以在调用程序时设置其名称),还必须编写辅助输出,我希望它们具有与"main.in"或"main.out"类似的名称(它们是实际上并没有被称为"主要"); 但是,当我使用时:
INQUIRE(UNIT=5,NAME=sInputName)
Run Code Online (Sandbox Code Playgroud)
sInputName的内容变为"Stdin"而不是文件名.有没有办法获取程序调用时链接到stdin/stdout的文件名?
我正在尝试建立一个有用的函数库.我还不太了解这一点,但显然大部分,如果不是全部,都需要包含在一个模块中(或者在程序内部的一个接口中,但是由于这个目的是建立一个库,所以似乎是一个选择)或者我将使用它们的程序将无法识别它们.
我可以创建一个包含所有这些函数的模块的长文件,但我想将不同的函数保存在不同的短文件中.但是,如果我这样做,我将不得不为每个函数创建一个不同的模块,如果我想在程序中使用它们,我会有一个很长的USE声明列表(更不用说.mod文件的数量了会产生).
我想出的唯一可能的解决方案就是使用USE所有其他模块的声明来创建另一个模块,但我认为必须有另一种方法来拥有一个包含迄今为止尚未获取的函数的库.
另外,为什么我有这个功能问题而不是子程序?是因为命令CALL立即将该行标识为子程序调用,而函数只是通过名称调用,没有命令告诉编译器"嘿,这是一个函数",所以它必须知道什么是函数,什么不是事先?
我举了一个例子(按照http://www.oceanographers.net/forums/showthread.php?378-How-to-make-a-FORTRAN-library中的说明,并使用正确的'路径').
TestFunc.F90
FUNCTION SumNum(nNum1,nNum2) RESULT(nResult)
IMPLICIT NONE
INTEGER,INTENT(IN) :: nNum1,nNum2
INTEGER :: nResult
nResult=nNum1+nNum2
RETURN;END FUNCTION
Run Code Online (Sandbox Code Playgroud)
TestProg.F90
PROGRAM TestProg
IMPLICIT NONE
WRITE(6,*) SumNum(2,2)
STOP;END PROGRAM
Run Code Online (Sandbox Code Playgroud)
命令行
> gfortran -c TestFunc.F90 -o TestFunc.o
> ar ruv libmylib.a *.o
> gfortran TestProg.F90 -o Test.x -L/path -lmylib.a
TestProg.F90:6.12:
WRITE(6,*) SumNum(2,2)
1
Error: Function 'sumnum' at (1) has no IMPLICIT type
Run Code Online (Sandbox Code Playgroud) Gfortran不会让我编译以下代码,因为nLines并且nIOstts不能像这样初始化; 所以我必须先声明它们然后在代码中添加两行来设置它们所需的初始值.
为什么这样工作?也许因为INTENT(OUT)它更有意义,因为函数将存储数据的变量已经存在(我现在不记得Fortran子程序是否通过引用工作),但对于RESULT变量,它似乎是不必要的.这是编译器特有的还是一般的Fortran特性?
FUNCTION LinesInFile(nUnit,nIOstts) RESULT(nLines)
IMPLICIT NONE
INTEGER,INTENT(IN) :: nUnit
INTEGER,INTENT(OUT) :: nIOstts=0
INTEGER :: nLines=-1
DO WHILE (nIOstts.EQ.0)
READ(UNIT=nUnit,FMT='(A)',nIOstts)
nLines=nLines+1
ENDDO
END FUNCTION
Run Code Online (Sandbox Code Playgroud) 它被认为是好的还是坏的做法?我的一位朋友告诉我,一般来说,现在大多数语言都不被认为是好习惯,但是他认为他听说这不是fortran的情况.这是真的?如果是真的,为什么?
我知道私有变量的想法是不应该访问它们,并且我确实希望它在程序的其余部分中使用模块时以这种方式工作,但我需要它来检查内部工作的模块.
说我有以下简化示例:
module mod
implicit none
private
integer :: value
public :: set_value
contains
subroutine set_value(input)
implicit none
integer,intent(in) :: input
value=input
end subroutine
end module
Run Code Online (Sandbox Code Playgroud)
我现在想测试子程序,看看它是否实际上正在做我想要的:我想编写一个使用该模块的程序,set_value用输入8 调用例程,然后检查内部变量value现在是否为8.
我可以这样做吗?或者它是否有另一种单元测试私有变量初始化器的方法?
是否可以指定 pydantic 模型中包含的字典中的各个字段?我找不到任何东西,但也许我使用了错误的关键字。我在想这样的事情:
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str = 'Jane Doe'
stats = {
age: int,
height: float,
}
Run Code Online (Sandbox Code Playgroud)
编辑:经过一些反馈后,我觉得我需要澄清一些条件并给出一个更完整的示例。我想要做的与此更相似:
from pydantic import BaseModel, NonNegativeInt, NonNegativeFloat
from pydantic.generics import GenericModel
DataT = TypeVar('DataT')
class Trait(GenericModel, Generic[DataT]):
descript: str
value: DataT
class CharacterBarbarian(BaseModel):
id: int
name: str = 'Barbarok'
traits = {
strength: Trait[NonNegativeInt] = Trait[NonNegativeInt](descript='the force', value=18),
height: Trait[NonNegativeFloat] = Trait[NonNegativeFloat](descript='tallness', value=1.8),
weight: Trait[NonNegativeFloat] = Trait[NonNegativeFloat](descript='width', value=92.1),
}
class CharacterWizard(BaseModel):
id: int
name: str = …Run Code Online (Sandbox Code Playgroud)