fortan笔记

来源:互联网 发布:成都java培训费用多少 编辑:程序博客网 时间:2024/06/05 16:16

fortran基础知识

语句结构

  • fortran语句分为两种: 可执行语句、不可执行语句
  • fortran语句可以书写行的任意位置,语句间行间的衔接用&符号,类似c/c++语言中的\
  • 语句标号是fortran语句的名字,可以使用1~99999之间的任何一个数字,使用标号可以在程序的其他部分引用这条语句。
  • 感叹号是注释
  • 程序分为3个部分:
    1. 声明部分:定义程序名和程序引用的数据以及变量的类型
      program语句,对fortran编译器指定程序的名字,必须是程序的第一个语句行
    2. 执行部分:描述语句完成的操作
    3. 终止部分,由一条或终止程序执行的语句组成
      终止部分由STOP和END PROGRAM语句组成,STOP语句告诉计算机停止运行,END PROGRAM语句告诉编译器程序中不再有语句需要编译。

程序书写格式

  • 保留字大写,程序的变量用小写字母表示。大写保留字和常量,变量名、过程名等则小写。

编译、链接、执行

  • 两种方式
    1. 批处理
    2. 交互处理

fortran数据类型

  1. 三个对数字有效:INTEGER,REAL,COMPLEX
  2. 一个逻辑:LOGICAL
  3. 一个字符串:CHARACTER
    • fortran允许定义派生数据类型

实型变量由2部分组成:尾数和指数,分配给存放尾数的位数决定常量的精度
- 字符常量与变量
字符类型由字母字符串组成,一个字符常数是单引号或双引号括住的字符串。两个连续的单引号包含着重符。

  • 定义变量类型的方式:
    1. 默认式
      任何以字母I,J,K,L,M或N开头的变量名假定为INETEGER,其他字母开头的变量名假定为REAL。
    2. 显示定义:
      INTEHER::var1,var2....
      REAL :: var1,var2
  • 常数命名
    用PARAMETER属性来创建,格式:type,PARAMETER::name=value [,name2=value2,...]
    type是常数的类型,name是赋给常数value的名字

fortran算数运算符

        • / **(指数运算)
  1. 整型运算是没有小数点,直接截断

  2. 在混合模式下,在进行实数与整数操作的情况下,计算机将整数转换为实数,然后进行实数运算。
  3. 类型转化函数
    INT(X) NINT(X) CEILING(X) FLOOR(X) REAL(I)

输入和输出语句

  • 输入语句格式: READ (*,*) input_list
    input_list是读入的值放置在里面的变量列表。
    圆括号(.)的第一数据域指明从哪个输入/输出单元 ,星号意味着从标准输入读。圆括号的第二个数据域指明读入数据的格式,星号意味着表控输入,又称自由格式输入。
    表控输入意味着变量列表中的变量类型决定输入数据所需要的格式
    对于表控输入,如果含有空格,输入字符串必须用单或双引号括住
    程序的每条READ语句从输入数据的一个新行开始读取。

  • 表控输出格式:WRITE (*.*) Output_list

3种初始化变量

  1. 赋值语句
  2. READ语句
  3. 类型声明语句中的初始化
    type:: var1=value,[value=value,...]

IMPLICIT NONE语句

  • IMPLICIT NONE语句使Fortran中默认提供输入值的功能丧失,当程序含有IMPLICIT NONE语句,没有出现在显示类型声明语句中的变量被认为是错误的。IMPLICIT NONE语句出现在PROGRAM语句之后和类型语句之前。
    IMPLICIT NONE语句强制程序中所有的变量要显示声明类型。

STOP语句

STOP语句停止fortran程序的执行,程序可以有许多条STOP语句.


程序设计与分支结构

逻辑常数和变量

下列数值中的一个:.TRUE,.FALSE
逻辑变量利用LOGICAL语句来声明:LOGICAL:: var1[,var2,var3...]

关系运算符

新形式 旧形式 意义 == .EQ. 等于 /= .NE. 不等于 > .GT. 大于
=
.GE. 大于或等于 < .LT. 小于 <= .LE. 小于或等于

输入输出语句中的逻辑值

