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

查看:609
本文介绍了在Fortran中将数组成员用作do循环的控制变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

令我惊讶的是,您不能将数组成员作为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%in(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

再次

ij是名称.

出于兴趣,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天全站免登陆