我正在尝试将数组传递给函数,以便能够计算将替换该数组中原始值的新值。但是,我一直收到零返回,我不知道为什么。我的代码如下:
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
当我到达底部的“结”功能时出现问题。这就是函数的样子:
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
代码将在数据中读取正确,因为我有正确显示它的代码。但是,当我想在风速阵列中看到变化的数据时,所有数据点都是零。我是Fortran的新手,所以我不太清楚该怎么做。提前谢谢!
答案 0 :(得分:3)
如果我尝试使用gfortran 4.8.3编译问题中给出的代码(将所有内容放在同一个文件中),我会收到以下两个错误:
第一个错误:
return x
1
Error: Alternate RETURN statement at (1) is only allowed within a SUBROUTINE
第二个错误:
write (*,*) 'Wind Speeds: ', knots(speed, p)
1
Warning: Type mismatch in argument 'x' at (1); passed INTEGER(4) to REAL(4)
让我们来处理其中的第一个 - 与许多其他编程语言不同,它不用于设置返回值。
那么,为什么编译器只是抱怨你在一个函数而不是一个子例程中完成了这个,而不是编译器抱怨你在这里放了一个值?有一个称为备用返回的历史特征,有点像使用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
如果我们尝试编译,我们现在会收到一个新错误!
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
带参数/返回值的函数/子例程通常需要定义接口。有很多方法可以实现这一点,我将通过将函数放在一个模块中来实现:
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
然后我们需要将use myknots, only: knots
添加到主程序的顶部。现在这只剩下第二个错误了。
这告诉我们的是,您已将整数数组传递给期望实数值的函数。这是因为speed
被声明为整数,但结中的x
被声明为真实。为了解决这个问题,我们创建一个新的结函数,其中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
主程序看起来像
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
这解决了所有直接问题,但由于您尚未定义average
函数,因此仍无法生成可执行文件。希望上面的步骤足以让你自己实现它。
答案 1 :(得分:2)
你有一个功能knots
,它有一个真实的结果。看一下
write (*,*) 'Wind Speeds: ', knots(speed, p)
评估函数引用knots(speed, p)
以返回该实际结果,然后打印该结果。
基于相同的误解,存在两个问题:在函数knots
中,函数的结果具有名称knots
。这与intent(inout)
伪参数x
不同。
问题1:您没有在函数中定义knots
的值。
问题2:knots
的值不是您想要的值。您需要speed
的值(返回时)。
您可以将结果knots
定义为输出数组,也可以使用子例程。我不会详细介绍这两种方法(因为那里有大量资源),但我会清楚地注意到:如果knots
成为带有结果数组的函数,则需要{{3它被引用时可用。