How can I make the loop counter not be greater than the final value?

回眸只為那壹抹淺笑 提交于 2020-02-03 16:47:51

问题


So sample loop:

do i=1,1
    print *,i
enddo
print *,i

gives me 2 as the final value of i. How can I set up Intel Fortran for Visual Studio on Windows to give me a final value of 1 for i?


回答1:


You can't, because that's how DO works; it stops when the control variable exceeds the limit.

In general, in pretty much any language with a FOR/DO counting loop, you should only use the loop control variable inside the loop body, and treat it as undefined elsewhere, even if you can't actually limit its scope to the body.

In your case, I would use a different variable to keep track of the actual last value of i in any iteration:

lasti = 0
do i=1,1
   print *,i
   lasti = i
enddo
print *,lasti



回答2:


This has been the way that Fortran loops work for decades and you can't simply change this with a compiler option. The Fortran standard clearly states:

8.1.4.4.1 Loop initiation

(2) The DO variable becomes defined with the value of the initial parameter m1.

(3) The iteration count is established and is the value of the expression MAX (INT ((m2 – m1 + m3) / m3), 0)

Here m1, m2 and m3 are the three parameters in the loop-control: [,] var = m1,m2[,m3], Given your example of i=1,1 (m3 is implicitly 1 if omitted) the iteration count is MAX(INT((1-1+1)/1),0) which evaluates to 1, i.e. the loop should get executed once. i is initialised to 1 as per (2).

8.1.4.4.2 The execution cycle

The execution cycle of a DO construct consists of the following steps performed in sequence repeatedly until termination:

(1) The iteration count, if any, is tested. If the iteration count is zero, the loop terminates and the DO construct becomes inactive. If loop-control is [ , ] WHILE (scalar-logical-expr), the scalar-logicalexpr is evaluated; if the value of this expression is false, the loop terminates and the DO construct becomes inactive. If, as a result, all of the DO constructs sharing the do-term-shared-stmt are inactive, the execution of all of these constructs is complete. However, if some of the DO constructs sharing the do-term-shared-stmt are active, execution continues with step (3) of the execution cycle of the active DO construct whose DO statement was most recently executed.

Fortran tests if the remaining iteration count is greater than zero, not if the DO variable is less than (greater than) the end value.

(2) If the iteration count is nonzero, the range of the loop is executed.

(3) The iteration count, if any, is decremented by one. The DO variable, if any, is incremented by the value of the incrementation parameter m3.

The DO variable is always incremented as an iteration of the loop is being executed. Thus after the first execution i becomes incremented by 1 which evaluates to 2.

Except for the incrementation of the DO variable that occurs in step (3), the DO variable must neither be redefined nor become undefined while the DO construct is active.

8.1.4.4.4 Loop termination

When a DO construct becomes inactive, the DO-variable, if any, of the DO construct retains its last defined value.

The last defined value is 2. Thus after the DO loop has ended, i is equal to 2.

I've pulled the text out of ISO/IEC 1539:1991 (a.k.a. Fortran 90) but one can also find pretty much the same text in §11.10.3 of ISO/IEC 1539:1980 (a.k.a. ANSI X3J3/90.4 a.k.a. FORTRAN 77; sans the WHILE stuff which is not present in F77) as well as in §8.1.6.6 of ISO/IEC 1539-1:2010 (a.k.a. Fortran 2008).



来源:https://stackoverflow.com/questions/11874421/how-can-i-make-the-loop-counter-not-be-greater-than-the-final-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!