Fortran学习笔记5(数组Array)
数组的声明方式
数组是组织数据的一种方式。用来记录类型、性质相同的长串数据。不论定义多少维的数组,数据在内存中都是线状储存的。
一维数组
datatype name(size)
! datatype 是数组的类型,有整型、实型、复型、逻辑型、自定义型
! name 数组的名字
! size 数组的大小
integer a(10) ! 第一种定义方法
integer,dimension(10)::a !第二种定义方法
integer a !第三种定义方法,该方法先声明类型,在定义大小
dimension a(10)
二维数组
integer a(2,3) ! 最简单的方法
integer,dimension(2,3)::a ! 第二种方法
integer a ! 第三种方法
dimension a(10,10)
多维数组
Fortran最多可声明高达7维数组。
integer a(2,2,2,...,2)
integer,dimension(2,2,2,...,2)::a
integer a
dimension a(2,2,2,...,2)
数组索引值的改变
Fortran中数组的索引值可以改变,只需要在声明数组的时候注明特别赋值数组的坐标值范围。如:
integer a(0:5) ! 该数组的索引值为0,1,2,3,4,5
integer a(-2:2,0:4,-5:-1) ! 这也是可以的,有木有觉得很强大?
自定义类型的数组定义
直接给出例子:
Type::person
real::height,weight
character(len=80)::name
End type
Type(person)::a(10)
...
...
a(2)%height=180.0 !在变量后面加上%来使用变量中的元素
a(2)%weight=70
对数组内容的设置
数组内容的设置,既可以的那个元素设置,也可以对整个数组操作,还可以对数组中的部分判断操作。
利用“隐含式”循环设置数组初值
integer a(5)
data a /1,2,3,4,5/
integer a(5)
data a/5*3/ ! 5*3表示5个3.a(1)=3,a(2)=3,a(3)=3,a(4)=3,a(5)=3
integer a(5)
integer i
data(a(i),i=2,4)/2,3,4/ !设定a(2)=2,a(3)=3,a(4)=4;a(1)、a(5)没有设定
integer a(2,2)
data ((a(i,j),j=1,2),i=1,2)=/1,2,3,4/
integer::a(5)=(/1,2,3,4,5/) !括号和除号之间不能有空格
integer::i
integer::a(5)=(/1,(2,I=2,4),5/) !a(1)=1,a(2)=2,a(3)=2,a(4)=2,a(5)=5
integer::i
integer::a(5)=(/(i,i=1,5)/)
对整个数组操作
这个功能是Fortran90添加的,在Fortran77中不适用。
integer::a(5)
a=5 ! 最后得到a的五个元素都等于5
integer::a(5,5),b(5,5),c(5,5)
c=a+b ! 相当于c(i,j)=a(i,j)+b(i,j)
c=a-b ! 相当于c(i,j)=a(i,j)-b(i,j)
c=a*b ! 相当于c(i,j)=a(i,j)*b(i,j)
c=a/b ! 相当于c(i,j)=a(i,j)/b(i,j)
a=sin(b) ! 相当于a(i,j)=sin(b(i,j))
c=a>b ! 当a(i,j)>b(i,j)时,c(i,j)=.true.,否则c(i,j)=.Flase.
对部分数组的操作
除了一次对整个数组进行操作之外,Fortran90还提供一次只挑出部分数组来操作的功能。取出部分数组的语法看起来有点像隐含式循环。
a(3:5)=5 !a(3)=5,a(4)=5,a(5)=5
a(3:)=5 !a(3)=5,a(4)=5,...,a(n)=5
a(3:5)=/3,4,5/ !a(3)=3,a(4)=4,a(5)=5
a(1;3)=b(2:4) !a(1)=b(2),a(2)=b(3),a(3)=b(4)
a(1:5:2)=3 !a(1)=3,a(3)=3,a(5)=3,后面的2表示循环增量
a(1:10)=a(10:1:-1) ! 将a的值翻转
a(:)=b(:,2) ! a的元素与b的2列的元素对应
a(:,:)=b(:,1,:) !a的元素与b的1,3维元素对应相等
where函数
where命令经过逻辑判断来设定数组的一部分元素。where可以嵌套,也可以多重判断。where还可以命名,命名的where块要在结束时加上名字,以表明结束的是哪一个where。并且,where只用来数组赋值,不能用来干其他事。并且同一个where块中涉及运算的数组大小相同。
program main
implicit none
integer ::i
real::a(10)=(/ (i,i=1,10) /)
real::b(10)
where (a<3)
b=1
elsewhere(a<5)
b=2
elsewhere(a<8)
b=3
elsewhere
b=4
end where
write(*,100)a
write(*,101)b
100 format(T5,'Matrix A is : ',/,5(F6.2),' ')
101 format(T5,'Matrix B is : ',/,5(F6.2),' ')
end program
以下摘自彭国伦《Fortran95程序设计》
name: where(a<5) ! where模块可以取名字
b=a
end where name ! 有取名字的where结束时也要赋值名字
where(a<5) ! where可以嵌套
where(a/=2)
b=3
elsewhere
b=1
end where
else where
b=0
end where
Forall函数
Forall的语法为:
Forall(triple1[,triple2[,triple3...]],mask)
......
end forall ! mask是条件限制,满足该条件的数组元素进行Forall操作
例如:
integer::a(20,5)
integer::i,j
forall(i=2:20:3,j=1:5)
a(i,j)=i+j
end forall
Forall描述的程序模块如果只有一行代码,可以省略end Forall,把程序终结跟在Forall后面,写在同一行。下面给出几个例子。
integer::i,j
integer::a(20,10)
......
......
forall (i=1:5,j=2:8:2,a(i,j)<10) ! 只处理a中小于10的元素
a(i,j)=1
end forall
forall(i=2:13:3,j=1:5,((i>j).AND.a(i,j)>0)) a(i,j)=i**2+j**2
Forall可以写成多层嵌套,它里面也只能出现跟设置数组数值相关的命令程序,还可以在Forall中使用where,但是,不能再where中使用Forall。
下面给出一个例子,要求生成一个20*20的矩阵。该矩阵是一个带状矩阵。主对角元为8,上次一级为6,再次一级为0,再次一级为4,如此生成。下对角元和上对角元相同,只是把数字换成7,5,3,1。
program main
implicit none
integer::i,j,k
integer::a(20,20)
!数组置零
a(:,:)=0
Do k=-8,8,2
if(k<0)then
forall(i=1:20,j=1:20,i==j+k) a(i,j)=k+9
!请注意,Fortran在循环的过程中总是先循环最内层,所以这里i代表列,j代表行。不能搞反了。
end if
if(k>=0)then
forall(i=1:20,j=1:20,i==j+k) a(i,j)=-k+8
end if
End Do
write(*,100)a
100 format(T5,'矩阵为:',/,20(I2),' ')
end program
数组的保存规则
一个数组不论它是什么形状,它的元素在内存中的分布都是连续的。一维数组按顺序排列,多维数组在内存中按照“Column Major”的方法来排列。所谓“Column Major”总结起来就是先列后行,先低维在高维。在循环的过程中,要按照低维循环在内,高维循环在外的方式。
integer::a(2,2,2)
! 排列顺序为:
a(1,1,1)-a(2,1,1)-a(1,2,1)-a(2,2,1)-a(1,1,2)-a(2,1,2)-a(1,2,2)-a(2,2,2)
假设声明了一个n维数组A(D1,D2,…,Dn),设Sn=D1∗D2∗⋯∗Dn,则A(d1,d2,d3,...,dn)在第1+(d1−1)+(d2−1)∗S1+⋯+(dn−1)∗Sn−1个位置。
如果声明的n维数组有设定每一维的起始值A(S1:E1,S2,E2,⋯,Sn:En),设Mn=(E1−S1+1)∗(E2−S2=1)∗⋯∗(En−Sn+1),则A(d1,d2,d3,⋯.dn)在第1+(d1−S1)+(d2−S2)∗M1+⋯+(dn−Sn)∗Mn−1个位置。
可变大小的数组
Fortran77中没有可变大小的数组。Fortran90添加了可变大小的数组。使用可变大小的数组时要经过两个步骤。第一步是声明,在声明的时候要加上ALLOCATEBLE 。数组的大小用冒号代表。第二步是确定数组的大小。
allocate命令从内存中获得一定空间,deallocate释放掉该空间。
program main
implicit none
integer::size=0,error=0
integer,parameter::onemb=1024*1024
character,allocatable::a(:)
do while(.true.)
size=size+onemb
allocate(a(size),stat=error)
if(error/=0)exit
write(*,"('Allocate ',I10,' bytes')")size
write(*,"(F10.2,' Mb used')")real(size)/real(onemb)
deallocate(a)
end do
stop
end program
allocated用来检查一个可变大小的矩阵是否已经配置了内存,它会返回一个逻辑值。
if(.not. allocated(a))then
allocate(a(5))
end if
Fortran学习笔记5(数组Array)的更多相关文章
- [学习笔记]JS 数组Array push相关问题
前言: 今天用写了一个二维数组,都赋值为零,然后更新其中一个值,结果和预期是不一样,会整列的相同位置都是同一个值. 1.用Chrome的控制台样例如下: arrs[2][2] =1的赋值,竟然是三个数 ...
- Fortran学习笔记:03 数组(Array)
Fortran学习笔记目录 书接上回:Fortran学习笔记:02 流控制语句 数组(Array) 定义数组 一维数组 program main implicit none integer :: i ...
- (目录)Fortran学习笔记:开坑!!!
前言:因为某些原因,需要使用Fortran编写程序,记录下Fortran语法学习过程中的部分笔记.在此开坑记录,立下Flag,"希望年末能够更新完" Fortran 学习笔记 陈橙 ...
- PHP学习笔记之数组篇
摘要:其实PHP中的数组和JavaScript中的数组很相似,就是一系列键值对的集合.... 转载请注明来源:PHP学习笔记之数组篇 一.如何定义数组:在PHP中创建数组主要有两种方式,下面就让我 ...
- JavaScript学习笔记之数组(二)
JavaScript学习笔记之数组(二) 1.['1','2','3'].map(parseInt) 输出什么,为什么? ['1','2','3'].map(parseInt)//[1,NaN,NaN ...
- Fortran学习笔记4(循环语句)
Fortran学习笔记4 Fortran学习笔记4 逻辑运算 循环 Do语句 Do-While循环 循环控制 循环应用实例 逻辑运算 if命令需要和逻辑运算表达式搭配才能起到很好的效果.下面分别列出F ...
- Fortran学习笔记:01 基本格式与变量声明
Fortran学习笔记目录 01 基本格式与变量声明 格式 固定格式(Fixed Format):Fortran77 程序需要满足一种特定的格式要求,具体形式参考教材 自由格式(Free Format ...
- Fortran学习笔记:02 流控制语句
Fortran学习笔记目录 书接上回:Fortran学习笔记:01 基本格式与变量声明 流控制语句 IF语句 IF (逻辑表达式) THEN ... ELSE ... END IF SELECT-CA ...
- Scala入门学习笔记三--数组使用
前言 本篇主要讲Scala的Array.BufferArray.List,更多教程请参考:Scala教程 本篇知识点概括 若长度固定则使用Array,若长度可能有 变化则使用ArrayBuffer 提 ...
- JavaScript学习笔记:数组reduce()和reduceRight()方法
很多时候需要累加数组项的得到一个值(比如说求和).如果你碰到一个类似的问题,你想到的方法是什么呢?会不会和我一样,想到的就是使用for或while循环,对数组进行迭代,依次将他们的值加起来.比如: v ...
随机推荐
- 洛谷P2824 [HEOI2016/TJOI2016]排序(线段树)
传送门 这题的思路好清奇 因为只有一次查询,我们考虑二分这个值为多少 将原序列转化为一个$01$序列,如果原序列上的值大于$mid$则为$1$否则为$0$ 那么排序就可以用线段树优化,设该区间内$1$ ...
- APP上传
原文网址: http://blog.csdn.net/ayangcool 前言:作为一名IOS开发者,把开发出来的App上传到App Store是必须的.下面就来详细介绍下具体流程. 1.打开苹果开发 ...
- 用EnumSet代替位域
用EnumSet代替位域 如果一个枚举类型的元素主要用在集合中,一般使用int枚举模式,将2的不同倍数赋予每个常量: // Bit field enumeration constants - OB ...
- 当项目只有src文件和web文件时eclipse如何导入javaweb工程
原理是:利用工具生成class文件,并且在过程中检查出错误,生成对应的编译后文件,这样才能在tomcat等服务器上跑,服务器上只能跑编译后的文件. 1. 2. 3. . 4. 5. 6. 7.
- SqlServer存储过程调用接口
因项目需求.需实现新增数据->触发器->存储过程->调用接口. https://blog.csdn.net/u010485134/article/details/58603370 另 ...
- python入门之迭代器
迭代器 已知,可以直接作用于for循环的数据类型有: 一类是集合数据类型,如list.tuple.dict.set.str 一类是generator,包括生成器和带yield的generator fu ...
- java jps
jps:虚拟机进程状况工具: 命令格式: jps [options] [hostid] hostid 为RMI注册表中注册的主机名. 执行样例: options 参数: 选项 作用 -q 只输出L ...
- UEditor的KityFormula在IIS中部署,显示不了的解决方案
在此,首先感谢我的同事,找到了问题所在. 因Web项目中需要有输入公式的功能(高等数学中需要),普通公式插件无法满足,所以找了KityFormula这款插件. 看了下里面的公式,在数学方面确实比较全面 ...
- JS语法学习笔记
JS语法: JS知识点一览图 JS知识点一览图 在function中写this,在本function中可以显示,写Person则显示undefined. 在function中写Person,在func ...
- 【javascript】操作给定的二叉树,将其变换为源二叉树的镜像。
操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ 11 9 ...