Fortran Coder

标题: 随机数组 & 接口冲突 [打印本页]

作者: hanshikai    时间: 2014-4-4 17:09
标题: 随机数组 & 接口冲突
GFortran编译通过,但每次运行结果一样,无变化
IVF无法通过编译,并提示【there is a conflict beetween local interface and external interface [GET_RANDOM]】

文本为输入文件及运行结果[random.dat]
RANDOM.DAT (113 Bytes, 下载次数: 1)
[Fortran] 纯文本查看 复制代码
PROGRAM RANDOMNUM
IMPLICIT NONE
INTERFACE !为函数GET_RANDOM(N,L,U)定义接口
!==================================================
FUNCTION GET_RANDOM(N,L,U)
IMPLICIT NONE
INTEGER N,I
REAL L,U,LENGTH,t
REAL::GET_RANDOM(N)!除了N,L,U外应该不许要声明其他吧??
!RETURN
END FUNCTION
!==================================================
END INTERFACE
INTEGER N
REAL L,U
REAL,ALLOCATABLE::A(:)!因为我想让这个函数具有通用性,所以用了动态数组

CALL RANDOM_SEED()!随机数种子
!石头大人说可能是没有种子的原因,可是我这里一直都有哇。
!我用的GFortran,后来在IVF上试验,无法编译
OPEN(9,file='random.dat')
READ(9,*)N,L,U
ALLOCATE(A(N))
A=GET_RANDOM(N,L,U)
WRITE(9,90)A
90 FORMAT(/,F7.3)
DEALLOCATE (A)
END

!==================================================
FUNCTION GET_RANDOM(N,L,U)
IMPLICIT NONE
INTEGER N,I
REAL L,U,LENGTH,t
REAL::GET_RANDOM(N)
!L,U分别代表了数组的上下限
LENGTH=U-L
DO I=1,N
CALL RANDOM_NUMBER(t)
GET_RANDOM(I)=L+LENGTH*t
END DO

RETURN
END FUNCTION
!==================================================



作者: hanshikai    时间: 2014-4-4 17:10
本帖最后由 hanshikai 于 2014-4-4 17:31 编辑

不好意思,刚刚给代码加上了注释。已更新。

作者: 楚香饭    时间: 2014-4-4 18:06
1. GFortran 的 seed 函数需要费点劲,你需要手动获得系统时间并当做种子。它的帮助里给了一个例子,可以复制下来以后备用。
2. 你的程序在我的 IVF for windows XE2013 SP1 上可以编译。不会有冲突。
3. 返回数组的话,通常用subroutine,避免使用function。如果非要用 function,可以封装到 module 里。

!// 后面是我的注释
[Fortran] 纯文本查看 复制代码
program randomnum
  implicit none
  integer n
  real l,u
  real,allocatable::a(:)
  call init_random_seed() !// gfortran 的seed需要更标准的写法
  n=9 ;l=3.02;u= 311.0
  allocate(a(n))
  call get_random(n,l,u,a)
  write(*,90) a
  90 format(/,f7.3)
  deallocate (a)
end program randomnum
!==================================================
Subroutine get_random(n,l,u,a) !// 一般返回数组的话,用 subroutine 会简单一些
  implicit none
  integer n,i
  real l,u,length,t
  real::a(n)
  !l,u分别代表了数组的上下限
  length=u-l
  do i=1,n
    call random_number(t)
    a(i)=l+length*t
  end do
end Subroutine get_random
!==================================================
Subroutine Init_random_seed() !// 这个函数你可以复制下来以后使用
  integer :: i, n, clock
  integer, dimension(:), allocatable :: seed
  call random_seed(size = n)
  allocate(seed(n))
  call system_clock(count=clock)
  seed = clock + 37 * (/ (i - 1, i = 1, n) /)
  call random_seed(put = seed)
  deallocate(seed)
End Subroutine Init_random_seed

作者: hanshikai    时间: 2014-4-4 18:08
本帖最后由 hanshikai 于 2014-4-4 18:09 编辑
chuxf 发表于 2014-4-4 18:06
1. GFortran 的 seed 函数需要费点劲,你需要手动获得系统时间并当做种子。它的帮助里给了一个例子,可以复 ...


非常感谢

PS:我的ivf是11.*的

作者: hanshikai    时间: 2014-4-4 18:13
chuxf 发表于 2014-4-4 18:06
1. GFortran 的 seed 函数需要费点劲,你需要手动获得系统时间并当做种子。它的帮助里给了一个例子,可以复 ...

谢谢你指导性的意见【返回数组的话,通常用subroutine,避免使用function。如果非要用 function,可以封装到 module 里】

还有个问题:如果不用interface、module,是不是function不能返回数组?
作者: pasuka    时间: 2014-4-4 18:38
hanshikai 发表于 2014-4-4 18:13
谢谢你指导性的意见【返回数组的话,通常用subroutine,避免使用function。如果非要用 function,可以封 ...

可以预先定义结构体,里面设置一个动态分配数组
然后function里面分配动态数组并返回该结构体,只是有必要这么做吗?!
subroutine和function在fortran里面基本就是一码事
作者: 楚香饭    时间: 2014-4-4 18:40
hanshikai 发表于 2014-4-4 18:13
谢谢你指导性的意见【返回数组的话,通常用subroutine,避免使用function。如果非要用 function,可以封 ...

是的,不能。

你把一切都否定了,自然就不能了。

不要太介意 subroutine 和 function,他俩的差别很小。
作者: hanshikai    时间: 2014-4-4 18:48
chuxf 发表于 2014-4-4 18:40
是的,不能。

你把一切都否定了,自然就不能了。

谢谢,明白了。
作者: hanshikai    时间: 2014-4-4 18:49
pasuka 发表于 2014-4-4 18:38
可以预先定义结构体,里面设置一个动态分配数组
然后function里面分配动态数组并返回该结构体,只是有必 ...

谢谢。
结构体是什么? 英文?
作者: 楚香饭    时间: 2014-4-4 18:51
hanshikai 发表于 2014-4-4 18:49
谢谢。
结构体是什么? 英文?

C 里面叫 struct
Fortran 里面叫 type(中文通常叫派生类型)

其实两者是一回事。
作者: hanshikai    时间: 2014-4-4 18:52
chuxf 发表于 2014-4-4 18:51
C 里面叫 struct
Fortran 里面叫 type(中文通常叫派生类型)

3Q.又长知识了。




欢迎光临 Fortran Coder (http://bbs.fcode.cn/) Powered by Discuz! X3.2