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 ...
随机推荐
- Codevs 1569 最佳绿草
1569 最佳绿草 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description 贝茜正计划着这一天如何美美地咀嚼春天的绿 ...
- [Xcode 实际操作]七、文件与数据-(24)真机使用无线网络调试应用程序
目录:[Swift]Xcode实际操作 本文将演示如何通过无线网络,在真机上测试应用程序. 首先通过数据线,将移动设备和电脑连接, 然后点击顶部的[Window]窗口菜单, ->[Devices ...
- BackgroundWorker的使用一二(可视化编程,开始后台工作,报告进度,取消后台工作等)
C# 提供了BackgroundWorker功能非常强大,可以将某项工作放到后台运行,可以让后台报告进度,可以取消后台工作...... BackgroundWorker的上述功能是通过 1. 三个主要 ...
- D - Bomb
//反向62 #include <iostream> #include <algorithm> #include <string> #include <cst ...
- 关于 prototype与__proto__ (用到的时候再看一次 加深理解)
链接顺序: 1. https://blog.csdn.net/ligang2585116/article/details/53522741 2.https://www.jianshu.com/p/80 ...
- 小程序video置顶
page { overflow-y: none; height: 100vh; } .page__hd_media { position: fixed; width:100vw; top:; heig ...
- IP服务-1-ARP和代理ARP
代理ARP常被人忽视,因为现在基本不用了
- Influxdb 时序数据库 centos 安装
Influxdb 环境搭建 操作系统:CentOS 7 X64 SSH工具:PuTTY 操作系统安装,请参照官网文档进行:https://www.centos.org/ 使用PuTTY 通过ssh连接 ...
- jQuery制作一个多彩下拉菜单按钮
最终效果图: html代码: <div id="list"> <div id="btn"> <div class="ic ...
- 108 Convert Sorted Array to Binary Search Tree 将有序数组转换为二叉搜索树
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树.此题中,一个高度平衡二叉树是指一个二叉树每个节点的左右两个子树的高度差的绝对值不超过1.示例:给定有序数组: [-10,-3,0,5,9], ...