轉(zhuǎn)自:
http://zhousicheng.googlepages.com/a_015混合語言編程 Mixed-Language-Programming
用Fortran調(diào)用C++語言的程序
例如一個(gè)簡(jiǎn)單的C++語言程序,求直角三角形斜邊長(zhǎng)度的達(dá)哥拉斯公式:保存為crout.cpp文件。
!-----------------------------------------------------------------------
// C++ - Routine
#include <iostream.h>
#include <math.h>
extern "C" void pythagoras (float a, float b, float *c)
{
*c = (float) sqrt(a*a+b*b);
}
!-----------------------------------------------------------------------
注:如果用C語言,則用stdio.h代替iostream.h,并且不需要extern "C",其余過程類似。
Fortran程序:保存為fmain.f90
!-----------------------------------------------------------------------
! Demoprogramm:
! Aufrufen einer C-Routine von Fortran aus
! Die C-Routine wird innerhalb eines Modules deklariert
module cproc
interface ! definierte Schnittstelle
subroutine pythagoras (a, b, res)
!DEC$ ATTRIBUTES C :: pythagoras
!DEC$ ATTRIBUTES REFERENCE :: res
real :: a, b, res
end subroutine
end interface
end module
program fmain
use cproc
implicit none
real :: x, y, z
write(*,*) ' Berechnung der Hypotenusenlaenge eines rechtwickligen Dreiecks'
write(*,*) ' Geben Sie die beiden Seitenlaengen ein, die den rechten Winkel'
write(*,*) ' einschliessen:'
read(*,*) x, y
call pythagoras(x,y,z)
write(*,*) ' Die Laenge der Hypotenuse betraegt: ', z
end program fmain
!-----------------------------------------------------------------------
Fortran程序中添加的接口程序interface,對(duì)調(diào)用的C++與Fortran的數(shù)據(jù)傳遞進(jìn)行說明。
接口程序?qū)懺贛odule當(dāng)中,F(xiàn)ortran程序引用了該Module,就可以使用了。
參考鏈接:
http://www.math.utah.edu/software/c-with-fortran.htmlhttp://www.chiralcomp.com/support/mixing_f77_c_cpp/mixing_f77_c_cpp.htmlhttp://www.acronymchile.com/fortran_and_cplusplus.htmlhttp://arnholm.org/software/cppf77/cppf77.htm一個(gè)VC++調(diào)用Fortran動(dòng)態(tài)鏈接庫的例子:
http://www.vckbase.com/code/viewcode.asp?id=2052http://zhidao.baidu.com/question/652950.html?fr=qrl3系統(tǒng)時(shí)間日期的子程序
date_and_time([date][,time][,zone][,values])
date 至少8位字符,最左邊的8位字符為JJJJMMTT (年月日)
time 至少10位字符,最左邊的10位字符為hhmmss.sss (時(shí)分秒.毫秒)
zone 至少5位字符,最左邊的5位字符為±hhmm (時(shí)分) 相對(duì)于
世界標(biāo)準(zhǔn)時(shí)間 values 一維整型數(shù)組,長(zhǎng)度至少為8,分別為:年,月,日,時(shí)區(qū),小時(shí),分,秒,毫秒
例如:
!-----------------------------------------------------------------------
character(len=10) :: d,t
integer,dimension(8) :: V
d = ""
call date_and_time(date=d,time=t)
call date_and_time(values=V)
PRINT *, "Date=",d,"Time=",t
PRINT *, V
end
!-----------------------------------------------------------------------
系統(tǒng)時(shí)鐘子程序
system_clock ([count] [,count_rate] [,count_max])
count 與計(jì)算機(jī)型號(hào)有關(guān),基于計(jì)算機(jī)時(shí)鐘,
count_rate 一秒鐘count的增加量
count_max count的最大值
三個(gè)數(shù)字均為數(shù)字,可以用來計(jì)算一個(gè)程序運(yùn)行的時(shí)間:秒數(shù)=(t1-t0)/Δt
!-----------------------------------------------------------------------
integer :: n_p_sec, ia, ie; real :: t
call system_clock(count_rate=n_p_sec)!once
call system_clock(count=ia)
DO i=1,10000
j=i
END DO ! 被測(cè)試d程序塊
call system_clock(count=ie)
t = (ie-ia)/real(n_p_sec)
write(unit=*,fmt=*) "Zeit in Sekunden:",t
end
!-----------------------------------------------------------------------
(以下程序轉(zhuǎn)自 編程愛好者論壇 — Fortran討論區(qū) )
1. 如何加大Stack size?
選Project => Settings => Link => Category: Output =>
Stack allocations
Reserve: 這里填新值(默認(rèn)為1M,若需要10M,則填10000000)
2. 如何用Fortran批量生成文件?
設(shè)要生成4000個(gè)文件,文件名為AA1-AA4000,如何寫循環(huán)生成文件,而不用寫4000次write命令呢?
用內(nèi)部文件:
character(len=80) :: filename,form
integer :: i
do i=1,4000
select case (i)
case (1:9)
write(form,'(i1)') i
case (10:99)
write(form,'(i2)') i
case (100:999)
write(form,'(i3)') i
case (1000:9999)
write(form,'(i4)') i
end select
write(filename,*) "AA",trim(form),".TXT"
open(10,file=filename)
write(10,*) i
close(10)
end do
stop
end
3. 如何用Fortran動(dòng)態(tài)生成輸出格式?
設(shè)有一個(gè)數(shù)組data(100),輸出時(shí),希望每行輸出num個(gè)數(shù),而num由用戶輸入,如何實(shí)現(xiàn)?
用內(nèi)部文件:
character(len=80) :: form
real :: data(100)
integer :: i,num
data = (/ (i,i=1,100) /)/10.0
read(*,*) num
write(form,*) "(",num,"f10.3)"
write(*,form) data
stop
end
將字符串改為大寫的子程序
subroutine UpCase (str)
!=========================================
! change to upper case
!=========================================
character(len=*),intent(in out) :: str
integer(4) :: icha,LL,icval
integer(4),parameter :: diff = ichar('a') - ichar('A')
LL = len_trim(str)
do icha=1,LL
icval = ichar(str(icha:icha))
if (icval>=ichar('a') .and. icval<=ichar('z')) then
str(icha:icha) = char(icval-diff)
end if
end do
return
end subroutine UpCase
5. 如何用F90/95生成隨機(jī)數(shù)?
注意:
現(xiàn)在計(jì)算機(jī)產(chǎn)生的隨機(jī)數(shù)都是偽隨機(jī)數(shù)。
random_number(x) 產(chǎn)生一個(gè)0到1之間的隨機(jī)數(shù)(x可以是向量),但是每次總是那幾個(gè)數(shù)。
用了random_seed ()后,系統(tǒng)根據(jù)日期和時(shí)間隨機(jī)地提供種子,使得隨機(jī)數(shù)更隨機(jī)了。
program random
implicit none
real :: x
call random_seed () ! 系統(tǒng)根據(jù)日期和時(shí)間隨機(jī)地提供種子
call random_number (x) ! 每次的隨機(jī)數(shù)就都不一樣了
write(*,*) x
stop
end program random
6. 函數(shù)/子程序超載的例子
設(shè)要編一個(gè)兩個(gè)變量值互換的子程序swap(a,b),啞元a,b可能是實(shí)型數(shù),整型數(shù),數(shù)組,矩陣,字符串,派生類型等等。但是希望只用一個(gè)子程序接口swap(a,b)來實(shí)現(xiàn)。F90可以用類屬接口來實(shí)現(xiàn)這種子程序超載:
module Utilities
implicit none
private I_Swap,R_Swap,RVec_Swap,RMat_Swap,Type_Swap
public :: Swap
interface Swap
module procedure I_Swap,R_Swap,RVec_Swap,RMat_Swap,Type_Swap
end interface
contains
subroutine i_swap (a,b) ! 整型置換
integer (ikind),intent(in out) :: a,b
integer (ikind) :: t
。。。 ! 略
end subroutine i_swap
subroutine r_swap (a,b) ! 實(shí)型置換
real (rkind), intent(in out) :: a,b
real (rkind) :: t
t = a
a = b
b = t
return
end subroutine r_swap
subroutine RVec_swap (a,b) ! 實(shí)型向量置換
real (rkind), intent(in out) :: a(:),b(:)
integer (ikind) :: i
do i=1, size(a)
call R_Swap (a(i),b(i))
end do
return
end subroutine RVec_swap
subroutine RMat_swap (a,b) ! 實(shí)型矩陣置換
。。。 ! 略
end subroutine RMat_swap
subroutine Type_swap (a,b) ! 派生類型置換
。。。 ! 略
end subroutine Type_swap
end module Utilities
8. 推薦好的代碼風(fēng)格
根據(jù)F90子集語言ELF90和F的要求整理(部分)。
“強(qiáng)迫用”的語言特性:
+ F90的自由格式的源代碼。
+ implicit none。
+ 子過程的啞元都要有intent屬性。
+ 函數(shù)子程序的啞元必須指定為intent(in)。
+ 所有子程序和函數(shù)都放在模塊(module)中,然后引用(use)該模塊;或者放在program中。
+ 數(shù)組啞元要求是假定形狀的,或者有固定的維數(shù)和大小。字符啞元要求是假定長(zhǎng)度的。
+ 對(duì)于recursive function(遞歸函數(shù))語句,必須有result子句。
+ 在所有派生類型(type)的定義語句中,必須用雙冒號(hào)分隔符(::)。
+ 主程序要求有program語句。
+ 在程序單元的end語句中要求后跟程序單元的類型和名稱。
+ 在end type語句中要求后跟類型的名稱。
+ end program前必須有stop語句以表示停止執(zhí)行。
+ 子過程中必須有return語句,以表示返回。
+ subroutine s( )并且call s( ),即必須有括號(hào)。
“不得用”的語言特性:
- allocatable、intent、pointer、save、dimension、parameter和target語句形式。(用屬性形式代替。)
- external語句形式。(用顯式的接口代替。)
- assign、賦值go to、交錯(cuò)return、continue、entry、和計(jì)算go to 語句。
- include文件。(用模塊代替。)
- data和block data。(在類型聲明語句中進(jìn)行初始化或賦值。)
- common塊。(將全局?jǐn)?shù)據(jù)放在模塊中,用模塊代替。)
- equivalence。(被認(rèn)為是許多難以查找的編程錯(cuò)誤的來源。)
- double precision語句。(用real語句聲明雙精度的實(shí)型數(shù)。)
- 語句函數(shù)。(用內(nèi)部函數(shù)代替。)
- 專用固有函數(shù)。(用類屬函數(shù)代替。)
- 假定大小數(shù)組。(用假定形狀數(shù)組代替。)
- do n (其中n為語句標(biāo)號(hào))。(用do和end do代替。)
- 非整數(shù)do變量和表達(dá)式。
- 同一行上多條語句。
- 邏輯型case表達(dá)式。
- 從if塊外面分支到end if。
- where語句形式。(用where結(jié)構(gòu)形式。)
- 在open和inquire語句中的blank= 說明符。
- 雙字關(guān)鍵詞之間要求有空格:in out,go to。不能寫為inout,goto。