回 帖 发 新 帖 刷新版面

主题:第一次发帖,希望大家不吝赐教 O(∩_∩)O

大家好,我是最近刚刚接触Fortran不久  ,最近在看彭国伦的一本书中有一些问题。
书的p209 在讲module中的函数时的一个程序:
==================================================================================
module constant
  implicit none
  real, parameter :: PI = 3.14159
  real, parameter :: G  = 9.81
end module

module typedef
  implicit none
  type player
    real :: angle
    real :: speed
    real :: distance
  end type
end module

module shoot
  use constant
  use typedef
  implicit none
contains
    ! 由角度、切线速度来计算投射距离
    subroutine Get_Distance( person )
      implicit none
      type(player) :: person
      real rad, Vx, time

      rad  = Angle_TO_Rad( person%angle )      ! 单位转换
      Vx   = person%speed * cos(rad)           ! 水平方向速度
      time = 2.0 * person%speed * sin(rad) / G ! 在空中飞行时间
      person%distance = Vx * time              ! 距离 = 水平方向速度 * 飞行时间

      return
    end subroutine

    ! 把0~360的角度转换成0~2PI的弧度
    real function Angle_TO_Rad( angle )
      implicit none
      real angle
      Angle_TO_Rad = angle*pi/180.0
      return
    end function

end module

program ex0837
  use shoot
  implicit none
  integer, parameter :: players = 5
  type(player) :: people(players) = (/ player(30.0, 25.0, 0.0),&
                                       player(45.0, 20.0, 0.0),& 
                                       player(35.0, 21.0, 0.0),&
                                       player(50.0, 27.0, 0.0),&
                                       player(40.0, 22.0, 0.0) &
                                     /)
  integer :: I

  do I=1, players
     call Get_Distance( people(I) )
     write(*,"('Player ',I1,' =',F8.2)") I, people(I)%distance
  end do

  stop
end
==============================================================================
在这个程序的module typedef中,创建了type(player),这样在主程序和子程序中就无需在创建,而只需声明了,
在主程序和子程序中分别声明了 people和person这两个player类型的数据。我的想法是能不能把
type(player)::people和type(player)::person声明部分也放到module中,并设置为全局变量
这样在程序中仅仅是用就可以了。
我大概的想法是:
==============================================================================
module constant
implicit none
real,parameter::pi=3.14159
real,parameter::g=9.81
end module

module typedef
implicit none
type player
real angle
real speed
real distance
end type
end module

module shoot
use constant
use typedef
type(player)::person
type(player)::people
common person,people
implicit none
end module shoot
========================================
real function angle_to_rad(angle)
use shoot
implicit none 
real angle 
angle_to_rad=angle*pi/180.0
return
end function angle_to_rad
========================================
subroutine get_distance(person)
use shoot
implicit none
!type(player)::person
real rad,vx,time
!封装在一个module中的子程序要调用函数时无需声明
rad=angle_to_rad(person%angle)
vx=person%speed*cos(rad)
time=2.0*person%speed*sin(rad)/g
person%distance=vx*time
return 
end subroutine get_distance
end module shoot 
==========================================
program main
use shoot
implicit none
integer,parameter::players=5
!type(player)::
people(players)=(/ player(30.0,25.0,0.0),player(45.0,20.0,0.0),player(35.0,21.0,0.0),player(50.0,27.0,0.0),player(40.0,22.0&
                               ,0.0)/)

integer i
do i=1,players
call get_distance(people(i))
write(*,"('player',i1,'=',f8.2)")i,people(i)%distance
end do
stop
end program main
===========================================================================
在module shoot中直接把type(player)::people和type(player)::person直接申明成全局变量。
并且没有用contains,而是直接把每个函数都封装好。
但是这样编译时总是有问题,我用的是cvf6.6
我觉得这条错误信息很关键:If a common-block-object is of a derived type, it must be of a sequence type
但不知道是什么意思,另外还有一些别的错误,比如,会说函数的参数没有声明。
希望大家能帮我看看,为什么我这样做不行,应该如何解决。自定义类型的数据能否设置为全局变量,应该如何设置。
谢谢大家了!

回复列表 (共5个回复)

沙发

你把自定义类型变量放在module应该是可以的. 但既然自定义了一种类型, 程序里面可能会用到不少, 放到module里面我觉得没什么好处.
你不要contains的话, 那两个函数就不是在module里面, 在调用它们的函数里面还要做一个interface声明, 那样就更麻烦了. 用module来封装显得更方便易用.

板凳

楼主看书还是想了想的,但有问题可以放在心里,将来知识具备的时候再自行解答则最佳。个人建议:1。 先好好的把书通读几遍,做做一些简单的练习;   2。 多上该论坛看看别人有什么问题,自己能否解答;   3。If a common-block-object is of a derived type, it must be of a sequence type 这个问题,你可以先看看 the Fortran 2003 Handbook;知道一些 Common  &  Sequence & Data alignment; 但这个超出初学者的理解能力了。

    无论如何,祝你早日成长起来,成为一个 Fortran “高手”。

3 楼


大家能否推荐一些较好的初级学习资料,或是能学习的代码,让我能弄懂一些基本的数据结构,类型,比如module,common.我现在是刚起步,还有很多需要学习的地方。谢谢大家。
另外,对于Fortran与c的混合编程,有无一些好的资料供查阅。再次感谢。

4 楼


我感觉在这种情况下,调用函数不需要做interface。因为返回值只有一个,并且是实数变量。不知道对不对。望指教。thanks a lot

5 楼

似乎在同一个文件里面把子函数写在前面(这种用法我只在ivf和cvf下用过, 做测试的时候偷懒)可以不写interface, 不过规范来说还是应该写的. 跟你返回多少个值无关.
如果将程序是自己写代码的话, common了解一下能够看别人的代码就够用了. common的功能已经慢慢被替代和淘汰. 
资料可以参考
http://bbs.pfan.cn/post-300812.html
我比较推荐学了彭书之后看我签名那本书, 比较简单和实用, 论坛现在好像不现实签名了, 我贴出来.
http://www.namipan.com/d/74f4e588e0164521831e78499711920fd9a58b2f969d8000
fortran_95-2003_for_scientists_and_engineers__3rd_edition

我来回复

您尚未登录,请登录后再回复。点此登录或注册