《FORTRAN 95程序设计》学习笔记 下载本文

内容发布更新时间 : 2024/12/24 3:46:51星期一 下面是文章的全部内容请认真阅读。

《Fortran95 程序设计》学习笔记 by 柳柳

★ 【语法】WHERE

? where (a<3) ?对所有a<3的位置

? b = 1 ?设置b=1,注意,a、b同大小 ? else where ?亦可elsewhere (a>5)这样的东西 ? b = 2 ? end where

★ 【语法】FORALL:使用方法forall(范围1,范围2…条件)

? forall (I=1:5,J=1:5,a(I,J)/=0) a(I,J) = 1/a(I,J) ? 相当于:do I=1,5 ;do j=1,5; if a(I,J) /=0 …

★ 【内存细节】数组保存:假设一个A(3,3),则内存排列:

? A(1,1) => A(2,1) => A(3,1) => A(1,2) => A(2,2) => A(3,2) => A(1,3) => A(2,3) =>

A(3,3)。注意,为了使用告诉cache,应尽量使用编号相近的内容,选用内存相近的内容。所以integer::a(2,2)=(/1,2,3,4/)就是a(1,1)=1;a(2,1)=2;a(1,2)=3;a(2,2)=4,按内存分配4个东西。

★ 【语法】可变数组

? 声明: integer,allocatable :: a( : ) ?allocatable表示可变数组;a( : )表示可变一维数

组;多维的可以a(4,: ),a(: , : )这样。

? 分配内存: allocate(a(大小), stat=error) ?这个error整型,=0为成功,否则失败 ? 释放内存: deallocate(a)

? 判断是否已经分配内存:allocated(某),能够return .true. / .false. (Ruby: if xx != nil)

函数与子程序(子程序、函数、全局变量)

★ 【子程序】Subroutine

? program main ?主程序 ? 内容 ?主程序代码 ? end program main ?主程序结束

? subroutine sub1(参数) ?子程序1,调用方法:call sub1 ? 内容,注:可以使用return (Ruby return) ? end subroutine sub1 ?子程序1结束

第 6 页 共 16 页

《Fortran95 程序设计》学习笔记 by 柳柳

? 说明:子程序独立拥有属于自己的变量声明,同时子程序和Ruby一样也是传进来

地址,所以可以在子程序中修改传入内容的数值。

? 有关字符串:character(*) :: first,传进来的时候可以用*,大小任意。这种功能用于

子程序接受字符串或者初始化给定常量字符串,如:character(*),parameter :: a=”123”

★ 【函数】function

? 声明函数:real,external :: add ,分别定义返回类型,声明为函数,以及函数名。注

意,声明的时候不带参数。 ? function add(a,b)

? real :: add,a,b ?add为返回的参数 ? end function add

? 使用函数时的一个不成文规定:传递进来的东西,只读他的数值就好了,不要去改

变他的数值。

★ 【不推荐的方法】全局变量 (建议使用module)

? integer::a, b ? common a, b ? 使用的时候

? integer:: n1,n2

? common n1,n2 (只能和位置对应,和名字不对应,所以common多了比较无

奈。此时可以用比如common a(2)这样数组一类的,不过都不如用module) ? 此外还可以用比如common /group1/ a这样来分组,初始化需要用block data

写在主程序之外,如:

? block data ?主程序之前就执行,只能赋初值,注意全局变量不能做常量 ? integer a, b

? common /group1/ a,b ? data a,b /3,4/ ? end block data

★ 【小技巧】函数传递参数中的小技巧,不赋值初大小的数值

? subroutine userA(num,n2) ? integer :: num(*) ?不赋值大小

? integer :: n2(6) ?取地址中的前6个东西,汗。此处也可重设范围,如(-2,2)

第 7 页 共 16 页

《Fortran95 程序设计》学习笔记 by 柳柳

★ 【提示】变量生存周期提示:Visual Fortran不自动释放变量内存,所以函数中使用变量

的时候一定要使用明显的初始化,不要设置integer :: a=1这样的初始化,因为这个是分配内存时的初始化,第二次执行函数会被无视。 ★ 【语法技巧】传递函数:

? real,external :: func ?声明自定义函数 ? real,intrinsic :: sin ?声明sin是库函数 ? call execfun(sin)

? subroutine execfun(f) ?子程序定义 ? real,external :: f ? write(*,*) f(1.0) ? end subroutine

★ 【猥琐】子程序中的特殊参数:integer,intent(in) :: a; integer,intent(out):: b 表示a只读,b

应被重新赋值。这只是编程的时候让编译器帮忙检查错误,对实际没有意义。 ★ 【语法】函数的使用接口(Interface)

