我正在尝试将数组传递到函数中,以便能够计算将替换该数组中的原始值的新值。但是,我不断收到返回的零,我不知道为什么。我的代码如下:
program HW10
implicit none
integer :: i
integer, parameter :: &
p=38 !lines to read
real, parameter :: &
g=9.81 !Value of gravity acceleration
integer , dimension(p) :: direction, speed, rh, speedconv
real, dimension (p) :: pressure, height, temp, dewpt, mixr
real :: average, knots
open(1,file='HW10input.txt', status='old', action='read')
10 format (F6.1, T9, F6.1, T16, F5.1, T23, F5.1, T33, I2, T38, F4.2, T46, I3, T53, I3)
do i=1,p
read(1,10)pressure(i), height(i), temp(i), dewpt(i), rh(i), mixr(i), direction(i), speed(i)
end do
close (1)
open(2, file='outputfilehw10.txt', status='new', action='write')
do i=1,p
write (*, 20) pressure(i), height(i), temp(i), dewpt(i), rh(i), mixr(i), direction(i), speed(i)
20 format (F6.1, T9, F6.1, T16, F5.1, T23, F5.1, T33, I2, T38, F4.2, T46, I3, T53, I3)
end do
write (*,*) 'Average= ', average(temp, p)
do i=1,p
write (*,*) 'Wind Speeds: ', knots(speed, p)
end do
end program HW10
Run Code Online (Sandbox Code Playgroud)
当我到达底部的函数“knots”时,问题就出现了。该函数如下所示:
real function knots (x, n)
integer, intent(in) :: n
real, dimension(n), intent(inout) :: x
integer :: i
do i = 1, n
x(i) = (x(i) * 0.514444 )
end do
return x
end function knots
Run Code Online (Sandbox Code Playgroud)
该代码将很好地读取数据,因为我的代码可以正确显示它。然而,当我想查看风速数组中变化的数据时,所有数据点都为零。我是 Fortran 新手,所以我不太确定该怎么做。提前致谢!
如果我尝试使用 gfortran 4.8.3 编译问题中给出的代码(将所有代码放在同一个文件中),则会出现以下两个错误:
第一个错误:
return x
1
Error: Alternate RETURN statement at (1) is only allowed within a SUBROUTINE
Run Code Online (Sandbox Code Playgroud)
第二个错误:
write (*,*) 'Wind Speeds: ', knots(speed, p)
1
Warning: Type mismatch in argument 'x' at (1); passed INTEGER(4) to REAL(4)
Run Code Online (Sandbox Code Playgroud)
让我们处理第一个 - 与许多其他编程语言不同,它不用于设置返回值。
那么,为什么编译器只是抱怨您在函数而不是子例程中完成了此操作,而不是编译器抱怨您在此处放置了一个值呢?有一个称为交替返回的历史功能,有点像使用goto
- 这些只允许在子例程中使用。
因此,让我们替换return x
为return
-- 这可以避免编译器错误,但是代码如何知道要返回什么值?在 fortran 中定义函数时,您可以显式指定结果的名称,但如果您不这样做,那么它会假设您的结果是与函数同名的变量,因此在您的情况下knots
. 因此,在您的代码中,调用了要返回的变量knots
,但它从未被设置为任何内容。通过“巧合”,看起来用于存储结果的内存位(从未明确设置为任何内容)要么被编译器初始化为零,要么您只是访问恰好充满零的未初始化内存。
那么我们该如何解决这个问题呢?让我们明确定义结果
function knots (x, n) result(y)
implicit none
integer, intent(in) :: n
real, dimension(n), intent(inout) :: x
real, dimension(n) :: y
integer :: i
do i = 1, n
y(i) = (x(i) * 0.514444 )
end do
return
end function knots
Run Code Online (Sandbox Code Playgroud)
如果我们尝试编译,我们现在会收到一个新错误!
write (*,*) 'Wind Speeds: ', knots(speed, p)
1
Error: The reference to function 'knots' at (1) either needs an explicit INTERFACE or the rank is incorrect
Run Code Online (Sandbox Code Playgroud)
具有参数/返回值的函数/子例程通常需要定义一个接口。有很多方法可以实现这一点,我将通过将函数放入模块中来实现:
module myknots
implicit none
public :: knots
contains
function knots (x, n) result(y)
implicit none
integer, intent(in) :: n
real, dimension(n), intent(inout) :: x
real, dimension(n) :: y
integer :: i
do i = 1, n
y(i) = (x(i) * 0.514444 )
end do
return
end function knots
end module myknots
Run Code Online (Sandbox Code Playgroud)
然后我们需要添加use myknots, only: knots
到主程序的顶部。现在只剩下第二个错误了。
这告诉我们您已将整数数组传递给需要实数的函数。这是因为speed
被声明为整数,但x
在结中被声明为实数。为了解决这个问题,让我们创建一个新的knots函数,其中x
被声明为整数。我还将使用显式接口来允许我们使用名称来引用任一版本的结knots
。这样做myknots
模块看起来像
module myknots
implicit none
private
public :: knots
interface knots
module procedure knots_r
module procedure knots_i
end interface knots
contains
function knots_r (x, n) result(y)
implicit none
integer, intent(in) :: n
real, dimension(n), intent(inout) :: x
real, dimension(n) :: y
integer :: i
do i = 1, n
y(i) = (x(i) * 0.514444 )
end do
return
end function knots_r
function knots_i (x, n) result(y)
implicit none
integer, intent(in) :: n
integer, dimension(n), intent(inout) :: x
real, dimension(n) :: y
integer :: i
do i = 1, n
y(i) = (x(i) * 0.514444 )
end do
return
end function knots_i
end module myknots
Run Code Online (Sandbox Code Playgroud)
主程序看起来像
Program HW10
use myknots, only: knots
implicit none
integer :: i
integer, parameter :: &
p=38 !lines to read
real, parameter :: &
g=9.81 !Value of gravity acceleration
integer , dimension(p) :: direction, speed, rh, speedconv
real, dimension (p) :: pressure, height, temp, dewpt, mixr
real :: average
open(1,file='HW10input.txt', status='old', action='read')
10 format (F6.1, T9, F6.1, T16, F5.1, T23, F5.1, T33, I2, T38, F4.2, T46, I3, T53, I3)
do i=1,p
read(1,10)pressure(i), height(i), temp(i), dewpt(i), rh(i), mixr(i), direction(i), speed(i)
end do
close (1)
open(2, file='outputfilehw10.txt', status='new', action='write')
do i=1,p
write (*, 20) pressure(i), height(i), temp(i), dewpt(i), rh(i), mixr(i), direction(i), speed(i)
20 format (F6.1, T9, F6.1, T16, F5.1, T23, F5.1, T33, I2, T38, F4.2, T46, I3, T53, I3)
end do
write (*,*) 'Average= ', average(temp, p)
do i=1,p
write (*,*) 'Wind Speeds: ', knots(speed, p)
end do
end program HW10
Run Code Online (Sandbox Code Playgroud)
这已经解决了所有直接问题,但您仍然无法生成可执行文件,因为您尚未定义该average
函数。希望上述步骤足以让您自己实现这一点。
归档时间: |
|
查看次数: |
4912 次 |
最近记录: |