FORTRAN 五种数据类型中,有两种非数值型数据:逻辑型、字符型。要运用这两种数据,同样要掌握它们的变量说明、常数书写格式、表达式、赋值语句、编辑符、输入输出格式。掌握这两种类型,能实现信息管理方面的强大功能,在处理办公室报表、文件、文本、文本编辑时有足够手段。并使数值型计算也变得更为丰富。
4.2.1 逻辑型数据
逻辑型数据与数值型数据有本质的不同。它的 值不是 具体的数,而是对某个论点 作出 的判断,常用的逻辑数据是对两个数值间等或不等关系的判断、两个字符串之间的等或不等关系的判断,也即是一个关系表达式。如果 该关系 成立,则称其逻辑型是‘真’,不成立则称其逻辑型是‘假’。因此 逻辑型值只有 两个:真或假,不像整型、 实型的值可以 取无穷多个。复杂的逻辑表达式的基础仍是上述关系不等式,只是这些关系表达式是以某种方式连接起来的较为复杂的判断,如逻辑表达式 X>3.AND.X<5 ,即‘ X > 3 而且 X < 5 ’,则当点 X 落在此 区间时判断成立,逻辑表达式值为真,否则为假。
有关逻辑型数据的运算和逻辑表达式已在第二章中作了介绍,这里仅就涉及其说明和赋值语句。
逻辑型变量
对于逻辑值在程序中可变的量,则称逻辑变量,逻辑变量取名的法则同数值型变量,它也要作类型说明,而后才能在程序中按逻辑数据使用与读写。逻辑型类型说明关键字是 LOGICAL ,其类型说明语句一般形式为:
LOGICAL[(KIND= 种别值 )][, 属性说明表 ]:: 变量名表 [= 初始值 ]
例如: LOGICAL(KIND=2),DIMENSION(1:10) :: X ,说明 X 数组内有元素 X(1),X(2), … ,X(10) 都是种别值为 2 的逻辑型数据。
变量名表中要说明为逻辑型的对象可以是一般变量名、数组名、函数名、构造 名等等 ,彼此用逗号分开,还可以对变量赋以初值。例如要说明 L1,L2 是逻辑型变量,并且置 L1 初值为真,可写成:
LOGICAL : : L1=.TRUE.,L2
逻辑变量取值的方法和数值型数据类似:赋初值、读入、使用逻辑赋值语句赋值。逻辑赋值语句的一般形式是: 逻辑变量=逻辑表达式 。它通常用来将一个较长的表达式的 值赋给 一个逻辑型变量,而后作为条件写在 IF 语句或选择构造中,使条件变得简短明确。
例:输入实数 x ,求下面的函数值。
Program Sample
implicit none
real : : x,y
logical : : in_side
read *, x ; print *, ‘ x= ’ ,x
in_side =x>1 ..and.x <2.
if( in_side ) then
y=x*x
y=1-x
end if
print *, ‘ y= ’ ,y
End Program Sample
4.2.2 字符型数据
字符常数的一般形式是由一对单引号‘ ’或一对双引号“”限定的一串字符。字符串中的字符,允许是 PORTRAN 字符集的任意字符,如果系统还支持其它字符,例如汉字、希腊字、化学符号、数学符号,也可引入字符串内,用一对‘ ’或“”界定。
字符型数据除了有类型、种别外,比其它类型还多了一个长度特性,即规定它有几个字符数。字符型说明语句的关键字是 CHARACTER ,其长度说明方法是紧跟在 CHARACTER 后面写一对括号, 括号内写 LEN= 字符长度。其一般形式是:
CHARACTER[(LEN= 整型字符长度表达式 [,KIND= 种别值 ])][, 属性说明 ] :: 变量名表 [= 初始值 ]
其中 LEN 后面的整常数表达式规定被说明字符变量长度,为正整数, LEN 的参数与 KIND 的参数都写在括号内,次序可以任意。在字符型说明语句中,长度说明必须有,不可省略,种别参数可以省略,此时 取标准 值。仅有关键字 CHARACTER 而没有括号时认为字符是一个字节长。可以省去 LEN= 及 KTND= ,只写参数值,此时字符长度必须写在前面。只有长度说明的语句可分为有括号和无括号两种,例如:
CHARACTER( LEN=12,KIND=1) :: A,B
CHARACTER( KIND=1,LEN=12) :: A,B
CHARACTER( 12,1) :: A,B
CHARACTER* 12 : : A,B
都是等价的,前者说明 X 、 Y2 是字符型变量,种别参数为 3 .每个变量长度为 12 。后者说明表明长度为 12 ,种别值为 1 。
长度也可以写成一个 * 号,表示长度暂不确定,待以后与程序中实际需要的长度相一致。例如:
CHARACTER(LEN=*),PARAMETER :: C_NAME= ‘ GIRL ’
CHARACTER(LEN=*),PARAMETER :: C_NAME= ‘ BOY ’
都是合法的说明语句,说明字符常量 C_NAME ,前者长度为 4 ,后者长度为 3 。
用字符型变量作为过程 的哑元时 ,可以用正整数作长度,也可以把 * 作长度,后者可以与任何长度的实元 作哑实结合 ,相当于以实元的具体长度 为哑元的 长度。
CHARACTER 后面说明的长度是其后所有实体名的公共长度,如果某一变量的长度与其它不同,可以在其变量名后标出自己的特有长度,方法是在变量名后写上 * 及长度。 例加 :
CHARACTER( LEN=12) :: A,B*5,C,D*7,E
字符数据中某一部分相连的字符为 字符子串 ,也可以作为一个实体与字符变量一样参加操作。 字符子串的 一般形式是: V(e1:e2) 。 V 是字符型实体名,包括字符变量名、字符函数名、字符数组元素等等。 e1,e2 是整型表达式 或正整常数 , e1 的值指明子串在 V 中的 起始列号 , e2 的值指明子串在 V 中的 终止列号 。如果 e1 省略,表示 子串从 第一个 字符取起 ; e2 省略, 表示子串取到 末尾;如 e1,e2 都省略,表示 子串从头 取到尾。例如:设有字符变量 A ,其取值为‘ ABCDE12345FGH ’,则下面 的子串取值 为:
A(3:11) -> ‘ CDE12345F ’,
A(I+4:9) -> ‘ E1234 ’ (I=1) ,‘ 1234 ’ (I=2)
A(:5) -> ‘ ABCDE ’
A(11:) -> ‘ FGH ’
A(:) -> ‘ ABCDE12345FGH ’
A(3:3) -> ‘ C ’
子串在程序中可直接引用,也可被其它字符实体再赋值,因此可使程序员任意地取出一部分字符,并按需要替换一部分字符,非常灵活。例如: PRINT * , (A(I:I + 1),I=6,9) ,可以打印‘ 12 ’、‘ 23 ’、‘ 34 ’、‘ 45 ’。
字符操作与赋值
字符操作符只有一个,称 并置符 ,为两相连的斜杠“ // ”,其功能是把前后两个字符串拼连在一起。表达式中的操作对象可以是字符变量,字符常数、 字符子串 、字符函数值、字符数组元素等。例如: ‘ AB ’ / / ‘ CDE ’ 的值 为 ‘ ABCDE ’。 C/ / ‘ ABC ’ //A(2:6)//B(1:4)//D 是把几个字符串连在一起。
字符赋值语句的一般形式是: 字符变量=字符表达式 。在字符赋值语句中,要求两边种别 值一致 ,此外还有长度问题。当两边长度不等时,赋值时以左边的字符变量说明长度为准,当右边小于左边时,尾部补空格,否则将右边尾部的多余部分截去。
对每种机器,系统都把本机上可以使用的各种字符按先后排列成某种次序,每个字符在排序中有确定的位置,称为 排序号 。有了排序号,字符之间就可以比较大小及相等与否,组成关系表达式。
各种系统字符排序不一样,同一字符,在不同机上排序 值可能 不一样。以 ASCII 码为例,有 128 个字符,它的第一个字符序号为零,最后一个序号为 127 。例如 A 的排序号为 65 ,数码 0 的排序号为 32 。序号 0 ~ 31 及序号 127 的字符称为控制字符,用来控制操作,它们是非打印字符,屏幕上不可见,通常编程时可于忽略。从 ASCII 码字符集的排序可以看出,小写英文字母排序在大写英文字母之后,它们的序号不同。因此,虽然在书写 FORTRAN 语句时,大小写字母是等价的,但当进行字符操作和字符比较时必须看成是不同的。
字符作比较实际上是比较它们的序号大小。字符比较的一般形式是两端为字符表达式的关系表达式: <字符表达式><关系操作符><字符表达式> 。例如 : ‘ A ’ < ‘ B ’ 的比较结果为真, C1/ / ‘ CCTV ’ >= ( ‘ XY ’ //C2)//C3 式当 C1 、 C2 、 C3 是字符型 变量名时是 合法的,要先计算两端字符表达式的值,而后比较它们是否满足≥关系。比较的方法 随关系 操作符而异:
>、<关系操作符
只要两边表达式第一个字符不等就可求得关系表达式的值。如 : ‘ ABC ’ > ‘ CDE ’ , 因第一个字符 ‘ A ’ < ‘ C ’ 不满足>关系,故表达式的逻辑值为假,后面各位不再比较。如果第一位相等,则对第二位字符作比较得出整个关系表达式值为‘真’或‘假’,如此类推。如果两端字符表达式的值长度不等,则短的一端尾部添空格 再按位比较 。如: ‘ ABC12 ’ > ‘ ABC ’ ,因在 ASCII 码中‘ 1 ’ 的序号为 49 ,空格的序号为 32 。故上述关系表达式的值为真。
== 关系操作符
先作第一位比较,如不等,关系表达式值为‘假’,如相等,再比较第二位,一直比较到最后一位都相等(不足添空格),才能得出关系表达式值为真,否则值都为假。 如作不等 /= 比较,只要有一位不等就可得出表达式的值为真,否则一直比较到末位。设有字符型变量名为 NAME ,其值为 ‘ Einstein ’ , 则关系 表达式:
NAME== ‘ Einstein ’ -> 真
NAME== ‘ Ein ’ / / ‘ stein ’ -> 真
NAME/= ‘ Ein ’ / / ‘ Stein ’ -> 真
NAME== ‘ EINSTEIN ’ ->
F90 的内部函数中有许多与字符型操作有关的函数供用户使用,可以很方便地进行各种文本编辑。
字符与数值相互转换的函数: ICHAR , CHAR , IACHR , ACHAR
F90 允许把字符型的值转换成整型值 ( 已知字符,取字符型的序号数值 ) ,也允许把数值型的值转换成字符型的值 ( 已知序号,取它对应的字符 ) 。函数 ICHAR 的功能是把字符型转换成数值,它的引用方式是: ICHAR( 字符实体 ) 。这里自变量的字符实体不一定是单个字符,也可以是字符变量、 字符子串 、字符数组元素、字符函数 值等等 以及由它们组成的字符表达式。函数值 ICHAR 返回字符实体第一个字符的序号值。如果指明要按照 ASCII 码求它 的序号, 则本功能 的 函数名应改写 为 IACHAR ,例如:
print *, ichar ( ‘ A ’ ), ichar ( ‘ A_dog ’ ), ichar ( ‘ A_dog ’ / / ‘ in_my_room ’ )
打印的结果是 3 个数字 65(A 的序号是 65) 。
函数 CHAR 的功能是把一个序号转换成它的字符。它的引用方式是: CHAR( 整型数值表达式 ) 。先计算整型表达式的值,再以这个值为序号,返回相应的单个字符,如 CHAR(65) 的值是‘ A ’。如果按照 ASCII 码求它 的对应字符,则函数名为 ACHAR 。函数 CHAR 可以有两个自变量,此时引用形式为: CHAR( 序号值,种别值 ) 。缺省种别值时表示 取标准值即 ASCII 码。
有了字符与数值的转换函数,就可处理字符循环。 例如设要连续 打印 DIMENSION A , DIMENSION B ,…, DIMENSION Z ,则程序可写成:
DO I=0 ,25
PRINT * , ‘ DIMENSION ’ //CHAR(I+6)
END DO
求字符串长度的函数: LEN
函数 LEN 的功能是求出一个字符实体的长度,引用方式是: LEN( 字符实体 ) 。函数值返回一个 正整教 ,为该字符实体的长度(包括尾随空格、中间空格在内)。如: LEN ( ‘ ABCD 12 ’ ) 的值是 8 ( 6 个字符数加 2 个空格数)。
不计尾部空格的字符串长度函数: LEN_TRIM
如: LEN_TRIM ( ‘ ABCD 12 ’ ) 的值是 7 ( 6 个字符数加 1 个空格数)。
求子 串在父串位置 的函数: INDEX
函数 INDEX 的功能找出指定子串在字符串内的指定位置,其引用方式是: INDEX( 父串 , 子串 ) 。函数值返回一个正整数,指明子串在 父串中 是从第几个字符开始的。 父串、子串都 可以是各种形式的字符实体。如果第二个字符实体不是第一个字符实体 的子串 ,返回函数值为 0 。如: INDEX ( ‘ Einstein ’ , ‘ s ’ ) 的值 4 。
验证字符串的函数: VERIFY
函数 VERIFY 的功能确认指定的字符集是否包含了给定字符串中所有的字符,其引用方式是: VERIFY( 字符串 , 字符集 ) 。函数值返回一个正整数,指明字符串中与字符集相异的第一个字符是从左边第几个字符开始的。如果没有相异的字符,则返回函数值为 0 。如: VERIFY( ‘ Einstein ’ , ‘ in stant ’ ) 的值为 1 , VERIFY( ‘ in stant ’ , ‘ Einstein ’ ) 的值为 5 , VERIFY( ‘ Einstein ’ , ‘ abcdefghijklmnABCDEFGHIJKLMN ’ ) 的值为 4 。
除去尾部空格函数: TRIM
如: TRIM ( ‘ ABCD 12 ’ )/ / ‘ 34 ’ 的值 是 ‘ ABCD 12 34 ’。
比较字符大小的函数: LGE 、 LGT 、 LLE 、 LLT
比较字符大小的四个函数都有两个字符型实体作自变量,用来判断它们之间是否满足各种>、<关系的,其函数值是一个逻辑值,满足该不等关系为真,否则为假。它们的引用方式与功能如下: