Fortran Coder

查看: 8922|回复: 4
打印 上一主题 下一主题

[求助] 關於矩陣在副程序宣告問題

[复制链接]

35

帖子

12

主题

0

精华

熟手

F 币
173 元
贡献
117 点
跳转到指定楼层
楼主
发表于 2015-8-19 19:02:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 max533 于 2015-8-19 19:06 编辑

我在windows7-64bit作業系統
使用FTN95編譯軟體
在編譯程序的過程中出現


line 133 - error 941 - array2 is adummy argument and so cannot be allocatable
line 132 - error 941 - array_sort is a dummy argument and so cannot be allocatable
line 163 - error 1173 - only character variable can be assigned to character variables, found integer (kind=3)
line 166 - error 1173 - only character variable can be assigned to character variables, found integer (kind=3)


這四個bug我一直找不出問題的癥結點,想說上來請各位高手幫忙解決這難題。
先在這邊感謝各位高手幫忙。


[Fortran] 纯文本查看 复制代码
!input gps_all_info.txt dbar_pick_info.txt
!output result.out result_new.out
program site_distance
implicit none

integer :: number1,number2,k,stat,error,error2,error3,stat2,i
character(len=6),allocatable :: gps_array(:),cwb_array(:)
character :: site1*4,site2*6,cwb*6,gps*4
real*8 :: lat1,lon1,lat2,lon2,distance,height1,height2
real*8,allocatable :: distance_array(:)

!--------------------------------------------------  calculate distance of two station
open(11,file='gps_all_info.txt')
open(12,file='dbar_pick_info.txt')
open(13,file='result.out')

number1=0
do while(number1==0)
        read(11,*,iostat=number1) lon1,lat1,site1,height1
                  if(number1/=0)exit
  
        number2=0
           do while(number2==0)
                  read(12,*,iostat=number2) lon2,lat2,site2,height2
                  if(number2/=0) exit
                         
                if(site1/=site2)then
                call dis(lat1,lon1,lat2,lon2,distance)
        write(13,'(a4,2x,a6,2x,f13.7)')site1,site2,distance
                end if

        end do
    rewind(12)
end do

close (11)
close (12)
close (13)
!--------------------------------------------------  calculate distance of two station

!--------------------------------------------------  give sequence of distance
open(13,file='result.out')
open(14,file='result_new.out')

stat=0
k=0
do while (stat==0)  
  read (13,*,iostat=stat) gps,cwb,distance
  if (stat/=0) exit
  k=k+1
end do

error=0
allocate( distance_array(k), stat=error )
if (error == 0) then
  write(*,*)'The distance array allocated successfully.'
else if (error /= 0) then
  write(*,*)'The distance array failed to allocated.'
end if

error2=0
allocate(gps_array(k),stat=error2)
if (error2 == 0) then
  write(*,*)'The site_gps array allocated successfully.'
else if (error2 /= 0) then
  write(*,*)'The site_gps array failed to allocated.'
end if

error3=0
allocate(cwb_array(k),stat=error3)
if (error3 == 0) then
  write(*,*)'The site_cwb array allocated successfully.'
else if (error3 /= 0) then
  write(*,*)'The site_cwb array failed to allocated.'
end if

k=0
stat2=0
do while (stat2==0)
  k=k+1
  read (13,*,iostat=stat2) gps_array(k),cwb_array(k),distance_array(k)
  if (stat2/=0) exit
end do 
k=k-1
call bubble_sort(distance_array,gps_array,cwb_array,k)

do i=1,k
  write (14,20) gps_array(i),cwb_array(i),distance_array(i)
  20 format (a4,1x,a6,1x,f13.7)
end do
  
deallocate (distance_array)
deallocate (gps_array)
deallocate (cwb_array)

close (13)
close (14)
!--------------------------------------------------  give sequence of diatance
end program

!-----------------------------------------  subroutine : calculate distance of two station

subroutine dis(rlat1,rlon1,rlat2,rlon2,distance)
implicit none
  
  real*8 :: rlat1,rlon1,rlat2,rlon2,distance
  real*8 :: clat1,clat2,slat1,slat2,cdlon,crd
  real*8,parameter :: rerth=6.3712e6
  real*8,parameter :: pi=3.14159265358979, dpr=180.0/pi
  
  
  if ((abs(rlat1-rlat2).lt.0.0001) .and. (abs(rlon1-rlon2).lt.0.0001)) then
    distance=0.
  else
    clat1=cos(real(rlat1)/dpr)
    slat1=sin(real(rlat1)/dpr)
    clat2=cos(real(rlat2)/dpr)
    slat2=sin(real(rlat2)/dpr)
    cdlon=cos(real((rlon1-rlon2))/dpr)
    crd=slat1*slat2+clat1*clat2*cdlon
    distance=real(rerth*acos(crd)/1000.0)
  endif

 end subroutine

!------------------------------------------subroutine : give sequence of distance 
subroutine bubble_sort(array_sort,array1,array2,array_dimension)
implicit none

integer :: array_dimension,scan_number,scan_order,temp_sort,temp1,temp2
!character(len=6) :: array1(array_dimension),array2(array_dimension)
real*8,allocatable :: array_sort(:)
character(len=*),allocatable :: array1(:),array2(:)


allocate( array_sort(array_dimension) )

if (.not. allocated(array_sort))  then
  write(*,*)'In the subroutine buule_sort,The array_sort failed to allocate.'
end if

allocate( array1(array_dimension) )

if (.not. allocated(array1))  then
  write(*,*)'In the subroutine buule_sort,The array1 failed to allocate.'
end if

allocate( array2(array_dimension) )

if (.not. allocated(array_sort))  then
  write(*,*)'In the subroutine buule_sort,The array2 failed to allocate.'
end if

do scan_number=array_dimension-1,1,-1
  do scan_order=1,scan_number,1

    if  (array_sort(scan_order) > array_sort(scan_order+1)) then
        temp_sort=array_sort(scan_order)
        array_sort(scan_order)=array_sort(scan_order+1)
        array_sort(scan_order+1)=temp_sort
        temp1=array1(scan_order)
        array1(scan_order)=array1(scan_order+1)
        array1(scan_order+1)=temp1
        temp2=array2(scan_order)
        array2(scan_order)=array2(scan_order+1)
        array2(scan_order+1)=temp2
    end if
    
  end do
end do
return
end subroutine
    

分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

736

帖子

4

主题

0

精华

大师

农村外出务工人员

F 币
700 元
贡献
359 点

新人勋章爱心勋章水王勋章元老勋章热心勋章

沙发
发表于 2015-8-19 20:12:11 | 只看该作者
如果实参是可分配数组,那么建议分配以后再传入子程序进行计算。
此时,虚参定义为普通数组(不建议定义为可分配数组)

另外。bubble_sort 里面 temp1, temp2 应该为 character 类型变量。

[Fortran] 纯文本查看 复制代码
Module bubble_mod
Contains
  ! ------------------------------------------subroutine : give sequence of distance
  Subroutine bubble_sort(array_sort, array1, array2)
    Implicit None
    Integer :: array_dimension, scan_number, scan_order, temp_sort
    Character (Len=6) :: temp1, temp2
    Real *8 :: array_sort(:)
    Character (Len=*) :: array1(:), array2(:)
    array_dimension = size(array1)
    Do scan_number = array_dimension - 1, 1, -1
      Do scan_order = 1, scan_number, 1
        If (array_sort(scan_order)>array_sort(scan_order+1)) Then
          temp_sort = array_sort(scan_order)
          array_sort(scan_order) = array_sort(scan_order+1)
          array_sort(scan_order+1) = temp_sort
          temp1 = array1(scan_order)
          array1(scan_order) = array1(scan_order+1)
          array1(scan_order+1) = temp1
          temp2 = array2(scan_order)
          array2(scan_order) = array2(scan_order+1)
          array2(scan_order+1) = temp2
        End If
      End Do
    End Do
    Return
  End Subroutine bubble_sort