逻辑变量出现在以READ开头的语句中,相应的输入值必须以T或F开头的一个或一组字符。如果输入的字符是T,那么逻辑变量就是.TRUE.
如果输入的第一个字符是F,那么逻辑变量就是.FALASE.

控制结构:分支

  • IF语句格式:
    IF (logical_expr) THEN
    statement1
    statement2

    END IF

IF(...) then是一个fortran语句,必须一起写在同一行上,并且要执行的语句必须占用IF(…)then语句下面单独的一行。紧随其后的END IF语句必须另起一行,在包含end if语句的行上不能有行号。

  • ELSE和ELSE IF子句

            语句1        语句2        ...    ELSE IF(逻辑表达式2)  THEN        语句1        语句2        ...    ELSE        语句1        语句2        ...    END IF
  • 命名的IF结构块
    带有名称的结构的一般形式为
    [名称: ] IF(逻辑表达式_1) THEN
    语句1
    语句2

    ELSE IF(逻辑表达式_2) THEN [名称]
    语句1
    语句2

    ELSE [名词]
    语句1
    语句2

    END IF [名称]

  • 逻辑IF语句
    IF(逻辑表达式) 语句

select case结构

  • 一般形式
    [name:] SELECT CASE (case_expr)
    CASE (情况选择子_1) [name]
    语句1
    语句2
    ...
    CASE (情况选择子_2) [name]
    语句1
    语句2
    ...
    CASE DEFAULT [name]
    语句1
    语句2
    ...
    END SELECT [name]

    如果给SELECT CASE语句指定了名字,那么必须在相关的END SELECT上出现相同的名字。

循环和字符操作

循环有2种结构:当循环和迭代循环(计数循环)
1. 当循环
DO
...
IF(逻辑表达式) EXIT
...
END DO

在DO和END DO之间不间断重复运行,直到逻辑表达式为真,执行了EXIT语句。当EXIT语句执行后,控制语句转到END DO之后的第一条语句处。

  1. DO WHILE循环
    “`
    DO WHILE(逻辑表达式)



    END DO

  2. 计数循环
    “`
    DO index=istart,iend,incr
    语句1
    语句2
    END DO
    incr如果缺少,默认是1
    3个循环参数istart,iend,incr可以是常量、变量或者表达式。如果是变量或者表达式,其值是在循环开始前进行计算,产生的数值用于控制循环。
    如果index*incr《=iend*incr,程序执行循环体内的数据。
    只要index*incr <=iend*incr,就反复执行。

  3. CYCLE和EXIT语句
    如果CYCLE语句在循环体内执行,当前循环的执行将被终止,控制器将返回到循环的顶部。(相当于C中的continue语句)
    如果在循环中执行EXIT语句,循环的执行将终止,控制器将转到循环后面的第一条可执行语句处。

  4. 命名循环

    • 带有名称的当循环
      [名称:]DO
      语句
      语句
      语句
      IF(逻辑表达式) CYCLE [名称]

      IF(逻辑表达式) EXIT [名称]
      END DO

    • 带有名称的计数循环
      [名称:] DO index=istart,iend,incr
      语句
      语句
      IF(逻辑表达式) CYCLE [名称]

      END DO[名称]

字符赋值和字符操作

