问题
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