Fortran学习笔记6(函数、子程序)
程序代码中,常常会在不同的地方重复用到某一功能和重复某一代码,这个时候就要使用函数。函数包括内嵌函数,自定义函数,子程序。
子程序Subroutine
子程序之所以叫子程序,是因为在没有经过调用之前,它不会被执行。(当然,如果把编译器对主函数的调用也看做同样的话则另当别论。)
包含子程序的程序的格式:
program main
......
......
call sub_1(...)
......
call sub_2(...)
......
end program main
subroutine sub_1(...)
...
end subroutine sub_1
subroutine sub_2(...)
...
end subroutine sub_2
主程序并不一定要放在最开始,它可以放在程序的任何地方(但是最好放在最开始或者结尾,如果你放在了一大段程序的中间……何苦为难自己!)子程序之间也可以互相调用。甚至可以自己调用自己,这个算法就叫递归,但是Fortran77不支持。调用语句为call。
有关子程序,一个很重要的概念是,子程序独立的拥有属于自己的变量申明。主程序和子程序,不同的子程序之间的变量名可以相同,他们互不干扰。除了变量独立,子程序还独立拥有自己的行代码。
在子程序的调用中会涉及到参数传递。Fortran中的参数传递使用的是传址调用。也就是说,实参和形参公用一块内存,两者改变其中之一,另一者也会发生变化,(其实是形参暂时的借住在实参家里。)
自定义函数Function
自定义函数的运行和上面的子程序没有什么两样,也需要调用才能被执行,也可以独立声明变量,参数传递的方法和子程序相同。尽管如此,自定义函数和子程序还是有两点不同:
- 调用自定义函数前要声明。
- 自定义函数调用后会返回一个数值。
下面是一个简单的程序:用牛顿法来解方程。
program main
implicit real*8(a-z)
external f,g
integer::max
integer::i,k=1
real*8::x0,x1,x2,dx,tol,f,g
open(unit=11,file='fin.txt')
open(unit=12,file='fout.txt')
read(11,*)x0,max,tol
do
x1=x0-f(x0)/g(x0)
dx=abs(x1-x0)
if(dx<=tol) exit
k=k+1
if(k>=max) exit
x0=x1
end do
write(12,*)x0
end program main
function f(x)
implicit none
real*8::f,x
f=x**3+2*x**2+10*x-20
end function
function g(x)
implicit none
real*8::g,x !,dx
g=3*x**2+4*x+10
end function
下面是一个更简单的例子:(摘自彭国伦《Fortran95程序设计》一书)
program main
implicit none
real::a=1,b
real add
add(a,b)=a+b
! 简单的子程序直接写在主程序里面,并且不用call调用。并且这样的函数只能在本主函数中使用,其他地方不能调用。
write(*,*)add(a,3.0)
stop
end program
写函数的时候请注意,尽量不要去改变传入的参数的数值,最好另开辟一个内存来存储要用的应变量,而不要随意去改变传入的自变量。
全局变量COMMON
不同的程序之间,也就是在不同的函数之间,除了可以通过传递参数的方法来共享内存,还可以通过全局变量来让不同程序中声明出来的变量使用相同的内存位置。
program main
implicit none
integer::a,b
common a,b
a=1
b=2
call sub()
end program
subroutine sub()
implicit none
integer::num1,num2
common num1,num2
write(*,*)num1,num2
return
end subroutine sub
由于全局变量使用的“地址对应”的方法在程序中共享数据,所以在程序设计时常常会出现一些不方便,比如在主程序中声明了6个全域变量,而你在子程序中只需要使用第六个全域变量,但是你不得不把前五个都写出来。这样很麻烦,一个幼小的解决办法是将全域变量分区。
program main
implicit none
integer::a,b,c,d
common/group1/ a,b
common/group2/ c,d
a=1
b=2
c=3
d=4
call sub_1()
call sub_2()
end program
subroutine sub_1()
implicit none
integer::num1,num2
common/group1/ num1,num2
write(*,*)num1,num2
return
end subroutine sub_1
subroutine sub_2()
implicit none
integer::num1,num2
common/group2/ num1,num2
write(*,*)num1,num2
return
end subroutine sub_2
BLOCK DATA
关于COMMON设置初值,不能直接在子程序或者主程序中使用data来设置初值,要在block data程序模块中使用data命令来设置初值。BLOCK data很像一段子程序,它也是一段独立的程序模块,也拥有自己的变量声明,不过它不需要别人调用就可以自己执行。事实上,这段程序会在主程序执行前生效,不过它的功能只在于设置全局变量的初值,不能有其他执行命令出现。具体语法如下:
block data name ! name可以省略
implicit none ! 最好不要省略
integer... ! 声明变量
real...
common ... ! 把变量放在公共空间
common/group1/... ! 公共空间分区
data var1,var2,...,varn/value1,value2,...,valuen/ ! data语句赋初值
...
...
end block data name ! 可以只写end或end block data
还有一点要注意,全局变量不能声明成常量。所以block data中不能出现parameter。
实际的例子如下:
program main
implicit none
integer::a,b
common a,b
integer::c,d
common/group1/c,d
integer::e,f
common/group2/e,f
write(*,*)a,b,c,d,e,f
stop
end program main
block data name ! name可以省略
implicit none ! 最好不要省略
integer::a,b
common a,b
data a,b/1,2/
integer::c,d
common/group1/ c,d
data c,d/3,4/
integer::e,f
common/group2/e,f
data e,f/5,6/
end block data name ! 可以只写end或end block data
小结
COMMON语法在数据共享式会出现很多限制和不足,建议不要使用而采用module语句来实现数据共享。
Fortran学习笔记6(函数、子程序)的更多相关文章
- Fortran学习笔记:01 基本格式与变量声明
Fortran学习笔记目录 01 基本格式与变量声明 格式 固定格式(Fixed Format):Fortran77 程序需要满足一种特定的格式要求,具体形式参考教材 自由格式(Free Format ...
- (目录)Fortran学习笔记:开坑!!!
前言:因为某些原因,需要使用Fortran编写程序,记录下Fortran语法学习过程中的部分笔记.在此开坑记录,立下Flag,"希望年末能够更新完" Fortran 学习笔记 陈橙 ...
- Matlab学习笔记 figure函数
Matlab学习笔记 figure函数 matlab中的 figure 命令,能够创建一个用来显示图形输出的一个窗口对象.每一个这样的窗口都有一些属性,例如窗口的尺寸.位置,等等.下面一一介绍它们. ...
- matlab学习笔记 bsxfun函数
matlab学习笔记 bsxfun函数 最近总是遇到 bsxfun这个函数,前几次因为无关紧要只是大概看了一下函数体去对比结果,今天再一次遇见了这个函数,想想还是有必要掌握的,遂查了些资料总结如下. ...
- Fortran学习笔记4(循环语句)
Fortran学习笔记4 Fortran学习笔记4 逻辑运算 循环 Do语句 Do-While循环 循环控制 循环应用实例 逻辑运算 if命令需要和逻辑运算表达式搭配才能起到很好的效果.下面分别列出F ...
- matlab学习笔记13_1 函数返回值
一起来学matlab-matlab学习笔记13函数 13_1 函数返回值 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 https://blog.csdn.net/qq_36556 ...
- Fortran学习笔记:03 数组(Array)
Fortran学习笔记目录 书接上回:Fortran学习笔记:02 流控制语句 数组(Array) 定义数组 一维数组 program main implicit none integer :: i ...
- Fortran学习笔记:02 流控制语句
Fortran学习笔记目录 书接上回:Fortran学习笔记:01 基本格式与变量声明 流控制语句 IF语句 IF (逻辑表达式) THEN ... ELSE ... END IF SELECT-CA ...
- swift学习笔记2——函数、闭包
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- haskell学习笔记_函数
一开始学习函数式编程语言就被告知函数式编程语言是一种“定义式”的语言,而不是一种命令式的语言,在学习haskell的函数语法时,此感觉更加强烈,haskell的函数定义倾向于一种类似C++里面的swi ...
随机推荐
- line-height与图文对齐 笔记
基本概念: 块:block 特点独行 内联:inline 内联块:inline-block 如果元素display属性默认值为block,则为块元素.如div p 如果元素display属性默认值为i ...
- 虚拟机无法分配内存 virtual memory exhausted: Cannot allocate memory
1.内存交换空间(swap)的构建 安装Linux时一定需要的两个分区:根目录和swap(内存交换空间). swap的功能:在应付物理内存不足的情况下所造成的内存扩展记录的功能. 物理内存不足的时候, ...
- JDBC | 查询表数据行数
两种方法: 1. "select * from userinfo" 利用ResultSet的last和getRow方法来获得ResultSet的总行数,适用于在查询数据的同时统 ...
- POJ-1062-昂贵的聘礼(枚举)
链接:https://vjudge.net/problem/POJ-1062 题意: 年轻的探险家来到了一个印第安部落里.在那里他和酋长的女儿相爱了,于是便向酋长去求亲.酋长要他用10000个金币作为 ...
- ctypes to load library in c/c++
cdll.LoadLibrary(...) restype (default is c_int) argtypes (what's the default? c_int?) customized da ...
- Oracle Database Hang While Loading 3rd party SBT Library And After This Nobody Can Access The Database (windows login 登陆hang )
Applies to: Oracle Database - Enterprise Edition - Version 11.2.0.4 and later Microsoft Windows x64 ...
- Linux--NiaoGe-Service-05
1.设置网络参数的命令 命令名称 作用 ifconfig 查询.设置网卡与IP网络等相关参数 ifup.ifdown 启动.关闭网络接口 route 查看配置路由表(route table) ip 整 ...
- mybatis(错误) 项目启动时报“Result Maps collection already contains value forxxx”的解决方案
使用逆向工程生成代码时,一定要将原来的代码删除干净,如果覆盖的话,不是真正的覆盖,在原来的代码上增加重复的代码,导致出错
- phpdesigner 配置SVN
- CF1025B Weakened Common Divisor
思路: 首先选取任意一对数(a, b),分别将a,b进行因子分解得到两个因子集合然后取并集(无需计算所有可能的因子,只需得到不同的质因子即可),之后再暴力一一枚举该集合中的元素是否满足条件. 时间复杂 ...