如何在Fortran的main.f95中正确导入roll_dice.f95子程序?
Fortran模块化导入子程序的解决方法
错误原因
你遇到的编译错误本质是Fortran语法规则限制:当用include将子程序代码插入主程序时,子程序不能直接放在主程序的执行语句区域(比如call语句前后)。主程序的结构要求,内部子程序必须放在contains块中;如果要作为独立文件的外部子程序,需要用模块或者分开编译链接。
另外你代码里还有两个小问题:
- 输出骰子图案时的反斜杠
\是多余的,Fortran不需要转义加号,会导致输出多余的反斜杠 - 最后输出掷骰结果的格式串
"('You rolled a ', 5(i0, ' and ', i0))"有误,5是多余的,会导致格式不匹配
解决方法一:修正include的用法(适合简单场景)
把include放在主程序的contains块中,让子程序成为主程序的内部子程序:
修改后的main.f95
program main implicit none ! 这里可以声明变量或添加use语句 call roll_dice() ! 调用子程序 contains ! 将子程序文件包含在contains块内,符合Fortran语法 include 'roll_dice.f95' end program main
修正后的roll_dice.f95
去掉多余的反斜杠,修正格式串:
subroutine roll_dice() real :: r(2) integer :: i(2) call random_seed() call random_number(r) ! 转换为1-6的整数 i = 1 + nint(5 * r) ! 第一个骰子图案 select case (i(1)) case (1) print *, "+-------+" print *, "| |" print *, "| * |" print *, "| |" print *, "+-------+" case (2) print *, "+-------+" print *, "| * |" print *, "| |" print *, "| * |" print *, "+-------+" case (3) print *, "+-------+" print *, "| * |" print *, "| * |" print *, "| * |" print *, "+-------+" case (4) print *, "+-------+" print *, "| * * |" print *, "| |" print *, "| * * |" print *, "+-------+" case (5) print *, "+-------+" print *, "| * * |" print *, "| * |" print *, "| * * |" print *, "+-------+" case (6) print *, "+-------+" print *, "| * * |" print *, "| * * |" print *, "| * * |" print *, "+-------+" case default print *, "第一个随机数无效" end select ! 第二个骰子图案 select case (i(2)) case (1) print *, "+-------+" print *, "| |" print *, "| * |" print *, "| |" print *, "+-------+" case (2) print *, "+-------+" print *, "| * |" print *, "| |" print *, "| * |" print *, "+-------+" case (3) print *, "+-------+" print *, "| * |" print *, "| * |" print *, "| * |" print *, "+-------+" case (4) print *, "+-------+" print *, "| * * |" print *, "| |" print *, "| * * |" print *, "+-------+" case (5) print *, "+-------+" print *, "| * * |" print *, "| * |" print *, "| * * |" print *, "+-------+" case (6) print *, "+-------+" print *, "| * * |" print *, "| * * |" print *, "| * * |" print *, "+-------+" case default print *, "第二个随机数无效" end select ! 修正格式串,正确输出两个骰子的点数 print "('你掷出了 ', i0, ' 和 ', i0)", i end subroutine roll_dice
编译运行:
gfortran main.f95 -o dice_game ./dice_game
解决方法二:使用Fortran模块(推荐,适合大型模块化程序)
这是Fortran标准的模块化编程方式,更适合后续扩展多个子程序的场景:
修改后的roll_dice.f95(改为模块)
module dice_mod implicit none contains subroutine roll_dice() real :: r(2) integer :: i(2) call random_seed() call random_number(r) ! 转换为1-6的整数 i = 1 + nint(5 * r) ! 第一个骰子图案 select case (i(1)) case (1) print *, "+-------+" print *, "| |" print *, "| * |" print *, "| |" print *, "+-------+" case (2) print *, "+-------+" print *, "| * |" print *, "| |" print *, "| * |" print *, "+-------+" case (3) print *, "+-------+" print *, "| * |" print *, "| * |" print *, "| * |" print *, "+-------+" case (4) print *, "+-------+" print *, "| * * |" print *, "| |" print *, "| * * |" print *, "+-------+" case (5) print *, "+-------+" print *, "| * * |" print *, "| * |" print *, "| * * |" print *, "+-------+" case (6) print *, "+-------+" print *, "| * * |" print *, "| * * |" print *, "| * * |" print *, "+-------+" case default print *, "第一个随机数无效" end select ! 第二个骰子图案 select case (i(2)) case (1) print *, "+-------+" print *, "| |" print *, "| * |" print *, "| |" print *, "+-------+" case (2) print *, "+-------+" print *, "| * |" print *, "| |" print *, "| * |" print *, "+-------+" case (3) print *, "+-------+" print *, "| * |" print *, "| * |" print *, "| * |" print *, "+-------+" case (4) print *, "+-------+" print *, "| * * |" print *, "| |" print *, "| * * |" print *, "+-------+" case (5) print *, "+-------+" print *, "| * * |" print *, "| * |" print *, "| * * |" print *, "+-------+" case (6) print *, "+-------+" print *, "| * * |" print *, "| * * |" print *, "| * * |" print *, "+-------+" case default print *, "第二个随机数无效" end select ! 修正格式串 print "('你掷出了 ', i0, ' 和 ', i0)", i end subroutine roll_dice end module dice_mod
修改后的main.f95(使用模块)
program main ! 导入模块,这样就能使用其中的子程序 use dice_mod implicit none call roll_dice() ! 调用模块中的子程序 end program main
编译运行:
# 方式一:分开编译 gfortran -c roll_dice.f95 gfortran main.f95 roll_dice.o -o dice_game ./dice_game # 方式二:一次性编译 gfortran main.f95 roll_dice.f95 -o dice_game ./dice_game
内容的提问来源于stack exchange,提问作者Jace
相关产品推荐
相关产品推荐

