第4546讲计算机应用基础2.docx
《第4546讲计算机应用基础2.docx》由会员分享,可在线阅读,更多相关《第4546讲计算机应用基础2.docx(22页珍藏版)》请在冰豆网上搜索。
第4546讲计算机应用基础2
五、输入输出语句
(一)表控输入输出
表控输入输出语句是一种隐含格式的输入输出语句,其格式由程序编译系统提供,在程序语句中不予表示。
1.表控输出语句
FORTRAN77表控输出语句有两种方式:
PRINT*,输出量表
WRITE(*,*)输出量表
这两种表控输出语句的作用是相同的,但一般微机上的FORTRAN77子集不提供PRINT语句,所以通常使用WRITE语句。
2.表控输入
FORTRAN77表控输入语句有两种型式:
READ*,输入量表
READ(*,*)输入量表
表控输入又称为自由格式输入。
表控输入语句要求用户在隐含的输入设备(通常是键盘)上输入所需的数据,在输入数据时,各数据之间用逗号或空格分隔。
(二)格式输入输出
1.格式输出数据语句WRITE语句和FORMAT语句
WRITE语句的一般形式为:
WRITE(u,f)输出量表
其中,u为部件说明符,用以指出在哪个设备上进行输出,通常也称为通道号,当U为记号*时,表示在显示器(标准输出设备)上进行输出。
f为格式说明,它通常是一个格式语句的标号,用以指出输出数据所采用的格式。
格式语句的一般形式为:
标号FORMAT(格式说明)
例如:
WRITE(*,10)A,B,A*B
10FORMAT(lX,F6.2,F7.3,F10.4)
FORMAT语句中,第一个"1X"称为纵向控制符,它表示前进一空格后再输出后面的数据,后面的三个项分别说明了三个实型数据输出的,称为格式编辑符。
FORTRAN77也允许在WRITE语句中直接指定输出格式,从而可以省略格式语句FORMAT。
例如,上面的输出语句与格式语句可以合并成一个,即:
WRITE(*,I(1X,F6.2,F7.3,F10.4)')A,B,A*B
2.格式编辑符FORTRAN常用的格式符有十几种,详细可参照任何一本FORTRAN教材或专用于册。
(三)隐循环的输入输出
数组元素的输入输出可以采用循环方式实现。
例如:
DIMENSIONX(20)
DO101=1,20
20READ*,X(I)
程序段执行时进行20次循环,每次输入1个数据。
这个输入程序段可以改写如下:
DIMENSIONX(20)
READ*,(X(I),I=1,20)
其中第2句就是隐循环的输入语句。
循环控制变量I的初值为1,终值为20,步长为1而予以省略。
隐循环语句的作用与∞语句是相同的;但使用隐循环语句时,20个数据允许一次性输入,当然,数据与数据之间要用空格符或逗号区别开来。
隐循环语句也用于输出语句,也可使用多重循环。
例如
DIMENSIONY(l0,6)
READ(*,*)((Y(I,J),J=1,6),I=1,10)
WRITE(*,5)((Y(I,J),J=1,6),I=1,10)
5FORMAT(lX,6F10.2)
运行程序段时,首先读入60个数据,Y(1,1),Y(1,2),……,Y(1,6),Y(2,1),Y(2,2),……,Y(2,6),……,Y(10,1),Y(10,2),……,Y(10,6),然后输出60个数据,每行输出6个数据,数据的排列顺序与输入时相同。
六、控制语句
一般情况下,FORTRAN程序是按语句顺序执行的,但需要时,可以改变这种顺序。
这种改变可以通过各种控制转移语句、逻辑条件语句等来实现。
(一)转移语句
1.无条件转移语句
无条件转移语句的一般形式为:
GOTOn
当程序流程到达GOTO语句时,随后就转向语句标号为n的语句。
标号为n的语句必须是可执行语句,但它在程序中的排列位置,可以在引导到它的GOTO语句之后,也可以在该GOTO语句之前。
元条件转移语句常和其他控制语句结合起来使用。
2.算术条件转移语句
算术条件转移语句的一般形式为:
IF(e)nl,n2,n3
其中,e必须是算术表达式,当表达式运算结果e<0时,程序转向标号为n1的语句;当e=0时,转向标号为n2的语句;当e>0时,转向标号为n3的语句。
例如,计算边长为B的正方形中挖去半径为R的圆后的面积,若B<2R,则给出相关信息。
该问题的FORTRAN程序可用别辽条件转移语句编写如下。
CComputationofarea.
READ*B.R
IF(B-2*R)5,15,15
5WRITE(*,10)
10FORMAT('Errormessage:
Blessthan2*R‘)
GOTO20
15AREA=B*B-3.14159*R*R
WRITE*AREA
20CONTINUE
END
本例中,在算术条件转移语句的第1个分支后,使用了GOTO语句;倘没有此语句,则程序按顺序仍会执行标号为15的语句,从而得出不正确的结果。
3.计算转移语句
计算转移语句的一般形式为:
GOTO(n1,n2,……,nm),e
其中,ni(i=1,2,……,m)是被转向的语句标号,共m个;e是一个整型算术表达式,其值不得小于1且不得大于m。
当e的值等于1时,程序转向标号nl的语句,当e的值等于2时转向标号n2的话句,当e的值为m时转向标号为nm的语句。
整型算术表达式e前的逗号可以省略。
计算转移语句通常也和GOTO语句结合起来使用。
例如,有如下一个程序:
READ*,M
GOTO(20,30,40,50)M
20N=MGOTO60
30N=M*2GOTO60
40N=M*3GOTO60
50N=M*4
60WRITE铃,N
END
程序运行时,若输入1,则转向标号为20的语句,x的值为1;若输入2,则转向标号为30的语句,x的值为4;输入3,转向标号为40的语句,x的值为9,输入4,转向标号为50的语句,x的值为160
(二)逻辑条件语句
1.逻辑IF语句
逻辑IF语句用来实现选择结构。
它的一般形式为:
IF(逻辑表达式)内嵌语句
其中内嵌语句是单独的一个可执行语句。
逻辑IF语句执行时,首先计算逻辑表达式的值,如果逻辑表达式的值为"真",则执行内嵌语句,若内嵌语句非转移语句,则执行该语句后继续按顺序往下执行,若内嵌语句是转移语句,则转向指定的语句;如果逻辑表达式的值为"假",则不执行内嵌语句,而直接执行该语句后面的语句。
例如,从键盘读入一个代表百分制成绩的数据,如果数据在90-100之间就输出‘Excellent',在80-89之间输出‘Good',在60-79之间输出‘Pass',在60以下则输出‘Notpass'。
其程序可以如下编写:
READ(*.*)IPOINT
IF(IPOINT.GT.100.OR.IPOINT.LT.0)WRITE(*,*)'DATAERROR'
IF(IPOINT.GE.90.AND.IPOINT.LE.100)WRITE(*.*)'Excellent'
IF(IPOINT.GE.80.AND.IPOINT.LT.89)WRITE(*.*'Good'
IF(IPOINT.GE.60.AND.IPOINT.LT.79)WRITE(*.*)'Pass'
IF(IPOINT.GE.0.AND.IPOINT.LT.59)WRITE(*.*)'NotPass'
END
2.块IF结构的各种形式
(1)块IF和ENDIF形式
IF(逻辑表达式)THEN
语句块
ENDIF
当逻辑表达式的值为"真"时,执行语句块,否则按顺序执行ENDIF后的语句。
例如,如下程序段:
READ*,RN,AN
IF(RN.GE.O.O.AND.AN.GT.0.0)THEN
STRESS=RN/AN
WRITE*RN,AN,STRESS
END
当RN大于等于零且AN大于零时,执行赋值语句和输出语句。
(2)使用ELSE的形式
IF(逻辑表达式)THEN
语句块1
ELSE
语句块2
ENDIF
当逻辑表达式的值为"真"时,执行语句块1,当逻辑表达式的值为"假"时,执行语句块2。
由此可见,使用ELSE的形式,可以进行两个分支的选择。
(3)使用ELSEIF的形式
IF(逻辑表达式1)THEN
语句块1
ELSEIF(逻辑表达式2)THEN
语句块2
ELSE
语句块3
ENDIF
这种形式,允许在三个分支中作出选择。
当逻辑表达式1的值为"真"时,执行语句块1表示的分支;当逻辑表达式1的值为"假"而逻辑表达式2的值为"真"时,执行语句块2表示的分支;当逻辑表达式1的值和逻辑表达式2的值均为"假"时,执行语句块3表示的分支。
3.块IF结构的嵌套
在一个块IF结构的语句块中,可以完整地包含另一个或多个块IF结构,称为块IF的嵌磁。
块的嵌套可以多层。
七、函数与子程序(过程)
(一)内部函数
内部函数是预先编制的一些常用函数或算法的过程,由FORTRAN语言提供,可以,直接调用。
内部函数调用时的一般形式是:
内部函数名(实元表)
实元表中元素的数据类型、个数是预先规定的。
常用内部函数及其功能可查阅FORTRAN教材或用户手册。
(二)语句函数
1.语句函数的定义
定义语句函数的语句称为语句函数语句。
其一般形式为:
函数名(形参表)=表达式。
其中,函数名的命名规则与一般变量名相同,所以它也可以用类型说明语句等来说明。
形参又称哑元,是一些变量名,一般应出现在表达式中。
语句函数在程序单位中的位置,应在所有可执行语句之前。
2.语句函数的调用
调用语句函数的结果是得到一个函数值,因此,调用语句函数时代之以实际变量(又称实元)。
(三)函数子程序
一个函数子程序是一个独立的FORTRAN程序单位。
它的第一个语句必须是FUNCTION语句,最后一个语句必须是END语句。
即函数子程序的一般结构为:
[类型说明]FUNCTION函数名(形参表)
语句块
[RETURN]
END
也可以写为:
FUNCTION函数名(形参表)
[类型说明函数名]
语句块
[RETURN]
END
其中函数名的命名规则与变量相间,而函数名的类型决定了函数值的类型。
在函数子程序中,形参可以是变量名、数组名、外部过程名,而形参的命名与类型说明也与变量相同,形参数组也必须在函数子程序中予以定义。
函数子程序的函数值由函数名带回到调用该函数子程序的程序,因此,在函数子程序中必须对函数名赋值。
在函数子程序中,函数名应该像普通变量那样来使用。
在函数子程序中,所有的名字、语句标号都可以和其他程序单位中的相同而彼此没有任何关系。
在函数子程序中,END语句的功能有两个:
一是表示该程序单位的结束,二是具有返回语句RETURN的功能。
函数子程序中必须有并且只有一个END语句,而且只能是子程序的最后一个语句。
当在子程序的其他位置须要返回时,可以使用RETURN语句。
(四)子程序
1.子程序的结构
一个子程序是一个独立的FORTRAN程序单位。
子程序的第一个语句必须是SUBROUTINE语句,最后一个语句必须是END语句。
即子程序的一般结构为:
SUBROUTINE子程序名(形参表)
语句块
[RETURN]
END
子程序名的命名规则与普通变量相同。
但是子程序中的子程序名不能用于返回数值,这与函数子程序是不同的。
因此,子程序名没有类型,它不能在本程序单位中使用。
SUBROUTINE语句中的形参表可以省略。
这时子程序名后的括弧不要保留。
对子程序的其他有关规定与函数子程序相同。
2.子程序的调用
子程序调用通过CALL语句实现。
其形式为:
CALL子程序名(实参)
其他有关对子程序的调用规定与函数子程序相同。
八、程序单位间的数据传递
(一)虚实结合
虚实结合又称哑实结合,是各程序单位(主程序和各种过程如函数子程序)之间传递数据的一种重要途径。
1.变量的虚实结合
当子程序等过程的形参为变量时,则在调用时所对应的实参可以是类型相同的常数、变量、数组元素或表达式;子程序调用后,其运行的结果通过这些实参返回到调用者。
在FORTRAN77中,当形参变量所对应的实参是变量或数组元素时,则它们之间的结合方式是地址结合;而当形参变量所对应的实参是常数或表达式时,其结合方法对于不同的FORTRAN系统有可能是不同的。
2.数组的虚实结合
当子程序中的形参为数组名时,则在调用时所对应的实参必须是数组名或数组元素。
如果实参是数组名,则实参数组与形参数组按地址结合,实参数组与形参数组都从第一个元素开始按列逐个对应。
例如,有主程序与子程序如下:
PROGRAMMAIN
INTEGERA(0:
5)
CALLSB(A)
END
SUBROUTINESB(B)INTEGERB(-1:
2)
END
则在主程序中使用CALL语句调用子程序SB时,实参数组与形参数组的结合情况如下:
实参数组形参数组
A(0)——B(-1)
A
(1)一一B(0)
A
(2)——B
(1)
A(3)一一B
(2)
A(4)
A(5)
也即调用SB时,A数组的头4个元素与B数组的元素对应,这些对应元素实际上为同一存储地址。
如果实参是数组元素,则从该元素开始依次与形参数组的第一个元素起按列逐个对应,它们也是按地址结合。
例如,有主程序与子程序如下:
PROGRAMMAIN
DIMENTIONA(8)
CALLSB(A(5))
END
SUBROUTINESB(B)DIMENSIONB(3)
END
则在调用语句执行时,实参数组A与形参数组B的结合情况如下:
实参数组形参数组
A
(1)
A
(2)
A(3)
A(4)
A(5)——B
(1)
A(6)一一B
(2)
A(7)——B(3)
A(8)
FORTRAN77规定,不管实参是数组名还是数组元素,用作实参的数组,其维数、各维下标的上下限及数组中元素个数可以和与之结合的形参数组不同,但要求从与形参数组的第一个元素结合的实参数组元素算起,以后的实参数组元素的个数不能少于形参数组元素的个数。
多维数组或数组元素虚实结合时,要特别注意FORTRAN中数组按列存放的规定,不要搞错存储地址的对应关系。
例如:
PROGRAMMAIN
DIMENSIONA(3,2)
CALLSB(A)
。
。
。
END
SUBROUTINESB(B)
DIMENSIONB(2,3)
。
。
。
END
这种情况下,数组元索地址的对应关系是:
实参数组形参数组
A(1,1)一一B(1,1)
A(2,1)一一B(2,1)
A(3,1)一一B(1,2)
A(1,2)一一B(2,2)
A(2,2)一一B(1,3)
A(3,2)一一B(2,3)
3.可调数组
在主程序中定义数组元素时,定义说明符中各维下标的上下限必须为整常数,不能是变量或算术表达式。
但在子程序中定义数组时,允许用变量来定义各维下标的上下限。
子程序中用变量来定义各维下标上下限的数组称为可调数组。
但使用可调数组必须遵循以下几个原则。
(1)可调数组名必须是形参数组名。
(2)说明可调数组各维下标上下限的表达式中只能出现整型变量,且这种变量必须是形参或出现在COMMON语句中。
但在某些FORTRAN77子集中,定义可调数组各维下标上下限时只能是整型变量,而不能是任何算术表达式。
(3)可调数组的大小不得超过对应实参数组的大小。
4.字符型变量的虚实结合
(1)当子程序中的形参为字符型变量时,对应的实参必须是字符型变量、字符常数、字符型数组元素或字符表达式。
字符型实参必须用CHARACTER语句加以说明。
(2)如果字符型形参的长度小于对应的实参长度,则从实参中最左边的字符开始与形参结合,而实参中右边多余的字符被截去。
例如:
CHARACTERA*5
A=ABCDE'
CALLSB(A)
END
SUBROUTINESB(X)
CHARACTERX*3
WRITE(*,*)X
END
程序执行后的输出结果为:
ABC。
(3)在FORTRAN77中,对字符型形参的长度还可以用"*"号来说明,此时,形参字符变量自动与对应的实参取相同的长度。
例如在上面的子程序SB中,如果将CHARACTERX*3改变为CHARACTERX*(*),则执行后,输出的结果为:
ABCDE。
(4)当子程序中形参为字符型数组时,如果形参字符型数组元素的长度与对应实参字符型数组元素长度一致,则其虚实结合的情况与一般的数组虚实结合的情况相同。
如果形参与实参的字符型数组元素长度不同,则按字符依次对应。
例如,有主程序与子程序如下:
CHARACTERA(5)*3
DATAAI'ABC','DEF','GHI','JKL','MNO'/
CALLSB(A)
END
SUBROUTINESB(D)CHARACTERD(4)*2
END
则形参数组D中元素的值为:
D
(1):
'AB'
D
(2):
'CD'
D(3):
'EF'
D(4):
'GH'
(5)过程名的虚实结合FORTRAN允许子程序中的形参为过程名,此时,调用程序中的实参必须是过程名.如果实参是外部过程名(如函数子程序名、子程序名),则该外部过程名在调用程序中必须用EXTERNAL语句说明。
如果实参是内部过程名(如内部函数名),则该内部过程名在调用中必须用INTRINSIC语句说明。
(二)公用区语句
1.公用区语句的一般形式
COMMON[公用区名l/]变量表1,[公用区名2/变量表2]…
没有公用区名的就称为无名公用区,其他都是有名公用区;一个完整的程序只能设置一个无名公用区,但可以有多个有名公用区;变量表中,可以是变量名、数组名、数组说明符,互相之间用逗号隔开。
例如:
COMMONa,b(3),c
(2)
定义了b是3个元素的一维数组,c是2个元素的一维数组。
这条语句与下面两句语句是等价的:
DIMENSIONb(3),c
(2)
COMMONa,b,c
2.利用公用区进行数据传递时,在元名公用区或同名的有名公用区中,位置排列相同的变量、数组,实际上使用同一存储地址,亦即共享同一数据。
例如:
PROGRAMMAIN
COMMONa,I
(2)/COMl/d,c
。
。
。
CALLSB
END
SUBROUTINESB
COMMONaa,]K
(2)/COMl/f,g
END
其中,主程序中的变量a的数据与子程序的变量aa共享,数组1的数据与JK共享,而d,c的数据分别与f,g共享。
由此可以知道,各个程序单位中COMMON语句中的变量类型必须按位置一一对应一致才能正确传递数据。
九、文件
FORTRAN程序输入输出的基本单位称为记录。
记录是数值或字符的序列。
记录的集合称作文件。
(一)文件的存取方式
1.顺序文件
顺序文件中的记录是一个接一个按顺序存放的,即总从第1个记录开始,然后是第2个记录,第3个记录,…,要取任何一个记录,都必须从第1个记录开始。
2.直接文件
直接文件又称直接存取文件,或随机文件。
它可以按任意顺序读写某一记录。
直接文件中每个记录的长度都是相等的。
(二)文件操作语句
文件操作语句有打开文件的OPEN语句和关闭文件的CLOSE语句。
此外还有文件的读写语句READ语句和WRITE语句。
(三)文件定位
设想在文件的读写操作时存在一根指针。
起先指针停在文件的开始处,随着文件存取的进行,指针在文件中移动。
控制指针的位置,即定位,在FORTRAN中可以通过如下语句来实现。
I.REWIND语句
REWIND语句也称回绕语句。
它的形式是:
REWIND设备号
它使与指定设备号相连的文件中的指针定位在文件的开头。
在FORTRAN中,用OPEN语句打开一个文件,指针也是在文件的开头位置。
因此对一个已经打开的文件,要使指针移到开头,也可组合使用CLOSE和OPEN语句。
2.BACKSPACE语句
语句BACKSPACE的形式是:
BACKSPACE设备号
它使与指定设备号相连的文件中的指针退回一个记录。
例题:
1.语句序列
DO10I=1,5,2
DO10J=2,6,2
10K=I+J
WRITE(*,*)
执行的结果是(C)
(A)K=9(B)K=10(C)K=11(D)K=12
2.若有INTEGERA(-2:
0:
3,1:
2),按照在内存中的存储次序,数组A中第8号元素为(B)
(A)A(-1,0,2)(B)A(0,1,1)
(C)A(2,1,2)(D)A(1,1,1)
3.对下列程序段
READ(*,*)X
IF((X.LT.-5.0).OR.(X.EQ.-1.0))THEN
Y=0.0
ELSEIF(X.LT.0.0)THEN
Y=1.0/(X+1.0)
ELSEIF(X.LT.5.0)THEN
Y=1.0/(X+2.0)
ELSE
Y=0.0
ENDIF
WRITE(*,*)Y
若输入4.0,则结果为:
(A)0.0(B)1/5(C)1/6(D)1/4十2.0
4.以下程序段
PROGRAMMAIN
EXTERNALFX
Y=TX(FX,3,2)
PRINT*,Y
END
FUNCTIONTX(FUN,A,B)
TX=(FUN(A)-FUN(B))/2.0
END
FUNCTIONFX(X)
FX=X*X
END
运行的结果为(C)
(A)9(B)4(C)2.5(D)6.5
习题:
1.以下程序段
DIMENSIONA(4)
READ*,A
10J=I+1
20IF(A(I).LT.A(J))THEN
T=A(J)
A(J)=A(I)
A(I)=T
ENDIF
J=J+l
IF(J.LE.A)GOTO20
I=I+1
IF(1.LE.3)GOTO10
PRINT*,A(4)
END
若输入4,2,3,5,则程序运行结果为(B)
(A)4
(B)2
(C)3
(D)5
2.对下列程序段
PARAMETER(N=3)
INTEGERA(N,N)
READ*,A
DO10J=1,N
LS=0
DO201=1,N
20LS=LS+A(I,J)
LS=LS/N
DO30I=1,N
30A(I,J)=A(I,J)-LS
10CONTINUE
PRINT*,A
END
若输入2,4,6,8,10,12,14,16,18