End Module bubble_mod
Program site_distance
  Use bubble_mod
  Implicit None
  Integer :: number1, number2, k, stat, error, error2, error3, stat2, i
  Character (Len=6), Allocatable :: gps_array(:), cwb_array(:)
  Character :: site1*4, site2*6, cwb*6, gps*4
  Real *8 :: lat1, lon1, lat2, lon2, distance, height1, height2
  Real *8, Allocatable :: distance_array(:)
  ! --------------------------------------------------  calculate distance of two station
  Open (11, File='gps_all_info.txt')
  Open (12, File='dbar_pick_info.txt')
  Open (13, File='result.out')
  number1 = 0
  Do While (number1==0)
    Read (11, *, Iostat=number1) lon1, lat1, site1, height1
    If (number1/=0) Exit
    number2 = 0
    Do While (number2==0)
      Read (12, *, Iostat=number2) lon2, lat2, site2, height2
      If (number2/=0) Exit
      If (site1/=site2) Then
        Call dis(lat1, lon1, lat2, lon2, distance)
        Write (13, '(a4,2x,a6,2x,f13.7)') site1, site2, distance
      End If
    End Do
    Rewind (12)
  End Do
  Close (11)
  Close (12)
  Close (13)
  ! --------------------------------------------------  calculate distance of two station
  ! --------------------------------------------------  give sequence of distance
  Open (13, File='result.out')
  Open (14, File='result_new.out')
  stat = 0
  k = 0
  Do While (stat==0)
    Read (13, *, Iostat=stat) gps, cwb, distance
    If (stat/=0) Exit
    k = k + 1
  End Do
  error = 0
  Allocate (distance_array(k), Stat=error)
  If (error==0) Then
    Write (*, *) 'The distance array allocated successfully.'
  Else
    Write (*, *) 'The distance array failed to allocated.'
  End If
  error2 = 0
  Allocate (gps_array(k), Stat=error2)
  If (error2==0) Then
    Write (*, *) 'The site_gps array allocated successfully.'
  Else
    Write (*, *) 'The site_gps array failed to allocated.'
  End If
  error3 = 0
  Allocate (cwb_array(k), Stat=error3)
  If (error3==0) Then
    Write (*, *) 'The site_cwb array allocated successfully.'
  Else
    Write (*, *) 'The site_cwb array failed to allocated.'
  End If
  k = 0
  stat2 = 0
  Do While (stat2==0)
    k = k + 1
    Read (13, *, Iostat=stat2) gps_array(k), cwb_array(k), distance_array(k)
    If (stat2/=0) Exit
  End Do
  k = k - 1
  Call bubble_sort(distance_array, gps_array(1:k), cwb_array(1:k))
  Do i = 1, k
    Write (14, 20) gps_array(i), cwb_array(i), distance_array(i)
  End Do
  Deallocate (distance_array)
  Deallocate (gps_array)
  Deallocate (cwb_array)
  Close (13)
  Close (14)
  20 Format (A4, 1X, A6, 1X, F13.7)
  ! --------------------------------------------------  give sequence of diatance
End Program site_distance
! -----------------------------------------  subroutine : calculate distance of two station
Subroutine dis(rlat1, rlon1, rlat2, rlon2, distance)
  Implicit None
  Real *8 :: rlat1, rlon1, rlat2, rlon2, distance
  Real *8 :: clat1, clat2, slat1, slat2, cdlon, crd
  Real *8, Parameter :: rerth = 6.3712E6
  Real *8, Parameter :: pi = 3.14159265358979, dpr = 180.0/pi
  If ((abs(rlat1-rlat2)<0.0001) .And. (abs(rlon1-rlon2)<0.0001)) Then
    distance = 0.
  Else
    clat1 = cos(real(rlat1)/dpr)
    slat1 = sin(real(rlat1)/dpr)
    clat2 = cos(real(rlat2)/dpr)
    slat2 = sin(real(rlat2)/dpr)
    cdlon = cos(real((rlon1-rlon2))/dpr)
    crd = slat1*slat2 + clat1*clat2*cdlon
    distance = real(rerth*acos(crd)/1000.0)
  End If
