版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
FORTRAN語言
--FORTRAN77結(jié)構(gòu)化程序設(shè)計(jì)講師:徐紅波Email:第九章子程序
應(yīng)用程序由一個(gè)主程序和若干個(gè)子程序組成。程序中可以只有主程序而沒有子程序,但是不能沒有主程序而只有子程序。以前程序舉例都只是由主程序組成的。程序在運(yùn)行時(shí)總是從主程序開始執(zhí)行,所以如果沒有主程序,程序就無法運(yùn)行。 子程序有函數(shù)子程序、子例行程序和數(shù)據(jù)塊子程序三種。數(shù)據(jù)塊子程序僅用來給公用區(qū)中的變量賦初值,故將它放在后面與公用區(qū)的使用同時(shí)介紹。
子程序可以被主程序調(diào)用,也可以被其它子程序調(diào)用,但是子程序不能直接或間接地自己調(diào)用自己,不允許遞歸調(diào)用。把調(diào)用子程序的主程序和子程序統(tǒng)稱為調(diào)用程序,把被調(diào)用的子程序統(tǒng)稱為被調(diào)用程序。9.1函數(shù)子程序函數(shù)實(shí)例:f(x)=x4+x3+2x-7 +1 (x>0) Y=0 (x=0) -1 (x<0)函數(shù)子程序:
FUNCTIONY(X) IF(X.GT.0.0)THEN Y=1.0 ELSEIF(X.EQ.0.0)THEN Y=0.0 ELSE Y=-1.0 ENDIF END
三種函數(shù):內(nèi)部函數(shù)、語句函數(shù)、函數(shù)子程序(外部函數(shù))。 函數(shù)子程序是一個(gè)單獨(dú)的程序單位,它不屬于調(diào)用程序所在的程序單位,因此它稱為外部函數(shù)。語句函數(shù)則屬于其所在的程序單位,只能被本程序單位中表達(dá)式引用。內(nèi)部函數(shù)是FORTRAN提供的系統(tǒng)標(biāo)準(zhǔn)函數(shù),可以為任何程序單位引用。[例9.1]編寫求實(shí)型數(shù)絕對值的函數(shù) REALFUNCTIONMYABS(X) REALX IF(X.LT.0)THEN MYABS=-1*X RETURN ELSE MYABS=X ENDIF END PROGRAMMAIN REALMYABS,X,A WRITE(*,*)‘Enteranumber:’ READ(*,*)A X=MYABS(A) WRITE(*,*)‘A=’,A,‘X=’,X END9.1.1函數(shù)子程序的定義格式1:類型說明FUNCTION函數(shù)名(虛擬參數(shù)表)格式2:FUNCTION函數(shù)名(虛擬參數(shù),…)
類型說明函數(shù)名格式3:類型說明FUNCTION函數(shù)名()虛參可以是變量名、數(shù)組名、子程序名。9.1.2函數(shù)子程序的調(diào)用
外部函數(shù)的調(diào)用形式與內(nèi)部函數(shù)的調(diào)用形式完全相同,其形式如下:
函數(shù)名(實(shí)在參數(shù),…)或者函數(shù)名()[9.2]編寫求1+2+…+n的函數(shù)子程序,調(diào)用此函數(shù)求以下表達(dá)式的值Y=((1+2+3)+(1+2+3+4)+(1+2+3+4+5))/((1+2+3+4+5+6)+
(1+2+3+4+5+6+7)) PROGRAMMAIN2 N=3 Y=(SUM(N)+SUM(N+1)+SUM(N+2))/(SUM(N+3)+SUM(N+4)) WRITE(*,*)‘Y=’,Y END FUNCTIONSUM(X) INTEGERX SUM=0 DO10I=1,X SUM=SUM+I10 CONTINUE END[例9.3]已知sinh(x)=(ex-e-x)/2,由程序輸入x的值,求出sinh(x),其中ex=1+x+x2/2!+x3/3!+...+xn/n!
PROGRAMMAIN3 REALMYEXP READ(*,*)X Y=(MYEXP(X)-MYEXP(-X))/2.0 WRITE(*,*)‘SINH(‘,X,‘)=’,Y END FUNCTIONMYEXP(X) REALMYEXP N=0 T=1 S=1 DO10WHILE(ABS(T).GT.1E-5) N=N+1
T=T*X/N S=S+T10 CONTINUE MYEXP=S END9.2子例行程序
子例行程序和函數(shù)子程序都是子程序,它們的區(qū)別在于:函數(shù)子程序的名字代表一個(gè)值,在函數(shù)子程序中求出的函數(shù)值存放在函數(shù)名中。因此,函數(shù)名是函數(shù)值的體現(xiàn)者,對函數(shù)名應(yīng)作類型說明。而子例行程序的名字只供調(diào)用,它不代表某個(gè)值,當(dāng)然也不屬于某個(gè)類型。在子例行程序中求得的值不是由子程序名帶回調(diào)用單位,而是通過實(shí)參與虛參的聯(lián)系帶回調(diào)用單位。[例9.4]使用子例行程序求1+2+...+n SUBROUTINESUM(N,S) INTEGERN REALS S=0 DO10I=1,N S=S+I10 CONTINUE END PROGRAMMAIN4 CALLSUM(3,Y1) CALLSUM(4,Y2) CALLSUM(5,Y3) CALLSUM(6,Y4) CALLSUM(7,Y5) Y=(Y1+Y2+Y3)/(Y4+Y5) WRITE(*,*)‘Y=’,Y END11.2.1子例行程序的定義
子例行程序必須以SUBROUTINE語句開頭,以END語句結(jié)束。 形式如下:
SUBROUTINE子例行程序名(虛擬參數(shù),…)
SUBROUTINE子例行程序名9.2.2子例程程序的調(diào)用
必須用一條獨(dú)立的CALL語句來調(diào)用子例行程序,CALL語句的形式如下:
CALL子例行程序名(實(shí)在參數(shù),…)
當(dāng)子例行程序沒有虛參時(shí),則調(diào)用形式可以以下兩種形式之一:
CALL子例行程序名或CALL子例行程序名()子例行程序和函數(shù)子程序的主要差別: 1、名字的作用不同。子例行程序名只供調(diào)用時(shí)使用,不得在子程序體內(nèi)賦值;函數(shù)子程序名除了供調(diào)用時(shí)使用外,還代表著函數(shù)值,因此必須在返回前在函數(shù)體內(nèi)給函數(shù)名賦予函數(shù)值。
2、調(diào)用的方式不同。函數(shù)子程序的調(diào)用總是出現(xiàn)在表達(dá)式中,并將所得的函數(shù)值參與表達(dá)式的運(yùn)算;子例行程序必須用一條獨(dú)立的CALL語句調(diào)用。
在程序設(shè)計(jì)中,如果只需得到一個(gè)計(jì)算值,一般采用函數(shù)子程序的形式。在設(shè)計(jì)函數(shù)子程序時(shí)通常不主張?jiān)诤瘮?shù)體內(nèi)改變形參的值,從而保證不使對應(yīng)的實(shí)參發(fā)生變化。如果希望通過子程序的運(yùn)算操作得到一批數(shù)組(例如矩陣相加的結(jié)果),則應(yīng)該采用子例行程序,將得到的新值通過實(shí)參與虛參的結(jié)合傳送回調(diào)用單位,這是由在子例行程序體內(nèi)給形參賦值實(shí)現(xiàn)的。另外,還通過使用子例行程序來完成一些特定的操作。[例9.5]編寫子例行程序用來在一行上打印20個(gè)星號SUBROUTINEASTERISKCHARACTER*20STARSTAR=‘********************’PRINT*,STARENDPROGRAMMAIN5CALLASTERISKCALLASTERISKEND[例9.6]編寫子例行程序分別求出5*5矩陣兩個(gè)對角線上元素值和 PROGRAMMAIN6 REALW(5,5) CALLREADIN(W) CALLOPP(W,X1,X2) END SUBROUTINEREADIN(A) REALA(5,5) WRITE(*,*)‘Enter5*5matrix:’ DO10I=1,5 READ(*,*)(A(I,J),J=1,5)10CONTINUE END SUBROUTINEOPP(A,S1,S2) REALA(5,5) S1=0 DO10I=1,5 S1=S1+A(I,I)10CONTINUE S2=0 DO20I=1,5 J=5-I+1 S2=S2+A(I,J)20 CONTINUE END9.3實(shí)參和虛參之間的數(shù)據(jù)傳送
函數(shù)子程序和子例行程序中的虛參可以是變量名、數(shù)組名、函數(shù)名、子例行程序名,在子例行程序中還可用星號作為虛參。 當(dāng)函數(shù)子程序和子例行程序被調(diào)用之前,所有虛參都無定義,所有虛參既沒有具體的存儲(chǔ)單元也沒有具體的值,只是起到形式上的作用,所以人們也經(jīng)常將虛擬參數(shù)稱為形式參數(shù)(或簡稱形參)。當(dāng)執(zhí)行的流程轉(zhuǎn)向子程序時(shí),實(shí)參和虛參按地址結(jié)合,這時(shí)實(shí)參的存儲(chǔ)單元就是對應(yīng)虛參的存儲(chǔ)單元。當(dāng)執(zhí)行的流程退出子程序時(shí),該子程序的虛參又變成無定義的。9.3.1變量作為虛參
當(dāng)虛參是變量時(shí)對應(yīng)的實(shí)參可以是用一類型的常量、變量、數(shù)組元素和表達(dá)式。 如果實(shí)參是變量或數(shù)組元素,在調(diào)用子程序時(shí),對應(yīng)的虛參實(shí)際上將與之共用同一個(gè)存儲(chǔ)單元。因此,虛參的值就是實(shí)參的值,虛參的值改變時(shí),對應(yīng)實(shí)參的值也就同時(shí)改變。PROGRAMMAINSUBROUTINESUB(X,A)INTEGERA,C(3) INTEGERX,ADATAC/3*0/ A=2*XA=100 X=2*ACALLSUB(A,C(2)) ENDWRITE(*,*)‘A=’,A,‘C(2)=’,C(2)END
如果實(shí)參是常量或表達(dá)式,則子程序中對應(yīng)的虛參變量的值不應(yīng)當(dāng)改變,也就是說在這種情況下虛參變量不應(yīng)當(dāng)在子程序中被賦值,否則會(huì)引起不可預(yù)料的結(jié)果。 如果虛參是字符變量,則它的長度定義應(yīng)當(dāng)遵循以下兩條規(guī)則之一:(1)虛參字符變量的長度定義必須小于等于對應(yīng)實(shí)參變量的長度。(2)虛參字符變量的長度可用(*)來定義,表示長度不定。當(dāng)調(diào)用子程序時(shí),具有不定長度的虛參變量自動(dòng)定義成為與對應(yīng)實(shí)參具有同樣長度。例如以下程序中:PROGRAMMAIN SUBROUTINESUB(CH)CHARACTERSTR1*8,STR2*40 CHARACTER*(*)CH…. ….CALLSUB(STR1) ENDCALLSUB(STR2)….END9.3.2數(shù)組作為虛參
當(dāng)虛參是數(shù)組名時(shí),對應(yīng)的實(shí)參可以是同一類型的數(shù)組名或數(shù)組元素。以下將區(qū)分各種情況加以說明。 (1)如果虛參數(shù)組是數(shù)值類型或邏輯類型,并且對應(yīng)實(shí)參也是相同的類型,在調(diào)用子程序時(shí)將把實(shí)參數(shù)組第一個(gè)元素的地址傳送給子程序作為虛參數(shù)組的第一個(gè)元素的地址,從而導(dǎo)致了它們共用一個(gè)存儲(chǔ)單元。由于每個(gè)數(shù)組占一串連續(xù)的存儲(chǔ)單元,因此虛參數(shù)組的第二個(gè)元素必須按存放次序與實(shí)參數(shù)組的第二個(gè)元素共用存儲(chǔ)單元,其它依次類推。圖9.2給出了一維數(shù)組情況下虛參和實(shí)參數(shù)組結(jié)合的示意圖。
PROGRAMMAIN DIMENSIONA(8) CALLSUB(A) END
SUBROUTINESUB(B) DIMENSIONB(-1,5)
…. END圖9.3給出了不同維數(shù)情況下,虛參和實(shí)參數(shù)組結(jié)合的示意圖PROGRAMMAINDIMENSIONA(2,4)….CALLSUB(A)….ENDSUBROUTINESUB(B)DIMENSIONB(6)….END圖9.4給出了3*3的實(shí)參數(shù)組與2*2的虛參數(shù)組結(jié)合的情況PROGRAMMAINDIMENSIONA(3,3)……CALLSUB(A)……ENDSUBROUTINESUB(B)DIMENSIONB(2,2)……END
注意,在子程序中說明虛參數(shù)組時(shí),它的元素個(gè)數(shù)必須小于等于對應(yīng)實(shí)參數(shù)組中元素的個(gè)數(shù)。虛參數(shù)組總是按照內(nèi)存排列次序與實(shí)參數(shù)組結(jié)合。 雖然虛實(shí)結(jié)合的數(shù)組允許維數(shù)不同,下標(biāo)的上下界不同,但在這種情況下由于對應(yīng)元素使用的下標(biāo)完全不同使程序很難讀懂,也很容易造成一些隱藏的錯(cuò)誤,因此應(yīng)該盡量避免出現(xiàn)這種情況。(2)如果虛參數(shù)組是數(shù)值類型或邏輯類型;并且對應(yīng)實(shí)參是一個(gè)相同類型的數(shù)組元素,在調(diào)用子程序時(shí),將把該元素的地址傳送到子程序作為虛參數(shù)組第一個(gè)元素的地址,從而使它們共用一個(gè)存儲(chǔ)單元;并且虛參數(shù)組的其余元素將與該實(shí)參數(shù)組元素后的元素按排列順序一一對應(yīng)結(jié)合。 在這種情況下,子程序中實(shí)際用到的虛參數(shù)組最后一個(gè)元素必須落在對應(yīng)實(shí)參數(shù)組的范圍內(nèi),而且與數(shù)組維數(shù)無關(guān)。圖9.5給出了當(dāng)虛參為數(shù)組名,對應(yīng)實(shí)參為數(shù)組元素時(shí),兩個(gè)數(shù)組結(jié)合的情況。 PROGRAMMAIN DIMENSIONA(8) …… CALLSUB(A(3)) …. END
SUBROUTINESUB(B) DIMENSIONB(4)
…… END圖9.6給出了當(dāng)虛參為數(shù)組名,對應(yīng)實(shí)參為不同維數(shù)的實(shí)參數(shù)組元素時(shí)兩個(gè)數(shù)組結(jié)合的情況。PROGRAMMAINDIMENSIONA(3,3)……CALLSUB(A(1,2))……ENDSUBROUTINESUB(B)DIMENSIONB(4)……END圖9.7中虛參數(shù)組的元素已超出對應(yīng)實(shí)參數(shù)組的范圍。這將引起運(yùn)行時(shí)出錯(cuò)。PROGRAMMAINDIMENSIONA(6)……CALLSUB(A(3))……ENDSUBROUTINESUB(B)DIMENSIONB(6)……END(3)當(dāng)數(shù)組是字符類型時(shí),虛參和實(shí)參數(shù)組不是按數(shù)組元素的順序一一對應(yīng)結(jié)合,而是按字符位置一一對應(yīng)結(jié)合。虛參數(shù)組中允許的字符總數(shù)必須小于等于實(shí)參數(shù)組中允許的字符總數(shù)。在此條件下,虛、實(shí)數(shù)組的維數(shù)可以不同,下標(biāo)的上、下界可以不同,數(shù)組元素的字符長度可以不同。圖9.8給出了字符類型數(shù)組結(jié)合的示意圖。 PROGRAMMAIN CHARACTER*4B(6) …… CALLSUB(B) …… END SUBROUTINESUB(C) CHARACTER*5C(4) …… END
除非特殊需要,虛參字符數(shù)組元素的長度應(yīng)該與對應(yīng)實(shí)參相同,這樣的程序不僅可讀性好,而且易于調(diào)試檢查。 與虛參字符數(shù)組對應(yīng)的實(shí)參也可以是一個(gè)字符數(shù)組元素,虛參字符數(shù)組的第一個(gè)字符與該元素的第一個(gè)字符結(jié)合,其它按次序依次類推,只是虛參字符數(shù)組中最后一個(gè)字符必須落在對應(yīng)實(shí)參數(shù)組的范圍之內(nèi)。(4)在子程序中,允許虛參數(shù)組是可調(diào)數(shù)組??烧{(diào)數(shù)組的使用大大提高了子程序的通用性和靈活性。讀者在了解數(shù)組虛實(shí)結(jié)合情況的基礎(chǔ)上應(yīng)該充分利用可調(diào)數(shù)組這一強(qiáng)有力的工具來進(jìn)行程序設(shè)計(jì)。
PROGRAMMAIN DIMENSIONA(10),B(4,3) M1=4 M2=3 CALLSUB(A,10,B,M1,M2) … END
SUBROUTINESUB(X,NX,Y,N1,N2)
DIMENSIONX(NX),Y(N1,N2) ... END 可調(diào)數(shù)組名必須是虛參??烧{(diào)數(shù)組中每一維的上下界可以是整型虛參變量,其值通過對應(yīng)的實(shí)參傳送過來;也可以是公用區(qū)中變量。為了使程序清晰易讀,建議采用虛參變量來說明可調(diào)數(shù)組的上、下界而不用公用區(qū)變量。另外可調(diào)數(shù)組也遵循前述1、2、3中的有關(guān)規(guī)定。對于初學(xué)者來說要特別注意,只能在子程序中使用可調(diào)數(shù)組,而且對于那些只是在子程序中局部使用的(并非通過虛實(shí)結(jié)合傳送的)數(shù)組不允許是可調(diào)的。(5)虛實(shí)數(shù)組中最后一維的上界可以用星號(*)表示。例如:
PROGRAMMAIN SUBROUTINESUB(X,Y) DIMENSIONA(10),B(4,3) DIMENSIONX(0,*),Y(2,*) ... ... CALLSUB(A,B) END ... END
用這種方式定義的數(shù)組稱為不定長數(shù)組。以上SUB子程序中的X、Y數(shù)組在調(diào)用之前其大小不固定,當(dāng)調(diào)用該子程序時(shí),它們的大小由對應(yīng)的實(shí)參數(shù)組來確定。因此在上例中當(dāng)執(zhí)行了CALLSUB(A,B)調(diào)用語句后,SUB子程序中X、Y的實(shí)際說明為:
DIMENSIONX(0,9),Y(2,3)9.3.3子程序名作為虛參 在虛參表中允許出現(xiàn)函數(shù)名和子例行程序名。FORTRAN編譯程序完全根據(jù)某個(gè)虛參名字在子程序中出現(xiàn)時(shí)的上下文關(guān)系來確定它是函數(shù)名還是子例行程序名。函數(shù)名在必要時(shí)應(yīng)該進(jìn)行類型說明。 例如以下子例行程序中:
SUBROUTINESUB(A,N,X,F) DIMENSIONA(N) ... Y=F(I)+1 X=A(I)+1 ... END
虛參A由說明語句可知是一個(gè)數(shù)組名,子程序表達(dá)式中A(I)的形式是數(shù)組元素的引用。N和X分別是整型和實(shí)型變量名。虛參中,F(xiàn)是以F(I)的形式出現(xiàn)在表達(dá)式中,在FORTRAN中,F(xiàn)(I)的形式可能是數(shù)組元素的引用或者可能是函數(shù)的調(diào)用。由于在SUB子程序中并沒有說明F為數(shù)組名,因此FORTRAN編譯程序根據(jù)上下文關(guān)系確定F為實(shí)型函數(shù)名。又如以下子例行程序中:
SUBROUTINESUB(X,P) ... CALLP ... END
由于虛參P出現(xiàn)在CALL語句中,因此確定P為子例行程序名。 在虛參中的函數(shù)名、子例行程序名(如以上的F、P)只是一個(gè)虛設(shè)的名字,它并不代表程序中實(shí)際存在的某個(gè)函數(shù)名或子例行程序名,實(shí)際的函數(shù)名或子例行程序名要在調(diào)用時(shí)通過實(shí)參傳送給它。如果虛參是一個(gè)函數(shù)名,要求對應(yīng)的實(shí)參代表一個(gè)在程序中實(shí)際存在的尾部函數(shù)名或內(nèi)部函數(shù)名。如果虛參是一個(gè)子例行程序名,則要求對應(yīng)的實(shí)參代表一個(gè)在程序中實(shí)際存在的子例行程序名。 當(dāng)在調(diào)用的程序單位中,實(shí)在參數(shù)中出現(xiàn)外部函數(shù)名或子例行程序名時(shí),必須在調(diào)用程序的說明部分用EXTERNAL語句說明這些名字。如果在實(shí)在參數(shù)表中出現(xiàn)內(nèi)部函數(shù)名時(shí),必須在調(diào)用程序的說明部分用INTRINSIC語句說明這些名字。以下我們通過例子來說明函數(shù)名和子例行程序名的虛實(shí)結(jié)合以及EXTERNAL和INTRINSIC語句的使用。[例9.7]編寫一個(gè)函數(shù)子程序,通過函數(shù)名的傳送,使之既能求正切值TAN(X)又能求余切值CTN(X)PROGRAMMAIN7INTRINSICSIN,COSX=3.14159/5.0Y1=TRIANGLE(SIN,COS,X)Y2=TRIANGLE(COS,SIN,X)WRITE(*,*)‘TAN(‘,X*180/3.14159,’)=‘,Y1WRITE(*,*)‘CTN(‘,X*180/3.14159,’)=’,Y2ENDFUNCTIONTRIANGLE(F1,F2,X)TRIANGLE=F1(X)/F2(X)END[例9.8]以下程序由你選擇對輸入的兩個(gè)數(shù)(X1,X2)進(jìn)行加法(Add)運(yùn)算還是減法(Subtract)。當(dāng)你打入字母A(或a)時(shí),則對隨后輸入的兩個(gè)數(shù)進(jìn)行加法運(yùn)算并輸出結(jié)果;當(dāng)你打入字母S(或s)時(shí),則對隨后輸入的兩個(gè)數(shù)進(jìn)行減法運(yùn)算并打印出結(jié)果。 PROGRAMMAIN8 EXTERNALADD,SUB CHARACTERCH WRITE(*,*)‘EnterA(Add)orS(Subtract):’ READ(*,‘(A)’)CH WRITE(*,*)‘EnterX1,X2:’ READ(*,*)X1,X2 IF(CH.EQ.‘A’.OR.CH.EQ.‘a(chǎn)’)THEN CALLTEST(ADD,X1,X2,Y)
WRITE(*,100)X1,‘+’,X2,‘=’,Y
ELSEIF(CH.EQ.‘S’.OR.CH.EQ.‘s’)THEN CALLTEST(SUB,X1,X2,Y)
WRITE(*,100)X1,‘-‘,X2,‘=’,Y ELSE WRITE(*,*)‘Selecterror!’ ENDIFFORMAT(1X,2(F6.1,A),F6.1)ENDSUBROUTINETEST(T,X2,X2,X)CALLT(X1,X2,X)ENDSUBROUTINEADD(A,B,C) C=A+BENDSUBROUTINESUB(A,B,C) C=A-B END 9.3.4星號作為虛參 當(dāng)形參表中出現(xiàn)一個(gè)*號時(shí),對應(yīng)的實(shí)參應(yīng)該是一個(gè)冠有*號的語句標(biāo)號。例如:
PROGRAMMAIN SUBROUTINEEXAM(A,*,*) ... IF(...)THEN120X=X1+X2 ... ... RETURN1 CALLEXAM(X,*120,*140) ELSEIF(…)THEN … …140… RETURN2 END ENDIF … END
在CALLEXAM(X,*120,*140)語句中,與虛參第一個(gè)*號對應(yīng)的語句標(biāo)號為120,與虛參第二個(gè)*號對應(yīng)的語句標(biāo)號為140。在執(zhí)行EXAM子例行程序時(shí),如果遇到END語句,執(zhí)行的流程將按正常情況返回到調(diào)用語句的后繼語句去繼續(xù)執(zhí)行。當(dāng)遇到RETURN1語句時(shí),執(zhí)行的流程返回主程序并跳到與第1個(gè)*號對應(yīng)的語句標(biāo)號120去繼續(xù)執(zhí)行。當(dāng)遇到RETURN2語句時(shí),執(zhí)行的流程返回主程序并跳到與第3個(gè)星號對應(yīng)的語句標(biāo)號140去繼續(xù)執(zhí)行。 用星號作為形參將使子程序有一個(gè)入口而有多個(gè)出口,這種返回方式不符合結(jié)構(gòu)化程序設(shè)計(jì)的要求,因此除非特殊需要,一般不主張采用。9.4利用子程序?qū)崿F(xiàn)程序的模塊化設(shè)計(jì)
函數(shù)子程序和子例行程序都是獨(dú)立的程序單位,可以單獨(dú)進(jìn)行編譯。除了函數(shù)子程序名和子例行程序名外,子程序內(nèi)所用的語句標(biāo)號、變量、數(shù)組、符號常量等都只局限于本程序單位;子程序中可以通過虛實(shí)結(jié)合使用可調(diào)數(shù)組,可以通過虛實(shí)結(jié)合傳送子程序名,這都為結(jié)構(gòu)化程序設(shè)計(jì)提供了有力的工具。
在開發(fā)程序的時(shí)候,總是把一個(gè)大任務(wù)分解成若干個(gè)小子任務(wù),并且更進(jìn)一步把子任務(wù)分解成更小的子任務(wù),一直細(xì)分到每一個(gè)子任務(wù)只完成比較簡單的操作為止。當(dāng)把所有的子任務(wù)都由子程序來完成時(shí),通常細(xì)分的程度以每個(gè)子程序不超過50-60語句行為宜。子程序可以多次調(diào)用,這使得一些相同的操作都可調(diào)用同一個(gè)子程序來完成而不必重復(fù)編程。用這種方法設(shè)計(jì)出現(xiàn)的程序不僅可讀性好而且容易調(diào)試、修改和維護(hù)。在調(diào)試程序時(shí)可以一個(gè)個(gè)模塊逐塊進(jìn)行;當(dāng)需要修改程序時(shí),對一個(gè)模塊的修改往往不會(huì)影響到其它模塊。主程序子程序1子程序n……9.5在子程序中的SAVE語句和DATA語句
函數(shù)子程序或子例行程序中用到的所有變量,在被調(diào)用前通常都沒有確定的存儲(chǔ)單元,每當(dāng)子程序被調(diào)用時(shí)才臨時(shí)分配存儲(chǔ)單元,而且在退出子程序時(shí)這些存儲(chǔ)單元又都被釋放并重新分配另作它用。所以這些變量的值不被保留。在下次進(jìn)入子程序時(shí),給這些變量分配的可能是另外的一些存儲(chǔ)單元,上次調(diào)用時(shí)這些變量所具有的值已不復(fù)存在。稱這些變量在子程序未調(diào)用時(shí)是無定義的。 在函數(shù)或子例行程序中可以使用SAVE說明語句來指定子程序中的某些變量的存儲(chǔ)單元不被釋放,它們的內(nèi)容在退出子程序期間保持不變,在下次調(diào)用時(shí)仍可使用。SAVE語句的形式如下:
SAVE變量表或SAVE
變量表可以是本子程序中的變量名、數(shù)組名,若變量或數(shù)組名不止一個(gè),它們之間用逗號隔開。在SAVE語句中不允許出現(xiàn)虛擬參數(shù)名。當(dāng)SAVE語句中帶有變量表時(shí),則為變量表中指定的變量和數(shù)組保留存儲(chǔ)單元,如果SAVE語句中沒有變量表,則表示讓子程序中所有的變量和數(shù)組在程序執(zhí)行期間都占有確定的存儲(chǔ)單元,不因退出子程序而被釋放。[例9.9]求階乘的函數(shù),每次調(diào)用此函數(shù)時(shí),把最后一項(xiàng)乘數(shù)放在變量N0中,把階乘的值放在變量F中。當(dāng)下次調(diào)用此函數(shù)時(shí),如果N大于等于N0,則不必再從頭開始進(jìn)行連乘運(yùn)算,只需把上次的函數(shù)值再乘以N0+1、N0+2、…N即可。 PROGRAMMAIN9 WRITE(*,*) WRITE(*,*)‘ENTERN:’ READ(*,*)N DO10WHILE(N.GE.0) WRITE(*,*)’FUN=’,FUN(N) WRITE(*,*)‘ENTERN:’ READ(*,*)N10 CONTINUE END FUNCTIONFUN(N) SAVEN0,F DATAN0/0/,F/1/ IF(N.LT.0)THEN WRITE(*,*)‘DATAERROR!’ FUN=-1 RETURN ELSEIF(N.LE.N0)THEN F=1 N0=1 ENDIF DO10I=N0+1,N F=F*I10 CONTINUE FUN=F N0=N END
對于只需在第一次調(diào)用時(shí)賦初值,后續(xù)調(diào)用不必賦初值的情況,使用DATA語句是合適的。當(dāng)用DATA語句給子程序中的變量或數(shù)組賦初值時(shí),這些變量和數(shù)組元素只是在子程序第一次調(diào)用時(shí)才有初值。如果沒有SAVE語句說明,DATA語句中的變量和數(shù)組在第一次調(diào)用退出后就變成無定義的了。不要誤解為調(diào)用一次子程序DATA語句就賦一次初值,因?yàn)镈ATA是非執(zhí)行語句。如果每調(diào)用一次就需要賦一次相同的初值,這應(yīng)該用賦值語句來實(shí)現(xiàn)。FUNCTIONFAC(N)FUNCTIONFAC(N)
DATAF/1/ F=1IF(N.LT.0)THEN IF(N.LT.0)THEN WRITE(*,*)‘ERROR’WRITE(*,*)‘DATAERROR!’ FAC=-1 FAC=-1 RETURN RETURNELSE ELSE DO10I=1,N DO10I=1,N
F=F*I F=F*I10 CONTINUE 10CONTINUE ENDIF ENDIF FUN=F FUN=F END END[例9.10]給出一個(gè)產(chǎn)生偽隨機(jī)數(shù)的函數(shù)RAND(),函數(shù)沒有自變量,產(chǎn)生的隨機(jī)數(shù)在0到1之間,不包括0和1 PROGRAMMAIN10 DIMENSIONA(10) DO10I=1,10 A(I)=RAND()10 CONTINUE WRITE(*,*)A END
FUNCTIONRAND() SAVESEED INTEGERSEED,C1,C2,C3 PARAMETER(C1=29,C2=217,C3=1024) DATASEED/0/ SEED=MOD(SEED*C1+C2,C3) RAND=REAL(SEED)/C3 END從程序運(yùn)行的結(jié)果可以看到,每次產(chǎn)生相同的隨機(jī)數(shù)序列。這是因?yàn)槊看芜\(yùn)行開始,隨機(jī)數(shù)的種子SEED的初值總是為0。如果每次運(yùn)行時(shí)想從終端輸入種子SEED的初值,從而使每次運(yùn)行時(shí)產(chǎn)生不同的隨機(jī)數(shù)序列,可把函數(shù)改寫如下: FUNCTIONRAND() SAVESEED INTEGERSEED,C1,C2,C3 PARAMETER(C1=29,C2=217,C3=1024) DATASEED/0/ IF(SEED.EQ.0)THEN WRITE(*,*)‘ENTERRANDNUMBERSEED:’ READ(*,*)SEED ENDIF SEED=MOD(SEED*C1+C2,C3) RAND=REAL(SEED)/C3 END9.6程序舉例
[例9.11]編寫函數(shù)求去掉尾部空格后字符串的長度 PROGRAMMAIN11 CHARACTER*80LINE READ(*,*)LINE L=LENGTH(LINE) WRITE(*,*)L END FUNCTIONLENGTH(LINE) CHARACTER*(*)LINE I=LEN(LINE) DO10WHILE(I.GT.0.AND.LINE(I:I).EQ.‘‘) I=I-110CONTINUELENGTH=IEND[例9.12]編寫子例行程序把字符串中的小寫字母轉(zhuǎn)換成大寫字母,其它字符不變
SUBROUTINETOUPCASE(STR) CHARACTER*(*)STR,CH*1 L=LEN(STR) DO10I=1,L,1 IF(STR(I:I).GE.‘a(chǎn)’.AND.STR(I:I).LE.‘z’)THEN CH=CHAR(ICHAR(STR(I:I))+ICHAR(‘A’)-ICHAR(‘a(chǎn)’)) STR(I:I)=CH ENDIF10 CONTINUE ENDPROGRAMMAIN12CHARA
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 國壽福祿雙喜亮點(diǎn)賣點(diǎn)分析及成功銷售四部曲
- 危險(xiǎn)吊裝安全經(jīng)驗(yàn)分享
- 齒輪科技:過去與未來-探究工業(yè)機(jī)械齒輪的歷史與前景
- 室內(nèi)設(shè)計(jì)入門教程
- 甘肅省蘭州市2020年中考語文真題試卷(含答案)
- 二年級上冊心理健康教育教案
- 七彩管弦(三)-.a小調(diào)鋼琴三重奏 課件 2024-2025學(xué)年湘教版初中音樂八年級上冊
- 高壓氧艙事故應(yīng)急救援預(yù)案
- 2014-2019年中國松花粉市場調(diào)研及投資發(fā)展趨勢預(yù)測報(bào)告
- 2010年中國催化劑行業(yè)市場研究及競爭力分析報(bào)告
- 語文論文淺談如何在語文教學(xué)中培養(yǎng)學(xué)生情感
- 危險(xiǎn)化學(xué)品安全使用許可適用行業(yè)目錄(2013年版)3
- 濕法脫硫工藝計(jì)算書
- 轎車子午線輪胎用簾線品種及其性能
- (醫(yī)學(xué)PPT課件)NT檢查規(guī)范
- 天然氣室外立管吊裝專項(xiàng)施工方案(完整版)
- 淺談博物館布展設(shè)計(jì)的內(nèi)容與形式
- 在音樂教學(xué)中培養(yǎng)學(xué)生的人文素養(yǎng)
- 4各部門定期識(shí)別適用的安全法律法規(guī)、標(biāo)準(zhǔn)規(guī)范和其他要求清單
- 最新和君創(chuàng)業(yè)《管理咨詢技藝》頁(實(shí)用)
- U型管卡標(biāo)準(zhǔn)[圖表卡片]
評論
0/150
提交評論