Fortran程序设计第4章FORTRAN 95语言的形貌.docx
《Fortran程序设计第4章FORTRAN 95语言的形貌.docx》由会员分享,可在线阅读,更多相关《Fortran程序设计第4章FORTRAN 95语言的形貌.docx(21页珍藏版)》请在冰豆网上搜索。
Fortran程序设计第4章FORTRAN95语言的形貌
第2篇.计算的叙述
算法的每一个步骤,都必须给予确切的定义。
对于算法当中所
考虑的每一种情况,每一个有待执行的动作,都必须严格地和
不含混地加以规定。
…对于以描述算法作为目的而设计出来
的,采用了形式的定义的程序设计语言,或者说计算机语言,
它的每一个语句都必须有非常确切的意义。
----D.E.Knuth[1]《TheArtofComputerProgramming》
本质上FORTRAN就是一门语言,一门人与计算机赖以进行有效交流的语言,在这个意义上和我们使用的中文,英文等没有本质差别。
现在假设要来描述一种大家都陌生的语言,那么总是要分成两个方面来描述,即一方面要描述这门语言的表象和形态,也就是它使用哪些符号,哪些词汇,一般的句式如何,怎样才能完整叙述一个任务之类;另一方面需要说明这门语言的语义,也就是说这门语言是如何用来表达我们需要它表达的意思的。
第4章基本上就是描述FORTRAN作为一种语言的基本形态,也就是书写这种语言的书写规则。
接下来几章则逐步说明如何用FORTRAN来表达我们的要求,或者反过来说,FORTRAN提供了些什么表达方式,以便我们用来向计算机提出合理的任务:
●表达基本数据;
●表达数据的结构;
●完整地描述数据;
●构造表达式;
●驱动计算的赋值;
●计算过程的结构控制;
在整个第二篇,我们将领略到FORTRAN95是如何能够做到精致地描述计算的,而把一个问题阐述清楚了,就意味着问题已经解决了一大半。
[1]DonaldE.Knuth(高纳德),StanfordUniversity的TheArtofComputerProgramming荣休教授,而TheArtofComputerProgramming(计算机程序设计技巧)正是他的伟大著作的名称。
洋洋七大卷的《TheArtofComputerProgramming》是当今全世界每一个计算机科学家所膜拜的圣经。
1974年在该书刚完成前面很少一部分时,就给他带来了计算机科学家们梦寐以求的图灵奖。
第4章 FORTRAN95语言的形貌
要说明一门语言的形态,必须回答以下问题:
● 它使用哪些符号来表达信息?
● 它的词汇如何构成?
● 它的语句如何构成?
● 如何表达一个完整的任务?
具体的对于一门计算机语言,把这几个问题更加明确地转换过来,就是:
● 它使用键盘上的哪些符号,各个符号有哪些用途?
● 它的词汇如何由键盘字符构成?
含有哪些固定的词汇?
以及容许自由构成合法词汇的规则是什么?
● 它具有哪些固定的语句格式?
以及容许自由构成合法语句的规则是什么?
● 我们交待给计算机的任何任务,都必须明确说明任务的开始,执行步骤和完成,因此一段完整的源代码应该具备什么样的形式?
以及应该具备哪些要素?
本章就是要回答这些问题。
4.1 FORTRAN语言所使用的字符
从最抽象的层面来看,人与计算机的交流只是信息的交流,而信息总是需要依靠某种信号来表示,对于人来说,最方便的就是字符。
而对于计算机来说,自然就是键盘所能敲出的那些字符(信号),因此下面就是要说明:
● FORTRAN95能识别键盘上敲出的哪些字符?
● 每个字符对于FORTRAN95来说又意味着什么?
4.1.1 FORTRAN95所使用的基本字符
按照FORTRAN95标准的规定,一切FORTRAN95的实现平台都必须使用下面表4-1所列出来的这个基本的字符集,或者说,这个字符集是所有遵循FORTRAN95标准的编译器所使用的字符集的公共子集。
这样原则上,局限在这个字符集上的源码是能够被任何遵循FORTRAN95标准的编译器所识别的。
表4-1基本的FORTRAN95字符集:
文字字符
英文字母 ABCDEFGHIJKLMNOPQRSTUVWXYZ
数字0123456789
下划线_
特殊字符
图形名称
图形名称
空格
:
冒号
=等号
!
叹号
十加号
”引号
一减号
%百分号
*星号
&英语的and
/斜线
;分号
(左括号
<小于
)右活号
>大于
,逗号
?
问号
.小数点或句号
$货币符号
’撇号
可以看到基本字符分为两大类:
文字字符和特殊字符。
除了货币符号可以本地化之外,其他任何字符都必须依照表里的形式。
对于基本字符有如下几个问题需要予以注意。
一.文字字符的用处:
● 主要是命名的作用,可以用来命名语言中的一切对象,这三种符号可以混合使用;
● 其中数字还具有它本来的含义,就是表示数目。
二.特殊字符的用处:
特殊字符主要具有功能的意义,如编辑功能,运算功能,语法功能等。
FORTRAN95标准原则上接受小写字母。
因此除了以下位置,大小写是等价的。
三.大小写必须区分的位置:
● 作为字符常量的字符串里面;
● 输入输出的纪录里面;
● 作为编辑描述符的引号或撇号里面。
因为在上述几种情形,大小写是字符型数据的不同数据取值。
如果不幸遇到一个FORTRAN95标准的怪异的编译平台,偏偏不接受小写字母,这是FORTRAN95标准所许可的,这时就得小心了。
不过幸好我们常用的编译平台,例如CVF,都是接受小写字母的。
另外,在OPEN或者INQUIRE语句里面的FILE=或NAME=后面是否区分大小写,也是由编译平台指定的。
如果是需要调用其他语言写的子程序,而恰好该种语言(例如C语言)是区分大小写的,这时就需要特别小心。
【例4-1】如果用C写了两个子程序EIGEN和eigen,然后有如下的FROTRAN片断:
EXTERNALEIGEN
...
CALLEIGEN
...
END
这时它是该引用EIGEN还是eigen呢?
如果所使用的FROTRAN系统正好是怪异的那种,没问题。
如果是常见的如CVF,这时它就无法区分EIGEN和eigen,这样就必须给它们更换名称了。
四.数字的涵义:
除了以下情形,数字总是表示十进位数字
● 属于二进制,八进制,十六进制的字面常量;
● 带有B,O,Z编辑描述符的输入输出纪录。
【例4-2】以下语句当中的数字不是属于十进位数字:
DATAI,J,K/O’1001’,23.54,Z’5CA2’/
其中第一个为八进制数,第二个为十进制数,第三个为十六进制数。
五.下划线的涵义:
● 下划线的主要作用就是置于单词之间代替空格,使得我们在命名时使用清楚的英语词汇。
● 下划线不能置于任意名称的前面,但是可以置于名称的最后。
● 下划线也用于在字面常量中区隔常量的值和种别参数。
无论给什么对象起名,都尽量使用完整的英语单词,同时使用下划线以区隔不同的单词。
所谓好记性不如烂笔头,只有这样才能切实保证你在任何时候,在程序代码的任意位置都知道任意变量等的含义。
4.1.2 与平台有关的FORTRAN辅助字符集
上节列出的基本字符集是在一切FROTRAN的编译平台都可以使用的,被FORTRAN95标准规定为必须使用的默认字符集。
另外还有些辅助的字符则是不同的平台有不同的用法约定。
辅助字符分两类:
可打印字符和不可打印字符。
● 可打印字符;
各种本地化语言的字符,象汉字,希腊字母等,都可以应用在字符串,注释,和输入输出纪录当中。
● 不可打印字符。
主要就是控制字符,例如制表符Tab键。
制表符(Tab键)在FORTRAN77标准当中主要用来表示6个空格,这样在固定源程序形式的代码的每行的开头使用Tab,就自动地空出6个空格。
对于一个FORTRAN77标准的编译系统来说,在固定源程序形式里的Tab被看成是至少6个空格,而在自由源程序形式里的Tab被看成1个空格。
这样如果Tab被放在文本当中用于输出格式控制,那么这种默认的转换方式,有时就会导致输出格式的混乱。
有关FORTRAN95的辅助字符集的使用规则,请参考具体的编译系统的说明。
4.2 词汇
所谓FORTRAN的词汇就是一个语句的最小的意义单位,它由一个或多个FORTRAN字符集里的字符组成。
包括两类共6种,分类例举如下:
● 由文字字符组成的词汇,包括4种:
·语句关键词:
IMPLICIT
·名称:
EIGEN_FREQUENCY_3
·由单个词汇组成的字面常量:
1.234567_long
·标识符:
213
● 由特殊字符组成的—
·算符:
+,.OR.
·定界符:
逗号,=,=〉,:
,:
:
,;,%。
FORTRAN95的一切合法的词汇都必须按照语法来构成。
完备的构词语法规则在附录B给出。
下面分别予以详细说明。
1.语句关键词
语句关键词的功用:
● 标志语句本身。
【例4-3】下面的DO语句中的关键词DO本身标志了该语句
DOI=1,500
● 标志选项。
【例4-4】下面的INTENT语句当中的IN,OUT,或INOUT。
INTENT(IN),A。
B
INTENT(INOUT),X,Y,Z
● 用在语句当中,起分界的作用。
【例4-5】如下面DO语句当中的WHILE
DOWHILE(.NOT.VECTOR)
并非所有的语句都必须包含关键词,在FORTRAN里面,赋值语句和函数都不需要关键词。
尽管FORTRAN95不区分大小写,本书任何地方出现的语句关键词都使用大写字母。
纯粹是为了醒目的原因。
2.名称
在一个程序当中,任何对象都需要有一个名称,给它们命名所得到的词汇,可以说就是一般语言里的名词,这样的对象包括:
变量,命名常量,程序单元,过程,公用块,构造,派生类型,哑元等。
名称的拼写规则为:
●名称必须由字母开头,可以由文字字符混合组成,而下划线不能作为名称的第一个字符。
●一个名称至多允许含有31个字符。
3.常量
一个常量就是对一个值的合乎语法的字符标记。
常量分为字面常量和命名常量两种:
● 一个值如果没有在程序里面经过命名,则称为字面常量,这种常量不能取派生数据类型。
【例4-6】
66953
Z’5120A’
2.3417
.TRUE.
(33.2,5.0)
●一个值如果在程序里面经过命名,则称为命名常量,这种常量能取派生数据类型。
【例4-7】在如下声明语句当中的常量UNSTABLE_POINT为命名常量:
REAL,DIMENSION(3),PARAMETER:
:
UNSTABLE_POINT=&
(/5.332,0.221,190.632/)
对于常量的语义,将在说明数据时进一步讨论。
4.语句标签
在一个程序单元内部,对任何一条语句,都可以在该语句的前面加上语句标签,以便在该程序单元内部的任何其他位置引用该语句。
需要引用其他语句的语句包括CALL语句,DO结构,分支语句,输入输出语句等。
语句标签的书写规则为:
●语句标签由1到5个十进制数字组成,其中必须至少有一个数字不能是0,例如000不能作为标识符;
●标识符以0开头是没有任何意义的,例如0034与34没有区别。
●标识符不能放置于空语句之前。
【例4-8】
456
上面的语句只出现了一个语句标签,是不合法的。
● 对于在一个程序单元内部,标识符不唯一出现的情形,具有特殊的含义,将在后面讨论。
5.算符
算符用在表达式当中,通过运算而获得某种类型的值。
算符分为固有算符和自定义算符两类:
● 固有算符
在FORTRAN95语法当中,R310规定了固有算符的构成法则。
【例4-9】
//表示字符串的连接
+表示对数值的加法
.NOT.表示逻辑否
.OR. 表示逻辑或
上面都是固有算符。
● 自定义算符
自定义算符的一般语法形式为:
.XXX….
即在两个句点之间有n个字符构成的字符串,n不大于31。
中间的字母串最好是一个表达该运算含义的英文单词。
这个单词不能与固有算符或者逻辑常量里面已经使用了的单词重复。
6.定界符
全部的定界符有如下12种形式:
/ ( ) (/ /) , = => :
:
:
; %
其中(和),(/和/)都必须成对出现
顾名思义,这些定界符的功能就是在一个连续的源码文本当中,用来把不同性质的源码成分区分开。
它们的具体含义将在具体的语句当中说明。
4.3 语句
一条语句由一些词汇组成,可以理解为表示要求计算机进行的一个动作,但一个说明,一个描述之类的,表面看好象不是计算机的一个动作,不过实质上同样要求机器内部的一个动作与之相对应,因此同样也构成FORTRAN的一条语句。
FORTRAN95的语句分为两大类:
● 非执行语句
当需要引入或说明一个程序单元或子程序,或者是说明数据类型时,就需要使用非执行语句。
● 可执行语句
当需要计算机进行一个指定动作时,就需要使用可执行语句。
FORTRAN95全部的语句的具体分类,以及语法和例示参见附录A,语句的语法也参见附录B。
在后面的有关章节则分别说明了所涉及到的主要的语句。
4.4 源码形式
一个FORTRAN95程序就是由以下三种形式的程序成分所构成的分行的文本:
● FORTRAN语句
● 注释
● INCLUDE行
在一个FORTRAN95程序里面,一条语句占一行或多行,一行也可以有多条语句,程序文本当中可以包含空行,但不具有任何含义,被FORTRAN编译器忽略。
这种形态的文本就是FORTRAN的源代码(源程序)。
从FORTRAN90开始,对于源程序的书写格式要求已经完全现代化了,也就是出现了所谓自由源程序格式,而此前,FORTRAN的固定源程序格式一直是初学者视为畏途的主要因素,那种传统的固定源程序格式完全是FORTRAN作为始祖级的高级语言的遗留痕迹,因为早期的源程序输入不是通过键盘,而是运用穿孔纸带,正是穿孔纸带的格式规定了相应的源程序的书写格式。
现在之所以我们还需要了解这点,是因为FORTRAN的悠久历史,决定了有大量的源代码正是使用了那种古老格式,那是一个今天我们不得不继承的宝库,要想使用它们,显然就得会读那种格式,因此我们只需要了解固定格式,却不需要遵循固定格式来写代码。
【例4-10】
在这个例子里面,表明了行与语句之间可以有多种排列形式:
这里的例子显示了所谓自由源程序格式的自由之所在。
这里使用了&作为一个语句在行与行之间连续的标志,而!
后面的字符永远是注释。
23FORMAT(6Y,J9)!
这是一条语句占有完整的一行的例子
37FUNCTIONstring_concat(s1,&!
这里一条语句被分到两行s2)
空格是被忽略的。
64FORMAT(6Y,J0);37FUNCTION&!
这里一行里有两条语句,其中一条
string_concat(s1,s2)!
语句还只是它的一部分。
TYPE(string):
:
s1,s2,string_concat
string_concat%string_data=s1%string_data(1:
s1%length)//&
s2%string_data(1:
s2%length);string_concat%length&!
这行里包含两条
=s1%length+s2%length!
部分语句。
ENDFUNCTIONstring_concat
源码文本的一般规则如下:
●在一个程序单元内部,行与行之间的顺序是有意义的,只有两个例外:
•注释行的顺序与位置可以非常自由;
•在CONTAINS语句和END语句之间的子程序的顺序也可以是任意的。
●在一个程序单元内部,或者完全使用自由格式,或者完全使用固定格式。
但是一个程序内部的不同程序单元则可以使用不同的格式。
后面要说明为了便于协调起见,如何使用一种自由格式与固定格式兼容的特定格式。
●所谓字符文本是指如下两种情形下的字符串:
•作为一个字符字面常量的取值的字符或字符串;
•被字符串编辑描述符控制的字符或字符串。
那么描述符本身和续行符&永远都不属于其邻近的字符文本。
●针对字符文本的规则与针对非字符文本的规则是不一样的。
【例4-11】下面例子说明了空格在字符文本与非字符文本当中的不同使用规则:
22CHAR=NAME01//“KNOWLEDGE ARCHIVE”
23CHAR=NAME02//“KNOWLEDGEARCHIVE”
在双引号里的字符串之间的空格是有意义的,因此上面的两个字符串是不同的。
DO43I=1,N
DO43I=1,N
而上面这两条语句是等价的。
4.4.1 自由源程序格式
自由源程序格式的主要思想就是不限制语句在行内的位置。
与固定格式相比,主要是空格的用法有差异。
自由源程序格式的一般规则如下:
● 对于FORTRAN的基本字符集而言,一行至多能容纳132个字符,如果出现非基本字符集当中的字符,则具体的平台会有相应的规定,这时,可能能够容纳的字符数目就会少于132。
【例4-12】假如下面的语句刚好包含132个字符,但是其中含有中文字符:
TEXT=CHINESE_SENTENCE’thislinehasexactly132charactersandcontains人’
这时,一个具体的实现平台会有相应的规定,一般来说它会认为上面语句的字符太
多了,因此为保险起见,尽量使用续行符。
● 只要字符!
不是作为字符文本当中的一个字符,那么在该行内它后面的所有字符都是属于注释的内容。
而FORTRAN对于注释内容没有任何限制,可以是任意形式,因为反正任何编译器对于注释部分都是忽略掉的。
一行内可以在语句后面接注释内容,也可以整行就以!
开头,这时该行就是完全的注释行。
总之,注释的位置可以是任意的,关键是一行的任意位置只要出现了注释符!
,那么它后面直到行末,都会被编译器认为是注释内容而不加理会。
因此不要把语句放置在一行内的注释后面。
● 只要字符&不是作为字符文本当中的一个字符,那么在该行内它后面只能接空格以及注释,在紧接着的行内只要存在非注释部分,那就是和该&前面的部分是连续的,被称为连续行。
在FORTRAN里,一个语句所跟随的连续行不能超过39行。
一行的非注释部分不能只是一个续行符&。
注释不能利用该字符来表示续行,因此如果注释部分的行末为字符&,则它只是属
于注释内容的一个字符,不具有续行的意思。
● 一行如果只包含空格字符,或者根本不包含任何字符(这两者表现一样),那么编译器总是把该行视为注释行,予以忽略。
● 一行之内可以不止包含一条语句,语句之间必须用(;)加以分隔。
● 任何辅助字符集当中的字符都可以在字符字面常量和字符串编辑符当中使用。
● 标签被放置于语句之前,任何情形下都必须避免标签被认为是属于一条语句内部的字符。
按照FORTRAN语法,空语句是合法语句,只要空语句不是出现在一行的开头,因此连续的;;,甚至中间包含空格;;,都会被认为是单个的;,因为字符;总是意味着它的前面是一条语句,即使为空语句,也不算语法错误。
【例4-13】下面的语句都是合法的。
X=(3.0,4.6);Y=(44.5,566.0)
这里的;是作为语句分隔符
X=(3.0,4.6);
这里的;被忽略而不认为是错误
X=(3.0,4.6);;;;;Y=(44.5,566.0)
这里的;;;;;等价于一个;,因为分号之间的空格被认为是空语句,不算语法错误。
X=(3.0,4.6)&
;Y=(44.5,566.0)
这里分号放在一行的开头,因为该行是连续行。
Y=(44.5,&
566.0);Z=”ZERO”
【例4-14】下面的写法是错误的。
53INTEGERX,Y!
这里53是合法的标签
IF(X==0)76Y=X !
这里的标签76不能说明自己不属于IF语句
下面我们更加详细地说明在自由源码形式里面续行符和空格的用法。
1.续行符
只是采用续行符的不同用法,就有可能产生完全不等价的语句,因为续行符能够导致名称的变化。
所以如果一个名称,字符常量,或词汇被迫分行,则必须在前一行的末尾和后一行的开头紧接着字符使用&。
【例4-15】
ENERGY=0.5*MASS*VILOC& !
这里VILOCITY是一个变量名
&ITY**2
ENERGY=0.5*MASS*VILOC& !
这里变量名成了VILOCITY!
&ITY**2
ENERGY=0.5*MASS*VILOC&&!
这里变量名成了VILOC&ITY!
&ITY**2
上面的三个语句是完全不等价的!
2.空格的使用规则
在具有固定名称以及固定格式的算符当中,不能随意使用空格。
因为空格默认的功能就是分隔不同的词汇。
【例4-16】
CALLSUBROUTINEA
CALLSUBRO UTINEA!
错误语句!
IFX=.NOT.
IFX=.NOT.!
这两条语句不同
【例4-17】下面语句当中的空格是不可少的:
INTEGERX,Y
IFA=0
DOY=1,20
但不是所有情形下的词汇之间必须要有空格,在不会产生混乱的前提下,有些语句关键词之间的空格是可以省略的,对于语句关键词来说,所有这些不同的情形列举如下表4-1:
表4-1语句关键词中间空格含义的不同情形
非必须的空格
必要的空格
BLOCKDATA
CASEDEFAULT
DOUBLECOMPLEX
DOWHILE
DOUBLECOMPLEX
DOWHILE
DOUBLEPRECISION
IMPLICITtype-specifier
ELSEIF
IMPLICITNONE
ENDBLOCKDATA
INTERFACEASSIGNMENT
ENDDO
INTERFACEOPERATOR
ENDFILE
MODULEPROCEDURE
ENDFORALL
RECURSIVEFUNCTION
ENDFUNCTION
RECURSIVESUBROUTINE
ENDIF
RECURSIVEtype-specifierFUNCTION
ENDINTERFACE
type-specifierFUNCTION
ENDMODULE
type-specifierRECURSIVEFUNCTION
ENDPROGRAM
ENDSELECT
ENDSUBROUTINE
ENDTYPE
ENDWHERE
GOTO
INOUT