程序结构:
program main
......
stop
end
end 语句的三种写法(根据 Fortran 90 标准):
end
end program
end program main
这三种写法在功能上是等效的,可以根据编程习惯或代码规范选择使用。
write(*, *) a
第一个 *:输出位置(默认是屏幕,即标准输出)。
第二个 *:不指定输出格式(自由格式输出)。
write(6, *) "string" ! 较严谨写法,6 通常代表屏幕(标准输出)
write(unit=6, fmt=*) "string" ! 最严谨写法,显式指定 unit 和 fmt
unit=6:通常指屏幕输出(但具体数值可能因系统而异)。
fmt=*:表示自由格式输出。
输出双引号:在字符串中输出 " 时,需连用两个双引号 “”。
write(*, *) "This is a ""quoted"" string." ! 输出:This is a "quoted" string.
program example
implicit none
integer :: a = 10
write(*, *) "The value of a is:", a ! 自由格式输出
write(6, '(A, I3)') "Formatted a:", a ! 指定格式输出
end program example
关键点总结
write(*, *) 是最简单的写法,适用于快速输出。
write(unit=6, fmt=*) 更严谨,适用于正式代码。
自动换行,若需连续输出不换行,需调整格式或使用 advance='no'(在 Fortran 95+ 支持)。
双引号转义 使用 ""。
print *, a
*:表示不限定输出格式(自由格式输出)。
无括号:print 语句不使用括号,区别于 write。
print 只能输出到屏幕(标准输出),不能像 write 那样指定输出位置(如文件)。
自动换行:
格式限制:
特性 | print |
write |
---|---|---|
语法 | print *, a (无括号) |
write(*, *) a (带括号) |
输出目标 | 仅屏幕(不能改) | 可指定(如屏幕 6 或文件) |
格式控制 | 仅自由格式 * |
可自由格式 * 或自定义格式 |
严谨性 | 较简单,适合调试 | 更灵活,适合正式代码 |
program example
implicit none
integer :: x = 42
print *, "The value of x is:", x ! 输出到屏幕,自由格式
end program example
基本格式:
read(*,*) a
第一个星号 * 表示输入来源为默认设备(通常是键盘)。
第二个星号 * 表示不指定输入格式,采用自由格式读取。
严谨写法:
read(5,*) a
使用设备号 5(通常代表键盘输入),格式自由。
read(unit=5, fmt=*) a
最严谨的写法,明确指定输入设备(unit=5)和自由格式(fmt=*)。
注意事项:
设备号 5 是传统约定,具体数值可能因编译器或系统而异。
自由格式(*)适合简单输入,复杂数据建议指定明确格式。
integer :: a ! 默认整型,具体字节数取决于编译器(通常为4字节)
Fortran 90 风格(推荐):
integer(kind=4) :: a ! 明确指定4字节整型
Fortran 77 传统风格:
integer*4 :: b ! 4字节整型(旧式写法)
integer(4) :: c ! 4字节整型(旧式写法)
Fortran 90 风格(推荐):
integer(kind=2) :: a ! 明确指定2字节整型
Fortran 77 传统风格:
integer*2 :: b ! 2字节整型(旧式写法)
integer(2) :: c ! 2字节整型(旧式写法)
kind 值(如 kind=4) 取决于编译器,不同系统可能不同。
可移植替代方案:使用 selected_int_kind 函数,如:
integer, parameter :: long = selected_int_kind(9) ! 至少支持9位十进制数
integer(kind=long) :: big_num
标准声明(单精度,通常4字节):
real :: a ! 默认浮点型(单精度,具体字节数取决于编译器)
Fortran 90 风格(推荐):
real(kind=4) :: a ! 明确指定4字节单精度浮点数
Fortran 77 传统风格:
real*4 :: b ! 4字节单精度浮点数(旧式写法)
real(4) :: c ! 4字节单精度浮点数(旧式写法)
Fortran 90 风格(推荐):
real(kind=8) :: a ! 明确指定8字节双精度浮点数
Fortran 77 传统风格:
real*8 :: b ! 8字节双精度浮点数(旧式写法)
real(8) :: c ! 8字节双精度浮点数(旧式写法)
Fortran 90 风格:
real(kind=16) :: a ! 16字节扩展精度浮点数(部分编译器支持)
Fortran 77 风格:
real*16 :: b ! 16字节扩展精度浮点数(非标准,部分编译器支持)
可移植替代方案:使用 selected_real_kind 函数,如:
integer, parameter :: dp = selected_real_kind(15, 307) ! 至少15位有效数字,指数范围±307
real(kind=dp) :: double_num
标准声明(单精度复数,实部和虚部各占4字节):
complex :: z ! 默认复数类型(单精度,实部和虚部均为 `real` 类型)
Fortran 90 风格(推荐):
complex(kind=4) :: z ! 单精度复数(实部、虚部均为 `real(4)`)
Fortran 77 传统风格:
complex*4 :: z1 ! 单精度复数(旧式写法)
complex(4) :: z2 ! 单精度复数(旧式写法)
Fortran 90 风格(推荐):
complex(kind=8) :: z ! 双精度复数(实部、虚部均为 `real(8)`)
Fortran 77 传统风格:
complex*8 :: z1 ! 双精度复数(旧式写法)
complex(8) :: z2 ! 双精度复数(旧式写法)
直接赋值:
complex :: z
z = (1.0, 2.0) ! 实部=1.0,虚部=2.0(默认单精度)
双精度复数赋值:
complex(kind=8) :: z
z = (1.0d0, 2.0d0) ! 使用 `d0` 表示双精度常量
kind=4 对应单精度(real(4)),kind=8 对应双精度(real(8))。
可移植写法建议使用 selected_real_kind 定义 kind:
integer, parameter :: dp = selected_real_kind(15, 307) ! 双精度
complex(kind=dp) :: z
complex(kind=8) :: z1, z2, z_sum
z1 = (1.0d0, 2.0d0) ! 1 + 2i
z2 = (3.0d0, 4.0d0) ! 3 + 4i
z_sum = z1 + z2 ! 结果为 (4.0d0, 6.0d0)
单字符声明:
character :: ch ! 声明单个字符(默认长度为1)
Fortran 90 风格(推荐):
character(len=10) :: str ! 声明长度为10的字符串
Fortran 77 传统风格:
character(10) :: str1 ! 长度为10的字符串
character*10 :: str2 ! 旧式写法
character*(10) :: str3 ! 旧式写法
character(len=10) :: str
str = "Hello" ! 赋值后,str为"Hello "(剩余部分用空格填充)
动态截断或填充:
Fortran 会自动截断超长字符串或用空格填充不足部分。
子字符串操作:
character(len=10) :: str = "ABCDEFGHIJ"
str(2:5) = "1234" ! 修改部分内容,结果为"A1234FGHIJ"
字符串连接(使用 // 操作符):
character(len=5) :: s1 = "Hello"
character(len=6) :: s2 = "World!"
character(len=11) :: s3
s3 = s1 // s2 ! 结果为"HelloWorld!"
动态长度字符串(Fortran 2003+):
character(len=:), allocatable :: dyn_str ! 可动态分配长度的字符串
dyn_str = "Flexible length" ! 自动分配所需长度
program string_example
implicit none
character(20) :: string
string = "Good morning."
write(*,*) string ! 输出: Good morning.
string(6:) = "evening."
write(*,*) string ! 输出: Good evening.
string(3:3) = '!'
write(*,*) string ! 输出: Go!d evening.
string(1:2) = '60'
write(*,*) string ! 输出: 60!d evening.
stop
end program string_example
子串索引:
string(start:end):从 start 到 end 的子串。
string(start:):从 start 到字符串末尾。
空格填充:
Fortran 固定长度字符串始终用空格填充未使用的部分。
错误处理:
原代码 string([3:1:3]=‘!" 语法错误,应为 string(3:3) = ‘!’。
字符串赋值需用单引号(’)或双引号(")包裹。
program example ! 程序开始,名称为 example
character(20) :: string ! 声明长度为20的字符串变量 string
character(30) :: add ! 声明长度为30的字符串变量 add
string = "Good morning." ! 为 string 赋值(13字符,剩余7空格填充):"Good morning. "(7个尾部空格)
add = string // "Fortran!" ! 连接 string 和 "Fortran!",结果存入 add
write(*, *) add ! 输出 add 的内容:"Good morning. Fortran! "(尾部补2空格)
stop ! 程序终止
end program example ! 程序结束
program improved_example
implicit none
character(20) :: string = "Good morning."
character(len=:), allocatable :: add ! 动态长度
add = trim(string) // " Fortran!" ! 精确连接
write(*, '(a)') 'Result: ', add ! 格式化输出
end program improved_example
显式修剪空格:
使用 trim 函数移除尾部空格后再连接:
add = trim(string) // " Fortran!" ! 输出:"Good morning. Fortran!"
Fortran 字符串处理函数总结:
函数名 | 功能描述 | 示例 |
---|---|---|
char(num) |
返回 ASCII 字符表中数值 num 对应的字符 |
char(65) → 'A' |
ichar(char) |
返回字符 char 对应的 ASCII 码(整数) |
ichar('A') → 65 |
len(string) |
返回字符串声明时的固定长度(包括空格) | len("Hello ") → 8 (若声明为 character(8) ) |
len_trim(string) |
返回字符串去除尾部空格后的实际长度 | len_trim("Hello ") → 5 |
index(string, key) |
返回子串 key 在 string 中第一次出现的起始位置(未找到则返回 0) |
index("Fortran", "ran") → 4 |
trim(string) |
返回去除尾部空格后的字符串(不改变原字符串) | trim("Hello ") → "Hello" |
program string_functions
implicit none
character(15) :: s = " Fortran "
print *, "char(65): ", char(65)
print *, "ichar('A'): ", ichar('A')
print *, "len(s): ", len(s)
print *, "len_trim(s): ", len_trim(s)
print *, "index(s, 'ran'): ", index(s, 'ran')
print *, "trim(s): '", trim(s), "'"
end program string_functions
输出
char(65): A
ichar('A'): 65
len(s): 15
len_trim(s): 8
index(s, 'ran'): 6
trim(s): ' Fortran'
program example
character(20) :: string ! 声明长度为20的字符串
string = "Good morning." ! 赋值(13字符 + 7空格填充)
write(*,*) len(string) ! 输出: 20(声明长度)
write(*,*) len_trim(string) ! 输出: 13(实际有效长度)
stop
end program example
函数 | 说明 | 示例输出 |
---|---|---|
len(string) |
返回字符串的声明长度(固定值,包含空格) | 20 |
len_trim(string) |
返回字符串去除尾部空格后的实际长度 | 13 |
logical :: a, b ! 声明逻辑变量
a = .true. ! 赋值为真
b = .false. ! 赋值为假
关键特性
取值:仅有两个值:.true. 和 .false.(注意前后点号)。
默认值:未初始化的逻辑变量值取决于编译器(通常为 .false.)。
运算与用途
逻辑运算符:
.and. .or. .not. .eqv.(逻辑等价) .neqv.(逻辑不等价)
if (a .and. .not. b) then
print *, "条件成立"
end if
格式控制符 | 描述 |
---|---|
Aw | 以w个字符宽来输出字符串 |
BN | 定义文本框中的空位为没有东西,在输入时才需要使用 |
BZ | 定义文本框中的空位代表0,在输入时才需要使用 |
Dwd | 以w个字符宽来输出指数类型的浮点数,小数部分占d个字符宽 |
Ewd[Ee] | 以w个字符宽来输出指数类型的浮点数,小数部分占d个字符宽,指数部分占e个字符 |
ENwd[Ee] | 以指数类型来输出浮点数 |
ESwd[Ee] | 以指数类型来输出浮点数 |
Fwd | 以w个字符宽来输出浮点数,小数部分占d个字符宽 |
Gwd[Ee] | 以w个字符宽来输出任何种类的数据 |
Iw[m] | 以w个字符宽来输出整数,最少输出m个数字 |
Lw | 以w个字符宽来输出T或F的真假值 |
nX | 在输出的位置前添加n个空格 |
/ | 换行 |
: | 在没有更多数据时结束输出 |
kP | k值控制输入输出的scale |
Tn | 输出的位置移动到本行的第n列 |
TLn | 输出的位置向左相对移动n列 |
TRn | 输出的位置向右相对移动n列 |
SP | 在数值为正时加上“正号” |
SS | 取消SP |
以下是Fortran 90添加的格式:
格式控制符 | 描述 |
---|---|
Bw[m] | 把整数转换成二进制来输出,输出会占w个字符宽,m值可以不给定 |
Ow[m] | 把整数转换成八进制来输出,输出会占w个字符宽,m值可以不给定 |
Zw[m] | 把整数转换成十六进制来输出,输出会占w个字符宽,m值可以不给定 |
program example
integer :: a = 20
write(*,"(I4)") a ! 格式化输出:" 20"
write(*,*) a ! 自由格式输出:"20"
end program example
格式字符串需用双引号包裹:“(I4)”
等效于独立的 format(I4) 语句,但更简洁
字母 I 表示整型,4 控制输出宽度
格式化输出:需要对齐数据时(如生成表格)
write(*,"('Value=',I4)") a ! 输出:"Value= 20"
调试输出:快速查看变量值
write(*,*) "Debug:", a ! 输出:"Debug: 20"
I:整型(如 I5)
F:浮点型(如 F8.2)
A:字符型(如 A10)
嵌入式格式中,多个变量需用逗号分隔:
write(*,"(I4,F6.2)") num, value
program example
integer :: a = 20, b = 10
write(*,"(4I4)") a,b ! 输出:" 20 10"(使用前两个I4)
write(*,"(I4,I4)") a,b ! 输出:" 20 10"
write(*,*) a ! 输出:"20"
end program example
代码行 | 格式说明 | 输出结果 |
---|---|---|
write(*,"(4I4)") a,b |
4I4表示连续4次I4格式(只使用前2次) | " 20 10" |
write(*,"(I4,I4)") a,b |
显式指定两个I4格式 | " 20 10" |
write(*,*) a |
自由格式输出 | “20” |
Fortran 允许变量不声明直接使用,其类型由变量名的首字母自动决定:
整型变量:首字母为 I, J, K, L, M, N(记忆口诀:I Just Know Lots More Numbers)
iCount = 10 ! 自动视为整型(无需声明)
浮点型变量:其他首字母(如 A, B, X, Y)
average = 3.14 ! 自动视为浮点型
隐式类型的问题
代码可读性差:未声明的变量难以追踪类型。
潜在错误:拼写错误会隐式创建新变量(如误写 tolal 代替 total 不会被编译器报错)。
维护困难:团队协作时易引发类型不一致问题。
使用 implicit 自定义规则
可显式指定某些首字母的默认类型(但仍不推荐):
implicit integer (A-D) ! A/B/C/D 开头的变量为整型
implicit real (X-Z) ! X/Y/Z 开头的变量为浮点型
program bad_example
implicit integer (A-C)
amount = 10 ! 自动为整型(因为A开头)
count = 3.14 ! 仍为整型(C开头),3.14被截断为3!
end program
program good_example
implicit none ! 禁用隐式类型
integer :: i ! 必须显式声明
real :: x
i = 10 ! 合法
x = 3.14 ! 合法
! total = 5.0 ! 编译错误:未声明变量total
end program
常量的基本概念
不可变性:常量(Constant)是程序运行期间值固定不变的量,一旦定义后不能修改。
用途:用于定义数学常数(如π)、物理常数或固定配置参数。
定义常量的两种语法
(1) 现代风格(Fortran 90+ 推荐)
real, parameter :: pi = 3.1415926 ! 显式声明类型并初始化
(2) 传统风格(Fortran 77)
real pi
parameter(pi = 3.1415926) ! 分开声明和赋值
常量命名规则
遵循变量命名规则(字母开头,可包含数字和下划线)。
通常使用全大写或首字母大写以区分变量(如 PI 或 MaxIter)。
常量类型扩展
常量支持所有基本数据类型:
integer, parameter :: MAX_STEPS = 1000 ! 整型常量
real, parameter :: GRAVITY = 9.81 ! 浮点型常量
character(len=*), parameter :: NAME = "Fortran" ! 字符串常量
logical, parameter :: DEBUG_MODE = .true. ! 逻辑型常量
real :: a, b
equivalence(a, b) ! a和b指向同一内存地址
integer :: int_val
real :: float_val
equivalence(int_val, float_val) ! 允许通过int_val修改float_val的二进制表示
program equiv_example
real :: x, y
equivalence(x, y)
x = 3.14
print *, y ! 输出3.14(y与x共享内存)
y = 2.71
print *, x ! 输出2.71
end program
integer :: i
real :: x
equivalence(i, x) ! 危险:修改i会破坏x的浮点表示
数组对齐:可用于数组部分重叠(需确保内存对齐正确)。
real :: arr1(10), arr2(5)
equivalence(arr1(6), arr2(1)) ! arr2共享arr1的第6-10元素
program example
integer :: a = 20 ! 声明整型变量a并初始化为20
write(*,*) a ! 输出: 20
integer :: b = [0] ! 使用方括号初始化(Fortran 2003+特性)
write(*,*) b ! 输出: 0
end program example
语法 | 说明 |
---|---|
integer :: a = 20 |
标准初始化方式,兼容所有 Fortran 版本 |
integer :: b = [0] |
Fortran 2003 引入的数组构造器风格初始化,适用于标量或数组初始化 |
program example
implicit none ! 强制显式声明变量
! 定义派生类型 person
type :: person
character(len=10) :: name ! 姓名(10字符)
integer :: age ! 年龄
real :: height ! 身高(注意原代码拼写错误为hight)
real :: weight ! 体重
character(len=50) :: address ! 地址(50字符)
end type person
! 声明 person 类型变量
type(person) :: a, b
! 初始化方法1:整体构造
a = person("Peter", 20, 170.0, 60.0, "China")
! 初始化方法2:逐成员赋值
b%name = "Fortran" ! 其他成员未初始化(默认值)
! 输出
write(*,*) a ! 输出 a 的所有成员
write(*,*) b%name ! 仅输出 b 的 name 成员
end program
可在类型定义中设置默认值:
type :: person
character(len=10) :: name = "Unknown"
integer :: age = 0
! ... 其他成员
end type
显式初始化所有成员:
b = person(name="Fortran", age=0, height=0.0, weight=0.0, address="")
使用命名关联(提高可读性):
a = person(name="Peter", age=20, height=170.0, weight=60.0, address="China")
派生类型数组:
type(person) :: people(3)
people(1) = person("Alice", 25, 165.0, 55.0, "USA")
program example
implicit none ! 强制显式变量声明
integer :: a = 1 ! 初始化变量a
if (a > 2) then ! 条件判断:a是否大于2?
write(*,*) "a>2" ! 条件成立时执行
end if
end program example
program example
implicit none ! 强制显式变量声明
integer :: a = 1 ! 初始化变量a
if (a > 2) then ! 条件判断
write(*,*) "a>2" ! 条件成立时执行
else
write(*,*) "a<=2" ! 条件不成立时执行
end if
end program example
program example
implicit none
integer :: a = 1
if (a > 2) then
write(*,*) "a>2"
else if (a == 2) then
write(*,*) "a=2"
else if (a < 2) then
write(*,*) "a<2"
else
write(*,*) "---" ! 兜底分支(此处不会执行)
end if
end program
运算符 | 含义 |
---|---|
== | 等于 |
/= | 不等于 |
> | 大于 |
>= | 大于或等于 |
< | 小于 |
<= | 小于或等于 |
运算符 | 含义 |
---|---|
.EQ. | 等于(Equivalent) |
.NE. | 不等于(Not Equivalent) |
.GT. | 大于(Greater Than) |
.GE. | 大于或等于(Greater or Equivalent) |
.LT. | 小于(Little Than) |
.LE. | 小于或等于(Little or Equivalent) |
当我们要表示一个变量大于1小于3时,有以下示例:
if (1 ! 错误
if (x>1 .and. x<3) then
! 正确运算符 | 含义 |
---|---|
.and. | 逻辑与,如果两边的表达式都成立,则返回“真” |
.or. | 逻辑或,两边的表达式只要有一个成立,则返回“真” |
.not. | 逻辑反向,两边的表达式都不成立,则返回“真” |
.eqv. | 两边表达式的逻辑运算结果相同时,则返回“真” |
.neqv. | 两边表达式的逻辑运算结果不同时,则返回“真” |
case default是可选的,并不一定要出现在代码中。
case(1:5)代表在这两个数字范围内的所有数值,case括号内还可以用逗号来放入多个数值。
使用selectcase来代替if-elseif的多重分支语句,可以使代码看起来更加简洁,但是也有如下的一些限制:
program example
implicit none
integer :: a = 4
select case(a) ! 选择变量a
case(1) ! a==1时执行
write(*,*) "This is 1"
case(2) ! a==2时执行
write(*,*) "This is 2"
case(3) ! a==3时执行
write(*,*) "This is 3"
case(4,5) ! a==4或5时执行(多值匹配)
write(*,*) "This is 4 or 5"
case default ! 默认分支(可选)
write(*,*) "Unknown"
end select
end program
1.goto命令
goto命令提供给程序员一个任意跳跃到程序任意一行代码的能力,被跳过的代码则不会被执行。虽然这在某种情况下很方便,但是会影响代码的可读性,所以不太建议在程序中使用。
2.pause命令
程序执行到pause时,会暂停执行,直到用户按下Enter键才会继续执行。这可以应
用在当屏幕上要连续输出大量数据时,在适当的位置暂停程序,以便用户更好的阅读输出的内容。
3.continue命令
continue命令没有什么实际的用途,它的功能就只是“继续向下执行程序”。
4.stop命令
终止程序。
counter是“计数器”,counter=1表示初始值为1,counter在使用之前需要先进行声明。
lines是计数器的终止数值,counter<=lines时会执行循环语句。
最后面的数值1代表counter变量的增量,I每执行一次循环,counter就加1。
do循环中,计数器的初值、循环终止值、以及循环增量值都可以用常量或者变量来指定。
program example
implicit none
integer :: a
do a = 1, 10, 1 ! 循环:a从1到10,步长1
write(*,*) a ! 输出当前a值
end do
end program
在循环次数未知但是循环条件已知的情况下,可以使用dowhile循环。
cycle命令
cycle命令可以跳出本次循环,进行下一次的循环,相当于C++中的continue。
exit命令
exit命令可以跳出当前循环,如果是循环嵌套的情况,则跳出的是exit语句所
在的循环,而外层循环不会被其影响,相当于C++中的break。
program example
implicit none
integer :: a, b
do a = 1, 4 ! 外层循环(a从1到4)
do b = 1, 5 ! 内层循环(b从1到5)
if (b == 3) then
write(*,*) "我跳出本次循环了!"
cycle ! 跳过本次内层循环
end if
write(*,"(2(A4,I3))") "a=", a, "b=", b
end do
end do
end program
循环还可以取“名字”,这个用途可以在编写循环时,能明白enddo这个描述的位置是否正确,尤其是嵌套循环中。署名的循环也可以配合cycle和exit来使用。
program example
implicit none
integer :: a, b
loop1: do a = 1, 10 ! 外层循环(标签loop1)
loop2: do b = 1, 5 ! 内层循环(标签loop2)
write(*,*) "This is a test!"
end do loop2 ! 显式标记内层循环结束
end do loop1 ! 显式标记外层循环结束
end program
一维数组的声明格式(最简单的一种):数据类型数组名(数组大小)
例如:
integer arr(10)
在声明数组时,数组大小只能使用常数来指定,常数包括直接填入数字或者使用parameter修饰后的常量。
数组除了可以使用5种基本数据类型之外,还可以使用自定义数据类型。
二维数组的声明格式(最简单的一种):
数据类型数组名(sizel,size2)
例如:
integer arr(2,3)
与其他程序语言不同,Fortran中数组的索引值都是从i开始,但是可以经过特别声明的方法来改变这个默认的规则,在声明时,可以特别赋值数组的坐标值使用范围,例如:
integer a(0:5)
上面的例子把数组的索引值设置为从0到5。除了一维数组之外,二维数组也可以使用这种方式来声明数组的索引值。
Fortran 一维数组初始化方法总结
program array_init
implicit none
! 方法1: DATA语句
integer :: a(5)
data a /1,2,3,4,5/
! 方法2: 直接初始化
integer :: b(5) = (/10,20,30,40,50/)
! 方法3: 现代数组构造器
integer :: c(5) = [5,10,15,20,25]
! 方法4: 隐含DO循环(需先声明i)
integer :: d(5), i
data (d(i), i=2,5) /2,3,4,5/ ! d(1)未初始化
print *, 'a:', a
print *, 'b:', b
print *, 'c:', c
print *, 'd:', d ! d(1)可能为随机值
end program
基础初始化方式
| 方法 | 语法示例 | 说明 | 特点 |
| ------------ | ---------------------------------- | ------------------------ | -------------------------------------- |
| DATA语句 | `data a /1,2,3,4,5/` | 传统Fortran初始化 | 需单独声明和初始化 |
| 重复值 | `data a /5*3/` | 快速填充相同值 | 5个元素均为3 |
| 直接初始化 | `integer :: a(5) = (/1,2,3,4,5/)` | 现代Fortran风格 | 声明时初始化,注意(/和/)无空格 |
现代初始化扩展(Fortran 90+)
| 方法 | 语法示例 | 说明 | 特点 |
| ------------ | ---------------------------------- | ------------------------ | -------------------------------------- |
| DATA语句 | `data a /1,2,3,4,5/` | 传统Fortran初始化 | 需单独声明和初始化 |
| 重复值 | `data a /5*3/` | 快速填充相同值 | 5个元素均为3 |
| 直接初始化 | `integer :: a(5) = (/1,2,3,4,5/)` | 现代Fortran风格 | 声明时初始化,注意(/和/)无空格 |
Fortran 隐含循环(Implied DO Loop)总结
隐含循环是 Fortran 中一种无需显式 do-end do 结构的循环语法,主要用于:
核心语法
(array_expr, index = start, end [, step])
index:循环变量
start/end:循环范围
step:步长(默认1)
典型应用场景
数组输出控制
integer :: a(5) = [1, 3, 5, 7, 9]
write(*,*) (a(i), i=2, 5) ! 输出:3 5 7 9
write(*,*) (a(i), i=1, 5, 2) ! 输出:1 5 9(步长2)
数组初始化
integer :: b(5)
data (b(i), i=1,5) /1,2,3,4,5/ ! 传统方法
integer :: c(5) = [(i**2, i=1,5)] ! 现代方法:1,4,9,16,25
多维数组操作
integer :: mat(3,3)
write(*,*) ((mat(i,j), j=1,3), i=1,3) ! 按行展开输出
program implied_loop_demo
implicit none
integer :: i, a(6) = [10,20,30,40,50,60]
! 输出偶数索引元素
write(*,*) "Even indices:", (a(i), i=2,6,2) ! 20 40 60
! 生成平方数数组
integer :: squares(5) = [(i**2, i=1,5)]
write(*,*) "Squares:", squares ! 1 4 9 16 25
! 嵌套隐含循环(3x3矩阵)
write(*,*) "Matrix:", ((i+j, j=1,3), i=1,3) ! 2,3,4,3,4,5,4,5,6
end program
Fortran 多维数组初始化与隐含循环总结
(1) DATA语句 + 嵌套隐含循环(传统方式)
integer a(2,2), i, j
data ((a(i,j), i=1,2), j=1,2) /1,2,3,4/
内存顺序:列优先(Column-major)
a(1,1)=1, a(2,1)=2
a(1,2)=3, a(2,2)=4
(2) 直接初始化(现代方式)
integer :: a(2,2) = reshape([1,2,3,4], [2,2])
明确维度:使用reshape函数控制布局
(1) 部分元素重复赋值
integer :: a(5) = (/1, (2, i=2,4), 5/) ! a=[1,2,2,2,5]
(2) 序列生成
integer :: a(5) = (/1, (i, i=2,4), 5/) ! a=[1,2,3,4,5]