Eastsheng's Wiki

Fortran-04

2022-07-24 18:11:28

[toc]

数据类型

  • F90程序中的数据都有三个特征:类型、种别、属性.
  • 一般形式:类型说明[(种别说明)][,属性说明] :: 变量名[=初值]
  • 例:REAL(KIND=2), DIMENSION(1:10):: X,Y
  • 种别说明与属性说明可以省略,类型说明:: 变量名

类型说明

> 三种数值型:整数型(`INTEGER`)、实数型(`REAL`)、复数型(`COMPLEX`)
> 两种非数值型:逻辑型、字符型
  • 在F90中,每个变量名都应该在说明部分中说明其类型,不应该使用隐式说明,应该在程序说明部分开始就写出语句:IMIPLlCIT NONE,既声明不使用隐式说明。

种别说明

  • 种别值确定了数据的大小范围和精度。有了种别说明后,程序更易于移植。(因为在不同的计算机系统上,同一种变量类型可以有不同的精度,因此当程序在另一种机子上运行时可能出现溢出或下溢。规定种别后可以避免这种情况的出现。)
  • 种别由种别选择符说明,写在类型关键字后括号内,其关键字是KIND,后跟=号及种别值。其形式为:类型说明([KIND=]种别值)
  • 一个变量必有一个种别,如果变量的类型说明语句中没有种别说明符,说明采用系统规定的标准值。
种别函数
  • KIND(X):与python中的type(x)相似;

属性说明

  • 一个对象被说明具有某一属性时,就使该对象具有某种附加功能、特殊的使用方式与适用范围。
  • 一个被说明对象可以没有附加的属性说明,此时它只是最基本的变量,与F77中的变量相同。
  • 它也可以有多个属性说明,分别对被说明对象附加各件功能,规定它在各种场合下的使用方式。
  • 每种属性说明都有专门的关键字,各属性关键字间用逗号分开,全部属性关键字写在说明语句种别说明符之后,双分隔号::之前,各属性关键字之间次序任意。属性不仅用于说明数据,还用于说明过程。
  • 常见属性:
属性关键字 描述 适用范围
ALLOCATABLE 说明动态数组 数组
DIMENSION 说明数组 数组变量
PARAMETER 声明常量 常量

输入实数x,求下面的函数值–逻辑变量赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
! 逻辑变量的赋值
program main
implicit none
real :: x,y
logical :: in_side

print*," x^2 (1<x<2)"
print*,"y = {"
print*," 1-x (x<=1, x>=2)"
print *, "请输入x值:"
read *,x
print *,"x=",x
in_side=x>1.0.and.x<2.0 !这里赋值给in_side一个逻辑值,是或否
if(in_side) then
y = x**2
else
y = 1-x
end if
print *,"y= ",y

end program main

字符型数据

  • 字符型数据除了有类型、种别外,比其它类型还多了一个长度特性,即规定它有几个字符数
  • 一般形式:CHARACTER[(LEN=整型字符长度表达式[,KIND=种别值])][,属性说明] :: 变量名表[=初始值]
  • 在字符型说明语句中,长度说明必须有,不可省略,为正整数;
  • 仅有关键字CHARACTER而没有括号时认为字符是一个字节长;
  • 可以省去LEN=及KTND=,只写参数值,此时字符长度必须写在前面;
  • 只有长度说明的语句可分为有括号和无括号两种,例如以下语句都是等价的:
    1
    2
    3
    4
    5
    6
    7
    8
    CHARACTER(LEN=12,KIND=1) :: A,B
    CHARACTER(KIND=1,LEN=12) :: A,B
    CHARACTER(12,1) :: A,B
    CHARACTER*12 :: A,B
    ```
    - 长度也可以写成一个*号,表示长度暂不确定,待以后与程序中实际需要的长度相一致,如:
    ```f90
    CHARACTER(LEN=*),PARAMETER :: C_NAME=‘GIRL’
  • 说明字符常量C_NAME,长度为4

  • PARAMETER表示常量。

  • CHARACTER后面说明的长度是其后所有实体名的公共长度,如果某一变量的长度与其它不同,可以在其变量名后标出自己的特有长度,例加:

    1
    CHARACTER(LEN=12) :: A,B*5,C,D*7,E

字符串操作

  • 形式基本和python相似,差别是形式不同,
    1
    2
    3
    A = "ABCDEFG"
    A[1:5] #python
    A(1:5) !fortran
  1. 字符串拼接//—并置符
    1
    "AB"//"CDE" ! "ABCDE"
  2. 字符比较

    各种系统字符排序不一样,同一字符,在不同机上排序值可能不一样。
    小写英文字母排序在大写英文字母之后,它们的序号不同。
    虽然在书写FORTRAN语句时,大小写字母是等价的,但当进行字符操作和字符比较时必须看成是不同的。
    字符作比较实际上是比较它们的序号大小。

