算法的每一个步骤,都必须给予确切的定义。对于算法当中所
考虑的每一种情况,每一个有待执行的动作,都必须严格地和
不含混地加以规定。…对于以描述算法作为目的而设计出来
的,采用了形式的定义的程序设计语言,或者说计算机语言,
它的每一个语句都必须有非常确切的意义。
---- D.E.Knuth[1]《The Art of Computer Programming》
本质上FORTRAN就是一门语言,一门人与计算机赖以进行有效交流的语言,在这个意义上和我们使用的中文,英文等没有本质差别。现在假设要来描述一种大家都陌生的语言,那么总是要分成两个方面来描述,即一方面要描述这门语言的表象和形态,也就是它使用哪些符号,哪些词汇,一般的句式如何,怎样才能完整叙述一个任务之类;另一方面需要说明这门语言的语义,也就是说这门语言是如何用来表达我们需要它表达的意思的。
第4章基本上就是描述FORTRAN作为一种语言的基本形态,也就是书写这种语言的书写规则。
接下来几章则逐步说明如何用FORTRAN来表达我们的要求,或者反过来说,FORTRAN提供了些什么表达方式,以便我们用来向计算机提出合理的任务:
● 表达基本数据;
● 表达数据的结构;
● 完整地描述数据;
● 构造表达式;
● 驱动计算的赋值;
● 计算过程的结构控制;
在整个第二篇,我们将领略到FORTRAN 95是如何能够做到精致地描述计算的,而把一个问题阐述清楚了,就意味着问题已经解决了一大半。
[1] Donald E. Knuth (高纳德), Stanford University的The Art of Computer Programming荣休教授,而The Art of Computer Programming(计算机程序设计技巧)正是他的伟大著作的名称。洋洋七大卷的《The Art of Computer Programming》是当今全世界每一个计算机科学家所膜拜的圣经。1974年在该书刚完成前面很少一部分时,就给他带来了计算机科学家们梦寐以求的图灵奖。
要说明一门语言的形态,必须回答以下问题:
● 它使用哪些符号来表达信息?
● 它的词汇如何构成?
● 它的语句如何构成?
● 如何表达一个完整的任务?
具体的对于一门计算机语言,把这几个问题更加明确地转换过来,就是:
● 它使用键盘上的哪些符号,各个符号有哪些用途?
● 它的词汇如何由键盘字符构成?含有哪些固定的词汇?以及容许自由构成合法词汇的规则是什么?
● 它具有哪些固定的语句格式?以及容许自由构成合法语句的规则是什么?
● 我们交待给计算机的任何任务,都必须明确说明任务的开始,执行步骤和完成,因此一段完整的源代码应该具备什么样的形式?以及应该具备哪些要素?
本章就是要回答这些问题。
从最抽象的层面来看,人与计算机的交流只是信息的交流,而信息总是需要依靠某种信号来表示,对于人来说,最方便的就是字符。而对于计算机来说,自然就是键盘所能敲出的那些字符(信号),因此下面就是要说明:
● FORTRAN 95能识别键盘上敲出的哪些字符?
● 每个字符对于FORTRAN 95来说又意味着什么?
按照FORTRAN 95标准的规定,一切FORTRAN 95的实现平台都必须使用下面表4-1所列出来的这个基本的字符集,或者说,这个字符集是所有遵循FORTRAN 95标准的编译器所使用的字符集的公共子集。这样原则上,局限在这个字符集上的源码是能够被任何遵循FORTRAN 95标准的编译器所识别的。
表4-1基本的FORTRAN 95字符集:
文字字符 |
|
英文字母 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z |
|
数字 0 1 2 3 4 5 6 7 8 9 |
|
下划线 _ |
|
特殊字符 |
|
图形名称 |
图形名称 |
空格 |
: 冒号 |
=等号 |
!叹号 |
十加号 |
” 引号 |
一减号 |
% 百分号 |
* 星号 |
& 英语的and |
/斜线 |
; 分号 |
( 左括号 |
< 小于 |
) 右活号 |
> 大于 |
,逗号 |
?问号 |
.小数点或句号 |
$ 货币符号 |
’撇号 |
|
可以看到基本字符分为两大类:文字字符和特殊字符。除了货币符号可以本地化之外,其他任何字符都必须依照表里的形式。
对于基本字符有如下几个问题需要予以注意。
一.文字字符的用处:
● 主要是命名的作用,可以用来命名语言中的一切对象,这三种符号可以混合使用;
● 其中数字还具有它本来的含义,就是表示数目。
二.特殊字符的用处:
特殊字符主要具有功能的意义,如编辑功能,运算功能,语法功能等。
FORTRAN 95标准原则上接受小写字母。因此除了以下位置,大小写是等价的。
三.大小写必须区分的位置:
● 作为字符常量的字符串里面;
● 输入输出的纪录里面;
● 作为编辑描述符的引号或撇号里面。
因为在上述几种情形,大小写是字符型数据的不同数据取值。
如果不幸遇到一个FORTRAN 95标准的怪异的编译平台,偏偏不接受小写字母,这是FORTRAN 95标准所许可的,这时就得小心了。不过幸好我们常用的编译平台,例如CVF,都是接受小写字母的。
另外,在OPEN或者INQUIRE语句里面的FILE=或NAME=后面是否区分大小写,也是由编译平台指定的。
如果是需要调用其他语言写的子程序, 而恰好该种语言(例如C语言)是区分大小写的,这时就需要特别小心。
【例4-1】 如果用C写了两个子程序EIGEN和eigen,然后有如下的FROTRAN片断:
EXTERNAL EIGEN
...
CALL EIGEN
...
END
这时它是该引用EIGEN还是eigen呢?如果所使用的FROTRAN系统正好是怪异的那种,没问题。如果是常见的如CVF,这时它就无法区分EIGEN和eigen,这样就必须给它们更换名称了。
四.数字的涵义:
除了以下情形,数字总是表示十进位数字
● 属于二进制,八进制,十六进制的字面常量;
● 带有B,O,Z编辑描述符的输入输出纪录。
【例4-2】 以下语句当中的数字不是属于十进位数字:
DATA I, J, K / O’1001’, 23.54, Z’5CA2’ /
其中第一个为八进制数,第二个为十进制数,第三个为十六进制数。
五.下划线的涵义:
● 下划线的主要作用就是置于单词之间代替空格,使得我们在命名时使用清楚的英语词汇。
● 下划线不能置于任意名称的前面,但是可以置于名称的最后。
● 下划线也用于在字面常量中区隔常量的值和种别参数。
无论给什么对象起名,都尽量使用完整的英语单词,同时使用下划线以区隔不同的单词。所谓好记性不如烂笔头,只有这样才能切实保证你在任何时候,在程序代码的任意位置都知道任意变量等的含义。
上节列出的基本字符集是在一切FROTRAN的编译平台都可以使用的,被FORTRAN 95标准规定为必须使用的默认字符集。另外还有些辅助的字符则是不同的平台有不同的用法约定。
辅助字符分两类:可打印字符和不可打印字符。
● 可打印字符;
各种本地化语言的字符,象汉字,希腊字母等,都可以应用在字符串,注释,和输入输出纪录当中。
● 不可打印字符。
主要就是控制字符,例如制表符Tab键。
制表符(Tab键)在FORTRAN77标准当中主要用来表示6个空格,这样在固定源程序形式的代码的每行的开头使用Tab,就自动地空出6个空格。
对于一个FORTRAN77标准的编译系统来说,在固定源程序形式里的Tab被看成是至少6个空格,而在自由源程序形式里的Tab被看成1个空格。这样如果Tab被放在文本当中用于输出格式控制,那么这种默认的转换方式,有时就会导致输出格式的混乱。
有关FORTRAN 95的辅助字符集的使用规则,请参考具体的编译系统的说明。
所谓FORTRAN的词汇就是一个语句的最小的意义单位,它由一个或多个FORTRAN字符集里的字符组成。包括两类共6种,分类例举如下:
● 由文字字符组成的词汇,包括4种:
· 语句关键词:IMPLICIT
· 名称:EIGEN_FREQUENCY_3
· 由单个词汇组成的字面常量:1.234567_long
· 标识符:213
● 由特殊字符组成的—
· 算符: +,.OR.
· 定界符:逗号,=,=〉,:,::,;,%。
FORTRAN 95的一切合法的词汇都必须按照语法来构成。完备的构词语法规则在附录B给出。
下面分别予以详细说明。
语句关键词的功用:
● 标志语句本身。
【例4-3】 下面的DO语句中的关键词DO本身标志了该语句
DO I=1,500
● 标志选项。
【例4-4】 下面的INTENT语句当中的IN,OUT,或INOUT。
INTENT(IN),A。B
INTENT(INOUT),X,Y,Z
● 用在语句当中,起分界的作用。
【例4-5】 如下面DO语句当中的WHILE
DO WHILE( .NOT. VECTOR )
并非所有的语句都必须包含关键词,在FORTRAN里面,赋值语句和函数都不需要关键词。
尽管FORTRAN 95不区分大小写,本书任何地方出现的语句关键词都使用大写字母。纯粹是为了醒目的原因。
在一个程序当中,任何对象都需要有一个名称,给它们命名所得到的词汇,可以说就是一般语言里的名词,这样的对象包括:变量,命名常量,程序单元,过程,公用块,构造,派生类型,哑元等。
名称的拼写规则为:
● 名称必须由字母开头,可以由文字字符混合组成,而下划线不能作为名称的第一个字符。
● 一个名称至多允许含有31个字符。
一个常量就是对一个值的合乎语法的字符标记。
常量分为字面常量和命名常量两种:
● 一个值如果没有在程序里面经过命名,则称为字面常量,这种常量不能取派生数据类型。
【例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/)
对于常量的语义,将在说明数据时进一步讨论。
在一个程序单元内部,对任何一条语句,都可以在该语句的前面加上语句标签,以便在该程序单元内部的任何其他位置引用该语句。需要引用其他语句的语句包括CALL语句,DO结构,分支语句,输入输出语句等。
语句标签的书写规则为:
● 语句标签由1到5个十进制数字组成,其中必须至少有一个数字不能是0,例如000不能作为标识符;
● 标识符以0开头是没有任何意义的,例如0034与34没有区别。
● 标识符不能放置于空语句之前。
【例4-8】
456
上面的语句只出现了一个语句标签,是不合法的。
● 对于在一个程序单元内部,标识符不唯一出现的情形,具有特殊的含义,将在后面讨论。
算符用在表达式当中,通过运算而获得某种类型的值。
算符分为固有算符和自定义算符两类:
● 固有算符
在FORTRAN 95语法当中,R310规定了固有算符的构成法则。
【例4-9】
//表示字符串的连接
+ 表示对数值的加法
.NOT. 表示逻辑否
.OR. 表示逻辑或
上面都是固有算符。
● 自定义算符
自定义算符的一般语法形式为:
.XXX… .
即在两个句点之间有n个字符构成的字符串,n不大于31。
中间的字母串最好是一个表达该运算含义的英文单词。这个单词不能与固有算符或者逻辑常量里面已经使用了的单词重复。
全部的定界符有如下12种形式:
/ ( ) (/ /) , = => : :: ; %
其中(和),(/和/)都必须成对出现
顾名思义,这些定界符的功能就是在一个连续的源码文本当中,用来把不同性质的源码成分区分开。它们的具体含义将在具体的语句当中说明。
一条语句由一些词汇组成,可以理解为表示要求计算机进行的一个动作,但一个说明,一个描述之类的,表面看好象不是计算机的一个动作,不过实质上同样要求机器内部的一个动作与之相对应,因此同样也构成FORTRAN的一条语句。
FORTRAN 95的语句分为两大类:
● 非执行语句
当需要引入或说明一个程序单元或子程序,或者是说明数据类型时,就需要使用非执行语句。
● 可执行语句
当需要计算机进行一个指定动作时,就需要使用可执行语句。
FORTRAN 95全部的语句的具体分类,以及语法和例示参见附录A,语句的语法也参见附录B。在后面的有关章节则分别说明了所涉及到的主要的语句。
一个FORTRAN 95程序就是由以下三种形式的程序成分所构成的分行的文本:
● FORTRAN语句
● 注释
● INCLUDE行
在一个FORTRAN 95程序里面,一条语句占一行或多行,一行也可以有多条语句,程序文本当中可以包含空行,但不具有任何含义,被FORTRAN编译器忽略。
这种形态的文本就是FORTRAN的源代码(源程序)。
从FORTRAN90开始,对于源程序的书写格式要求已经完全现代化了,也就是出现了所谓自由源程序格式,而此前,FORTRAN的固定源程序格式一直是初学者视为畏途的主要因素,那种传统的固定源程序格式完全是FORTRAN作为始祖级的高级语言的遗留痕迹,因为早期的源程序输入不是通过键盘,而是运用穿孔纸带,正是穿孔纸带的格式规定了相应的源程序的书写格式。现在之所以我们还需要了解这点,是因为FORTRAN的悠久历史,决定了有大量的源代码正是使用了那种古老格式,那是一个今天我们不得不继承的宝库,要想使用它们,显然就得会读那种格式,因此我们只需要了解固定格式,却不需要遵循固定格式来写代码。
【例4-10】
在这个例子里面,表明了行与语句之间可以有多种排列形式:
这里的例子显示了所谓自由源程序格式的自由之所在。这里使用了&作为一个语句在行与行之间连续的标志,而!后面的字符永远是注释。
23 FORMAT( 6Y, J9)!这是一条语句占有完整的一行的例子
37 FUNCTION string_concat(s1, & !这里一条语句被分到两行s2)
空格是被忽略的。
64 FORMAT( 6Y, J0);37 FUNCTION & !这里一行里有两条语句,其中一条
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!部分语句。
END FUNCTION string_concat
源码文本的一般规则如下:
● 在一个程序单元内部,行与行之间的顺序是有意义的,只有两个例外:
•注释行的顺序与位置可以非常自由;
•在CONTAINS语句和END语句之间的子程序的顺序也可以是任意的。
● 在一个程序单元内部,或者完全使用自由格式,或者完全使用固定格式。但是一个程序内部的不同程序单元则可以使用不同的格式。后面要说明为了便于协调起见,如何使用一种自由格式与固定格式兼容的特定格式。
● 所谓字符文本是指如下两种情形下的字符串:
• 作为一个字符字面常量的取值的字符或字符串;
• 被字符串编辑描述符控制的字符或字符串。
那么描述符本身和续行符&永远都不属于其邻近的字符文本。
● 针对字符文本的规则与针对非字符文本的规则是不一样的。
【例4-11】 下面例子说明了空格在字符文本与非字符文本当中的不同使用规则:
22 CHAR = NAME01 // “KNOWLEDGE ARCHIVE”
23 CHAR = NAME02 // “KNOWLEDGEARCHIVE”
在双引号里的字符串之间的空格是有意义的,因此上面的两个字符串是不同的。
DO43I=1,N
DO 43 I = 1,N
而上面这两条语句是等价的。
自由源程序格式的主要思想就是不限制语句在行内的位置。与固定格式相比,主要是空格的用法有差异。
自由源程序格式的一般规则如下:
● 对于FORTRAN的基本字符集而言,一行至多能容纳132个字符,如果出现非基本字符集当中的字符,则具体的平台会有相应的规定,这时,可能能够容纳的字符数目就会少于132。
【例4-12】 假如下面的语句刚好包含132个字符,但是其中含有中文字符:
TEXT = CHINESE_SENTENCE’this line has exactly 132 characters and contains人’
这时,一个具体的实现平台会有相应的规定,一般来说它会认为上面语句的字符太
多了,因此为保险起见,尽量使用续行符。
● 只要字符!不是作为字符文本当中的一个字符,那么在该行内它后面的所有字符都是属于注释的内容。而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】 下面的写法是错误的。
53 INTEGER X,Y !这里53是合法的标签
IF (X==0)76 Y=X !这里的标签76不能说明自己不属于IF语句
下面我们更加详细地说明在自由源码形式里面续行符和空格的用法。
只是采用续行符的不同用法,就有可能产生完全不等价的语句,因为续行符能够导致名称的变化。所以如果一个名称,字符常量,或词汇被迫分行,则必须在前一行的末尾和后一行的开头紧接着字符使用&。
【例4-15】
ENERGY = 0.5*MASS * VILOC& !这里VILOCITY是一个变量名
&ITY**2
ENERGY = 0.5*MASS * VILOC & !这里变量名成了VILOC ITY!
&ITY**2
ENERGY = 0.5*MASS * VILOC & & !这里变量名成了VILOC & ITY!
&ITY**2
上面的三个语句是完全不等价的!
在具有固定名称以及固定格式的算符当中,不能随意使用空格。因为空格默认的功能就是分隔不同的词汇。
【例4-16】
CALL SUBROUTINE A
CALL SUBRO UTINE A!错误语句!
IF X = .NOT .
IF X = .NOT. !这两条语句不同
【例4-17】 下面语句当中的空格是不可少的:
INTEGER X,Y
IF A=0
DO Y=1,20
但不是所有情形下的词汇之间必须要有空格,在不会产生混乱的前提下,有些语句关键词之间的空格是可以省略的,对于语句关键词来说,所有这些不同的情形列举如下表4-1:
表4-1语句关键词中间空格含义的不同情形
非必须的空格 |
必要的空格 |
BLOCK DATA |
CASE DEFAULT |
DOUBLE COMPLEX |
DO WHILE |
DOUBLE COMPLEX |
DO WHILE |
DOUBLE PRECISION |
IMPLICIT type-specifier |
ELSE IF |
IMPLICIT NONE |
END BLOCK DATA |
INTERFACE ASSIGNMENT |
END DO |
INTERFACE OPERATOR |
END FILE |
MODULE PROCEDURE |
END FORALL |
RECURSIVE FUNCTION |
END FUNCTION |
RECURSIVE SUBROUTINE |
END IF |
RECURSIVE type-specifier FUNCTION |
END INTERFACE |
type-specifier FUNCTION |
END MODULE |
type-specifier RECURSIVE FUNCTION |
END PROGRAM |
|
END SELECT |
|
END SUBROUTINE |
|
END TYPE |
|
END WHERE |
|
GO TO |
|
IN OUT |
|
SELECT CASE |
|
今天已经没有必要按照固定格式书写源程序,只需要能够阅读古老的使用固定格式的代码,如果有必要把固定格式的源程序转换为自由格式,也可以运用某些小软件完成,因此下面只是简要地介绍固定格式的几个规则。
● 语句只能书写在一行的第7到第72个格子上。
● 空格除了在字符常量里以外,都是没有意义的。
● 在某行第一格为字符C,或*,就表示该行整行都是注释。注释总是被忽略。
● 字符!只要不是出现在第6格,也不是属于字符文本,则从它开始一直到该行的行末,都属于注释。
● 一行如果只包含空格字符,或者根本不包含任何字符(这两者表现一样),那么编译器总是把该行视为注释行,予以忽略。
● 一行中的多条语句用一个或多个分号分隔;分号可以出现在行末,但没有更多的意义;分号不能是一行的第7到第72个格子上第一个非空格字符。
● 除了空格和0之外的任意字符,只要出现在某行第6格上,则表示该行为连续行。一行后面最多只能有19个连续行,第一行称为初始行。
● 标识符只能出现在第1到第5格上,被连续的语句只有第一行可以使用标识符,这样下面所有的连续行的第1到第5格上只能是空格。
● END语句不能被连续,它也不能被视为初始行。
在某些情形下,需要书写能够同时被自由格式和固定格式兼容的源码,要做到这点,只需要遵循以下规则即可:
● 标识符只能出现在第1到第5格上,语句只能书写在一行的第7到第72个格子上。
● 按照自由格式的规则使用空格。
● 使用!作注释符,但不要放置在第6格,也不要是用使用字符C,或*作注释符。
● 需要连续行时,在被连续行的第73格写&,同时在连续行的第6格也写&,第74格到80格保持空格或者只写注释。而连续行的第1到第5格上只能是空格。
下面就是一个同时满足两种源码形式要求的代码例程:
【例4-18】
Column:
12345678...73
_________________________________________________________________________
! Define the function CUT_SIN
DOUBLE PRECISION FUNCTION CUT_SIN(X)
CUT_SIN = X - X**3/FACTOR(3) + X**5/FACTOR(5)&
&- X**7/FACTOR(7)
CONTAINS
INTEGER FUNCTION FACTOR(N)
FACTOR = 1
DO 10 I = N, 1, -1
10 FACTOR = FACTOR * I
END FUNCTION FACTOR
END FUNCTION CUT_SIN
在FORTRAN 95的语法规则里面规定了程序结构的完整定义,参见附录B。
不过那里的语法规则并没有完备地表述在一个程序单元里,各种语句应该遵循什么顺序。下面给出一般原则:
● 数据类型声明和指定的语句必须放置在可执行结构或语句之前;
● FORMAT,DATA,ENTRY语句也可以放置在可执行语句中间,不过把DATA语句放置在可执行语句中间是一种过时的做法;
● 如果出现USE语句,必须总是放在最前面;
● 如果出现内部子程序或模块子程序,则必须跟在CONTAINS语句后面。
【例4-19】 下面是一个典型的只包含一个程序单元,也就是主程序的FORTRAN程序:
!本程序能够求出所有100-999之间每一位上的数字的立方和等于自身的三位数。
PROGRAM SUM_OF_CUBES
INTEGER A,B,C
DO A = 1,9
DO B = 0,9
DO C = 0,9
IF (100*A + 10*B + C == A**3 + B**3 + C**3) &
PRINT “(3I1)”, A,B,C
END DO
END DO
END DO
END PROGRAM SUM_OF_CUBES
RUN SUM_OF_CUBES
153
370
371
407
大家不妨尝试一下,1000-9999之间还存在这样的数字吗?如果是平方呢?
下面的表4-2给出了程序单元的基本模式,其中处于同一水平位置的各语句之间没有严格的前后顺序,而不同的行则表示了严格的在程序当中出现的前后顺序:
表4-2程序单元的基本模式
程序,函数,子例行程序,模块,数据块语句 |
||
USE语句 |
||
FORMAT语句, ENTRY语句 |
IMPLICIT NONE |
|
PARAMETER语句 |
IMPLICIT语句 |
|
PARAMETER语句, DATA语句 |
派生数据类型定义, 接口块, 数据类型声明语句, 语句函数语句, 特定语句 |
|
DATA语句 |
可执行结构 |
|
CONTAINS语句 |
||
内部子程序或模块子程序 |
||
END语句 |
||
●把 DATA语句放置在可执行结构中间已经过时。 ●语句函数语句已经过时。 |
表4-3给出一个特定的语句能够在什么结构中出现,不能在什么结构中出现的概貌:
表4-3 语句的环境
|
作用单元的种类 |
||||||
语句 |
主程序 |
模块 |
数据块 |
外部子程序 |
模块子程序 |
内部子程序 |
接口块 |
USE语句 |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
ENTRY语句 |
N |
N |
N |
Y |
Y |
N |
N |
FORMAT语句 |
Y |
N |
N |
Y |
Y |
Y |
N |
其他声明 |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
DATA语句 |
Y |
Y |
Y |
Y |
Y |
Y |
N |
派生类型定义 |
Y |
Y |
Y |
Y |
Y |
Y |
Y |
接口块 |
Y |
Y |
N |
Y |
Y |
Y |
Y |
语句函数 |
Y |
N |
N |
Y |
Y |
Y |
N |
CONTAINS |
Y |
Y |
N |
Y |
Y |
N |
N |
可执行语句 |
Y |
N |
N |
Y |
Y |
Y |
N |
其中Y表示该语句可以在相应的结构当中出现,N表示不能出现。
很多时候一个完整程序的源码还可以原封不动地移植到另一个程序源码的中间,这时并不需要把被移植源码完整地抄写过来,而只需要简单地运用INCLUDE行即可。
【例4-20】
PROGRAM GREEN_FUNCTION
REAL X,Y,Z
….!语句省略
INCLUDE ‘GAUSE’
….! 语句省略
END
这样源码文件GAUSE就直接进入程序GREEN_FUNCTION的源码里面,取代了INCLUDE行的位置。
INCLUDE行由关键词INCLUDE和其后的文件名称组成。其中的文件名称是一个字符文本常量。
● INCLUDE行只是针对编译器的一个提示,而不是属于程序内的FORTRAN语句。
● 其中的字符文本常量不能带作为命名常量的种别参数。
● INCLUDE行必须放置在程序当中,其所引用文件应当出现的位置。
● INCLUDE行所在行不能有任何其他文字,包括标识符,当然可以有注释。
● INCLUDE行可以进行嵌套,嵌套的层数由具体的编译器规定。注意在嵌套的同时不能导致定义循环。
● INCLUDE行之前的语句不能是被连续行,其后的语句也不能是连续行。
下面简要地比较一下,作为一种语言,FORTRAN和其它语言在总的语法风格方面的异同。
一种计算机语言的语法远比任何自然语言的语法要来得简单明了,计算机语言的语法风格可以明确地归结为各种基本语法要素的选择。因此可以按照语法要素对不同的语言加以比较。
按照语言的所谓形式定义,语言就是取自一个有限字符集合的任意字符所构成的有限字符串的集合。
显然,一种语言选择哪些字符作为它的字符集,正是语言文法设计的第一步。
最常用的字符集就是ASCII字符集,而一套完整的字符集除基本字母和数字外,通常还包含一些特殊字符,以便为语言提供足够的表达手段。
表面看来,一种语言所使用的字符越多,它的表达能力应该是越大,然而在增大字符集的同时,也增加了编译时词法分析的分量,因此这里的折衷方式的不同,造就了不同语言的字符集的差异。
字符集的选择首先来自语言的输入输出设备。对于FORTRAN,C等大多数语言,是面向以工业标准键盘为主的输入输出设备的,因此这些语言的字符集可以说是大同小异的,不过也有例外,如APL语言就使用了ASCII字符集之外非常特殊的字符,因此这种语言的字符集就不能被大多数输入输出设备直接使用。
从计算机历史来讲,到了1960年代的早期,计算机行业对字符的表示大都由六位字节转变为八位字节,这样理论上就有了256个字符可用,分配给52个大小写字母、十个数字以及一些标点符号,应该是足够了。不过,由于计算机语言本地化的趋势越来越流行,语言的国际化导致各种民族语言的文字都要求进入字符集。除了法语,德语里的语音符号之外,希腊语,阿拉伯语之类的语言有着完全不同的字符集。而如果中文和日文要进入计算机语言,则需要一个有一万多符号的字符集。因此甚至出现了一种想法,就是考虑用十六位(65536)来表示字符集。
在FORTRAN77及其前面的标准里,语句标签的使用具有严重的时代烙印,而随着技术的进步,这种过时的玩意在大多数情况下不再具有任何价值,特别是严重地损害源码的可读性。因此语句标签在任何语言里都是属于需要淘汰的对象。
字符+和-(加号和减号)在大多数语言里都是代表两种基本的数学运算,不过除了这两个符号之外,其他的运算算符就有相当多的花样了。
例如只是用特殊字符来表示基本运算算符,典型的就是APL语言,还有LISP语言、TIMES语言等的逻辑运算符;而大多数语言使用一些字符组合,同时也利用特殊字符来表示部分运算算符,有时还使用一些不属于上述两种之中任意一种的字符串来表示部分运算算符,例如FORTRAN里面的.EQ.表示相等,指数运算用**表示等。
计算机语言大都使用保留字与关键词,从而能够提高翻译器的检错能力。而且大多数以关键词开始的语句本身就表明了语句的类型。例如IF、READ等。
一种语言究竟使用多少保留字和关键词,往往是一个折衷的结果:保留字少,可以减少编程者的记忆负担,同时却会增加语法分析的困难;而如果使用大量的保留字,例如COBOL语言,使用了大量的保留字,使得编程者很难全部记下,因此就会常常出现不小心使用保留字作变量名的错误,当然使用很多的保留字,就会使得翻译过程中的语法分析变得更为简单。 特别需要注意的是,当一种语言出现新版本时,得小心是否引入了新的保留字,例如COBOL语言,就在新标准里引入了新的保留字,这就意味着那些在程序中使用新的保留字作为变量名(或其他名字)的旧程序,按照新标准在语法上就不再正确了,尽管这个程序一点也没有改过。对于FORTRAN来说,这类问题就没那么严重。
尽管注释一定是被编译器忽略的,但却是文件中十分重要的一部分,因为注释是保证源码的可读性非常重要的手段。在不同的语言里,表示注释的方式非常不同,甚至在一种语言里,也可能有几种方法引入注释:
在C语言程序中,需要使用/*和*/这样的特殊标记来界定而不管行边界,这时常常出现的错误就是漏掉结束的界定符,使得后面的语句也变成了注解!
FORTRAN 95语言中的! ,Ada语言中的-,或是C十十语言中的//,都是在行的任意位置开始而直到行的末尾结束。这种做法就更为合理方便。
在不同的语言里空格的使用规则非常不同。这点需要引起注意。在FORTRAN语言中,空格在除了字符串数据以外的任何其他地方都没有意义。而在很多语言当中使用空格来作为分界符,这就使得空格在语法中有实际的含义。对于初学者来说,常常意识不到空格带来的问题。
定界符的作用就是简单地标志类似语句或表达式之类的语法元素,目的就是增加源码的可读性,并且使得语法分析更加简单。特别需要注意的是,成对的定界符用来清楚地界定特定语法结构的边界,从而可以有效地消除二义性。
严格的固定字段格式一般是应用在汇编语言当中。而早期的FORTRAN则是使用了部分固定字段格式;其实很多语言早期同样是具有部分固定字段格式,不过现代语言的风格是完全排斥那种固定格式的,因此几乎所有语言,只要还没有被废弃,都已经采用了自由字段格式。