hanshikai 发表于 2014-4-4 17:09:56

随机数组 & 接口冲突

GFortran编译通过,但每次运行结果一样,无变化
IVF无法通过编译,并提示【there is a conflict beetween local interface and external interface 】

文本为输入文件及运行结果
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:47

本帖最后由 hanshikai 于 2014-4-4 17:31 编辑

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

楚香饭 发表于 2014-4-4 18:06:07

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

!// 后面是我的注释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:04

本帖最后由 hanshikai 于 2014-4-4 18:09 编辑

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

非常感谢

PS:我的ivf是11.*的

hanshikai 发表于 2014-4-4 18:13:50

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

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

还有个问题:如果不用interface、module,是不是function不能返回数组?

pasuka 发表于 2014-4-4 18:38:10

hanshikai 发表于 2014-4-4 18:13
谢谢你指导性的意见【返回数组的话,通常用subroutine,避免使用function。如果非要用 function,可以封 ...

可以预先定义结构体,里面设置一个动态分配数组
然后function里面分配动态数组并返回该结构体,只是有必要这么做吗?!
subroutine和function在fortran里面基本就是一码事

楚香饭 发表于 2014-4-4 18:40:33

hanshikai 发表于 2014-4-4 18:13
谢谢你指导性的意见【返回数组的话,通常用subroutine,避免使用function。如果非要用 function,可以封 ...

是的,不能。

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

不要太介意 subroutine 和 function,他俩的差别很小。

hanshikai 发表于 2014-4-4 18:48:06

chuxf 发表于 2014-4-4 18:40
是的,不能。

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


谢谢,明白了。:-)

hanshikai 发表于 2014-4-4 18:49:40

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

谢谢。
结构体是什么? 英文?

楚香饭 发表于 2014-4-4 18:51:20

hanshikai 发表于 2014-4-4 18:49
谢谢。
结构体是什么? 英文?

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

其实两者是一回事。
页: [1] 2
查看完整版本: 随机数组 & 接口冲突