在fortran中使用数组成员作为do循环的控制变量 [英] Using array member as the control variable of do loop in fortran

查看:26
本文介绍了在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?

还是允许但我做错了?

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%in(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

同样,ij 是名称.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