主题:自定义函数参数调用的问题
positron
[专家分:0] 发布于 2010-09-06 14:11:00
如下Fortran程序:
program diagonalize
implicit none
byte i,j,m,n,D,k
real A(2,2),B(2,2),AB(2,2)
real,external :: multiply
data A/1.d0,1.d0,1.d0,1.d0/
data B/2.d0,2.d0,2.d0,2.d0/
write(*,*) "main A="
call outputmatrix(A)
write(*,*) "main B="
call outputmatrix(B)
AB=multiply(A,B)
end
***** matrix multiplication
function multiply(A,B)
implicit none
byte i,j,k
real A(2,2),B(2,2),AB(2,2)
real multiply(2,2)
write(*,*) "multiply A="
call outputmatrix(A)
write(*,*) "multiply B="
call outputmatrix(B)
c do i=1,D
c do j=1,D
c AB(i,j)=0
c do k=1,D
c AB(i,j)=A(i,k)*B(k,j)+AB(i,j)
c end do
c end do
c end do
c multiply=AB
end
***** output matrix
subroutine outputmatrix(B)
implicit none
byte i,j
real B(2,2)
do i=1,2
write(*,*) B(i,1),B(i,2)
end do
end
子程序multiply中的A、B为什么和主程序中的不一样?
回复列表 (共11个回复)
沙发
yeg001 [专家分:14390] 发布于 2010-09-06 15:49:00
似乎声明一下接口就可以了.
[color=FF0000]想先问一下, 这个"byte"的变量声明是那里介绍的? 我在cvf和gfortran下编译都能通过. 可否介绍一下?[/color]
以下是修改后的代码
program diagonalize
implicit none
byte i,j,m,n,D,k
real A(2,2),B(2,2),AB(2,2)
[color=00FF00]!real,external :: multiply[/color]
[color=FF0000]interface
function multiply(A,B)
real A(2,2),B(2,2),multiply(2,2)
end function
end interface[/color]
data A/1.d0,1.d0,1.d0,1.d0/
data B/2.d0,2.d0,2.d0,2.d0/
write(*,*) "main A="
call outputmatrix(A)
write(*,*) "main B="
call outputmatrix(B)
AB=multiply(A,B)
end
!***** matrix multiplication
function multiply(A,B)
implicit none
byte i,j,k
real A(2,2),B(2,2),AB(2,2)
real multiply(2,2)
write(*,*) "multiply A="
call outputmatrix(A)
write(*,*) "multiply B="
call outputmatrix(B)
do i=1,2 [color=00FF00]!这里的D没有定义, 我换成2[/color]
do j=1,2 [color=00FF00]!这里的D没有定义, 我换成2[/color]
AB(i,j)=0
do k=1,2 [color=00FF00]!这里的D没有定义, 我换成2[/color]
AB(i,j)=A(i,k)*B(k,j)+AB(i,j)
end do
end do
end do
multiply=AB
end
!***** output matrix
subroutine outputmatrix(B)
implicit none
byte i,j
real B(2,2)
do i=1,2
write(*,*) B(i,1),B(i,2)
end do
end
板凳
adda [专家分:1520] 发布于 2010-09-06 18:17:00
编译器的扩展。以下摘自ifc的帮助文档
Specifies the BYTE data type, which is equivalent to INTEGER(1).
3 楼
yeg001 [专家分:14390] 发布于 2010-09-07 00:16:00
哦~
看表面意思能猜到是一个字节. 一个字节也可以做整数或者做一个字符, 所以才想看看介绍.
呵呵, 个人感觉还是写成integer(1)比较舒服.
4 楼
cgl_lgs [专家分:21040] 发布于 2010-09-07 07:42:00
在F1键帮助里看过这东东,不过感觉作用不大,故从来没用过:)
5 楼
positron [专家分:0] 发布于 2010-09-07 11:18:00
多谢!不过我还想知道原来那种为什么会有那样的结果?
byte的定义如3L所述。
6 楼
positron [专家分:0] 发布于 2010-09-07 12:02:00
另一个问题:Fortran和C/C++的很过规则不一样,Fortran函数调用是传址调用,而C是传值调用;C里数组名实质上是个指针,指向数组第一个元素,那Fortran的数组名呢?
1L的程序那种结果是不是因为数组名指向的问题?
7 楼
cgl_lgs [专家分:21040] 发布于 2010-09-07 13:02:00
FORTRAN数组名与C是一样的,只是行列存储顺序不同。
8 楼
yeg001 [专家分:14390] 发布于 2010-09-07 13:46:00
1L的问题关键是你函数返回的是一个数组, 而不是一个数, 所以需要写interface. 或者你可以做成模块(module)
9 楼
positron [专家分:0] 发布于 2010-09-07 14:09:00
新的问题:
我的程序最终要实现的功能之一是对任意矩阵做乘法,矩阵(方阵)的的阶数在程序运行后屏幕输入,所以1L里面才有D这个没赋值的量。
这种情况下,interface会报错:
Error: A specification expression object must be a dummy argument, a COMMON block object, or an object accessible through host or use association [D]
real A(D,D),B(D,D),multiply(D,D)
相关代码如下:
program diagonalize
implicit none
byte i,j,m,n,D
real*8 r1,rand,max,phi,sp,sp2,cp,cp2
real*8,allocatable :: Mass(:,:),A(:,:),A1(:,:)
common D
interface
function multiply(A,B)
real A(D,D),B(D,D),multiply(D,D)
end function
end interface
***** input the dimension of the matrix
read(*,*) D
allocate(Mass(D,D)) ! non-diagonal mass matrix
allocate(A(D,D))
allocate(A1(D,D))
10 楼
positron [专家分:0] 发布于 2010-09-07 14:11:00
多谢!在书中找到说明了。
以前学的是C++,现在用Fortran很多规则不一样。
我来回复