用数组成员作为fortran中do循环的控制变量
我很惊讶,您不能像这样将数组成员作为do循环的控制变量:用数组成员作为fortran中do循环的控制变量,fortran,fortran90,do-loops,Fortran,Fortran90,Do Loops,我很惊讶,您不能像这样将数组成员作为do循环的控制变量: program test integer, dimension(2) :: i do i(1) = 1, 3 do i(2) = 1, 3 ! anything here write(*, *) i end do end do end program program test integer, dimension(2) :: i associa
program test
integer, dimension(2) :: i
do i(1) = 1, 3
do i(2) = 1, 3
! anything here
write(*, *) i
end do
end do
end program
program test
integer, dimension(2) :: i
associate (x => i(1), y => i(2))
do x = 1, 3
do y = 1, 3
! anything here
write(*, *) i
end do
end do
end associate
end program
我的问题是为什么不允许这样做
编辑:
或者这是允许的,但我做错了
来自ifort v 11.1的错误消息为:
test.f90(4): error #5082: Syntax error, found IDENTIFIER 'I' when expecting one of: ( % : . = =>
do i(1) = 1, 3
-------^
test.f90(4): error #5082: Syntax error, found ',' when expecting one of: <END-OF-STATEMENT> ;
do i(1) = 1, 3
---------------^
test.f90(5): error #5082: Syntax error, found IDENTIFIER 'I' when expecting one of: ( % : . = =>
do i(2) = 1, 3
-------^
test.f90(5): error #5082: Syntax error, found ',' when expecting one of: <END-OF-STATEMENT> ;
do i(2) = 1, 3
---------------^
test.f90(4): error #6535: This variable or component must be of a derived or structure type [DO]
do i(1) = 1, 3
----^
test.f90(4): error #6460: This is not a field name that is defined in the encompassing structure. [I]
do i(1) = 1, 3
-------^
test.f90(8): error #6099: An ENDDO statement occurred without a corresponding DO or DO WHILE statement.
end do
----^
test.f90(9): error #6099: An ENDDO statement occurred without a corresponding DO or DO WHILE statement.
end do
----^
对不起,我第一次答错了 该限制源于语言规则: Fortran 2008(ISO/IEC 1539-1-2010)8.1.6.2: R818循环控制为,do变量= R819 do变量为,标量int变量名 C812(R819)do变量应为整型变量 因此,是的,在循环控制变量的位置只允许使用标量变量名
如果你问为什么语言的规则是这样的,你必须问标准的作者,SC22/WG5和X3J3,但我猜这与在固定源格式中语法明确的必要性有关。在固定源代码中,空格并不重要,很难找到明确的语法。Fortran 2003和更高版本有一个称为关联块的构造,在该块中,您可以将名称与任何表达式关联。在您的情况下,它看起来有点像这样:
program test
integer, dimension(2) :: i
do i(1) = 1, 3
do i(2) = 1, 3
! anything here
write(*, *) i
end do
end do
end program
program test
integer, dimension(2) :: i
associate (x => i(1), y => i(2))
do x = 1, 3
do y = 1, 3
! anything here
write(*, *) i
end do
end do
end associate
end program
这将更新双循环内的i
(注意:在@VladimirF在下面的评论中确认之前,我不确定这是否符合标准。谢谢)是正确的,但我们可以强调一点相关的内容
do变量的引用语法规则为
R819 do变量是标量整型变量名
非常重要的是要注意这到底意味着什么
当然,do变量必须是标量整型变量。在问题的情况下,数组元素i(1)
(和i(2)
)是标量整数变量:数组元素是秩为0的变量
然而,名称是一个进一步的限制i(1)
本身不是一个名称。我们看到了语法规则
R303名称为字母[字母数字字符]
这个超出标量整数变量的限制超出了数组元素。此外,以下可能是没有相应名称的变量:
- 派生类型的组件李>
- 具有指针结果的函数(Fortran 2008中的变量,而不是以前的变量)
type t
integer i
end type t
type(t) x
do x%i=1,1 ! x%i is not a name
end do
end
两者都不是
integer, target :: i
do f()=1,1
end do
contains
function f()
integer, pointer :: f
f=>i
end function
end
但是,如中所述,使用关联构造是成功的:
type t
integer i
end type
type(t) x
integer n(1)
associate (i=>x%i, j=>n(1))
do i=1,1
do j=1,1
end do
end do
end associate
end
虽然x%i
和n(1)
不是名称,但是associate
构造确实创建了名称:
R803关联stmt为[关联构造名称:]关联
(协会名单)
R804关联是关联名称=>选择器
请注意,仅将关联实体作为变量是不够的
同样,如果有名称,则允许使用指针:
type t
integer i
end type
type(t), target :: x
integer, target :: n(1)
integer, pointer :: i, j
i => x%i
j => n(1)
do i=1,1
do j=1,1
end do
end do
end
同样,i
和j
这里是名字
出于兴趣,NAG编译器将使用指针和关联实体作为do变量标记为“可疑”。事实上,我们必须格外注意避免更改循环变量。我使用了ifort v 11.1和gfortran 4.5.1&4.8.3来编译上述代码。我会在简短的问题中添加错误信息,因为这主要是语法问题,您认为解决这个问题的最佳方法是什么?(例如,在手动递增时执行,为每一步分配数组,如果指针有效,则分配指针)这三项都将有效。选择哪一个是风格的问题,它将取决于特定的代码段。这就是我昨天回到这里后立即想知道的。不确定这里是否允许关联名称,但可能是,我就是找不到。是F2018:11.1.3.3.5关联实体本身是一个变量。。。与F2008相比,这更加明确和清晰。是的,当然,但我的疑问是存在的,它是否是一个变量。从F2008文本中看不清楚。