Fortran Coder

查看: 30112|回复: 11
打印 上一主题 下一主题

[求助] 如何将fortran77的数组编程fortran90的

[复制链接]

9

帖子

2

主题

0

精华

入门

F 币
53 元
贡献
29 点
跳转到指定楼层
楼主
发表于 2016-9-7 19:59:24 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
感觉有了这个论坛,省去了大量时间,国内fortran讨论的论坛实在是少之又少啊。今天又碰到一个问题,麻烦大家帮助解答下:
我想把一个fortran77的程序转成fortran90,其中fortran77按照如下定义了一个函数
[Fortran] 纯文本查看 复制代码
  SUBROUTINE OTA(A, B, C, D, E, F, GGGG, TTTT)
      DIMENSION GGGG(*), TTTT(*)
     。。。。
  END

初学,不太清楚 GGGG(*), TTTT(*)表达的确切含义,猜测应当是长度任意的一维数组的意思吧。

现在我在调用这个函数,前面函数没做修改
[Fortran] 纯文本查看 复制代码
subroutine caller(A, B, C, D, E, F, GGGG, TTTT,....)
integer A,...
REAL B(A)...
integer GGGG(2*A+B)
I1=2*B+1
call OTA(A, B, C, D, E, F, GGGG, TTTT(I1))end
结果显示
error #6633: The type of the actual argument differs from the type of the dummy argument. 【GGGG】
请问怎么改才能通过? ... ....


分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

沙发
发表于 2016-9-7 20:38:13 | 只看该作者
这些老语法就是非常容易出错的。

对于虚参来说 DIMENSION GGGG(*), TTTT(*) 这种叫做 “假定大小”,是非常强烈不推荐使用的用法之一。它是万恶之源。
关于假定大小,建议看视频教程 http://v.fcode.cn/video-subroutine_and_function.html
当前的环境下,建议使用“假定形状”(具体用法视频教程中也有)

回到你的问题,在你的代码里,虚参 GGGG 和 TTTT ,只说明了 dimension ,而没有说明其变量类型。则遵循 IN 规则,它是 real 类型的
但是你给的实参,却是 integer 类型的。因此出错。

IN 规则也是极不推荐的用法之一。
当前环境下,建议使用 Implicit None 取消 IN 规则。
详见 http://define.w.fcode.cn

9

帖子

2

主题

0

精华

入门

F 币
53 元
贡献
29 点
板凳
 楼主| 发表于 2016-9-8 11:25:00 | 只看该作者
fcode 发表于 2016-9-7 20:38
这些老语法就是非常容易出错的。

对于虚参来说 DIMENSION GGGG(*), TTTT(*) 这种叫做 “假定大小”,是非 ...
没有耳机,刚才拖着看了下视频,讲得非常棒。尤其期待openmp和mpi的部分。我刚才改了一下,在OTA声明的时候,声明成:
integer,dimension(*) :: GGGG,TTTT能编译过去了。

不过新的问题又产生了,我程序里调用分三层,表示一下:
A调用B,B调用C

在函数A里定义的数组是固定的,假设数组是integer类型的WORK(N)

A将WORK(N))传给B,而在B中WORK对应的形参就是 integer dimension(*)类型的,这一步经过层主的解答下已经通过了。

现在B调用C,将WORK数组继续传下去。我不解的问题来了:
C中定义的WORK对应的形参是一个固定长度的二维数组,与我们定义的 integer ,dimension(*)显然不匹配啊

因为程序在fortran77下是通过了的,所以我在移植过程中没做改动,出现了错误:
The type of the actual argument differs from the type of the dummy argument
我觉得应该有这错误。

现在是,有没有一种方法改动最少的代码,程序能够继续,并得到正确的结果?

顺便问下,楼主是做地球物理吗,同道中人,能否留个联系方式

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

地板
发表于 2016-9-8 11:36:58 | 只看该作者
再强调一次,不要用假定大小!建议改为自动数组,或假定形状。
如果你确实要用,那么我用下面的代码做了测试,分别用 ivf for windows 和 gfortran for linux,运行正常:
[Fortran] 纯文本查看 复制代码
program a
  implicit none
  integer :: work(5) = 3
  call b(work)
end program a

Subroutine b( GGGG )
  implicit none
  integer,dimension(*) :: GGGG
  call c(GGGG)
End Subroutine b

Subroutine c(xxxx)
  implicit none
  integer xxxx(5,1)
  write(*,*) xxxx
End Subroutine c
我是搞地球物理的。联系方式嘛,可以找我的邮箱 gao[AT]fcode.cn


