日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【Fortran】过程设计之一(子例程SUBROUTINE)

發(fā)布時(shí)間:2023/12/20 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Fortran】过程设计之一(子例程SUBROUTINE) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

    • 前言
    • Fortran子例程(SUBROUTINE)
      • 1) 使用方式
      • 2) 子例程示意
      • 3) INTENT屬性
      • 4) 傳遞數(shù)組給子例程
      • 4) 傳遞可分配數(shù)組給子例程
      • 5) 傳遞字符變量給子例程
      • 6) 子例程作為參數(shù)傳遞
      • 7) 其它注意事項(xiàng)


前言

程序單元包括主程序、子例程、模塊、函數(shù)子程序。

Fortran中,大型程序可以拆分成多個(gè)獨(dú)立運(yùn)行和調(diào)試的子任務(wù),即程序單元(亦稱為外部過程)。
Fortran中有兩種外部過程:子例程和函數(shù)子程序。這種機(jī)制的優(yōu)點(diǎn)是:

  • 子任務(wù)單獨(dú)測試,相互之間不影響;
  • 避免重復(fù)造輪子,調(diào)用即可;
  • 將實(shí)現(xiàn)某一功能的代碼封裝起來,避免不經(jīng)意修改導(dǎo)致代碼錯(cuò)誤而不自知。

Fortran子例程(SUBROUTINE)

1) 使用方式

子例程(亦可稱為子程序)是一個(gè)Fortran過程,通過CALL語句進(jìn)行調(diào)用,并通過參數(shù)表獲取輸入數(shù)值和返回結(jié)果。
定義語句格式:

SUBROUTINE subroutine_name( argument_list_dum ) ! 定義子例程名和相關(guān)參數(shù)表(聲明部分)...(執(zhí)行部分)... RETURN END SUBROUTINE [ subroutine_name ] ! []表示可選

注意事項(xiàng)

  • subroutine_name由字母、數(shù)字和下劃線組成 ,最大長度可達(dá)63個(gè)字符,第一個(gè)字符為字母;
  • argument_list_dum,形參,一系列變量和/或數(shù)組,從調(diào)用程序傳遞給子例程;
  • 子例程是一個(gè)獨(dú)立的程序單元,開始于SUBROUTINE,結(jié)束于END SUBROUTINE,其中的局部變量名和語句標(biāo)號(“行號”)可以在其它地方復(fù)用(不用擔(dān)心重名);
  • 實(shí)際上沒有給形參分配內(nèi)存。

調(diào)用語句格式:
CALL subroutine_name( argument_list_act )
注意事項(xiàng)

  • 任何可執(zhí)行程序單元都可以調(diào)用子例程,但不能調(diào)用自身(除非定義為遞歸類型);
  • argument_list_act,實(shí)參。實(shí)參的個(gè)數(shù)、順序與類型必須和形參的個(gè)數(shù)、順序與類型相匹配。
  • 主程序和子例程之間采用地址傳遞進(jìn)行參數(shù)傳遞,具體過程是:由于主程序中的實(shí)參有具體的內(nèi)存存儲位置,當(dāng)調(diào)用子例程時(shí),主程序?qū)⑸啥鄠€(gè)指針來指向各個(gè)實(shí)參所對應(yīng)的存儲位置,并將指針傳遞給子例程,子例程調(diào)用的是參數(shù)的內(nèi)存位置,而非實(shí)參數(shù)據(jù)本身。

2) 子例程示意

已知三角形的兩條直邊,計(jì)算斜邊。要求計(jì)算過程用子例程,主程序直接輸入相應(yīng)數(shù)據(jù)后直接調(diào)用。

PROGRAM calc_hypotenuse_test ! 主程序 IMPLICIT NONE REAL :: s1 REAL :: s2 REAL :: hypotWRITE(*,*) '測試計(jì)算斜邊的子例程' WRITE(*,*)'輸入第一條直邊的長度:' READ(*,*) s1 WRITE(*,*)'輸入第二條直邊的長度:' READ(*,*) s2CALL calc_hypotenuse( s1, s2 , hypot ) ! 調(diào)用子例程WRITE( *, 100 ) hypot 100 FORMAT('斜邊長度為:' , F10.4)STOP END PROGRAM calc_hypotenuse_test SUBROUTINE calc_hypotenuse(side_1 , side_2 , hypotenuse) ! 子例程 IMPLICIT NONE REAL , INTENT(IN)::side_1 ! 第一條直邊長度,輸入,INTENT用法見下述 REAL , INTENT(IN)::side_2 ! 第二條直邊長度,輸入 REAL , INTENT(OUT)::hypotenuse ! 斜邊長度,輸出REAL::temp ! 聲明局部變量 temp = side_1**2 + side_2**2 hypotenuse = SQRT( temp ) END SUBROUTINE calc_hypotenuse