可以通过字符表达式操作字符数据,字符表达式可以由有效的字符常量、字符变量、字符操作符和字符函数组成。
字符操作符是一种作用于字符数据并产生字符结果的操作符。
字符操作符有2种基本类型:子字符串抽取和连接。
- 字符赋值
如果字符表达式的长度短语字符变量的长度,多余部分用空格补充
如果字符表达式的长度长于字符变量的长度,则截断。

  • 子串抽取
    一个子串表示为,在变量名后面的括号中放置两个由逗号隔开的表示开始和结束的字符编号的整数数值。如果字符结束编号小于开始编号,则返回空串。

  • 连接(//)操作符
    可以将两个或多个字符串或子串合并成一个大的字符串,这个操作称为连接。fortran中连接操作符是双斜线,斜线间无空格。

  • 字符数据的关系操作符
    ASCII字符比较,字符不能与整型比较,只能字符之间比较。

  • 内置字符函数


基本的I/O概念

格式和格式化语句

  • 格式可以指定程序输出打印变量的确切方式。指定变量在纸上的水平或垂直位置,也可指定打印的有效位数。
  • format语句
    WRITE (*,100) i, result
    100 FORMAT (' The result for iteration',I3,'is',F7.3)
  • 字符变量语句
    CHARACTER(len=20) :: string
    string='(1X,I6,F10.2)'
  • 字符常量语句
    WRITE(*,'string='(1X,I6,F10.2))

输出设备

输出缓冲区的第一个字符称为控制字符,指定了行的垂直间距。
对于表控输出[WRITE(,)],空格字符被自动地插入到每个输出缓冲区的开头。

格式描述符

  • 四个类别:
    1.描述文本行垂直位置的格式描述符
    2.描述行中数据水平位置的格式描述符
    3.描述特定数值的输出格式的格式描述符
    4.控制格式中一部分的重复的格式描述符
  • 格式描述符符号

    符号 含义 c 列号 d 实数输入或输出小数位右边的位数 m 要显示的最小位数 n 要跳过的空格数 r 重复计数——一个描述符或一组描述符的使用次数 w 域宽——输入或输出使用的字符数
  • 整数输出——I描述符
    格式如下:rIw或rIw.m

  • 实数输出——F描述符
    格式如下:rFw.d
  • 实数输出——E描述符
    以指数表示法打印输出
    格式:rEw.d
    E格式描述符域宽度必须满足w>=d+7
  • 真正的科学记数——ES描述符
    ES格式描述符具有的格式:rESw.d
    ES域必须满足w>=d+7
  • 逻辑输出——L描述符
    格式:rLw
    逻辑变量的值只能使用.TRUE或.FALSE
    逻辑变量的输出为T或F,在输出域内在右对齐
  • 字符输出——A描述符
    格式: rArAw
  • 水平定位——X和T描述符
    这两种格式描述符控制数据在输出缓冲区中的间距以及在最终输出行上的间距。
    可以在缓冲区中插入间距的X描述符,以及可以在缓冲区中跳过特定列的T描述符。
    X描述符的格式为:nX,n为要插入的空格数,用于在输出行上的两个数值之间添加一个或多个空格
    T描述符的格式为:Tc,c是要转到的列号,用来直接跳到输出缓冲区中一特定的列。
  • 格式描述符组的重复执行

格式化READ语句

  • 整数输入——I描述符
    读取整数数据的描述符rIw
  • 实数输入——F描述符
    F描述符是用于描述实数数据的输入格式的格式描述符rFw.d
  • 逻辑输入——L描述符
    语法:rLw
  • 字符输入——A描述符
    语法rArAw,rA描述符读取一个域中的字符数据,域宽度与被读取的字符变量的长度相同,rAw描述符读取一个具有固定宽度w的域中的字符数据。
  • 水平定位——X和T描述符
    X描述符的主要作用是跳过不想读取的输入数据的区域。
    T描述符也可,用两种不同的格式读取相同的数据。
  • 垂直定位——斜线(/)描述符
    斜线格式描述符可以使格式化READ语句放弃当前输入缓冲区的内容,而从输入设备中获取另一个,然后从新的输入缓冲区的头部开始处理,

文件及文件处理初步

  1. OPEN语句
    OPEN语句讲一个文件与一个给定的I/O单元号关联
    格式:OPEN(open_list)
    包含一组子句,分别指定I/O单元代号、文件名和关于如何存取文件的信息。

    • UNIT=子句指明与文件关联的I/O单元代号
      格式如下:UNIT=int_expr
    • FILE=子句指定要打开的文件名
      格式如下:FILE=char_expr
    • STATUS=子句指定要打开文件的状态
      格式如下:STATUS=char_expr
    • ACTION=子句指定一个文件是否以只读、只写或读写方式打开。
      格式如下:ACTION=char——expr
    • IOSTAT=子句指定一个整数变量名,打开操作的状态可以返回到这个变量中。
      格式如下:IOSTAT=int_var
    • IOMSG=子句指定一个字符变量名,如果发生错误,它就包含错误信息。(FRTRAN 2003特性)
      格式如下:IOMSG=chart_var
  2. CLOSE语句
    close语句关闭一个文件并释放与之关联的I/O单元代号
    格式如下:CLOSE(close_list)
    close_list必须包含一个指定I/O单元代号的子句,还可以指定其他选项。

    • READ语句中的IOSTAT=和IOMSG=子句
      当使用磁盘文件时,可以给READ语句增加IOSTAT=和IOMSG=子句
      格式:IOSTAT=int_var
      int_var是整型变量,如果READ成功执行,返回0。如果失败,返回一个相对应的错误整数。如果到达输入数据文件的尾部而使语句执行失败,就给该变量返回一个负数。
    • 文件定位
      BACKSPACE语句,每次调用它可以回退一个记录;BACKSPACE(UNIT=unit)
      REWIND语句,可以在文件头重新开始文件。语句格式:REWIND(UNIT=unit)

数组

  1. 声明数组
    数组的声明包含元素类型和个数。
    例如:声明16个元素的实型数组voltage,REAL,DIMENSION(16)::voltage
    DIMENSION属性说明被定义数组的大小。
  2. 在Fortran语句中使用数组元素
    数组元素初始化三种方式:
  3. 赋值语句初始化数组
  4. 编译时在类型声明语句中初始化数组
    用数组构建器声明相应语句中数组的初始值(/..../)
    隐式DO循环,常规格式:(arg1,arg2,...,index=istart,iend,incr)
    为指定下标的取值范围,可以在声明语句中包含起始下标和结束下标的数据,其间用冒号隔开。
    REAL,DIMENSION(lower_bound:upper_bound)::array
    大多数fortran编译器越界检查可选,打开这个选项,程序运行很慢,可以关闭越界检查,程序运行会快。
    • 在数组声明中使用有名常数
      用简单修改单个有名常数MAX_SIZE可以轻易改变所有数组的大小。
  5. 用READ语句初始化数组

fortran语句中使用整个数组和部分数组

  1. 操作部分数组
    局部数组被称为部分数组。部分数组用下标三元组或向量下标代替数组下标来指定
    常见形式:subscript_1:subscript_2:stride
    subscript_1是包含在部分数组中的第一个下标,subscript_2包含在部分数组中的最后一个下标,stride是遍历数据集时的下标增量。

输入和输出

  1. 数组元素的输入和输出
  2. 隐式DO循环
    隐式DO循环的WRITE和READ语句
    WRITE(unit,format) (arg1,arg2,...,index=istart,iend,incr)
    READ(unit,format)(arg1,arg2,...,index=istart,iend,incr)

  3. 整个数组和部分数组的输入和输出


过程

fortran可以在构建最终的程序前较容易地独立开发和调试子任务,可以把每个子任务作为独立的程序单元来编码,该独立程序单元被称为外部过程,每个外部过程都可以独立于程序中的其他子任务来进行编译、测试和调试。
Fortran有两种外部过程:子程序和函数子程序。
- 子程序通过在一个单独的CALL语句中引入子程序名来进行调用,并且可以通过调用参数来返回多个结果,
- 通过在表达式中引入函数名来进行调用,它的结果是单个数值,该值用来为表达式赋值。

子程序

子程序(subroutine)是一个fortran子过程,通过在CALL语句中使用过程名来调用,并通过参数表来获取输入参数,返回计算值,子程序的通用格式如下:
SUBROUTINE subroutine_name (argument_list)
...
(Declaration section)
...
(Execution section)
...
RETURN
END SUBROUTINE [name]

SUBROUTINE语句标志着子程序的开始,定义子程序名和相关参数表。
子程序命名遵循fortran命名规则:由字母和数字组成,最大31个字符,第一个字符必须为字母。
子程序必须包含声明部分和执行部分。当程序调用子程序时,调用程序的执行暂时被挂起,子程序执行部分开始运行。当运行到子程序的RETURN语句或END SUBROUTINE语句时,调用程序又开始运行调用子程序语句下面的代码。

调用程序使用CALL语句来调用子程序。CALL语句的格式如下:
CALL subroutine_name (argument_list)
1. INTENT属性
子程序的形参可以与一个INTENT属性联合使用。INTENT属性与类型声明语句联合使用,来声明每个形参的类型。可以写成下列中的形式:
INTENT(IN) 形参用于向子程序传递输入参数
INTENT(OUT) 形参仅用于将结果返回给调用程序
INTENT(INOUT) 形参用来向子程序输入数据,也用来向调用程序返回结果

  1. Fortran中的变量传递:地址传递方案
    Fortran程序和它的子程序之间用地址传递方案来进行通信。
    当调用子程序时,主程序传递一个指针来指向实参表中各个参数的存储位置。子程序查找调用程序所指向的内存位置,以获得它需要的形参值。
  2. 传递数组给子程序
    子程序中3种可能方式指明形参数组的大小。
    第一种方法实在子程序调用时,将数组每一维度的边界值传递给子程序,并且声明相应的形参数组为该长度。
    第二种方法是把子程序中的所有形参数组声明为不定结构的形参数组,以创建一个子程序的显示接口。
    第三种方法是用星号(*)来声明每一个形参数组的长度,这些数组被看成是不定大小的形参数组。(早期行为)
  3. 传递字符变量给子程序
    当一个字符变量被作为子程序的形参时,用*来声明字符变量的长度。因为没有实际给形参分配内存,所以在编译时不是必须直到字符参数的长度。
  4. 子程序中错误处理
    永远不要在子程序用使用stop语句

用模块共享数据

除了参数表之外,Fortran程序、子程序以及函数也可以通过模板来交换数据。
模块是一个独立编译的程序单元,包含了在程序单元间共享的数据的定义和初始值。
如果程序单元中使用了包含模块名的USE语句,则在那个程序单元中可以使用模块中定义的数据。使用同一个模板的程序单元可以访问同样的数据。模块是一个程序提供单元共享数据的方式。
模块以MODULE语句来表示开始,该语句指明了模块的名字。模块名的最大长度可达31字符。模块以END MODULE语句结束。
SAVE语句能够保证在模块中声明的数据被保护在不同过程间的引用中,所以共享数据应该始终被声明在模块中。
要使用模块中的数值,程序单元必须使用USE语句声明模块名。USE语句格式如下:USE module_name
USE语句必须出现在程序单元中的其他语句之前,除了PROGRAM或SUNROUTINE语句,也除了可以出现在任意位置的注释语句。用USE语句来访问模块中的数据被称为USE关联。

模块过程

模块除了可以有数据之外,还可以有完整的子程序和函数,他们被称为模块过程。
过程被当作模块的一部分进行编译,并且通过在程序单元中使用包含模块名的USE语句,从而可以在模块过程在程序单元中有效。包含在模块中的过程必须跟在模块的数据声明后面,前面加上CONTAINS语句。

Fortran函数

两种不同类型的函数:内部函数和用户自定义函数。
用户自定义Fortran函数的通用格式如下:

    ...    (Declaration seciton must declare type of name)    ...    (Execution section)    ...    name=expr    RETURN     END FUNCTION [name]

用户自定义函数的类型声明可以采用两种等价格式之一来完成:
INTEGER FUNCTION my_function(i,j)

FUNCTION my_function(i,j)
INTEGER::my_function

过程作为参数传递给其他过程

只有在调用和被调用函数中,才能被声明为外部量时,用户自定义函数才可以当作调用参数传递。当参数表中的某个名字被声明为外部变量,相当于告诉编译器在参数表章传递的是独立的已编译函数,而不是变量。
用EXTERNAL属性或者EXTERNAL语句可以声明函数为外部的,EXTERNAL属性像其他属性一样包括在函数声明语句中。
子程序可以作为调用参数传递给过程。


数组的高级特性

二维数组

  1. 声明二维数组
    例如:REAL,DIMESION(3,6)::sum
    INTEGER,DIMESION(0,100,0,20)::hist
    CHARACTER(len=6),DIMESION(-3,3,10)::counts
  2. 二维数组的存储
    fortran以列来存储对象,不是以行的顺序(c/c++)来存储。
  3. 初始化二维数组
    • 用赋值语句对二维数组初始化
      用循环语句赋值(DO END DO)或者RESHAPE函数
      RESHAPEh函数格式:output=RESHAPE(array1,array2)
      array1包含了要在改变结构的数据,array2描述新结构的一维数组。array2中的元素个数是输出数组的维数,array2数组中的元素值是每个维度的宽度。
    • 用类型声明语句对二维数组初始化
      也要使用RESHAPE函数
    • 用READ语句初始化二维数组
      如果在一条READ语句的参数列表中出现了一个没有下标的数组名,程序将会为数组中的所有元素读取数值,这些数值将会按照数组元素在计算机内存中的逻辑顺序为数组赋值。

5.整数数组的操作和部分数组
只要两个数组一直,就可以在数学运算和赋值语句中使用。
可以使用下标三元组或者下标向量从二维数组中选取部分数组,a(:1)选用的部分数组对应的是数组的第一列,a(1:)选用的部分数组是数组的第一行。

多维数组

为n维数组分配内存采用的方式是二维数组以列序分配的方式扩展。

对数组使用fortran内置函数

  1. 查询内置函数
函数名称和调用序列 用途 ALLOCATED(ARRAY) 判断可分配数组的分配状态 LBOUND(ARRAT,DIM) 如果缺少DIM,返回所有的ARRAY下界,如果给出了DIM,返回指定的ARRAY下界 SHAPE(SOURCE) 返回数组SOURCE结构 SIZE(ARRAY,DIM) 如果给出了DIM返回指定维度的ARRAY的宽度,否则返回数组中元素的总个数 UBOUND(ARRAY,DIM) 如果缺少DIM,返回所有的ARRAY上界,如果给出了DIM,返回指定的ARRAY上界

加掩码的数组赋值:WHERE语句

WHERE结构常用格式: [name:] WHERE(mask_expr1)                    Array Assignment Statement(s)                   ELSEWHERE (mask_expr2) [name]                    Array Assignment Statement(s)                  ELSEWHERE  [name]                    Array Assignment Statement(s)                   END WHERE [name]

FORALL结构

该结构允许一系列操作用于数组中部分元素,且是逐个用到数组元素上的。被操作的数组元素可以通过下标索引和通过逻辑条件进行选择。
格式如下:
[name:] FORALL(in1=triplet1[,in2=triplet2,…,logical_expr])
statement1
statement2

statement3
END FORALL [name]

FORALL语句中的每个索引都是通过下标的三元组形式来指定的。subscript_1:subscript_2:strid
subscript_1是索引的开始值,subscript_2是结束值,stride是增量值。

  • fortran95在类型声明语句中使用ALLOCATABLE属性来声明动态分配内存的数组,使用ALLOCATE语句实际分配内存,当程序使用完内存之后,使用EDALLOCATE语句释放内存。
    REAL,ALLOCATABLE,DIMENSION(:,:)::arr1
    数组实际的大小,声明中使用冒号作为占位符。
    用冒号来代表它维度的数组称为预定义结构数组。
    执行程序的时候,数组的实际大小通过ALLOCATE语句来指定。
    ALLOCATE语句格式如下:ALLOCATE(list of arrays to allocate,STAT=status)
    STAT=子句是可选的,出现了,将返回一个整数状态值。分配成功状态为0,失败出现一个正数。
    Fortran提供一个逻辑型内置函数ALLOCATED(),允许程序在使用数组之前先测试它的分配状态。

过程的附加特性

给子程序和函数传递多维数组

多维数组可以像一维数组那样传递给子程序或者函数。为了能够正确的使用数组,子程序或者函数需要直到数组的维数和每一维度的宽度。
1. 显式结构的形参数组
将数组或数组中的每一维度的取值返回传递给子程序,范围值用于在子程序中声明数组的大小。
2. 不定结构的形参数组
在子程序中声明所有的形参数组为不定结构的形参数组。声明不定结构的形参数组,数组中的每个下标都用冒号来代替。只有子程序或者函数有显示接口,才能使用这种数据。

save属性和语句

save在调用过程之间不修改保存的局部变量和数组
SAVE属性出现在类型声明语句中,在调用过程间,任何一个用SAVE属性定义的局部变量都会被保存,而不改变。
如果一个过程需要局部变量的值在连续调用时不被修改,那么应该在变量的类型声明语句中使用SAVE属性。或者在SAVE语句中包含该变量或者在变量的类型声明语句中初始化它。

原创粉丝点击