1.jpg (7.19 KB, 下载次数: 411)

1.jpg

2.jpg (5.76 KB, 下载次数: 450)

2.jpg

9

帖子

2

主题

0

精华

入门

F 币
53 元
贡献
29 点
5#
 楼主| 发表于 2016-9-8 12:29:08 | 只看该作者
fcode 发表于 2016-9-8 11:36
再强调一次,不要用假定大小!建议改为自动数组,或假定形状。
如果你确实要用,那么我用下面的代码做了测 ...

多谢版主!

9

帖子

2

主题

0

精华

入门

F 币
53 元
贡献
29 点
6#
 楼主| 发表于 2016-9-8 15:18:37 | 只看该作者
本帖最后由 heroinhell 于 2016-9-8 15:44 编辑

[Fortran] 纯文本查看 复制代码
program a
  implicit none
  integer :: work(5) = 3
  call b(work)
end program a

Subroutine b( GGGG )
  implicit none
  integer,dimension(*) :: GGGG
  integer I
  I=3
  call c(GGGG,GGGG(I))
End Subroutine b

Subroutine c(xxxx,iyyyy)
  implicit none
   !!!以下已经转换成f90
   real xxxx(5,1)
   integer  yyyy(5,1)
   !!原来77的代码如下
   !real xxxx
   !dimension  xxxx(5,1)
   !dimension  iyyyy(5,1)  因为没有implicit none,按IN规则处理
  write(*,*) xxxx
End Subroutine c


从代码上看,感觉work就是一块工作空间,这块工作空间实际是分配了大小的,然而,他想用这个空间一部分当integer的,一部分当real用
这样就出现矛盾了,在a中明确定义work是integer类型
在b中为了参数匹配上,也定义了integer类型,dimension(*),这是与77代码不同的地方,77的代码在这一块只声明dimension(*),所以能够灵活的定义integer和real,
那么后来在c中分别定义xxxx,yyyy为real和integer
我看到77代码是这样定义xxxx,iyyyy:
real xxxx
dimension(2,1)  xxxx
integer iyyyy
dimension(2,1)  iyyyy
这样就顺理成章了。

用fortran90,在b中,我必须声明integer类型与实参保持一致,才能不出错误。但是后面这个work确实是一分为二,半real半integer,还有办法弥补吗 ?

2033

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1641 元
贡献
709 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

7#
发表于 2016-9-8 16:31:59 | 只看该作者
实际上,不管在 Fortran77 还是 Fortran90,这样写都是不符合语法规范的。
(你以前用的什么编译器?可能是 Compaq 。现在用的是 IVF 吧?请注意,Compaq 和 IVF 都是完全的 Fortran77 和 Fortran90 编译器!!)
你说的差别,应该是不同编译器的差别。有的编译器检查了这个错误,有的不检查。你可以让 IVF 不检查。

111.png (25.67 KB, 下载次数: 467)

111.png

490

帖子

4

主题

0

精华

大宗师

F 币
3298 元
贡献
1948 点

水王勋章元老勋章热心勋章

8#
发表于 2016-9-8 22:09:14 | 只看该作者
本帖最后由 pasuka 于 2016-9-8 22:13 编辑
heroinhell 发表于 2016-9-8 15:18
[mw_shl_code=fortran,true]program a
  implicit none
  integer :: work(5) = 3

1、将一个代码行数超过5k的古董F77程序转成符合标准的F90等于推倒重来;
2、这个F77程序的科研与工程价值仍然存在的话,要么成功商业化,要么有类似功能与定位的能找到源代码的F90、C、C++、Matlab或者Python版本存在;

490

帖子

4

主题

0

精华

大宗师

F 币
3298 元
贡献
1948 点

水王勋章元老勋章热心勋章

9#
发表于 2016-9-8 22:11:26 | 只看该作者
fcode 发表于 2016-9-8 16:31
实际上,不管在 Fortran77 还是 Fortran90,这样写都是不符合语法规范的。
(你以前用的什么编译器?可能是 ...

这种黑魔法无论新手还是老鸟都是焦油坑,保准坑人不浅

9

帖子

2

主题

0

精华

入门

F 币
53 元
贡献
29 点
10#
 楼主| 发表于 2016-9-9 12:57:21 | 只看该作者
pasuka 发表于 2016-9-8 22:11
这种黑魔法无论新手还是老鸟都是焦油坑,保准坑人不浅

代码行数已经超过5K,正在坑内拼命挣扎,还没出坑。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-12-23 16:07

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表