直观的答案是永远不会输入循环.在我能提出的所有测试中似乎都是这种情况.我仍然很焦虑,并且在进入循环之前总是测试它.
这有必要吗?
不,没有必要.
文件明确指出:
for counter:= initialValue to finalValue do statement
要么:
for counter:= initialValue downto finalValue do statement
...
如果initialValue等于finalValue,则语句只执行一次.如果在for ... to语句中initialValue大于finalValue,或者在for ... downto语句中小于finalValue,则语句永远不会执行.
没有必要焦虑.
如果我们想进一步研究会发生什么,让我们举几个例子.先考虑一下:
program Project1;
{$APPTYPE CONSOLE}
var
i : integer;
begin
for i := 2 to 1 do WriteLn(i);
end.
Run Code Online (Sandbox Code Playgroud)
这会产生一个编译器提示:
[dcc32提示] Project1.dpr(6):H2135 FOR或WHILE循环执行零次 - 删除
因此编译器将简单地抛弃一个循环,其中常量不会产生循环迭代.即使关闭了优化,它也会这样做 - 根本不会为循环生成任何代码.
现在让我们更聪明一点:
program Project1;
{$APPTYPE CONSOLE}
var
i, j, k : integer;
begin
j := 2;
k := 1;
for i := j to k do WriteLn(i);
end.
Run Code Online (Sandbox Code Playgroud)
这实际上编译了循环.输出如下:
Project1.dpr.8: for i := j to k do WriteLn(i);
004060E8 A1A4AB4000 mov eax,[$0040aba4] {$0040aba4 -> j = 2}
004060ED 8B15A8AB4000 mov edx,[$0040aba8] {$0040aba8 -> k = 1}
004060F3 2BD0 sub edx,eax {edx = k - j = -1}
004060F5 7C2E jl $00406125 {was k-j < 0? if yes, jmp to end.}
004060F7 42 inc edx {set up loop}
004060F8 8955EC mov [ebp-$14],edx
004060FB A3A0AB4000 mov [$0040aba0],eax
00406100 A118784000 mov eax,[$00407818] {actual looped section}
00406105 8B15A0AB4000 mov edx,[$0040aba0]
0040610B E8E8D6FFFF call @Write0Long
00406110 E8C3D9FFFF call @WriteLn
00406115 E8EECCFFFF call @_IOTest
0040611A FF05A0AB4000 inc dword ptr [$0040aba0] {update loop var}
00406120 FF4DEC dec dword ptr [ebp-$14]
00406123 75DB jnz $00406100 {loop ^ if not complete}
Project1.dpr.9: end.
00406125 E88EE1FFFF call @Halt0
Run Code Online (Sandbox Code Playgroud)
所以,循环的第一件事就是检查它是否需要执行.如果初始值大于最终值(对于for..to循环),则它会完全跳过它.它甚至不会浪费周期来初始化循环计数器.