? 用途:1、返回数组,2、参数数目不定,3、返回指针,4、制定参数位置等 ? 举例:返回数组

? interface

? function rand10(lbound,ubound)

? real :: lbound,ubound ? real :: rand10(10) ?返回数组 ? end function; end interface ? 举例:不定参个数

? interface ? function sub(a,b)

? integer,optional :: b,a ?多态,表示a,b可以省略 ? 定义function时:if(present(b)) then…(Ruby: if b!=nil)

? 此外optional之后可以改变位置,比如上面:result = sub(b=2,a=1),意义不大

★ 【常用函数】随机数功能

? 取种子:call Random_Seed()

? 制造:call Random_number(t) ?t是0-1的随机数,注意也可以是直接生成数组

第 8 页 共 16 页

《Fortran95 程序设计》学习笔记 by 柳柳

★ 【语法】递归:声明:recursive integer function f(n) result(as);其中recursive表示可以递

归,result(as)这样表示可以用另一个名字做返回的内容,类型还是integer

★ 【语法】内部函数,只能在某范围内调用的函数,contains里面写内容(如函数、子程序

定义)即可。

★ 【少用语法】并行处理:pure,elemental,使用有很多限制,如所有参数为intent(in),

不能改变全局变量等。声明在定义处,如pure function fc()。个人认为暂时用不上这个,以前并行处理不是这么实现??

★ 【有用函数】记录时间:character(20):datatime;call data_and_time(data,time)

MODULE与面向对象(重载操作符、虚函数)

★ 【语法与范例】module用来封装程序模块范例

? module 模块名

? private a ?可以把a私有化,类内的,Ruby@ ? integer a,b

? common a,b ?这样就可以使用全局变量名。或:integer,save :: a,b ? type plea.. ?这样即可常用type(plea) :: XXXX为一个类型定义 ? type的定义内容 ? end type

? Use 父模块名 ?继承机制 ? Contains

? 定义函数、子程序。像是类的方法,默认均为public,如果需要私有化似乎

也可在前面(声明变量之前)private函数名

? end module

? 特别提示:当变量重名,可以use A,aa=>va (把A的va改名为aa用) ★ 【面向对象】同名函数重载。module中:

? interface fu ?虚函数,调用的时候自动从下面选一个参型合适的

? module procedure fu1 ? module procedure fu2 ? end interface

第 9 页 共 16 页

《Fortran95 程序设计》学习笔记 by 柳柳

★ 【面向对象】重定义操作符

? interface operator(+) ?特别说明,赋值号也可重载,用assignment(=)

? module procedure add ?候选的函数 ? end interface ? contains

? integer function add(a,b) ?比如a,b都是自定义type类型,返回一个integer,则可

c=a+b这样了。

? 说明:定义可以是已有的各种运算符也可是自定义的类型,比如.dot. (两边有点),

等号默认为赋值(参见数组那种),亦可自定义。

文件相关(OPEN、WRITE、READ)

★ 【编译器】VF中都放在一个Source Files中,可分别编译为*.obj,最后连接为一

个.EXE(RMXP的Script Editor,只是多了一个分别编译的过程)

★ 【语法】include ?文件名.后缀?,相当于把该文件的内容全部ctrl-c过来,对编译和执行

并没有什么意义

★ 【语法与操作】open 打开文件

? open(unit = 编号, file = “hello.txt”)即可打开文件,使用时:write(编号, *) “Hello” ★ 细节:open(unit = 编号, file = filename , form = ?formated文本格式/unformated二进制格

式? , status = ?new第一次打开/old已存在文件/replace重建/scratch弄个暂存盘可以不要file? , access = ?sequential顺序 / direct 直接?, recl = 长度, err=label出错跳转标签, IOStat = var这个数字>0出错,<0文件终了,=0正常, action = ?readwrite/read/write?) ★ 【重要语法】write / read (unit = number , fmt = Format , NML = namelist(专读某个

namelish,无用),rec = record(直读文件终,设置所读写文件模块位置),Iostat = var,ERR = label,END=label(遇到文件结尾的跳转标签),ADVANCE = ?yes/no是否读写后换行?) ★ 【语法】判断文件存在:inquire : inquire(file = filename, exist=alive) ★ 【语法】关闭文件close(fileid,status = ?keep/delete是否删除文件?)

★ 【其他极少用的】rewind(编号):把读写位置返回开头;backspace(..),endfile() ★ 【操作】文件操作:顺序文件、直接访问文件、二进制

? 顺序文件:read(unit = id , fmt = “..” , iostat = ..)接受read的东西;这样反复循环读

第 10 页 共 16 页