在Fortran中将数组成员用作do循环的控制变量 [英] Using array member as the control variable of do loop in fortran
问题描述
令我惊讶的是,您不能将数组成员作为do循环的控制变量,如下所示:
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?
修改: 还是允许,但我做错了?
Or is it permitted but I am doing wrong?
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)
推荐答案
弗拉基米尔F的答案是正确的,但我们可以再强调一点相关点.
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 是是 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.
但是,名称是进一步的限制. 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 :]关联 (关联列表)
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.
同样,如果有名称,也允许使用 pointers :
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
是名称.
出于兴趣,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屋!