Fortran三种数组传递方式
2016-06-27 10:55
323 查看
本文介绍了假定大小,假定形状,自动数组三种数组传递方式,并对比了其中的差别和优劣。适合新手阅读
Fortran 中,调用函数或子程序时,默认将实参的地址传递给形参,称为地址传递或引用传递。究其原因,是因为Fortran主要针对数值计算,参数多为大型数组(二维数组称矩阵),如果采用值传递,会复制实参的一个拷贝给形参,占用时间和内存,而地址传递则仅仅将实参数组的首地址传递给形参,没有时间和内存冗余。
这里介绍3种常见的数组传递方式。看下面的代码:
查看代码
打印?
执行结果:
三种方法的形参数组,第一种称假定大小数组(assumed-size arrays),第二种称自动数组(auto arrays),第三种称假定形状数组(assumed-shape arrays)。
第一种:可对数组元素或数组片段进行操作(如 a(3)=2, a(2:4)=3 ),但不能直接对数组名进行操作(如a=1)。如果对整个数组进行操作,需指明数组边界(如代码所示);
第二种:最常见,也最常用,不解释;
第三种:可用 size 函数获取数组每一维的元素个数:m = size(a,1),n = size(a,2),操作与第二种一致。注意:这种方式需要显式接口,可用 interface 指定接口,或将子程序写入 module 中使用。
在某些老代码中,可能会见到第四种写法,其与第一种类似。
查看代码
打印?
总结:
第一种将高维数组变形为1维数组,丢失了数组的维度信息,实参和形参元素的位置对应关系不确定。因此不建议使用。
第二种最常用,但需要传递额外的参数来指定数组大小。
第三种很灵活,能实现第二种的所有功能,而且减少了参数个数,但需要显式接口。推荐用这种方法,并封装与 module 中避免书写接口。
第四种则坚决反对使用。
Fortran 中,调用函数或子程序时,默认将实参的地址传递给形参,称为地址传递或引用传递。究其原因,是因为Fortran主要针对数值计算,参数多为大型数组(二维数组称矩阵),如果采用值传递,会复制实参的一个拷贝给形参,占用时间和内存,而地址传递则仅仅将实参数组的首地址传递给形参,没有时间和内存冗余。
这里介绍3种常见的数组传递方式。看下面的代码:
01 | Program www_fcode_cn |
02 | Implicit None |
03 | Real a ( 2 , 3 ) |
04 | Interface |
05 | Subroutine fun 3 ( a ) |
06 | Real a ( : , : ) |
07 | End Subroutine fun 3 |
08 | End Interface |
09 |
10 | Call fun 1 ( a ) |
11 | Write ( * , '(6f3.0)' ) a |
12 | Call fun 2 ( a , 2 , 3 ) |
13 | Write ( * , '(6f3.0)' ) a |
14 | Call fun 3 ( a ) |
15 | Write ( * , '(6f3.0)' ) a |
16 | End Program www_fcode_cn |
17 |
18 | ! 方法1 |
19 | Subroutine fun 1 ( a ) |
20 | Real a ( * ) |
21 | a ( 1 : 6 ) = 1 |
22 | End Subroutine fun 1 |
23 | ! 方法2 |
24 | Subroutine fun 2 ( a , m , n ) |
25 | Integer m , n |
26 | Real a ( m , n ) |
27 | a = 2 |
28 | End Subroutine fun 2 |
29 | ! 方法3 |
30 | Subroutine fun 3 ( a ) |
31 | Real a ( : , : ) |
32 | a = 3 |
33 | End Subroutine fun 3 |
三种方法的形参数组,第一种称假定大小数组(assumed-size arrays),第二种称自动数组(auto arrays),第三种称假定形状数组(assumed-shape arrays)。
第一种:可对数组元素或数组片段进行操作(如 a(3)=2, a(2:4)=3 ),但不能直接对数组名进行操作(如a=1)。如果对整个数组进行操作,需指明数组边界(如代码所示);
第二种:最常见,也最常用,不解释;
第三种:可用 size 函数获取数组每一维的元素个数:m = size(a,1),n = size(a,2),操作与第二种一致。注意:这种方式需要显式接口,可用 interface 指定接口,或将子程序写入 module 中使用。
在某些老代码中,可能会见到第四种写法,其与第一种类似。
1 | ! 方法4 |
2 | Subroutine fun 4 ( a ) |
3 | Real a ( 1 ) |
4 | a ( 1 : 6 ) = 4 !全部6个元素赋值为4 |
5 | a = 0 !第一个元素赋值0,其余不变 |
6 | End Subroutine fun 4 |
总结:
第一种将高维数组变形为1维数组,丢失了数组的维度信息,实参和形参元素的位置对应关系不确定。因此不建议使用。
第二种最常用,但需要传递额外的参数来指定数组大小。
第三种很灵活,能实现第二种的所有功能,而且减少了参数个数,但需要显式接口。推荐用这种方法,并封装与 module 中避免书写接口。
第四种则坚决反对使用。
相关文章推荐
- 重写页面渲染事件
- LVM
- 如何让android studio在运行时自带签名
- APK 瘦身总结
- leetcode-java-343. Integer Break
- oracle数据库基本操作
- Android 使用JmDNS查找和注册设备
- 在C语言中如何产生随机数
- lambda
- Umap2:开源USB host安全评估工具
- 经典算法体会之冒泡排序
- PrintWriter/Scanner/FileInputStream
- Win7(WinDbg) + VMware(Win7) 双机调试环境搭建之五
- Socket的3次握手链接与4次断开握手
- Myeclipse6.5加载tomcat7
- mybatis1
- 第十六周上机实践——项目5-二进制文件浏览器
- 暑期二(B)(hdu2042)
- android屏幕适配全面总结
- 设计模式- 适配器模式