Fortran Coder

查看: 642|回复: 2

Fortran编程技巧(持续更新)

[复制链接]

92

帖子

25

主题

1

精华

大师

F 币
897 元
贡献
507 点
发表于 2022-10-26 13:50:05 | 显示全部楼层 |阅读模式
本帖最后由 weixing1531 于 2022-10-31 18:00 编辑

学习Fortran已有近20年,收集了一些编程技巧。
(1)修改老程序goto语句
先构造一个只执行一次的命名循环,再使用exit退出命名循环从而避免使用goto语句
老程序
[Fortran] 纯文本查看 复制代码
if(...)then
  语句A
  goto 99
end if
if(...)then
  语句B
  goto 99
end if
语句C
99 语句D

等价于新程序
[Fortran] 纯文本查看 复制代码
out:do i=1,1
  if(...)then
    语句A
    exit out
  end if
  if(...)then
    语句B
    exit out
  end if
  语句C
end do out
语句D

(2)整数转换为字符串
[Fortran] 纯文本查看 复制代码
pure function int2str(j) result(f_string)
    integer,intent(in)::j !j为要转换的整数
    character(len=:),allocatable::f_string !递延长度字符串
    integer::length

    length=abs(j)/10+1+merge(0,1,j>=0) !负数需增加符号这一位
    allocate(character(len=length)::f_string) !根据j的位数分配字符串长度
    !整数转换为字符串
    write(f_string,"(i0)")j !f_string长度必须明确
end function int2str


(3)C字符串指针转换Fortran字符串
[Fortran] 纯文本查看 复制代码
FUNCTION C_to_F_string(c_string_pointer) RESULT(f_string) !C字符串指针转换Fortran字符串
        USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_F_POINTER, C_CHAR, C_NULL_CHAR
        type(C_PTR), INTENT(IN) :: c_string_pointer !C字符串指针
        CHARACTER(LEN=:), ALLOCATABLE :: f_string !延迟长度字符串
        CHARACTER(KIND=C_CHAR), DIMENSION(:), POINTER :: char_array_pointer => NULL() !Fortran字符数组指针
        CHARACTER(LEN=255) :: aux_string
        INTEGER :: i, length=0

        CALL C_F_POINTER(c_string_pointer, char_array_pointer, [255]) !C字符串指针转换为Fortran字符数组指针

        IF (.NOT.ASSOCIATED(char_array_pointer)) THEN !char_array_pointer为空指针
            ALLOCATE(CHARACTER(LEN=4)::f_string)
            f_string="NULL"
            return
        END IF

        aux_string=" "

        DO i=1,255
            IF (char_array_pointer(i)==c_null_char) THEN !达到字符串尾部
                length=i-1
                EXIT
            END IF

            aux_string(i:i)=char_array_pointer(i) !逐个元素复制字符
        END DO

        ALLOCATE(CHARACTER(LEN=length)::f_string)
        f_string=aux_string(1:length)
END FUNCTION C_to_F_string

(4)读写Excel数据
方法一:商业库Libxl提供了Fortran函数接口,序列号需要破解
https://www.libxl.com/
方法二:先读写csv文件,然后手动另存为xls格式
Github网上有现成的csv模块,作者:Jacob Williams
(5)日期与时间操作
Github网上有现成的datetime模块
https://github.com/wavebitscientific/datetime-fortran
(6)常用数值计算算法原代码
Numerical Recipe、宋叶志、何光渝、徐士良
(7)生成随着时间与日期变动的动态密码
[Fortran] 纯文本查看 复制代码
impure function GetPassword(PasswordLen,IsDay) !获得动态密码及长度
    integer,intent(out)::PasswordLen
    logical,intent(in),optional::IsDay !动态密码是否日变化
    character(len=:),allocatable::GetPassword !递延长度字符串
    character(8)  :: date,temp !CCYYMMDD
    character(10) :: time !HHMMSS.SSS
    
    call date_and_time(date,time) !返回当前日期与时间
    temp=date(3:8)//time(1:2) !界面进入原始密码 为与时间有关的动态密码YYMMDDHH 两位年月日时
    
    if(present(IsDay))then
        if(IsDay)temp=date(1:8) !界面进入密码 为与日期有关的动态密码CCYYMMDD 四位年月日
    end if
    
    GetPassword="Wx"
    GetPassword=GetPassword//temp(2:8)//temp(1:1) !加工后密码
    PasswordLen=len(GetPassword) !输出密码字符串长度
end function

(8)判断整数变量b的值是否与一维整数数组a的任意元素相等
方法一:
[Fortran] 纯文本查看 复制代码
Any(a==b) !T相等F不相等

方法二:
[Fortran] 纯文本查看 复制代码
FindLoc(a,b)==[0] !F相等T不相等

(9)常用参考网站
https://fortranwiki.org/fortran/show/HomePage
https://fortran-lang.org/
https://jblevins.org/mirror/amiller/







评分

参与人数 1F 币 +5 贡献 +3 收起 理由
fcode + 5 + 3 赞一个!

查看全部评分

1801

帖子

13

主题

5

精华

论坛跑堂

臭石头雪球

F 币
678 元
贡献
268 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

发表于 2022-10-28 08:53:15 | 显示全部楼层
楼主这个帖子主题不错。我也来一个技巧。

善用常量数组来替代一些 if else。
比如,经典的考试题目,星期一看电影,星期二看书,星期三聚会,星期四野营,星期五星期六旅行,星期日休息。
输入星期几,输出要做的事情。

普通代码:
[Fortran] 纯文本查看 复制代码
program fcode_cn
  integer :: wk
  read(*,*) wk
  select case(wk)
  case (1)
    write(*,*) "看电影"
  case (2)
    write(*,*) "看书"
  case (3)
    write(*,*) "聚会"
  case (4)
    write(*,*) "野营"
  case (5,6)
    write(*,*) "旅行"
  case (7)
    write(*,*) "休息"
  end select
end program fcode_cn


利用常量数组代码:
[Fortran] 纯文本查看 复制代码
program fcode_cn
  character(len=6) , parameter :: ACT(*) = &
    [character(len=6)::"看电影","看书","聚会","野营","旅行","旅行","休息"]
  integer :: wk
  read(*,*) wk
  write(*,*) ACT(wk)
end program fcode_cn


可以看到,合理的使用常量数组,不但代码简练,并且易于维护,以后增加和修改都更简单。
同时,也便与遍历整个星期。
[Fortran] 纯文本查看 复制代码
  do i = 1 , size(ACT)
    write(*,*) ACT(i)
  end do

1

帖子

0

主题

0

精华

新人

F 币
28 元
贡献
6 点
发表于 2022-11-11 02:22:48 | 显示全部楼层
fcode 发表于 2022-10-28 08:53
楼主这个帖子主题不错。我也来一个技巧。

善用常量数组来替代一些 if else。

学习了 这个方法真的好用
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2022-12-9 03:56

Powered by Tencent X3.4

© 2013-2022 Tencent

快速回复 返回顶部 返回列表