3) INTENT屬性

INTENT屬性在子例程的形參聲明時(shí)使用。

INTENT屬性的格式如下:

  • INTENT(IN),形參僅用于向子程序傳遞輸入數(shù)據(jù);
  • INTENT(OUT),形參僅用于將結(jié)果返回給調(diào)用程序;
  • INTENT(INOUT) 或 INTENT(IN OUT),形參既用來向子程序輸入數(shù)據(jù),也用來向調(diào)用程序返回結(jié)果。

屬性特點(diǎn)

  • 對于每一個(gè)形參來說,都應(yīng)該聲明一個(gè)合適的INTENT屬性;
  • INTENT屬性僅對過程的形參有效,如果用來聲明子例程的局部變量或主程序的變量則會(huì)出錯(cuò);
  • 對于每一個(gè)過程,都應(yīng)該聲明每一個(gè)形參的INTENT屬性。形參的INTENT屬性也可以用獨(dú)立的語句來聲明,如:INTENT(IN) :: arg1 , arg2,...。

4) 傳遞數(shù)組給子例程

如前所述,調(diào)用參數(shù)實(shí)際上是通過傳遞指向該實(shí)參的內(nèi)存位置指針來傳遞給子例程。對于實(shí)參是一個(gè)數(shù)組,其指針是指向數(shù)組中的第一個(gè)值。然而,子例程需要同時(shí)知道數(shù)組的地址和大小,保證不會(huì)發(fā)生越界,才能進(jìn)行數(shù)組操作。
在子例程中有三種方式來指明形參數(shù)組的大小:

  • 顯式結(jié)構(gòu)形參數(shù)組
    數(shù)組的維度大小需要作為參數(shù)進(jìn)行傳遞,一維數(shù)組為例:

    SUBROUTINE process(data1 , data2 , n , nvals) INTEGER , INTENT(IN) :: n , nvals ! n為數(shù)組的大小, nvals是數(shù)組操作的個(gè)數(shù) REAL , INTENT(IN) , DIMENSION(n)::data1 REAL , INTENT(OUT) , DIMENSION(n)::data2 INTEGER::iDO i = 1 , nvalsdata2( i ) = 3.*data1( i ) ! 將data1數(shù)組的數(shù)值乘以3,賦值為data2數(shù)組 END DOEND SUBROUTINE process

    二維數(shù)組為例:

    SUBROUTINE process1(data1 , data2 , m , n) INTEGER , INTENT(IN) :: m ,n ! m×n為數(shù)組的大小 REAL , INTENT(IN) , DIMENSION(m,n)::data1 REAL , INTENT(OUT) , DIMENSION(m,n)::data2 data2 = 3.*data1 ! 將data1數(shù)組的數(shù)值乘以3,賦值為data2數(shù)組,直接對數(shù)組進(jìn)行操作END SUBROUTINE process1

    由于形參數(shù)組的大小和結(jié)構(gòu)都已經(jīng)清晰,可以對形參數(shù)組進(jìn)行數(shù)組操作,以及切片操作。

  • 不定結(jié)構(gòu)形參數(shù)組
    把子例程中的所有形參數(shù)組聲明為不定結(jié)構(gòu)(數(shù)組的每個(gè)下標(biāo)用:來代替)的形參數(shù)組,只有當(dāng)子例程具有顯式接口時(shí),才能使用這種數(shù)組。因此,顯示接口能夠給編譯器提供每個(gè)數(shù)組的大小、結(jié)構(gòu)等詳細(xì)信息,在調(diào)用的時(shí)候不會(huì)出錯(cuò)。

    需注意的是,定義形參數(shù)組時(shí)只有它的結(jié)構(gòu)(但用:替代),沒有具體下標(biāo)范圍。因此,在把實(shí)參數(shù)組傳遞至形參數(shù)組時(shí),只傳遞了結(jié)構(gòu),并沒有傳遞實(shí)參數(shù)組每個(gè)維度的下標(biāo)取值范圍。此時(shí),可以用查詢函數(shù)獲取不定結(jié)構(gòu)數(shù)組的結(jié)構(gòu)。

    如果不需要將數(shù)組的每個(gè)維度下標(biāo)邊界從調(diào)用程序傳遞給子例程,則不定結(jié)構(gòu)形參數(shù)組比顯式結(jié)構(gòu)形參數(shù)組更方便使用。 二維數(shù)組的例子:

    MODULE module_process CONTAINSSUBROUTINE process2(data1 , data2 )REAL , INTENT(IN) , DIMENSION(:,:)::data1 REAL , INTENT(OUT) , DIMENSION(:,:)::data2 data2 = 3.*data1 ! 將data1數(shù)組的數(shù)值乘以3,賦值為data2數(shù)組,直接對數(shù)組進(jìn)行操作END SUBROUTINE process2 END MODULE module_process
  • 不定大小形參數(shù)組
    古老且過時(shí)的方法,用星號*來聲明形參數(shù)組的長度,表示大小不確定。因此不清楚數(shù)組的實(shí)際大小和結(jié)構(gòu),容易運(yùn)行錯(cuò)誤,且很難調(diào)試,建議不要使用。例子如下:

    SUBROUTINE process(data1 , data2 , nvals) INTEGER , INTENT(IN) :: nvals ! nvals是數(shù)組操作的個(gè)數(shù),因此數(shù)組的數(shù)據(jù)個(gè)數(shù)至少要為nvals REAL , INTENT(IN) , DIMENSION(*)::data1 ! 不定大小 REAL , INTENT(OUT) , DIMENSION(*)::data2 ! 不定大小 INTEGER::iDO i = 1 , nvalsdata2( i ) = 3.*data1( i ) ! 將data1數(shù)組的元素乘以3,賦值為data2數(shù)組 END DOEND SUBROUTINE process
  • 4) 傳遞可分配數(shù)組給子例程

    可分配數(shù)組作為參數(shù)傳遞給子例程時(shí),必須要結(jié)合顯式接口。

    注意事項(xiàng)

    • 當(dāng)傳遞的參數(shù)是可分配數(shù)組時(shí),子例程中形參聲明調(diào)用子程序的實(shí)參聲明必須都是可分配的;

    • 可分配形參可以使用INTENT屬性,但I(xiàn)NTENT屬性的具體參數(shù)可能會(huì)影響子例程中的操作:

      • INTENT(IN),在子例程中不允許對輸入可分配數(shù)組進(jìn)行重分配或者釋放內(nèi)存空間;
      • INTENT(INOUT),調(diào)用子例程時(shí),如果參數(shù)只有數(shù)組這一個(gè),那么實(shí)際上會(huì)將數(shù)組的狀態(tài)(是否可分配)和相應(yīng)數(shù)據(jù)傳遞至子例程中(實(shí)參——>形參),在子例程中可以對形參修改、釋放內(nèi)存、重分配等操作。形參的最終狀態(tài)和數(shù)據(jù)返回至調(diào)用程序中(相應(yīng)實(shí)參結(jié)果被修改了)。具體見下例;
      • INTENT(OUT),調(diào)用子例程時(shí),實(shí)參在入口處被自動(dòng)釋放掉,相應(yīng)的數(shù)據(jù)清除掉,可以在子例程中對其進(jìn)行操作,然后將形參的最終狀態(tài)和數(shù)據(jù)返回至調(diào)用程序中。

    例子
    取自《Fortran for Scientists and Engineers(4th) by Stephen J. Chapman》中的9-5例題,有少量修改,復(fù)制可運(yùn)行。

    PROGRAM test_allocatable_arguments ! 主程序USE test_module ! 先調(diào)用模塊 IMPLICIT NONEREAL,ALLOCATABLE,DIMENSION(:) :: a_main ! 定義舊版的可分配數(shù)組. INTEGER :: istat ! 分配的狀態(tài)! 指定大小,分配 ALLOCATE( a_main(6), STAT=istat )! 初始化數(shù)組 a_main = [ 1., 2., 3., 4., 5., 6. ]! 輸出調(diào)用前主程序中可分配數(shù)組 WRITE (*,'(A,6F4.1)') ' 調(diào)用子程序前主程序中的數(shù)組:', a_main! 再調(diào)用子例程 CALL test_allocate(a_main)! 輸出調(diào)用后主程序中可分配數(shù)組 WRITE (*,'(A,6F4.1)') '調(diào)用子程序后主程序中的數(shù)組: ', a_main END PROGRAM test_allocatable_arguments MODULE test_module ! 顯式接口CONTAINSSUBROUTINE test_allocate(array) ! 子例程IMPLICIT NONE! 過程中形參變量 REAL,DIMENSION(:),ALLOCATABLE,INTENT(INOUT) :: array ! 作為形參的可分配一維數(shù)組,這是屬于自動(dòng)分配內(nèi)存的定義! 過程中局部變量INTEGER :: i ! 循環(huán)下標(biāo)INTEGER :: istat ! 分配的狀態(tài)! 判斷數(shù)組的狀態(tài)IF ( ALLOCATED(array) ) THENWRITE (*,'(A)') '子程序分配成功!'WRITE (*,'(A,6F4.1)') '子程序輸入為: ', arrayELSEWRITE (*,*) '子程序沒有被分配'END IF! 釋放可分配數(shù)組的內(nèi)存(因?yàn)樵诼暶鞑糠忠呀?jīng)分配好了)IF ( ALLOCATED(array) ) THENDEALLOCATE( array, STAT=istat )END IF! 重新分配,按照5個(gè)元素的一維數(shù)組ALLOCATE(array(5), STAT=istat )! 往重分配的一維數(shù)組填入數(shù)據(jù)DO i = 1, 5array(i) = 6 - iEND DO! 展示重分配后的數(shù)組結(jié)果WRITE (*,'(A,6F4.1)') '子程序中輸出的數(shù)組 ', arrayEND SUBROUTINE test_allocate END MODULE test_module

    相應(yīng)的結(jié)果為:

    調(diào)用子程序前主程序中的數(shù)組: 1.0 2.0 3.0 4.0 5.0 6.0 子程序分配成功! 子程序輸入為: 1.0 2.0 3.0 4.0 5.0 6.0 子程序中輸出的數(shù)組 5.0 4.0 3.0 2.0 1.0 調(diào)用子程序后主程序中的數(shù)組: 5.0 4.0 3.0 2.0 1.0

    5) 傳遞字符變量給子例程

    當(dāng)一個(gè)字符變量被作為子例程的形參時(shí),用*號來聲明字符變量的長度。當(dāng)調(diào)用子例程時(shí),形參的長度將是實(shí)參的長度。如:

    SUBROUTINE example( string ) CHARACTER( len = * ) , INTENT(IN) :: string ! *號表示完全復(fù)制實(shí)參的長度 WRITE(*,*) 'The lengrh of string : ',LEN(string) ! 可以在子例程內(nèi)部實(shí)時(shí)返回實(shí)參的長度 END SUBROUTINE example

    如自動(dòng)數(shù)組一般,創(chuàng)建自動(dòng)字符變量:

    SUBROUTINE sample ( string ) CHARACTER(len=*) :: string CHARACTER(len=len(string)) :: temp ! 一個(gè)與形參相同大小的臨時(shí)變量,子例程調(diào)用結(jié)束時(shí)會(huì)被銷毀

    6) 子例程作為參數(shù)傳遞

    當(dāng)子例程a作為實(shí)參時(shí),傳遞給過程A(如另一子例程)一個(gè)指向該子例程a的指針。執(zhí)行該過程A時(shí),參數(shù)表中的子例程a將作為形參進(jìn)入到過程A的編譯當(dāng)中。

    要想實(shí)現(xiàn)子例程傳遞功能,必須要使用EXTERNAL屬性,將子例程聲明為外部,此時(shí)編譯器才會(huì)知道參數(shù)表中傳遞的是獨(dú)立的已編譯子例程,而不是常規(guī)變量。

    EXTERNAL屬性需要在聲明部分中使用,格式如下:

    TYPE, EXTERNAL ::sub_1 , sub_2 ! TYPE是指具體數(shù)據(jù)類型

    或者

    EXTERNAL ::sub_1 , sub_2

    同時(shí),在過程中需要結(jié)合CALL語句,以調(diào)用過程中子例程形參

    7) 其它注意事項(xiàng)

    • 不要在子例程中使用STOP語句,因?yàn)橐坏┱{(diào)用子例程時(shí),會(huì)停止程序。如果調(diào)用多個(gè)子例程(每個(gè)子例程都有STOP語句),則程序永遠(yuǎn)不會(huì)執(zhí)行成功;
    • 如果子例程中存在可能引發(fā)錯(cuò)誤的條件,應(yīng)該對錯(cuò)誤進(jìn)行檢測,并設(shè)置正確/錯(cuò)誤標(biāo)志,返回給調(diào)用程序(即作為形參其中之一),用于實(shí)時(shí)判斷預(yù)設(shè)條件的執(zhí)行成功與否(即可定義為一種狀態(tài)用于判斷)。

    總結(jié)

    以上是生活随笔為你收集整理的【Fortran】过程设计之一(子例程SUBROUTINE)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 天天碰天天碰 | 高清国产午夜精品久久久久久 | 亚洲国产精品国自产拍久久 | 国毛片 | 午夜免费视频 | 暗呦丨小u女国产精品 | 国产三级在线播放 | 国产精品久久 | 久久久永久久久人妻精品麻豆 | 日韩精品tv| 91中出 | 色久在线 | 中文字幕精品一区二区精 | 91看大片| 成年人性生活免费视频 | 665566综合网| 日韩av中文在线观看 | 日日干,夜夜操 | 天天干夜夜做 | 91免费看黄| 国产一区二区三区中文字幕 | 精品久久久久久久久久久国产字幕 | 茄子视频懂你更多在线观看 | 超碰caopor | fc2ppv色の美マンに中出し | 玖玖玖在线观看 | 国产美女性生活 | 久久人人爽人人爽人人片亚洲 | 丁香av | 污污视频在线播放 | 天堂网一区二区三区 | 三级色网 | 国产成人精品无码片区在线 | 日本涩涩网 | 天堂网站| 污版视频在线观看 | 国产视色 | 国产成人免费电影 | 日本国产高清 | 日韩不卡免费视频 | 天天插天天插 | 久久久久久网 | 亚洲美女性生活视频 | 午夜视频网 | 成人免费视频国产在线观看 | 日韩羞羞 | 欧美69视频| 精品国产丝袜一区二区三区乱码 | 亚洲蜜臀av一区二区三区 | avt天堂网 | 欧美极品videos精品 | 久久一二 | 欧美日韩一二三区 | 免费插插视频 | 亚洲精品一区二区三区在线观看 | 亚洲天堂av免费在线观看 | 日韩草比 | 免费观看一区二区三区毛片 | 性欧美另类 | 欧美激情亚洲色图 | 小泽玛利亚一区二区三区 | 五月婷婷伊人网 | 欧美在线一区二区三区 | 日本精品在线播放 | 亚洲国产精品久久久久爰色欲 | 男女激情av | 少妇被躁爽到高潮无码人狍大战 | 蜜桃精品视频在线观看 | 亚洲综合无码一区二区 | 欧美日韩1 | 无遮挡毛片 | 欧美成人一区二区视频 | 校园春色中文字幕 | 成人片在线播放 | 风韵多水的老熟妇 | 性猛交xxxx乱大交孕妇2十 | 五月婷婷激情五月 | 国产中文字字幕乱码无限 | 日本特级黄色 | 欧美久久久久久久久久 | 国产精品国产三级国产专播品爱网 | 九九九九精品九九九九 | 97免费观看视频 | √天堂| 国产吞精囗交免费视频网站 | 成人午夜免费福利视频 | 国产在线一 | 老局长的粗大高h | 天天拍天天射 | 成年人视频免费在线观看 | 无码日韩精品一区二区 | 欧美黑人性受xxxx精品 | 丝瓜色版| 在线观看亚洲精品视频 | 国产精品麻豆果冻传媒在线播放 | 亚洲巨乳在线 | 一色综合 | 一色桃子juy758在线播放 | 俄罗斯美女一级爱片 |