程序代码中,常常会在不同的地方重复用到某一功能和重复某一代码,这个时候就要使用函数。函数包括内嵌函数,自定义函数,子程序


子程序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

自定义函数的运行和上面的子程序没有什么两样,也需要调用才能被执行,也可以独立声明变量,参数传递的方法和子程序相同。尽管如此,自定义函数和子程序还是有两点不同:

  1. 调用自定义函数前要声明。
  2. 自定义函数调用后会返回一个数值

下面是一个简单的程序:用牛顿法来解方程。

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(函数、子程序)的更多相关文章

  1. Fortran学习笔记:01 基本格式与变量声明

    Fortran学习笔记目录 01 基本格式与变量声明 格式 固定格式(Fixed Format):Fortran77 程序需要满足一种特定的格式要求,具体形式参考教材 自由格式(Free Format ...

  2. (目录)Fortran学习笔记:开坑!!!

    前言:因为某些原因,需要使用Fortran编写程序,记录下Fortran语法学习过程中的部分笔记.在此开坑记录,立下Flag,"希望年末能够更新完" Fortran 学习笔记 陈橙 ...

  3. Matlab学习笔记 figure函数

    Matlab学习笔记 figure函数 matlab中的 figure 命令,能够创建一个用来显示图形输出的一个窗口对象.每一个这样的窗口都有一些属性,例如窗口的尺寸.位置,等等.下面一一介绍它们. ...

  4. matlab学习笔记 bsxfun函数

    matlab学习笔记 bsxfun函数 最近总是遇到 bsxfun这个函数,前几次因为无关紧要只是大概看了一下函数体去对比结果,今天再一次遇见了这个函数,想想还是有必要掌握的,遂查了些资料总结如下. ...

  5. Fortran学习笔记4(循环语句)

    Fortran学习笔记4 Fortran学习笔记4 逻辑运算 循环 Do语句 Do-While循环 循环控制 循环应用实例 逻辑运算 if命令需要和逻辑运算表达式搭配才能起到很好的效果.下面分别列出F ...

  6. matlab学习笔记13_1 函数返回值

    一起来学matlab-matlab学习笔记13函数 13_1 函数返回值 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 https://blog.csdn.net/qq_36556 ...

  7. Fortran学习笔记:03 数组(Array)

    Fortran学习笔记目录 书接上回:Fortran学习笔记:02 流控制语句 数组(Array) 定义数组 一维数组 program main implicit none integer :: i ...

  8. Fortran学习笔记:02 流控制语句

    Fortran学习笔记目录 书接上回:Fortran学习笔记:01 基本格式与变量声明 流控制语句 IF语句 IF (逻辑表达式) THEN ... ELSE ... END IF SELECT-CA ...

  9. swift学习笔记2——函数、闭包

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  10. haskell学习笔记_函数

    一开始学习函数式编程语言就被告知函数式编程语言是一种“定义式”的语言,而不是一种命令式的语言,在学习haskell的函数语法时,此感觉更加强烈,haskell的函数定义倾向于一种类似C++里面的swi ...

随机推荐

  1. apringboot aop权限控制

    + 定义切面: ···@Aspect @Component public class LoginInterceptor { @Around("@annotation(lock)") ...

  2. 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (一)

    本文属于图神经网络的系列文章,文章目录如下: 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (一) 从图(Graph)到图卷积(Graph Convolutio ...

  3. Zju1610 Count the Colors(lazy标记详解)

    Description 画一些颜色段在一行上,一些较早的颜色就会被后来的颜色覆盖了. 你的任务就是要数出你随后能看到的不同颜色的段的数目.  Input 每组测试数据第一行只有一个整数n, 1 < ...

  4. java数据结构----带权图

    1.带权图:要引入带权图,首先要引入最小生成树,当所有的边拥有相同的权值时.问题变得简单了,算法可以选择任意一条边加入最小生成树.但是当边有不同的权值时,需要用一些算法决策来选择正确的边. 2.带权图 ...

  5. Tinghua Data Mining 9

    关联规则,营销购物 空缺 协同过滤

  6. 洛谷P3603 || bzoj 4763 雪辉 && bzoj4812: [Ynoi2017]由乃打扑克

    https://www.luogu.org/problemnew/show/P3603 https://www.lydsy.com/JudgeOnline/problem.php?id=4763 就是 ...

  7. eShopOnContainers 是一个基于微服务的.NET Core示例框架

    找到一个好的示例框架很难,但不是不可能.大多数是小型Todo风格的应用程序,通常基于SimpleCRUD.值得庆幸的是,Microsoft已经为eShopOnContainers创建了一个基于微服务的 ...

  8. AttributeError: module 'shutil' has no attribute 'copyfileobj'

    import shutil #1.copyfileobj(源文件,目标文件) 将文件内容复制到另一个文件 shutil.copyfileobj(open('config.log','r'),open( ...

  9. SNMP4J 总结

    一.SNMP4J介绍 SNMP4J是一个用Java来实现SNMP(简单网络管理协议)协议的开源项目.它支持以命令行的形式进行管理与响应.SNMP4J是纯面向对象设计与SNMP++(用C++实现SNMP ...

  10. 转 Linux SendMail发送邮件失败诊断案例(四)

    http://www.cnblogs.com/kerrycode/p/7826036.html