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


子程序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. [Xcode 实际操作]一、博主领进门-(11)代码区的样式设置,设置模拟器启动的声音

    目录:[Swift]Xcode实际操作 本文将演示如何对Xcode代码区进行样式设置,从而调整代码的外观属性.随便打开一份代码文件. [Xcode]->[Preferences]参数设置-> ...

  2. perl 安装LOG4perl 模块

    环境信息 ubuntu 12.04 64位 桌面版 Log-Log4perl 的介绍网址:http://search.cpan.org/~mschilli/Log-Log4perl-1.49/lib/ ...

  3. physics(2018.10.27)

    这道题可以推出\(O(1)\)的算法,但是实际上暴力模拟就可以过了. 代码(暴力模拟): #include<cstdio> #include<algorithm> #inclu ...

  4. 黑马函数式接口学习 Stream流 函数式接口 Lambda表达式 方法引用

  5. go语言的特点

    Go语言保证了既能到达静态编译语言的安全和性能,又达到了动态语言开发维护的高效率 ,使用一个表达式来形容Go语言:Go = C + Python , 说明Go语言既有C静态语言程 序的运行速度,又能达 ...

  6. LM358与TL431验证

  7. javascript要点(上)

    立即执行函数 即Immediately Invoked Function Expression (IIFE),正如它的名字,就是创建函数的同时立即执行.它没有绑定任何事件,也无需等待任何异步操作: ( ...

  8. Java 过滤器实现(登录) + 拦截器(两种方法)

    以下是实现未登录不能进入页面的实现 使用了thyemeleaf+SpringBoot+过滤器实现的,过滤器的核心代码如下: @Component @WebFilter(filterName = &qu ...

  9. 导入动态Web项目到Eclipse中遇到的问题

    问题一:创建动态网页项目时,项目报错而无文件报错 当时解决方法:直接右击项目->properties->project facets将jdk改为1.8版本即可 如图: 问题二:Tomcat ...

  10. javascript 流程控制及函数

    回顾 基本语法 在html的使用 <script></script> 注释 ///* */ 指令结束符 ;换行 输出 console.log()document.write() ...