Fortran中的数据类型包含:
整数类型(
INTEGER
)、浮点数类型(REAL
)、字符类型(CHARACTER
)、复数类型(COMPLEX
)和逻辑变量(LOGICAL
)
参考书籍:彭国论.Fortran 95程序设计
文章目录
在Fortran中,声明时变量需注意:
- 变量的名称的前缀
必须
为英文字母,变量的名称可以包含字母、下划线及数字。 - 变量名字的长度,Fortran 90后变量名称最大支持31个字符长,而Fortran 77最大支持6个字符长。
- 变量名称的命名不能与Fortran的执行命令同名,也不能和主程序或者已经声明过的变量同名。
- Fortran中
不区分大小
写,因此abc、ABC以及aBc均为一个意思。
变量
整数类型(INTEGER)
整数顾名思义,用于存放整数,C语言中用
int
声明整型,Fortran中用integer
声明整型。
1)整数的声明
integer a
A=10
其中:
- integer表示整型类型,a表示整型变量
- 因为Fortran不区分大小写,因此a与A对应的是同一个变量
2)长整型与短整型
整数类型又分为长整型和短整型,其声明方法如下:
长整型:
integer(kind=4) a !Fortran 90
INTEGER*4 b !Fortran 77
INTEGER(4) C !Fortran 77
短整型:
integer(kind=2) a !Fortran 90
INTEGER*2 b !Fortran 77
INTEGER(2) C !Fortran 77
这里的4、2对应着长整型和短整型分别占用4个、2个字节(bytes)的空间。如果在声明时不指定字节大小,通常编译器会默认使用长整型。
3)一次声明多个变量
与C语言一样,Fortran在同时声明多个相同类型的变量时,变量之间可以用逗号
隔开。
integer a,b,c
除了上述的声明方式外,Fortran 90还可以在类型的后面先写::
,再声明变量名。
integer :: a
**注意:**与C语言一样,Fortran中两个整型变量做除法时,如果结果中含有小数部分,小数部分会被省略,只保留整数部分计算结果。
浮点数(REAL)
C语言用float和double来存储单精度和双精度类型,而Fortran中用REAL表示浮点数,通过改变KIND值来存储不同精度的小数。
1)单精度浮点数
real(kind=4) a
real*4 b
real(4) c
2)双精度浮点数
real(kind=8) a
real*8 b
real(4) c
3)浮点数中的有效位数
program test1
implicit none
integer(kind=4) a,b
a=100000
b=0.1
write(*,*) a+b
pause
end program test1
上述代码中:
- a=100000,b=0.1,a+b的结果应该是100000.1,但是测试结果却是100000
- 这是因为a和b是4个字节,计算机在存储浮点数时是以科学计数法进行存储的,单精度浮点数有效位数为6位,转换成科学计数法时,超过6位的数字会被忽略
- 将上述代码中‘kind=4’改成‘kind=8’即可得出正确答案,双精度浮点数拥有15位的有效数字
此外,Fortran中还有一些复杂的数学函数,例如三角函数:sin、cos、tan,Fortran中三角函数使用的单位是
弧度
,这一点大多数编程语言都是如此。在进行三角函数传参时,传入的参数不要是整数,也不要将sin的结果用整型去接收,因为这将会导致小数部分被省略掉。
三角函数运算示例:
program test2
implicit none
real :: x,y
x=3.1415926/2
y=sin(x)
write(*,*) "sin(",x,")=",y
end program test2
Fortran中乘幂计算可以用
**
来进行计算,将幂乘的数改为小数即变成开方,也可以使用sqrt
函数进行计算
平方与开方示例:
program test3
implicit none
real :: a=100
write(*,*) "2^3=", 2**3
write(*,*) "sqrt(",a,")=", sqrt(a)
write(*,*) "sqrt(",a,")=", 100**0.5
end program test3
结果如下:
2^3= 8
sqrt( 100.000000 )= 10.0000000
sqrt( 100.000000 )= 10.0000000
复数(COMPLEX)
Fortran是罕见的提供复数类型的语言,Fortran中通过两个浮点数来保存实部和虚部的数,因此复数也分单精度和双精度
1)复数的声明:
complex a
或者complex :: a
同理,通过kind
值来控制复数是单精度还是双精度,方法如下:
!单精度
complex(kind=4) a !fortran 90
complex*4 a !fortran 77
complex(4) a !fortran 77
!双精度
complex(kind=8) a !fortran 90
complex*8 a !fortran 77
complex(8) a !fortran 77
复数的赋值方法:a=(x,y)
,例如:a=(1.5,1.0)
表示a=1.5+1.0i
;不难看出,一个复数需要三个浮点数。
2)复数计算示例:
program test4
complex :: a,b
a=(1.0,1.0)
b=(2.0,-1.0)
write(*,*) a,"+",b,"=",a+b
write(*,*) a,"*",b,"=",a*b
end program test4
结果如下:
( 1.00000000 , 1.00000000 ) + ( 2.00000000 , -1.00000000 ) = ( 3.00000000 , 0.00000000 )
( 1.00000000 , 1.00000000 ) * ( 2.00000000 , -1.00000000 ) = ( 3.00000000 , 1.00000000 )
字符及字符串(CHARACTER)
Fortran中不区分大小写,但是字符串中的内容是区分大小写的,例如:“Hello World!”和“hello world!”是两个不同的字符串。
利用
len
可以控制字符串的大小,方法如下:
1)字符和字符串声明
character a !单个字符a
character(len=10) a !用于存放十个字符 90写法
character*=10 a !77写法
character(10) a
2)字符串赋值
- 用双引号赋值(Fortran 90写法)
a="Hello World!"
a="每天都要学习""Fortran"""
用双引号,封装字符串时,如果想输出双引号,需要连用两个双引号""
- 用单引号赋值(Fortran 77写法)
a='Hello World!'
a='每天都要学习''Fortran'''
同理,用单引号封装字符串时,如果想输出单引号,需要连用两个单引号''
3)更改字符串指定内容
Fortran中除了可以对字符串进行直接赋值外,还支持更改字符串中特定位置的内容
例如:
program test5
character(len=20) a
a="I love you!"
write(*,*) a
a(3:6)="hate"
a(11:11)"?"
write(*,*) a
end program test5
I love you!
I hate you?
其中:a(3:6)="hate"
的意思是将a中第3个字符到第6个字符的内容改成hate,a(11:11)"?"
的意思是只更改第11个字符,改成问号。
4)字符串相加
字符串
相加
不是数字意义上的相加,是将两个字符串进行前后拼接在一起。
字符串相加格式:arr=A//B
,示例如下:
program test6
character(len=6) a
character(len=10) b
character(len=20) c
a="Hello"
b="World!"
c= a//b
write(*,*) c
end program test6
**需要注意的是:**这里字符串a
和b
中都没有空格,但是打印出来的结果Hello World!
是有空格的,这是因为a
的长度为6,而字符串Hello
只有5个字符,在拼接时,多出来的位置会以空格显示。不难看出,//
会根据最大字符数很粗暴的将字符串首位相连。
5)与字符串有关的函数
函数 | 说明 |
---|---|
char(num) | num必须为整数,返回ASCII码值对应的字符 |
ichar(char) | 返回字符char所对应的ASCII码值 |
len(string) | 返回字符串string声明的长度,返回值为整数 |
len_trim(string) | 返回字符串去掉尾端空格后的实际长度 |
index(strng,key) | string和key均为字符串,用于查找字符串key第一次在string中出现的位置 |
trim(string) | 返回字符串string去掉尾端空格后,剩下的字符串内容 |
示例:
program test7
character(len=20) a="hello world! "
write(*,*)"ASCII码97的字符是:",char(97)
write(*,*)"a的ASCII码值是:",ichar('a')
write(*,*)"a的长度是:",len(a)
write(*,*)"a的实际长度:",len_trim(a)
write(*,*)"word第一次出现位置是:",index(a)
write(*,*)"a去掉尾端空格后的内容:",trim(a)
end program test7
打印结果如下:
ASCII码97的字符是:a
a的ASCII码值是: 97
a的长度是: 20
a的实际长度: 11
word第一次出现位置是: 7
a去掉尾端空格后的内容:hello world
因为使用的是默认格式,因此打印结果会有些丑陋。
逻辑变量(LOGICAL)
逻辑变量主要用于逻辑判断时使用,逻辑变量
.true.
和.false.
只占用1个字节,因此虽然也可以同kind去为逻辑变量设置空间大小,但实际上的意义不大。
逻辑变量声明:logical a
设置逻辑变量的方法如下:
program test7
implicit none
logical a
a=.true.
write(*,*) a
a=.false.
write(*,*) a
end program test7
用write打印逻辑变量只会显示
T
或者F
T
F
常量
常量的声明方法
格式:parameter(变量名=变量值)
例如:
real pi
parameter(pi=3.1415926)
在Fortran90中,parameter可以作为一个形容词,和变量的声明同时写在一起。
real,parameter :: pi=3,1415926
注意,变量前的冒号不能省略,冒号表示形容词已经形容完毕。
设置常量的优点
- 保护设成常量的值
- 增加程序的执行速度。使用变量时:CPU先要从它的内存位置中取出数值,再放到CPU的缓存器中使用。而在使用常数时,执行过程中可以直接把数字写入缓存器中,节省了到内存去“抓取”变量数据的时间。
设置变量的初值
上文中,已经有过设置变量值的例子,这里再详细的刨析一下。
变量的内容不一定要在程序执行时才设置,可以在声明时同时赋值。Fortran90中,允许在声明时直接给变量赋值,但是不能省略中间的冒号,例如:
integer :: a=10
real :: b=10.5
complex :: c=(1.0,2.0)
character(len=20) :: d="hello world!"
Fortran 77中要使用DATA命令来设置初值,虽然该方法比较麻烦,但还是需要能看懂这种写法的意思。
integer a
real b
complex c
character*(20) d
DATA a.b.c.d /10,10.5,(1.0,2.0),'hello world!'
DATA命令根据变量的次序一次赋值。
等价声明(equivalence)
把两个或两个以上的变量,声明它们使用用一块内存地址,就是等价声明。
因为使用同一块内存,因此只要改变其中一个变量的值,就会改变其他变量的数值。
等价声明格式:equivalence(a,b)
等价声明的优势:
- 节省内存:在同一个等价声明中的变量,都会占据同一块内存,会同时改变内容。这个功能可以声明一些暂时使用的变量,节省内存的使用。
- 精简代码:假设有一个三维数组
arr
,其中数组的某个值是需要多次使用的,那么将这个值与变量a进行等价声明,写代码时只需要调用a即可,例如equivalence(arr(1,1,5),a)
。
声明在程序中的结构
声明的位置应该放在程序代码的可执行描述之前,在程序开始出现数值计算和输入输出命令时,就不能再声明变量。
声明部分的程序代码在编译后,并不会生成任何的机器码。因为声明只是用来请编译器预留内存空间给程序使用,所以不被视为可执行描述。
如果使用DATA命令,DATA也算是声明的一部分,它也只能放在执行命令前,而且所要设置初值的变量最好先声明它的类型。