TGDZ Calc的Fortran90实现
我大学时学的是Fortran77,当时完全没有计算机的概念,一上来就学这个语言编程,很多编程的概念都没有建立起来,几年之后就完全忘光了.
今天拿起Fortran想把TGDZ Calc重新写一遍,又临时找了本FORTRAN教程来看,才发现当年的FORTRAN77真是憋屈的一个语言,用的是固定格式,语言中的一些设定也非常奇葩(比如“某某字母开头的代表是整形变量”,开头必须是数字以代表一行,多少列之后的字符会被忽略), 完全没有想再学一下的兴趣,于是直接跳到采用自由编码格式的Fortran90.
搞了一会儿,才明白subroutine之外还有function,前者大约相当于模块或其它源文件,后者则与现代的函数有点类似,有意思的是,f90中参数只读用indent 指令来限制,参数的类型不写在括号内而是放在函数内部的前面(这可能与当时的语法分析能力不足有关).F90的参数传地址,可以将函数作为参数传统等特点,又感觉有一点高级.这个东西对字符串的支持感觉比较少,连中文字串都容易乱码.
更奇葩的是,在测试中我发现有一行代码中,声明变量时并进行了初始化,但调试时发现根本就没有执行这个初始而导致出现了奇怪的错乱,可能是编译器的某个bug.
总体感觉下来,这是一个非常早期的语言,语法上很不灵活,主要限制在一些理工科计算的领域还在使用,在通用领域远不如C或C++等语言好用. 感觉如果要用的话,可以用它写一些基本的计算库,给C++来调用会比较好.
点击查看代码
program main
implicit none
!declare function returned value
character(len=4),external::YearToTGDZ
integer,external::CalcBaseYear, TGDZtoYear
character(len=4)::CalcedTGDZ
integer:: year, bYear, reCalcedYear
integer, parameter:: LastYear=2100
do year=1900, LastYear
bYear= CalcBaseYear (year)
CalcedTGDZ=YearToTGDZ(year)
reCalcedYear=TGDZtoYear(CalcedTGDZ, bYear)
print *, year, " --> ", CalcedTGDZ," start from ", bYear, ",reversed to ", reCalcedYear
end do
end
integer function CalcBaseYear(cy)
implicit none
integer,intent(in):: cy
integer:: by
if (cy >0) then
by=4
else
by=-57
end if
do while (by > cy)
by = by -60
end do
do while( (by+60) <=cy)
by = by+ 60;
end do
CalcBaseYear=by
return
end
character(len=4) function YearToTGDZ(y)
implicit none
integer,intent(in)::y ! describle the param
integer::tmpyear,offval, tgi, dzi ! define local variables
character(len=2):: tgArr(10), dzArr(12)
tmpYear=y ! copy the value
tgArr(1)="甲"
tgArr(2)="乙"
tgArr(3)="丙"
tgArr(4)="丁"
tgArr(5)="戊"
tgArr(6)="己"
tgArr(7)="庚"
tgArr(8)="辛"
tgArr(9)="壬"
tgArr(10)="癸"
dzArr(1)="子"
dzArr(2)="丑"
dzArr(3)="寅"
dzArr(4)="卯"
dzArr(5)="辰"
dzArr(6)="巳"
dzArr(7)="午"
dzArr(8)="未"
dzArr(9)="申"
dzArr(10)="酉"
dzArr(11)="戌"
dzArr(12)="亥"
if (tmpyear>0) then
offval=4
else
offval=3
end if
tmpyear = tmpyear - offval
do while(tmpyear<0)
tmpyear=tmpyear+60
end do
tgi= mod(tmpyear,10)
dzi=mod(tmpyear,12)
YearToTGDZ=tgArr(tgi+1)//dzArr(dzi+1)
return
end
integer function TGDZtoYear ( tgdzChars, givenBY)
implicit none
character(len=4),intent(in)::tgdzChars
integer,intent(in)::givenBY
integer::ti, di, m ! init ti=1 or di=1 sometimes is ingnored, wield!
character(len=2):: tgChar, dzChar
character(len=2):: tgArr(10), dzArr(12)
ti=1 ! Clearly set ti to 1 for each call
di=1
tgArr(1)="甲"
tgArr(2)="乙"
tgArr(3)="丙"
tgArr(4)="丁"
tgArr(5)="戊"
tgArr(6)="己"
tgArr(7)="庚"
tgArr(8)="辛"
tgArr(9)="壬"
tgArr(10)="癸"
dzArr(1)="子"
dzArr(2)="丑"
dzArr(3)="寅"
dzArr(4)="卯"
dzArr(5)="辰"
dzArr(6)="巳"
dzArr(7)="午"
dzArr(8)="未"
dzArr(9)="申"
dzArr(10)="酉"
dzArr(11)="戌"
dzArr(12)="亥"
tgChar=tgdzChars(1:2)
dzChar=tgdzChars(3:4)
!print *, tgchar
!print *, dzchar
! Calc the tgindex
do while(ti<=10)
if (tgArr(ti)==tgChar) then
exit ! ti is the target result
end if
ti=ti+1
end do
!Calc the dzIndex
do while(di<=12)
if (dzArr(di)==dzChar) then
exit ! when exit ti is the result
end if
di=di+1
end do
m=ti - di
if (m<0) then
m=12+m
end if
! use the function name to return the result value
TGDZtoYear=givenBY + 5*m + ti-1 ! ti is 1-based index, so sub 1 from result.
return
end
! Coded and debuged in Simply Fortran 3.40 build 4419, compiler is bundled gfortran.


浙公网安备 33010602011771号