End Subroutine dis

35

帖子

12

主题

0

精华

熟手

F 币
173 元
贡献
117 点
板凳
 楼主| 发表于 2015-8-20 17:01:30 | 只看该作者
本帖最后由 max533 于 2015-8-20 17:12 编辑
楚香饭 发表于 2015-8-19 20:12
如果实参是可分配数组,那么建议分配以后再传入子程序进行计算。
此时,虚参定义为普通数组(不建议定义为 ...

感謝楚大的的熱心答覆,但我有部分我不是很確定,想跟您討教一下。
第一個問題
LINE 099
Call bubble_sort(distance_array, gps_array(1:k), cwb_array(1:k))
此行是不是應該要改寫成
Call bubble_sort(distance_array(1:k), gps_array(1:k), cwb_array(1:k))

第二個問題
LINE 008
    Real *8 :: array_sort(:)
LINE 009
    Character (Len=*) :: array1(:), array2(:)

此兩行中
array_sort和array1, array2 在副程序裡面是可變數組
那為什麼您可以直接宣告成普通數組的樣子。
不是應該要宣告成
LINE 008
    Real *8,allocatable :: array_sort(:)
LINE 009
    Character (Len=*),allocatable :: array1(:), array2(:)

是因為傳進來的數組大小已經確定,所以不用去擔心數組是否可變的問題嗎?!

第三個問題
我是不是也能改寫成下面這樣呢?!
編譯的過程是沒有問題。但不知道
會不會有什麼其他問題產生呢?!
[Fortran] 纯文本查看 复制代码
Module bubble_mod
Contains
  ! ------------------------------------------subroutine : give sequence of distance
  Subroutine bubble_sort(array_sort, array1, array2,array_dimension)
    Implicit None
    Integer :: array_dimension, scan_number, scan_order, temp_sort
    Character (Len=6) :: temp1, temp2
    Real *8 :: array_sort(array_dimension)
    Character (Len=6) :: array1(array_dimension), array2(array_dimension)
    array_dimension = size(array1)
    Do scan_number = array_dimension - 1, 1, -1
      Do scan_order = 1, scan_number, 1
        If (array_sort(scan_order)>array_sort(scan_order+1)) Then
          temp_sort = array_sort(scan_order)
          array_sort(scan_order) = array_sort(scan_order+1)
          array_sort(scan_order+1) = temp_sort
          temp1 = array1(scan_order)
          array1(scan_order) = array1(scan_order+1)
          array1(scan_order+1) = temp1
          temp2 = array2(scan_order)
          array2(scan_order) = array2(scan_order+1)
          array2(scan_order+1) = temp2
        End If
      End Do
    End Do
    Return
  End Subroutine bubble_sort
End Module bubble_mod
Program site_distance
  Use bubble_mod
  Implicit None
  Integer :: number1, number2, k, stat, error, error2, error3, stat2, i
  Character (Len=6), Allocatable :: gps_array(:), cwb_array(:)
  Character :: site1*4, site2*6, cwb*6, gps*4
  Real *8 :: lat1, lon1, lat2, lon2, distance, height1, height2
  Real *8, Allocatable :: distance_array(:)
  ! --------------------------------------------------  calculate distance of two station
  Open (11, File='gps_all_info.txt')
  Open (12, File='dbar_pick_info.txt')
  Open (13, File='result.out')
  number1 = 0
  Do While (number1==0)
    Read (11, *, Iostat=number1) lon1, lat1, site1, height1
    If (number1/=0) Exit
    number2 = 0
    Do While (number2==0)
      Read (12, *, Iostat=number2) lon2, lat2, site2, height2
      If (number2/=0) Exit
      If (site1/=site2) Then
        Call dis(lat1, lon1, lat2, lon2, distance)
        Write (13, '(a4,2x,a6,2x,f13.7)') site1, site2, distance
      End If
    End Do
    Rewind (12)
  End Do
  Close (11)
  Close (12)
  Close (13)
  ! --------------------------------------------------  calculate distance of two station
  ! --------------------------------------------------  give sequence of distance
  Open (13, File='result.out')
  Open (14, File='result_new.out')
  stat = 0
  k = 0
  Do While (stat==0)
    Read (13, *, Iostat=stat) gps, cwb, distance
    If (stat/=0) Exit
    k = k + 1
  End Do
  error = 0
  Allocate (distance_array(k), Stat=error)
  If (error==0) Then
    Write (*, *) 'The distance array allocated successfully.'
  Else
    Write (*, *) 'The distance array failed to allocated.'
  End If
  error2 = 0
  Allocate (gps_array(k), Stat=error2)
  If (error2==0) Then
    Write (*, *) 'The site_gps array allocated successfully.'
  Else
    Write (*, *) 'The site_gps array failed to allocated.'
  End If
  error3 = 0
  Allocate (cwb_array(k), Stat=error3)
  If (error3==0) Then
    Write (*, *) 'The site_cwb array allocated successfully.'
  Else
    Write (*, *) 'The site_cwb array failed to allocated.'
  End If
  k = 0
  stat2 = 0
  Do While (stat2==0)
    k = k + 1
    Read (13, *, Iostat=stat2) gps_array(k), cwb_array(k), distance_array(k)
    If (stat2/=0) Exit
  End Do
  k = k - 1
  Call bubble_sort(distance_array(1:k), gps_array(1:k), cwb_array(1:k),k)
  Do i = 1, k
    Write (14, 20) gps_array(i), cwb_array(i), distance_array(i)
  End Do
  Deallocate (distance_array)
  Deallocate (gps_array)
  Deallocate (cwb_array)
  Close (13)
  Close (14)
  20 Format (A4, 1X, A6, 1X, F13.7)
  ! --------------------------------------------------  give sequence of diatance
End Program site_distance
! -----------------------------------------  subroutine : calculate distance of two station
Subroutine dis(rlat1, rlon1, rlat2, rlon2, distance)
  Implicit None
  Real *8 :: rlat1, rlon1, rlat2, rlon2, distance
  Real *8 :: clat1, clat2, slat1, slat2, cdlon, crd
  Real *8, Parameter :: rerth = 6.3712E6
  Real *8, Parameter :: pi = 3.14159265358979, dpr = 180.0/pi
  If ((abs(rlat1-rlat2)<0.0001) .And. (abs(rlon1-rlon2)<0.0001)) Then
    distance = 0.
  Else
    clat1 = cos(real(rlat1)/dpr)
    slat1 = sin(real(rlat1)/dpr)
    clat2 = cos(real(rlat2)/dpr)
    slat2 = sin(real(rlat2)/dpr)
    cdlon = cos(real((rlon1-rlon2))/dpr)
    crd = slat1*slat2 + clat1*clat2*cdlon
    distance = real(rerth*acos(crd)/1000.0)
  End If
End Subroutine dis

736

帖子

4

主题

0

精华

大师

农村外出务工人员

F 币
700 元
贡献
359 点

新人勋章爱心勋章水王勋章元老勋章热心勋章

地板
发表于 2015-8-20 19:21:00 | 只看该作者
问题1,是的。也需要修改,我没注意到。

问题2,见我之前的回答。

问题3,可以。你这样叫自动数组,我那样叫假定形状。
推荐用假定形状,这样少传递一个参数,简洁

35

帖子

12

主题

0

精华

熟手

F 币
173 元
贡献
117 点
5#
 楼主| 发表于 2015-8-20 20:28:17 | 只看该作者
楚香饭 发表于 2015-8-20 19:21
问题1,是的。也需要修改,我没注意到。

问题2,见我之前的回答。

感謝楚大,小弟受益良多。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

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

GMT+8, 2024-12-23 09:56

Powered by Tencent X3.4

© 2013-2024 Tencent

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