字符函数

  • F90允许把字符型的值转换成整型值(已知字符,取字符型的序号数值),

  • 也允许把数值型的值转换成字符型的值(已知序号,取它对应的字符)。

  • 字符与数值相互转换的函数(F90的内部函数):ICHAR,CHAR,IACHR,ACHAR

  • 函数ICHAR的功能是把字符型转换成数值,它的引用方式是:ICHAR(字符实体)

    函数值ICHAR返回字符实体第一个字符的序号值
    如果指明要按照ASCII码求它的序号,则本功能的函数名应改写为IACHAR

  • 函数CHAR的功能是把一个序号转换成它的字符。它的引用方式是:CHAR(整型数值表达式)

    如果按照ASCII码求它的对应字符,则函数名为ACHAR

  • 求字符串长度LEN(字符实体)

    函数值返回一个正整教,为该字符实体的长度(包括尾随空格、中间空格在内)

  • 不计尾部空格的字符串长度函数:LEN_TRIM

  • 求子串在父串位置的函数:INDEX(父串,子串)

    如:INDEX("Einstein","s")的值4。
    如果第二个字符实体不是第一个字符实体的子串,返回函数值为0。

  • 验证字符串的函数:VERIFY(字符串,字符集)

    确认指定的字符集是否包含了给定字符串中所有的字符
    函数值返回一个正整数,指明字符串中与字符集相异的第一个字符是从左边第几个字符开始的
    如果没有相异的字符,则返回函数值为0

  • 除去尾部空格函数:TRIM

    TRIM("ABCD 12 ")//"34"的值是"ABCD 1234"

  • 比较字符大小的函数:LGE、LGT、LLE、LLT

派生类型定义

  • 一般形式:
1
2
3
4
5
6
7
8
9
TYPE[,访问属性说明::] 派生类型名 !TYPE是关键字,表示派生类型定义开始

成员1类型说明

……

成员n类型说明

END TYPE [派生类型名]

数组

  • 数组的维数称为秩(rank),F90中规定数组最多可以有7维
  • 某一维中元素的个数称为该维的长度(extent)
  • 数组中所有元素的个数称为数组的大小(size),它等于各维的长度的乘积,数组的大小可以为0
  • 例如:
    1
    2
    REAL A(10,3,2)     ! 秩为3,大小为10×3×2=60,形状为10乘3乘2,或表示成(10,3,2)。
    SHAPE(A) ! 获得数组的形状结果为:(10,3,2)
  • 下标不是从0开始,是从1开始的,例如A(0,0,0)时错误的,A(1,1,1)是正确的

数组声明

1
2
3
4
5
6
7
REAL A(10,2,3) 				! 类型说明
DIMENSION B(10,2,3) ! DIMENSI0N语句
ALLOCATABLE C(:,:) ! ALLOCATABLE语句
POINTER D(:,:,:) ! POINTER语句
REAL, DIMENSION(2,5) :: E ! 类型说明中的DIMENSION属性
REAL, ALLOCATABLE :: F(:,:,:) ! 类型说明中的ALLOCATABLE属性
REAL, POINTER :: G(:,:) ! 类型说明中的POINTER属性
  • 无论何种情况,数组的秩总是要指定的;
  • 数组的大小和形状是否需要声明视数组的形式而定;
  • COMMON语句指定了数组的秩和大小后,只能定义数组的类型而不能再次重复给定维界.

数组索引、切片和赋值

1
2
3
4
5
A            ! 代表数组A中所有元素
A(1) ! 代表数组A中第一个元素
A(1:10:2) ! 三元下标, A(下界:上界:步长), 代表数组A从第1开始到第10,每隔2的元素,也即是第1 3 5 7 9
A(2) = 5.0 ! 给A(2)元素赋值
B(1:5,2:3,3:5) ! 三维数组切片
  • 对于—个多维数组的数组片段,它的每一维都可以用三元下标来声明
  • 三元下标只能算一个下标

向量索引(下标)

  • 向量下标可以以任何顺序来指定数组元素
1
2
3
4
5
6
7
8
9
10
11
12
program main
real A(10),B(5,5) ! 定义一个一维数组A,和二维数组B
integer I(4),J(3) ! 定义向量I、J的大小
I = (/5,3,8,2/) ! 定义向量I,表示第5、3、8、2位置的元素下标
J = (/3,1,5/) ! 定义向量J,表示第3、1、5位置的元素下标
A(I) = 3.0 ! 给一维素组中(向量I)下标为5,3,8,2的元素赋值为3.0
B(2,J)=5.0 ! 给二维素组中第二行中(向量J)下标为3,1,5的元素赋值为5.0
print*,I
print*,A
print*,J
print*,B
end program main

数组赋值

  • F90中数组赋值语句的形式为:V=eV代表数组名或数组片段,e为数组表达式,它们必须有相同的形状(即维数相同,每维长度相同但上下界可不同)。
  • V大小为0或为长度为0的字符型时,则没有值赋给V
  • e为标量时,则把e处理成与V相同的形状,V的每个元素均等于标量e的值。
  • 数组表达式e中允许使用+、-、*、/、**等内部算术操作符。
  • 例如,给A(2,2)中元素全部赋值为0:A = 0

数组构造器

  • 其一般形式为:(/取值列表/),取值列表可以是标量,隐DO循环或任意秩的数组。
1
2
3
4
A1 = (/1,2,3,4,5,6/)            !! 标量表示, 斜杠与括号间不能有空格
A2 = (/B(I,1:5),B(I:J,7:9)/) ! 数组表示
A3=(/(I,I=1,4)/) ! 隐DO循环
A4=(/4,C(1:5),(I,I=1,4),7/) ! 混合表示
  • 斜杠与括号间不能有空格
  • 可以用方括号代替括号和斜线:
    1
    2
    A1 = (/1,2,3,4,5,6/) 
    A1 = [1,2,3,4,5,6]
  • 冒号三元下标(代替隐DO循环)来指定值的范围和步长
1
2
A1 = (/1:6:2/)         !这种三元格式好像不行,老出错,找不到啥原因
A1 = (/(I,I=1,6,2)/)

RESHAPE语句

  • python相似:
  • 一般形式为:结果=RESHAPE(源,形状[,补充][,顺序])
  • 变成两行三列
    1
    RESHAPE((/3,4,5,6,7,8/),(/2,3/))