第一篇:關(guān)于Fortran調(diào)用C++函數(shù)的小結(jié)
關(guān)于Fortran調(diào)用C++函數(shù)的小結(jié)
2017-3-12 背景
工作中遇到了需要在Fortran代碼中調(diào)用C++提供的函數(shù)的情況。通過在網(wǎng)上查閱資料,總結(jié)了實(shí)現(xiàn)方法,制作了一個(gè)實(shí)例。
工具
集成開發(fā)環(huán)境是VS2010。由于默認(rèn)安裝模式下的VS2010是無(wú)法編譯調(diào)試Fortran的,所以又補(bǔ)充安裝了Intel(R)Virual Fortran 2011(英特爾可視化Fortran編譯器)。
參考資料分析
本文需要用到Fortran與C/C++的混合編程,F(xiàn)ortran和C/C++分別編譯各自的功能模塊源代碼,得到各自的目標(biāo)文件(.obj),然后集成鏈接這些obj 文件生成一個(gè)統(tǒng)一的可執(zhí)行文件,實(shí)現(xiàn)對(duì)對(duì)方函數(shù)的調(diào)用,數(shù)據(jù)交換通過約定接口來(lái)實(shí)現(xiàn)[1]。C++代碼中函數(shù)說(shuō)明前需要用到extern關(guān)鍵字,說(shuō)明函數(shù)可以在本模塊或其它模塊中使用[2]。extern與“C”一起連用時(shí),如: extern “C” void fun(int a, int b);則告訴編譯器在編譯fun這個(gè)函數(shù)名時(shí)按著C的規(guī)則去翻譯相應(yīng)的函數(shù)名而不是C++的,C++的規(guī)則在翻譯這個(gè)函數(shù)名時(shí)會(huì)把fun這個(gè)名字變得面目全非[3]。
要在Fortran中調(diào)用C++的函數(shù),意味著Fortran項(xiàng)目對(duì)C++項(xiàng)目產(chǎn)生了依賴關(guān)系,如果項(xiàng)目依賴項(xiàng)未設(shè)置會(huì)導(dǎo)致類似“無(wú)法解析的外部符號(hào) _XXX,該符號(hào)在函數(shù) _XX 中被引用”的錯(cuò)誤。另外還要保證Fortran與C++項(xiàng)目的運(yùn)行庫(kù)設(shè)置都是“多線程調(diào)試”[4]。
實(shí)現(xiàn)過程 創(chuàng)建Fortran項(xiàng)目
1)啟動(dòng)VS2010,新建一個(gè)Fortran控制臺(tái)應(yīng)用程序,名稱為Console1。2)在該項(xiàng)目下的Source Files下添加一個(gè)新文件Source1.f90。3)在Source1.f90中寫入如下代碼:
program main implicit none interface
subroutine SUB(a,b)!DEC$ ATTRIBUTES C,ALIAS:'_sub'::SUB!DEC$ ATTRIBUTES reference::a,b integer a , b end subroutine SUB end interface integer(4)a,b,c a=100 b=1 write(*,*)“開始調(diào)用C++里的函數(shù)SUB” call SUB(a,b)read(*,*)endprogram main
注:接口中為_sub這個(gè)來(lái)自于C++的函數(shù)起了個(gè)別名SUB,所以在后面調(diào)用SUB時(shí)其實(shí)就是調(diào)用_sub。在接口中還規(guī)定了a和b兩個(gè)參數(shù)的傳遞方式是傳引用。
創(chuàng)建C++項(xiàng)目
在解決方案資源管理器中的“解決方案”處右鍵,添加一個(gè)新建項(xiàng)目,在新建窗口中選中Win32控制臺(tái)應(yīng)用程序,輸入項(xiàng)目名稱Cpp2。在隨后彈出的應(yīng)用程序設(shè)置中選擇應(yīng)用程序類型為靜態(tài)庫(kù)。
在項(xiàng)目的頭文件中新建一個(gè)sub.h,在其中輸入如下代碼:
//sub.h #ifndef _SUB_H #define _SUB_H extern“C”void_cdecl sub(int *a,int *b);
[5]#endif 注:在頭文件中使用#ifdef和#ifndef是非常重要的,可以防止雙重定義的錯(cuò)誤。
在項(xiàng)目的源文件中新建一個(gè)sub.cpp,在其中輸入如下代碼:
//sub.cpp
#include“stdafx.h” #include“sub.h” #include
extern“C”void_cdecl sub(int *a,int *b){ std::cout<<“C++: 已經(jīng)進(jìn)入C++的函數(shù)內(nèi)部n”<<“a=”<<*a<<“, b=”<<*b< 設(shè)置Fortran項(xiàng)目的項(xiàng)目依賴項(xiàng) 在Console1項(xiàng)目上右鍵,選擇項(xiàng)目依賴項(xiàng),在彈出窗口中依賴項(xiàng)頁(yè)內(nèi)選中Cpp2,切換到生成順序頁(yè),可以看到Cpp2排在Console1前面。 設(shè)置運(yùn)行庫(kù) 1)設(shè)置Fortran項(xiàng)目的運(yùn)行庫(kù),在Console1項(xiàng)目上右鍵選擇屬性,然后找到【配置屬性】【Fortran】【Libraries】【Runtime Library】,設(shè)置其值為Debug Multithreaded(/libs:static/threads/dbglibs)即多線程調(diào)試。 2)設(shè)置C++項(xiàng)目的運(yùn)行庫(kù),在Cpp2項(xiàng)目上右鍵選擇屬性,找到【配置屬性】【C/C++】【代碼生成】【運(yùn)行庫(kù)】,設(shè)置其值為多線程調(diào)試(/MTd)。 生成項(xiàng)目 1)在解決方案上右鍵選擇重新生成解決方案。 2)在解決方案所在的Console1文件夾下找到Debug文件夾,可以看到其中有一個(gè)Cpp2.lib文件,這個(gè)靜態(tài)庫(kù)文件就是Cpp2項(xiàng)目生成的。 3)在Console1Console1Debug文件夾下可以看到Console1.exe文件,這個(gè)可執(zhí)行文件是Console1項(xiàng)目生成的。 注:如果要單獨(dú)生成Cpp2,可以在Cpp2項(xiàng)目上右鍵選擇重新生成。如果在Console1項(xiàng)目上右鍵選擇重新生成,因?yàn)榍拔脑O(shè)置了項(xiàng)目依賴項(xiàng)的關(guān)系,Cpp2也會(huì)被生成。 啟動(dòng)調(diào)試 按下F5,啟動(dòng)調(diào)試。可以看到調(diào)試成功。 參考文獻(xiàn) [1] suiyi1234546,第11章 Fortran和C的混合語(yǔ)言編程-授課版,百度文庫(kù),http://wenku.baidu.com/link?url=ogwgYldzkmbgJXM86iXjAMt60wimIN1bMVy6uoz1dFn0pWuPPj1mKapYZ9RAK1rXrMZCmQAmJYjGCA0B1IpvDh9wb1joBcFdJ3VO2fz19jO [2] ForFreeDom,關(guān)于C++的extern關(guān)鍵字,博客園,[3] chao_yu,C/C++中extern關(guān)鍵字詳解,博客園,http:// [5] Arthursky,C++在頭文件中使用#ifdef和#ifndef,ChinaUnix,http://blog.chinaunix.net/uid-11572501-id-2868707.html 1.單雙精度 Program ex01 implicit none real(kind=4):: a real(kind=8):: b a=3.***66666666_4 !確定這個(gè)數(shù)字是使用單精度 b=3.***66666666_8 !確定這個(gè)數(shù)字是使用雙精度 write(*,*)a,b End program ex01 2.判斷kind值 program ex02 Implicit none !判斷可以記錄9個(gè)位數(shù)的整數(shù)kind值 integer, parameter :: long_int = selected_int_kind(9)!判斷可以記錄3個(gè)位數(shù)的整數(shù)kind值 integer, parameter :: short_int = selected_int_kind(3) !判斷可以有3個(gè)有效位數(shù), 指數(shù)可以記錄到3的浮點(diǎn)數(shù)kind值 integer, parameter :: long_real = selected_real_kind(10, 50)!判斷可以有10個(gè)有效位數(shù), 指數(shù)可以記錄到50的浮點(diǎn)數(shù)kind值 integer, parameter :: short_real= selected_real_kind(3, 3)integer(kind=long_int):: a = 123456 integer(kind=short_int):: b = 123 real(kind=long_real) :: c = +1.23456789D45 real(kind=short_real) :: d =+1230 write(*, “(I3,1X,I10)”) long_int,a write(*, “(I3,1X,I10)”) short_int, b write(*, “(I3,1X,E10.5)”)long_real, c write(*, “(I3,1X,E10.5)”)short_real, d END 3.TYPE program ex0434 implicit none Type :: person !開始建立person這個(gè)類型 character(len=30):: name!人名 integer :: age !年齡 integer :: height !身高 INTEGER :: weight !體重 character(len=80):: address!地址 End type person type(person):: a !聲明一個(gè)person類型的變量 write(*,*)“NAME:” read(*,*)a%name write(*,*)“AGE:” read(*,*)a%age write(*,*)“HEIGHT:” read(*,*)a%height write(*,*)“WEIGHT:” read(*,*)a%weight write(*,*)“ADDRESS:” read(*,*)a%address write(*,100)a%name,a%age,a%height,a%weight 100 format(“Name:”,A10/,“Age:”,I3/,“Height:”,I3/,“Weight:”,I3/,& “Addres:”,A80)End 4.REAL 與 INTEGER Program ex0431 implicit none integer :: a=1 integer :: b=2 real :: c c=a/b!c=1/2=0, 雖然c是浮點(diǎn)數(shù),但因?yàn)閍,b是整數(shù),計(jì)算a/b時(shí)會(huì)用整數(shù)去計(jì)算.write(*,“(F5.2)”)c End 5.DATA 變量表/初值表/,變量表/初值表/,… PROGRAM ex0430 IMPLICIT NONE INTEGER A REAL B COMPLEX C CHARACTER(20)STR DATA A,B,C,STR /1, 2.0,(1.0,2.0), 'FORTRAN 77'/ WRITE(*,*)A,B,C,STR END 6.復(fù)數(shù)實(shí)虛部 Program ex0430 complex :: c =(1,2)write(*,100)real(c),'+',aimag(c),'i' 100 format(f5.1,a1,f5.1,a1)End 7.邏輯輸出 Program ex0416 logical a,b a=.true.b=.false.write(*,100)a,b format(L5,L4)End 8.Program ex0415 character(len=20)string character(len=5)substring string = “Have a nice day.” substring = “nice” write(*,*)ichar('A')!輸出字符A的ASCII碼 write(*,*)char(65) !輸出ASCII碼65所代表的字符,也就是A write(*,*)len(string)!輸出字符串string聲明時(shí)的長(zhǎng)度 write(*,*)len_trim(string)!輸出字符串string內(nèi)容的長(zhǎng)度 write(*,*)index(string, substring)!nice在Have a nice day的第8個(gè)位置 End 9.Program ex0414 character(len= 6)first character(len=10)second character(len=20)add first=“Happy ” second=“Birthday” add = first//second!經(jīng)由兩個(gè)連續(xù)的除號(hào)可以連接兩個(gè)字符串 write(*,100)add FORMAT('生日快樂',/,A)End 10.帶精度計(jì)算 Program ex0408 real(kind=8):: a,b a=1 b=0.1 write(*,*)a,“+”,b,“=”,a+b End 11.邏輯if語(yǔ)句 Program ex0504 implicit none integer rain, windspeed logical r,w write(*,*)“Rain:” read(*,*)rain write(*,*)“Wind:” read(*,*)windspeed r =(rain>=500) !如果rain>=150, r=.true, 不然r=.false.w =(windspeed>=10)!如果windspeed>=10, w=.true, 不然w=.false.if(r.or.w)then !只要r或w有一個(gè)值是true就成立 write(*,*)“停止上班上課” else write(*,*)“照常上班上課” End if End 12.Select Case用法 Program ex0512 implicit none integer :: score character grade write(*,*)“Score:” read(*,*)score select case(score) case(90:100) grade='A' case(80:89) grade='B' case default grade='?' End select write(*,“('Grade:',A1)”)grade End 13.IF GOTO語(yǔ)句 PROGRAM ex0514 IMPLICIT NONE REAL height REAL weight WRITE(*,*)“height:” READ(*,*) height WRITE(*,*)“weight:” READ(*,*) weight IF(weight > height-100)GOTO 200 100 WRITE(*,*)“Under control.” GOTO 300 200 WRITE(*,*)“Too fat!” 300 STOP END 14.DO WHILE 循環(huán) Program ex0604 implicit none integer, parameter :: limit=10 integer counter integer :: ans = 0 counter = 2 do while(counter <= limit) ans = ans + counter counter = counter + 2 end do write(*,*)ans END 15.CYCLE,EXIT 語(yǔ)句 Program ex0609 implicit none integer :: i,j loop1: do i=1,3 loop2: do j=1,3 if(i==3)exit loop1 !跳離loop1循環(huán) if(j==2)cycle loop2 !重做loop2循環(huán) write(*, “('(',i2,',',i2,')')”)i, j end do loop2 end do loop1 End 16.大小寫字符 Program ex0612 implicit none integer i integer strlen character(len=20):: string write(*,*)“String:” read(*,*)string strlen = LEN_TRIM(string) do i = 1, strlen string(i:i)= char(ichar(string(i:i))+32) end do write(*,“('encoded:',A20)”)string End 17.循環(huán)計(jì)算 Program ex0614 implicit none real a,b,ans character :: key = 'y' !為了至少循環(huán)一次 do while(key=='y'.or.key=='Y') read(*,*)a read(*,“(A1)”)key read(*,*)b select case(key)case('+') ans = a+b case('-') ans = a-b case('*') ans = a*b case('/') ans = a/b case default write(*,“('Unknown operator ',A1)”)key stop end select write(*,“(F6.2,A1,F6.2,'=',F6.2)”)a,key,b,ans write(*,*)“(Y/y)to do again.(Other)to exit.” read(*,“(A1)”)key end do End 18.矩陣相加 pogram ex implicit none integer, parameter :: row = 2 integer, parameter :: col = 2 integer :: matrixA(row,col) integer :: matrixB(row,col) integer :: matrixC(row,col) integer r integer c write(*,*)“Matrix A” do r=1, row do c=1, col write(*,“('A(',I1,',',I1,')=')”)r,c read(*,*)matrixA(r,c)end do end do write(*,*)“Matrix B” do r=1, row do c=1, col write(*,“('B(',I1,',',I1,')=')”)r,c read(*,*)matrixB(r,c)end do end do write(*,*)“Matrix A+B=” do r=1, row do c=1, col matrixC(r,c)= matrixB(r,c)+matrixA(r,c) write(*,“('(',I1,',',I1,')=',I3)”)r,c,matrixC(r,c)end do end do end pogram ex [ write(*,“(I3,I3,/,I3,I3)”)((mc(i,j), i=1,2),j=1,2)] 19.program ex implicit none integer, parameter :: row = 2 integer, parameter :: col = 2 integer :: a(2,2)=(/ 1,2,3,4 /) !a(1,1)=1, a(2,1)=2, a(1,2)=3, a(2,2)=4 integer :: b(4)=(/ 5,6,7,8 /) integer :: c(2) write(*,*)a,2) write(*,*)a(:,1) c = a(:,1) !c(1)=a(1,1), c(2)=a(2,1) write(*,*)c!c(1), c(2) c = a(2,:) !c(1)=a(2,1), c(2)=a(2,2) write(*,*)c!c(1), c(2) write(*,*)c(2:1:-1) !c(2), c(1) c = b(1:4:2) !c(1)=b(1), c(2)=b(3) write(*,*)c !c(1), c(2)End 20.FORALL語(yǔ)句 Program ex Implicit none integer :: I,J integer, parameter :: size = 5 integer :: a(size,size) forall(I=1:size, J=1:size, I>J)a(I,J)=1 !上半部分 forall(I=1:size, J=1:size, I==J)a(I,J)=2!對(duì)角線 forall(I=1:size, J=1:size, I !下半部分 write(*,“(5(5I5,/))”)a End 21.Allocatable Program EX Implicit none integer :: size, error=0 integer, parameter :: one_mb=1024*1024 !1MB character, allocatable :: a(:) Do size=size+one_mb! allocate(a(size), stat=error) if(error/=0)exit write(*,“('Allocate ',I10, ' bytes')”)size write(*,“(F10.2,' MB used')”)real(size)/real(one_mb) deallocate(a) End do End 22.Function 函數(shù) Program ex implicit none real :: a=10 real :: b=20 real :: add write(*,“(f6.2)”)add(a,b)End Function add(a,b)implicit none real :: a,b real :: add add = a*b End 23.SAVE語(yǔ)句 Program ex Implicit none call sub() call sub() call sub()End program Subroutine sub() Implicit none Integer :: count = 1 Save count !指定save變量永遠(yuǎn)活著,不會(huì)忘記它的內(nèi)容 Write(*,*)count count = count+1 End [運(yùn)行結(jié)果:1 2 3 ] 24.生成隨機(jī)數(shù) program ex implicit none interface!定義函數(shù)的接口 function random10(lbound, ubound)implicit none real :: lbound, ubound real :: random10(10) end function end interface real :: a(10) CALL RANDOM_SEED()!系統(tǒng)根據(jù)日期和時(shí)間隨機(jī)地提供種子 a = random10(1.0, 10.0) write(*,“(10F6.2)”)a end function random10(lbound, ubound)implicit none real :: lbound, ubound real :: len real :: random10(10) real t integer i len = ubound-lbound!計(jì)算范圍大小 do i=1,10 call random_number(t)!t會(huì)是0~1之間的隨機(jī)數(shù) random10(i)= lbound + len * t!把t轉(zhuǎn)換成lbound~ubound間的隨機(jī)數(shù) end do End 25.MODULE語(yǔ)句 Module global implicit none integer a,b common a,b End module Program ex0834 use global implicit none a=1 b=2 call sub()End program Subroutine sub() use global implicit none write(*,*)a,b return End subroutine 26.寫文件到text program ex0902 implicit none character(len=20):: string open(unit=10, file=“test.txt”) write(10,“(A20)”)“I LOVE YOU.”!寫到文件中 rewind(10) read(10,“(A20)”)string!從文件中讀出來(lái) write(*,“(A20)”)string!寫到屏幕上 end 27.隨機(jī)成績(jī) program gendata implicit none integer students integer i real r(3) write(*,“(4A5)”)“座位”,“語(yǔ)文”,“數(shù)學(xué)”,“英語(yǔ)” call random_seed() write(*,*)“How many students?” read(*,*)students do i=1,students call random_number(r) write(*,“(6I5)”)i,int(r*50+50) end do end program C++的學(xué)習(xí)心得 注意:因?yàn)槲覀冊(cè)趯?shí)驗(yàn)室大多是以項(xiàng)目為基礎(chǔ)來(lái)學(xué)習(xí)C++,這樣可能導(dǎo)致我們不能形成一個(gè)知識(shí)體系,所以建議大一同學(xué)腳踏實(shí)地的從頭學(xué)習(xí)C++,即使時(shí)間不充裕的大 二、大三同學(xué)在學(xué)習(xí)時(shí)也要做好筆記,以便下次遇到同樣的錯(cuò)誤能很快解決。 介于大多數(shù)人都要學(xué)C語(yǔ)言,所以本文就以C++與C語(yǔ)言的對(duì)比開始。 要區(qū)分C語(yǔ)言和C++的不同,首先要想明白,用磚頭建造城市、用房屋建造城市與用兩者共同建造城市的不同。1.想要學(xué)C++必須掌握C語(yǔ)言的基礎(chǔ)運(yùn)用,這要從C++的產(chǎn)生說(shuō)起。C++其實(shí)并不是一個(gè)新的計(jì)算機(jī)語(yǔ)言,它只是在C語(yǔ)言的基礎(chǔ)上預(yù)先編寫好了很多函數(shù)。所以如果把C語(yǔ)言比為磚塊,那么C++就是有磚塊組成的一些小的建筑。所以學(xué)習(xí)C++必需先掌握C語(yǔ)言的基礎(chǔ)運(yùn)用。2.C語(yǔ)言和C++哪個(gè)難? 其實(shí)這個(gè)問題提的很不理想。試問:建起一個(gè)城市,是用磚頭從頭建起來(lái)簡(jiǎn)單,還是把一些已經(jīng)建好,并且使我們需要的房子擺放好簡(jiǎn)單?很明顯C++本身的作用是為了方便使用C語(yǔ)言編程。3.C語(yǔ)言和C++在語(yǔ)法上有什么不同? 就我最近對(duì)C++學(xué)習(xí)時(shí)遇到的一些問題來(lái)看,C++在語(yǔ)法上基本與C語(yǔ)言一致。但是由于房屋是別人建的,要使用它就要明白它們的建造過程(當(dāng)然有些我們只要直接使用就行了,尤其是在前期)。而C++中封裝的函數(shù),也是C++的開發(fā)者已經(jīng)建好的,所以我們要很好地使用它們就要明白它們的建造方式,至少要知道它們的使用語(yǔ)法。 4.C++語(yǔ)言與C語(yǔ)言的不同之處(準(zhǔn)確的說(shuō)應(yīng)該是來(lái)看看C++開發(fā)者已經(jīng)為我們做好了什么) 注意:以下只是我在編寫六維鼠標(biāo)時(shí)遇到的,不全面,其余區(qū)別大家可以在以后的學(xué)習(xí)中自己摸索。1)c語(yǔ)言后綴.c,c++后綴.cpp。 2)當(dāng)函數(shù)定義放在函數(shù)調(diào)用之后時(shí),C程序的函數(shù)原型即聲明有時(shí)可省略,而C++的函數(shù)聲明不能省略,而且還要求函數(shù)的所有參數(shù)在函數(shù)原型的圓括號(hào)中聲明。一個(gè)不帶參數(shù)的C函數(shù)原型必須使用void關(guān)鍵字,而C++函數(shù)原型可以使用空參數(shù)表。 3)C++中用new和delete運(yùn)算符取代C的內(nèi)存分配和釋放函數(shù)malloc()和free()。4)const常量類型:用來(lái)表示一個(gè)“常值變量”與#define的區(qū)別: #define size 20 //不加;只是文本替換此后不再檢查,可能產(chǎn)生負(fù)作用 Const int size=20;//加;替換時(shí)進(jìn)行嚴(yán)格檢查,只有當(dāng)size是int型時(shí)才替換。 C++面向?qū)ο蟮某绦蛟O(shè)計(jì) 概述:面向?qū)ο蟛恢皇且环N程序設(shè)計(jì)方法,還是一種建立客觀事物模型、分析復(fù)雜事物的思想方法,他是以人們通常描述現(xiàn)實(shí)世界的方法來(lái)描述要解決的問題。 1.結(jié)構(gòu)化程序設(shè)計(jì):是一種自頂而下、逐步求精的模塊化程序設(shè)計(jì)方法。 類:對(duì)象是累的一個(gè)實(shí)例。類=數(shù)據(jù)結(jié)構(gòu)+對(duì)數(shù)據(jù)進(jìn)行操作的函數(shù) 面向?qū)ο蟮某绦蛟O(shè)計(jì)的基本特征:抽象、封裝、繼承和多態(tài)。 抽象:對(duì)一類對(duì)象進(jìn)行概括,抽出他們共同的性質(zhì)并加以描述的過程。 封裝:將抽象得到的屬性數(shù)據(jù)和行為代碼有機(jī)的結(jié)合,形成一個(gè)具有類特征的統(tǒng)一體。繼承:一個(gè)新類可以從已有的類派生而來(lái)。 多態(tài):不同對(duì)象對(duì)于同樣的施加于其上的作用會(huì)有不同的反應(yīng)。2.類的定義與實(shí)現(xiàn): 加上類名和作用域限定符(::)。 3.成員函數(shù)的定義形式與一般函數(shù)的定義形勢(shì)基本相同,但如果在類的外部定義成員函數(shù),必須在成員函數(shù)名前一般將類的定義放在頭文件(.h)中,類的實(shí)現(xiàn)放在源文件(*.cpp)中,二main主函數(shù)可以放在另一個(gè)源文件中。在源文件中用#include編譯預(yù)處理指令包含頭文件。 4.對(duì)象:對(duì)象是類的一個(gè)實(shí)例,定義并實(shí)現(xiàn)了類,就可以利用類來(lái)聲明對(duì)象,其形式與普通變量的聲明類似。 例如:以下用類Time聲明了對(duì)象t1,today和對(duì)象的指針pt1: Time t1,today;//聲明對(duì)象t1,today //聲明指向?qū)ο髏1的指針pt1 Time *pt1=&t1; 聲明對(duì)象后,就可以像引用結(jié)構(gòu)變量一樣,利用成員運(yùn)算符“.”或指向運(yùn)算符“->”引用對(duì)象的公有成員,但注意不能引用對(duì)象的非公有成員。如:pt1->setTime()或t1.showTime()5.構(gòu)造函數(shù)和析構(gòu)函數(shù):在聲明對(duì)象時(shí),對(duì)象一般需要進(jìn)行初始化,及對(duì)成員變量進(jìn)行初始化。在定義類時(shí)不能對(duì)成員變量進(jìn)行初始化,因?yàn)椴荒艽_定類中定義的成員變量是屬于哪一個(gè)對(duì)象。 構(gòu)造函數(shù):是一種特殊的成員函數(shù),特殊性在于:它不需要用戶程序調(diào)用,就能在創(chuàng)建對(duì)象時(shí)由系統(tǒng)自動(dòng)調(diào)用。其作用就是在對(duì)象被創(chuàng)建時(shí)利用初始值去構(gòu)建對(duì)象,使得在聲明對(duì)象時(shí)就能自動(dòng)地完成對(duì)象的初始化。析構(gòu)函數(shù):是在對(duì)象的生存期即將結(jié)束時(shí)由系統(tǒng)自動(dòng)調(diào)用的。析構(gòu)函數(shù)的作用與構(gòu)造函數(shù)相反,用來(lái)在對(duì)象被刪除前做一些清理工作和數(shù)據(jù)保存工作。 構(gòu)造函數(shù)的名稱與類名相同,析構(gòu)函數(shù)的名稱是在類明前加符號(hào)“~”構(gòu)成(表達(dá)取反的意思)。注意,構(gòu)造函數(shù)和析構(gòu)函數(shù)不能有任何返回類型,包括void類型;析構(gòu)函數(shù)不能有參數(shù)。下例說(shuō)明了構(gòu)造函數(shù)和析構(gòu)函數(shù)的定義方法及執(zhí)行順序 6.靜態(tài)數(shù)據(jù)成員在儲(chǔ)存類型上類似于一般的static靜態(tài)變量,也具有全局性。 靜態(tài)數(shù)據(jù)成員的屬性也可以是公有、私有或保護(hù)的。對(duì)于公有靜態(tài)數(shù)據(jù)成員,除了可以像一般數(shù)據(jù)庫(kù)成員那樣,直接通過對(duì)象或在成員函數(shù)中訪問它們,還可以利用類名加作用域限定符(::)來(lái)訪問他們。對(duì)于私有和保護(hù)屬性的靜態(tài)數(shù)據(jù)庫(kù)成員,只能在成員函數(shù)中訪問它們。 由于靜態(tài)數(shù)據(jù)成員不具體屬于哪一個(gè)對(duì)象,因此不能構(gòu)造函數(shù)或其他成員函數(shù)中對(duì)他們進(jìn)行初始化,他們的初始化必須在類體外進(jìn)行。 注意:靜態(tài)成員函數(shù)只能訪問類的靜態(tài)成員(成員變量和成員函數(shù)),而不能訪問非靜態(tài)函數(shù)。解決這個(gè)問題的方法是將對(duì)象作為靜態(tài)成員函數(shù)的參數(shù),然后在靜態(tài)成員函數(shù)中通過對(duì)象訪問非靜態(tài)成員。 7.this指針:在成員函數(shù)中訪問數(shù)據(jù)成員或調(diào)用其他成員函數(shù)不需要指定對(duì)象,因?yàn)樗麄兌际峭ㄟ^一個(gè)隱藏的this指針確定當(dāng)前的對(duì)象。 例如:void Time :: showTime(){cout< void Time :: showTime(Time* this){ cout< 8.友元 定義:友元的另一種類型是友元類,一個(gè)類可以聲明另一個(gè)類為其友元類,友元類的所有成員函數(shù)都可以訪問聲明其為友元類的所有成員。 構(gòu)成:一個(gè)函數(shù)要成為一個(gè)類的有元函數(shù),需要在類的定義中聲明該函數(shù),并在函數(shù)聲明的前面加上關(guān)鍵字friend。 作用:友元提供了不同類或不同類的成員函數(shù)之間以及成員函數(shù)和一般函數(shù)之間的數(shù)據(jù)共享機(jī)制。注意:友元關(guān)系是單方向的,不具有交換性和傳遞性。 9.常對(duì)象和常對(duì)象成員:對(duì)于急需要共享又需要安全的數(shù)據(jù),可以利用const來(lái)進(jìn)行保護(hù)。 常對(duì)象:常對(duì)象的數(shù)據(jù)成員的值在對(duì)象的整個(gè)生存期內(nèi)不能被改變,必須利用構(gòu)造函數(shù)進(jìn)行初始化,且以后不能再被更新。聲明格式有以下兩種: const<類名><對(duì)象名>(初始值類表)例如:const Time meeting(8,30,00);成員函數(shù)稱為常成員函數(shù)。格式如下: <函數(shù)類型> <函數(shù)名>(<參數(shù)表>)const;例如,下面聲明的成員函數(shù)MemberFun()就不能修改對(duì)象的數(shù)據(jù)成員。 void MemberFun()const;在常成員函數(shù)中只能調(diào)用常成員函數(shù),而調(diào)用其他普通函數(shù)可能會(huì)造成簡(jiǎn)介修改數(shù)據(jù)成員。 常數(shù)據(jù)成員:可以使用const關(guān)鍵字將數(shù)據(jù)成員聲明為常數(shù)據(jù)成員。常數(shù)據(jù)成員的初始值只能通過構(gòu)造函數(shù)獲取,并且只能在構(gòu)造函數(shù)的初始化列表中設(shè)置其初始值。靜態(tài)常數(shù)據(jù)成員初始化只能在類體外進(jìn)行。11. 繼承與派生:C++中,可以在已有類的基礎(chǔ)上定義一個(gè)新類,新類稱為原有類的派生類或子類,而原有類稱為新定義類的基類或父類。 語(yǔ)法如下: class<派生類名> : [<派生方式>] <基類名>{… 例如: //派生類新增加的成員聲明列表}; <類名> const <對(duì)象名>(初始值類表)10.常成員函數(shù):可以使用const關(guān)鍵字限制成員函數(shù)對(duì)數(shù)據(jù)成員進(jìn)行修改操作,這種使用const關(guān)鍵字進(jìn)行聲明的class Car : public Vehicle{… //在派生類Car中新增加的成員};基類中原有成員的訪問權(quán)限在派生類中可以被修改,它們的訪問權(quán)限由派生類定義中的<派生方式>決定。但注意,為了不破壞基類的封裝性,無(wú)論采用哪種派生方式,基類的私有成員在派生類中都是不可見的,即不允許在派生類的成員函數(shù)中訪問基類的私有成員。 public:punlic(公有派生)是類繼承中最常見派生方式。這樣就可以在派生類的成員函數(shù)中訪問基類中原有的非私有成員,并能通過派生類的對(duì)象直接訪問基類中原有的公有成員。private:采用private(私有派生),只允許在派生類的成員函數(shù)中訪問基類的非私有成員,不能通過派生類的對(duì)象直接訪問基類的任何成員。 protected:采用protected(保護(hù)派生),基類中所有的公有和保護(hù)成員在派生類中都成為保護(hù)成員??偨Y(jié):派生方式就是把基類的非私有成員在派生類中以什么類型存在。 ABAQUS與FORTRAN論壇問題小結(jié) Q:索了一下論壇發(fā)現(xiàn)以前的問題都是不同類型的子程序,如UEL, UMAT...這樣把它們放在一個(gè).for文件里不會(huì)有誤會(huì),但是如果都是UEL的話,該怎么識(shí)別呢? A:subroutine Umat()IF(CMNAME(1:4).EQ.'MAT1')THENCALL UMAT_MAT1(argument_list)ELSE IF(CMNAME(1:4).EQ.'MAT2')THENCALL UMAT_MAT2(argument_list)END IF上面是區(qū)分不同umat的方法,區(qū)分uel應(yīng)該類似吧 Q:行abaqus的時(shí)候出現(xiàn)這樣的提示“Problem during compilation-df.exe not found in PATH.”請(qǐng)問這是什么原因.A: 就是說(shuō)找不到用于編譯的df.exe文件(好像是Fortran的編譯運(yùn)行文件),在Windows控制面板的“系統(tǒng)”里,打開高級(jí)屬性,將系統(tǒng)的PATH添加上Fortran的路徑,最好也一并把INCLUDE和LIB也都添加上對(duì)應(yīng)的FORTRAN的路徑。 Q: 如何在ABAQUS中調(diào)用用戶子程序UMAT A:abaqus job=*** user=*.for or *.objA: 裝好fortran編譯器的前提下,有兩種方式: 1、命令行:abaqus job=*.inp user=*.for或 abaqus job=*.inp user=*.obj(可以由*.f90編譯后得到) 2、菜單格式:先運(yùn)行CAE,在general設(shè)置中可以指定Umat用戶子程序A: job=jobname user=yourfortran.for(其它類型子程序)A:如果是本構(gòu)的二次開發(fā):*material, user Q: abaqus job=job-name user={source-file | object-file}source-file和object-file各是什么? A: fortran的源文件(.for)或者目標(biāo)文件(.o)在command下面輸入以上命令行就可以正常運(yùn)行.用戶子程序再調(diào)用別的fortran程序時(shí),要加入abaqus 子程序中的include 'ABA_PARAM.INC'。 Q: 自己編寫子程序需要哪些工作步驟 A: 1.建立工作目錄 2.將abaqus安裝目錄6.4-pr11site下的aba_param_dp.inc 或 aba_param_sp.inc拷貝到工作目錄,并改名為aba_param.inc ; 3.將編好的fortran程序拷貝到工作目錄; 4.編譯fortran程序,將.obj文件拷貝到工作目錄; 5.建立好輸入文件.inp;6.運(yùn)行abaqus job=inp file name user=fortan name即可。我的要運(yùn)行abq64pr11 job=inp file name user=fortan name我也學(xué)了沒多久,按照這個(gè)過程成功了一個(gè)!你們?cè)囈幌掳?!Q: 想用FORTRAN實(shí)現(xiàn):...result = SYSTEMQQ('abq job=e:abaqu***amplesbeam interactive')...出錯(cuò)提示:ABAQUS ERROR:Unable to create a temporary directory C:DOCUME~1ADMINI~1LOCALS~1TEMPAdministrato_ e:abaqu***amplesbeam_3628 to be used for scratch files.ABAQUS/Analysis exited with errors.但如果是 result = SYSTEMQQ('abq job=beam interactive'),但需要在FORTRAN彈出的DOS窗口里手工輸入文件的絕對(duì)路徑則計(jì)算正常。但我的目的是實(shí)現(xiàn)Fortran程序?qū)BAQUS的計(jì)算程序的自動(dòng)調(diào)用。 A: 說(shuō)個(gè)投機(jī)的花招,有沒有試過在前面加上result = SYSTEMQQ('path=e:/abaqu***amples')這樣的命令~~方法簡(jiǎn)單,不過能解決問題最好 A:把要算的工況都集中在一個(gè)文件夾下,fortran生成.exe文件,放在該文件夾下,然后雙擊運(yùn)行。計(jì)算結(jié)束之后再把各種工況分類。笨招,但好用。 A: 我想,或者把systemQQ改一下,先cd e:...,然后再systemQQ(abaqus job=jobname interactive)。 Q: 偶想在FORTRAN里設(shè)定一個(gè)計(jì)時(shí)器,其功能就是每隔一段時(shí)間(如10s)就去讀一次ABAQUS的(.fil)文件。哪個(gè)函數(shù)可以實(shí)現(xiàn)這個(gè)功能?怎么實(shí)現(xiàn)?? A: 通過一個(gè)while循環(huán)和下面的語(yǔ)句:call sleepqq(時(shí)間間隔)就可以了。 Q: 本人嘗試使用ABAQUS的子程序SUBROUTINE,根據(jù)幫助文件需要編譯通過生成*.for和*.lib文件,可是編譯的時(shí)候出現(xiàn)錯(cuò)誤:Error: Cannot open include file 'ABA_PARAM.INC'不知道是什么原因,怎么解決? A: 1.確認(rèn)Visual Fortran及VC++正確安裝,并在安裝ABAQUS之前安裝。2.首先將用戶子程序*.f文件后綴名改為*.for。3.到控制面板-》系統(tǒng)-》高級(jí)-》環(huán)境變量中的 Administrator用戶變量:修改—— 變量名:lib變量值:C:Program FilesMicrosoft Visual StudioDF98LIB;C:Program FilesMicrosoft Visual StudioVC98LIB(我的問題就是因?yàn)橹患恿艘粋€(gè)LIB,必須兩個(gè)都加!)完成以上步驟以后,就可以運(yùn)行了。 Q: 怎樣把自己編寫的子程序倒入到*.INP文件中。 A: Using the following command : abaqus job=job-id As can be seen this is no different from running a standard abaqus job.The user subroutine itself can be embedded in the abaqus input file.Here it is illustrated with the umat subroutine.<....part of the abaqus input file....> ........*END STEP*USER SUBROUTINES SUBROUTINE UMAT(........) ........END ........Alternatively the user subroutine can be in a separate file(say my_material.f)and the INPUT parameter is set to that file name.<....part of the abaqus input file....> ........*USER SUBROUTINES, INPUT=my_material.f ........Q: 用Fortran SYSTEMQQ函數(shù)作批處理遇到問題,在fortran中使用result = systemqq(abaqus job=job1 interactive)作批處理,總是在計(jì)算兩個(gè)job之后就不繼續(xù)往下算了,cmd明令行提示:run time error:floating-point...請(qǐng)問這是怎么回事? A: 個(gè)方法就是做一個(gè)批處理文件,abaqus job=beam interactiveabaqus job=beam1 interactiveabaqus job=beam2 interactiveabaqus job=beam n? interactive存為.bat文件即可。python好像一般是做CAE前后處理界面的。 A:前面加call.call abaqus job=1 interactivecall abaqus job=2 interactivecall abaqus job=3 interactive Q:FORTRAN如何調(diào)用ABAQUS? A: use the function “system” or “systemqq” USE DFLIB LOGICAL(4)result result = SYSTEMQQ('abaqus job=xx')QA: 首先我用ABAQUS的VARIFY命令對(duì)系統(tǒng)進(jìn)行修正和檢測(cè),這個(gè)命令會(huì)自動(dòng)運(yùn)行,對(duì)ABAQUS進(jìn)行調(diào)試等操作,其中涉及到對(duì)用戶子程序的模擬計(jì)算,如果計(jì)算失敗,就會(huì)在VARIFY.LOG文件中說(shuō)明,確實(shí)發(fā)現(xiàn)“USER SUBROUTINE...和SINGLE...和DOUBLE...”失敗,說(shuō)明用戶子程序安裝不成功,肯定與VISUAL FORTRAN6.5有關(guān)!然后,找到FORTRAN_MAKE文本文件,發(fā)現(xiàn)錯(cuò)誤,可能是與FORTRAN安裝有關(guān)!于是卸載FORTRAN,重新安裝在C盤!安裝完畢后,改變環(huán)境變量如下: INCLUDE C:Program FilesMicrosoft Visual StudioDF98IMSLINCLUDE;C:Program FilesMicrosoft Visual StudioVC98INCLUDE;D:程序文件VC98INCLUDE;LIB C:Program FilesMicrosoft Visual StudioDF98IMSLLIB;C:Program FilesMicrosoft Visual StudioDF98LIB;C:Program FilesMicrosoft Visual StudioVC98LIB;D:程序文件VC98LIB;PATH C:Program FilesMicrosoft Visual StudioCommonTools;D:程序文件VC98BIN;%SystemRoot%system32;%SystemRoot%;%SystemRoot%System32Wbem;C:KAV6;D:程序文件KV6;c:program filesmicrosoft visual studiodf98bin;c:program filesmicrosoft visual studiovc98bin;c:program filesmicrosoft visual studiocommonmsdev98bin;D:ABAQUSCommands;C:Program FilesMicrosoft Visual StudioDF98BIN我們只需要關(guān)注MICROSOFT VISUAL STUDIO文件夾!最后,再次執(zhí)行VARIFY命令,等運(yùn)行完畢后,檢查VARIFY文本文件,發(fā)現(xiàn): ABAQUS/Standard with User Subroutines...PASSContinuing...ABAQUS/Explicit with User Subroutines(single precision)...PASSContinuing...ABAQUS/Explicit with User Subroutines(double precision)...PASSContinuing...OK!!?。。。。。?!搞定 Q: 因?yàn)锳BAQUS是用PYTHON編寫的,那么我想要PYTHON 的原代碼,因?yàn)槲蚁?在其中加一個(gè)橢圓程序,不知可行么?(訪問原代碼問題) A: 所有的PY都是差不多一樣的,把ABAQUS的PY拿到MARC試試看 文檔來(lái)源:http://www.tmdps.cn/bbs/redirect.php?fid=10&tid=9031&goto=nextnewset C++繼承中構(gòu)造函數(shù)、析構(gòu)函數(shù)調(diào)用順序及虛函數(shù)的動(dòng)態(tài)綁定 昨天面試被問到這些,慚愧的很,居然搞混了,悔恨了一把。決定要徹底搞清楚。也算是有所收獲。 首先說(shuō)說(shuō)構(gòu)造函數(shù),大家都知道構(gòu)造函數(shù)里就可以調(diào)用成員變量,而繼承中子類是把基類的成員變成自己的成員,那么也就是說(shuō)子類在構(gòu)造函數(shù)里就可以調(diào)用基類的成員了,這就說(shuō)明創(chuàng)建子類的時(shí)候必須先調(diào)用基類的構(gòu)造函數(shù),只有這樣子類才能在構(gòu)造函數(shù)里使用基類的成員,所以是創(chuàng)建子類時(shí)先調(diào)用基類的構(gòu)造函數(shù)然后再調(diào)用自己的構(gòu)造函數(shù)。通俗點(diǎn)說(shuō),你要用某些物品,但這些物品你沒辦法自己生產(chǎn),自然就要等別人生產(chǎn)出來(lái),你才能拿來(lái)用。 接著就是析構(gòu)函數(shù)了,上面說(shuō)到子類是將基類的成員變成自己的成員,那么基類就會(huì)只存在子類中直到子類調(diào)用析構(gòu)函數(shù)后。做個(gè)假設(shè):假如在基類的析構(gòu)函數(shù)調(diào)用比子類的先,這樣會(huì)發(fā)生什么事呢?類成員終止了,而類本身卻還在,但是在類存在的情況下,類成員就應(yīng)該還存在的,這不就產(chǎn)生矛盾了嗎?所以子類是調(diào)用自身的析構(gòu)函數(shù)再調(diào)用基類的析構(gòu)函數(shù)。 現(xiàn)在到了虛函數(shù)了,virtual主要作用是在多態(tài)方面,而C++的多態(tài)最主要的是類的動(dòng)態(tài)綁定,動(dòng)態(tài)綁定則是指將子類的指針或引用轉(zhuǎn)換成基類對(duì)象,基類對(duì)象就可以動(dòng)態(tài)判斷調(diào)用哪個(gè)子類成員函數(shù)。這就說(shuō)明在沒有子類指針或引用轉(zhuǎn)換為基類對(duì)象的話,virtual沒有存在意義(純虛函數(shù)除外),也就是有沒有virtual都是調(diào)用其自身的成員函數(shù)。通過這些分析,對(duì)于virtual就有了眉目了。當(dāng)子類指針或引用轉(zhuǎn)換為基類時(shí),若基類中有用virtual定義的函數(shù),被子類重寫后,此基類對(duì)象就會(huì)根據(jù)子類調(diào)用子類中的重寫后的函數(shù),而不是基類中的函數(shù);反之,若是基類中沒有用virtual定義,則不管基類被賦值的是哪個(gè)子類的值,調(diào)用的都是基類的成員函數(shù)(當(dāng)然指的是子類重載的基類函數(shù),不然就算要調(diào)用子類特有的成員函數(shù)也會(huì)編譯不過)。第二篇:Fortran語(yǔ)言編程小結(jié)
第三篇:C++學(xué)習(xí)心得小結(jié)
第四篇:ABAQUS與FORTRAN論壇問題小結(jié)
第五篇:構(gòu)造函數(shù)-析構(gòu)函數(shù)的調(diào)用順序