在fortran中使用数组成员作为do循环的控制变量 [英] Using array member as the control variable of do loop in fortran
问题描述
我很惊讶你不能像这样把一个数组成员作为循环的控制变量:
I was surprised that you cannot put a array member as the control variable of do loop like this:
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
我的问题是为什么不允许这样做?
My question is why it is not permitted?
还是允许但我做错了?
ifort v 11.1 的错误信息是:
The error message from ifort v 11.1 is:
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
----^
来自 gfortran V4.5.1 & 的错误消息4.8.3 是:
The error message from gfortran V4.5.1 & 4.8.3 is:
test.f90:4.4:
do i(1) = 1, 3
1
Error: Unclassifiable statement at (1)
test.f90:5.4:
do i(2) = 1, 3
1
Error: Unclassifiable statement at (1)
test.f90:8.7:
end do
1
Error: Expecting END PROGRAM statement at (1)
test.f90:9.7:
end do
1
Error: Expecting END PROGRAM statement at (1)
推荐答案
Vladimir F's answer 是正确的,但我们可以再强调一点.
Vladimir F's answer is correct, but we can stress a little more the pertinent point.
do 变量的引用语法规则是
The quoted syntax rule for the do variable is
R819 do-variable is scalar-int-variable-name
注意这意味着什么是非常重要的.
and it's very important to note exactly what this means.
do 变量当然必须是标量整型变量.在问题的情况下,数组元素 i(1)
(和 i(2)
)是一个标量整数变量:数组元素是 rank-0 的变量.
It is of course necessary for the do variable to be a scalar integer variable. In the case of the question the array element i(1)
(and i(2)
) is a scalar integer variable: array elements are variables of rank-0.
但是,name 是进一步的限制.i(1)
本身并不是一个名称.我们看到语法规则
However, name is a further restriction. i(1)
is not itself a name. We see the syntax rule
R303 名称 是 字母 [ 字母数字字符 ] ...
R303 name is letter [ alphanumeric-character ] ...
这种超出标量整数变量的限制超出了数组元素.此外,以下可能是没有对应名称的变量:
This restriction beyond scalar integer variable goes beyond array elements. In addition, the following may be variables which do not have corresponding names:
- 派生类型的组件;
- 具有指针结果的函数(Fortran 2008 中的变量,而不是之前的变量).
这意味着以下是不允许的:
This means that the following is not allowed:
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
<小时>
但是,如 chw21 的回答所述,使用关联构造是成功的:
However, as noted in chw21's answer there is success with using an associate construct:
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
构造确实会创建名称:
Although x%i
and n(1)
are not names, the associate
construct does create names:
R803 associate-stmt 是 [associate-construct-name :] ASSOCIATE(关联列表)
R803 associate-stmt is [associate-construct-name :] ASSOCIATE (association-list)
R804 关联 是 关联名称 => 选择器
R804 association is associate-name => selector
请注意,关联实体只是一个变量是不够的.
Note that the associate entity being simply a variable is not sufficient.
同样,指针是允许的,如果有名字的话:
Equally, pointers are allowed, if there is a name:
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
是名称.
Again, i
and j
here are names.
出于兴趣,NAG 编译器使用指针和关联实体将变量标记为有问题的".确实,必须格外小心以避免更改循环变量.
For interest, the NAG compiler marks using pointer and associate entities as do variables as "questionable". Indeed, one has to take extra care to avoid changing the loop variable.
这篇关于在fortran中使用数组成员作为do循环的控制变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!